Whamcloud - gitweb
LU-16335 mdt: skip target check for rm_entry
[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 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
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 411
63 fi
64
65 #                                  5              12     8   12  15   (min)"
66 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
67
68 if [ "$mds1_FSTYPE" = "zfs" ]; then
69         #                                               13    (min)"
70         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
71 fi
72
73 if [ "$ost1_FSTYPE" = "zfs" ]; then
74         always_except LU-1941 130b 130c 130d 130e 130f 130g
75 fi
76
77 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
78
79 # Get the SLES distro version
80 #
81 # Returns a version string that should only be used in comparing
82 # strings returned by version_code()
83 sles_version_code()
84 {
85         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
86
87         # All SuSE Linux versions have one decimal. version_code expects two
88         local sles_version=$version.0
89         version_code $sles_version
90 }
91
92 # Check if we are running on Ubuntu or SLES so we can make decisions on
93 # what tests to run
94 if [ -r /etc/SuSE-release ]; then
95         sles_version=$(sles_version_code)
96         [ $sles_version -lt $(version_code 11.4.0) ] &&
97                 always_except LU-4341 170
98
99         [ $sles_version -lt $(version_code 12.0.0) ] &&
100                 always_except LU-3703 234
101 elif [ -r /etc/os-release ]; then
102         if grep -qi ubuntu /etc/os-release; then
103                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
104                                                 -e 's/^VERSION=//p' \
105                                                 /etc/os-release |
106                                                 awk '{ print $1 }'))
107
108                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
109                         always_except LU-10366 410
110                 fi
111         fi
112 fi
113
114 build_test_filter
115 FAIL_ON_ERROR=false
116
117 cleanup() {
118         echo -n "cln.."
119         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
120         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
121 }
122 setup() {
123         echo -n "mnt.."
124         load_modules
125         setupall || exit 10
126         echo "done"
127 }
128
129 check_swap_layouts_support()
130 {
131         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
132                 skip "Does not support layout lock."
133 }
134
135 check_swap_layout_no_dom()
136 {
137         local FOLDER=$1
138         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
139         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
140 }
141
142 check_and_setup_lustre
143 DIR=${DIR:-$MOUNT}
144 assert_DIR
145
146 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
147
148 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
149 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
150 rm -rf $DIR/[Rdfs][0-9]*
151
152 # $RUNAS_ID may get set incorrectly somewhere else
153 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
154         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
155
156 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
157
158 if [ "${ONLY}" = "MOUNT" ] ; then
159         echo "Lustre is up, please go on"
160         exit
161 fi
162
163 echo "preparing for tests involving mounts"
164 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
165 touch $EXT2_DEV
166 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
167 echo # add a newline after mke2fs.
168
169 umask 077
170
171 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
172 lctl set_param debug=-1 2> /dev/null || true
173 test_0a() {
174         touch $DIR/$tfile
175         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
176         rm $DIR/$tfile
177         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
178 }
179 run_test 0a "touch; rm ====================="
180
181 test_0b() {
182         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
183         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
184 }
185 run_test 0b "chmod 0755 $DIR ============================="
186
187 test_0c() {
188         $LCTL get_param mdc.*.import | grep "state: FULL" ||
189                 error "import not FULL"
190         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
191                 error "bad target"
192 }
193 run_test 0c "check import proc"
194
195 test_0d() { # LU-3397
196         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
197                 skip "proc exports not supported before 2.10.57"
198
199         local mgs_exp="mgs.MGS.exports"
200         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
201         local exp_client_nid
202         local exp_client_version
203         local exp_val
204         local imp_val
205         local temp_imp=$DIR/$tfile.import
206         local temp_exp=$DIR/$tfile.export
207
208         # save mgc import file to $temp_imp
209         $LCTL get_param mgc.*.import | tee $temp_imp
210         # Check if client uuid is found in MGS export
211         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
212                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
213                         $client_uuid ] &&
214                         break;
215         done
216         # save mgs export file to $temp_exp
217         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
218
219         # Compare the value of field "connect_flags"
220         imp_val=$(grep "connect_flags" $temp_imp)
221         exp_val=$(grep "connect_flags" $temp_exp)
222         [ "$exp_val" == "$imp_val" ] ||
223                 error "export flags '$exp_val' != import flags '$imp_val'"
224
225         # Compare client versions.  Only compare top-3 fields for compatibility
226         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
227         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
228         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "exp version '$exp_client_version'($exp_val) != " \
231                         "'$(lustre_build_version client)'($imp_val)"
232 }
233 run_test 0d "check export proc ============================="
234
235 test_0e() { # LU-13417
236         (( $MDSCOUNT > 1 )) ||
237                 skip "We need at least 2 MDTs for this test"
238
239         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
240                 skip "Need server version at least 2.14.51"
241
242         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
243         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
244
245         [ $default_lmv_count -eq 1 ] ||
246                 error "$MOUNT default stripe count $default_lmv_count"
247
248         [ $default_lmv_index -eq -1 ] ||
249                 error "$MOUNT default stripe index $default_lmv_index"
250
251         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
252         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
253
254         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
255         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
256
257         [ $mdt_index1 -eq $mdt_index2 ] &&
258                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
259
260         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
261 }
262 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
263
264 test_1() {
265         test_mkdir $DIR/$tdir
266         test_mkdir $DIR/$tdir/d2
267         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
268         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
269         rmdir $DIR/$tdir/d2
270         rmdir $DIR/$tdir
271         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
272 }
273 run_test 1 "mkdir; remkdir; rmdir"
274
275 test_2() {
276         test_mkdir $DIR/$tdir
277         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
281 }
282 run_test 2 "mkdir; touch; rmdir; check file"
283
284 test_3() {
285         test_mkdir $DIR/$tdir
286         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
287         touch $DIR/$tdir/$tfile
288         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
289         rm -r $DIR/$tdir
290         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
291 }
292 run_test 3 "mkdir; touch; rmdir; check dir"
293
294 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
295 test_4() {
296         test_mkdir -i 1 $DIR/$tdir
297
298         touch $DIR/$tdir/$tfile ||
299                 error "Create file under remote directory failed"
300
301         rmdir $DIR/$tdir &&
302                 error "Expect error removing in-use dir $DIR/$tdir"
303
304         test -d $DIR/$tdir || error "Remote directory disappeared"
305
306         rm -rf $DIR/$tdir || error "remove remote dir error"
307 }
308 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
309
310 test_5() {
311         test_mkdir $DIR/$tdir
312         test_mkdir $DIR/$tdir/d2
313         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
314         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
315         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
316 }
317 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
318
319 test_6a() {
320         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
321         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
322         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
323                 error "$tfile does not have perm 0666 or UID $UID"
324         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
325         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
326                 error "$tfile should be 0666 and owned by UID $UID"
327 }
328 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
329
330 test_6c() {
331         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
332
333         touch $DIR/$tfile
334         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
335         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
336                 error "$tfile should be owned by UID $RUNAS_ID"
337         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
338         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by UID $RUNAS_ID"
340 }
341 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
342
343 test_6e() {
344         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
345
346         touch $DIR/$tfile
347         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
348         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
349                 error "$tfile should be owned by GID $UID"
350         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
351         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
352                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
353 }
354 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
355
356 test_6g() {
357         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
358
359         test_mkdir $DIR/$tdir
360         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
361         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
362         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
363         test_mkdir $DIR/$tdir/d/subdir
364         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
365                 error "$tdir/d/subdir should be GID $RUNAS_GID"
366         if [[ $MDSCOUNT -gt 1 ]]; then
367                 # check remote dir sgid inherite
368                 $LFS mkdir -i 0 $DIR/$tdir.local ||
369                         error "mkdir $tdir.local failed"
370                 chmod g+s $DIR/$tdir.local ||
371                         error "chmod $tdir.local failed"
372                 chgrp $RUNAS_GID $DIR/$tdir.local ||
373                         error "chgrp $tdir.local failed"
374                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
375                         error "mkdir $tdir.remote failed"
376                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
377                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
378                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
379                         error "$tdir.remote should be mode 02755"
380         fi
381 }
382 run_test 6g "verify new dir in sgid dir inherits group"
383
384 test_6h() { # bug 7331
385         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
386
387         touch $DIR/$tfile || error "touch failed"
388         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
389         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
390                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
391         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
392                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
393 }
394 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
395
396 test_7a() {
397         test_mkdir $DIR/$tdir
398         $MCREATE $DIR/$tdir/$tfile
399         chmod 0666 $DIR/$tdir/$tfile
400         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
401                 error "$tdir/$tfile should be mode 0666"
402 }
403 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
404
405 test_7b() {
406         if [ ! -d $DIR/$tdir ]; then
407                 test_mkdir $DIR/$tdir
408         fi
409         $MCREATE $DIR/$tdir/$tfile
410         echo -n foo > $DIR/$tdir/$tfile
411         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
412         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
413 }
414 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
415
416 test_8() {
417         test_mkdir $DIR/$tdir
418         touch $DIR/$tdir/$tfile
419         chmod 0666 $DIR/$tdir/$tfile
420         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
421                 error "$tfile mode not 0666"
422 }
423 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
424
425 test_9() {
426         test_mkdir $DIR/$tdir
427         test_mkdir $DIR/$tdir/d2
428         test_mkdir $DIR/$tdir/d2/d3
429         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
430 }
431 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
432
433 test_10() {
434         test_mkdir $DIR/$tdir
435         test_mkdir $DIR/$tdir/d2
436         touch $DIR/$tdir/d2/$tfile
437         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
438                 error "$tdir/d2/$tfile not a file"
439 }
440 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
441
442 test_11() {
443         test_mkdir $DIR/$tdir
444         test_mkdir $DIR/$tdir/d2
445         chmod 0666 $DIR/$tdir/d2
446         chmod 0705 $DIR/$tdir/d2
447         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
448                 error "$tdir/d2 mode not 0705"
449 }
450 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
451
452 test_12() {
453         test_mkdir $DIR/$tdir
454         touch $DIR/$tdir/$tfile
455         chmod 0666 $DIR/$tdir/$tfile
456         chmod 0654 $DIR/$tdir/$tfile
457         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
458                 error "$tdir/d2 mode not 0654"
459 }
460 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
461
462 test_13() {
463         test_mkdir $DIR/$tdir
464         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
465         >  $DIR/$tdir/$tfile
466         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
467                 error "$tdir/$tfile size not 0 after truncate"
468 }
469 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
470
471 test_14() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
478
479 test_15() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
483         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
484                 error "$tdir/${tfile_2} not a file after rename"
485         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
486 }
487 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
488
489 test_16() {
490         test_mkdir $DIR/$tdir
491         touch $DIR/$tdir/$tfile
492         rm -rf $DIR/$tdir/$tfile
493         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
494 }
495 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
496
497 test_17a() {
498         test_mkdir $DIR/$tdir
499         touch $DIR/$tdir/$tfile
500         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
501         ls -l $DIR/$tdir
502         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
503                 error "$tdir/l-exist not a symlink"
504         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
505                 error "$tdir/l-exist not referencing a file"
506         rm -f $DIR/$tdir/l-exist
507         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
508 }
509 run_test 17a "symlinks: create, remove (real)"
510
511 test_17b() {
512         test_mkdir $DIR/$tdir
513         ln -s no-such-file $DIR/$tdir/l-dangle
514         ls -l $DIR/$tdir
515         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
516                 error "$tdir/l-dangle not referencing no-such-file"
517         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
518                 error "$tdir/l-dangle not referencing non-existent file"
519         rm -f $DIR/$tdir/l-dangle
520         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
521 }
522 run_test 17b "symlinks: create, remove (dangling)"
523
524 test_17c() { # bug 3440 - don't save failed open RPC for replay
525         test_mkdir $DIR/$tdir
526         ln -s foo $DIR/$tdir/$tfile
527         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
528 }
529 run_test 17c "symlinks: open dangling (should return error)"
530
531 test_17d() {
532         test_mkdir $DIR/$tdir
533         ln -s foo $DIR/$tdir/$tfile
534         touch $DIR/$tdir/$tfile || error "creating to new symlink"
535 }
536 run_test 17d "symlinks: create dangling"
537
538 test_17e() {
539         test_mkdir $DIR/$tdir
540         local foo=$DIR/$tdir/$tfile
541         ln -s $foo $foo || error "create symlink failed"
542         ls -l $foo || error "ls -l failed"
543         ls $foo && error "ls not failed" || true
544 }
545 run_test 17e "symlinks: create recursive symlink (should return error)"
546
547 test_17f() {
548         test_mkdir $DIR/$tdir
549         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
550         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
554         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
555         ls -l  $DIR/$tdir
556 }
557 run_test 17f "symlinks: long and very long symlink name"
558
559 # str_repeat(S, N) generate a string that is string S repeated N times
560 str_repeat() {
561         local s=$1
562         local n=$2
563         local ret=''
564         while [ $((n -= 1)) -ge 0 ]; do
565                 ret=$ret$s
566         done
567         echo $ret
568 }
569
570 # Long symlinks and LU-2241
571 test_17g() {
572         test_mkdir $DIR/$tdir
573         local TESTS="59 60 61 4094 4095"
574
575         # Fix for inode size boundary in 2.1.4
576         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
577                 TESTS="4094 4095"
578
579         # Patch not applied to 2.2 or 2.3 branches
580         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
581         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
582                 TESTS="4094 4095"
583
584         for i in $TESTS; do
585                 local SYMNAME=$(str_repeat 'x' $i)
586                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
587                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
588         done
589 }
590 run_test 17g "symlinks: really long symlink name and inode boundaries"
591
592 test_17h() { #bug 17378
593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
594         remote_mds_nodsh && skip "remote MDS with nodsh"
595
596         local mdt_idx
597
598         test_mkdir $DIR/$tdir
599         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
600         $LFS setstripe -c -1 $DIR/$tdir
601         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
602         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
603         touch $DIR/$tdir/$tfile || true
604 }
605 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
606
607 test_17i() { #bug 20018
608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
609         remote_mds_nodsh && skip "remote MDS with nodsh"
610
611         local foo=$DIR/$tdir/$tfile
612         local mdt_idx
613
614         test_mkdir -c1 $DIR/$tdir
615         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
616         ln -s $foo $foo || error "create symlink failed"
617 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
618         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
619         ls -l $foo && error "error not detected"
620         return 0
621 }
622 run_test 17i "don't panic on short symlink (should return error)"
623
624 test_17k() { #bug 22301
625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
626         [[ -z "$(which rsync 2>/dev/null)" ]] &&
627                 skip "no rsync command"
628         rsync --help | grep -q xattr ||
629                 skip_env "$(rsync --version | head -n1) does not support xattrs"
630         test_mkdir $DIR/$tdir
631         test_mkdir $DIR/$tdir.new
632         touch $DIR/$tdir/$tfile
633         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
634         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
635                 error "rsync failed with xattrs enabled"
636 }
637 run_test 17k "symlinks: rsync with xattrs enabled"
638
639 test_17l() { # LU-279
640         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
641                 skip "no getfattr command"
642
643         test_mkdir $DIR/$tdir
644         touch $DIR/$tdir/$tfile
645         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
646         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
647                 # -h to not follow symlinks. -m '' to list all the xattrs.
648                 # grep to remove first line: '# file: $path'.
649                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
650                 do
651                         lgetxattr_size_check $path $xattr ||
652                                 error "lgetxattr_size_check $path $xattr failed"
653                 done
654         done
655 }
656 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
657
658 # LU-1540
659 test_17m() {
660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
661         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
662         remote_mds_nodsh && skip "remote MDS with nodsh"
663         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
664         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
665                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
666
667         local short_sym="0123456789"
668         local wdir=$DIR/$tdir
669         local i
670
671         test_mkdir $wdir
672         long_sym=$short_sym
673         # create a long symlink file
674         for ((i = 0; i < 4; ++i)); do
675                 long_sym=${long_sym}${long_sym}
676         done
677
678         echo "create 512 short and long symlink files under $wdir"
679         for ((i = 0; i < 256; ++i)); do
680                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
681                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
682         done
683
684         echo "erase them"
685         rm -f $wdir/*
686         sync
687         wait_delete_completed
688
689         echo "recreate the 512 symlink files with a shorter string"
690         for ((i = 0; i < 512; ++i)); do
691                 # rewrite the symlink file with a shorter string
692                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
693                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
694         done
695
696         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
697
698         echo "stop and checking mds${mds_index}:"
699         # e2fsck should not return error
700         stop mds${mds_index}
701         local devname=$(mdsdevname $mds_index)
702         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
703         rc=$?
704
705         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
706                 error "start mds${mds_index} failed"
707         df $MOUNT > /dev/null 2>&1
708         [ $rc -eq 0 ] ||
709                 error "e2fsck detected error for short/long symlink: rc=$rc"
710         rm -f $wdir/*
711 }
712 run_test 17m "run e2fsck against MDT which contains short/long symlink"
713
714 check_fs_consistency_17n() {
715         local mdt_index
716         local rc=0
717
718         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
719         # so it only check MDT1/MDT2 instead of all of MDTs.
720         for mdt_index in 1 2; do
721                 # e2fsck should not return error
722                 stop mds${mdt_index}
723                 local devname=$(mdsdevname $mdt_index)
724                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
725                         rc=$((rc + $?))
726
727                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
728                         error "mount mds$mdt_index failed"
729                 df $MOUNT > /dev/null 2>&1
730         done
731         return $rc
732 }
733
734 test_17n() {
735         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
737         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
738         remote_mds_nodsh && skip "remote MDS with nodsh"
739         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
740         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
741                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
742
743         local i
744
745         test_mkdir $DIR/$tdir
746         for ((i=0; i<10; i++)); do
747                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
748                         error "create remote dir error $i"
749                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
750                         error "create files under remote dir failed $i"
751         done
752
753         check_fs_consistency_17n ||
754                 error "e2fsck report error after create files under remote dir"
755
756         for ((i = 0; i < 10; i++)); do
757                 rm -rf $DIR/$tdir/remote_dir_${i} ||
758                         error "destroy remote dir error $i"
759         done
760
761         check_fs_consistency_17n ||
762                 error "e2fsck report error after unlink files under remote dir"
763
764         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
765                 skip "lustre < 2.4.50 does not support migrate mv"
766
767         for ((i = 0; i < 10; i++)); do
768                 mkdir -p $DIR/$tdir/remote_dir_${i}
769                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
770                         error "create files under remote dir failed $i"
771                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
772                         error "migrate remote dir error $i"
773         done
774         check_fs_consistency_17n || error "e2fsck report error after migration"
775
776         for ((i = 0; i < 10; i++)); do
777                 rm -rf $DIR/$tdir/remote_dir_${i} ||
778                         error "destroy remote dir error $i"
779         done
780
781         check_fs_consistency_17n || error "e2fsck report error after unlink"
782 }
783 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
784
785 test_17o() {
786         remote_mds_nodsh && skip "remote MDS with nodsh"
787         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
788                 skip "Need MDS version at least 2.3.64"
789
790         local wdir=$DIR/${tdir}o
791         local mdt_index
792         local rc=0
793
794         test_mkdir $wdir
795         touch $wdir/$tfile
796         mdt_index=$($LFS getstripe -m $wdir/$tfile)
797         mdt_index=$((mdt_index + 1))
798
799         cancel_lru_locks mdc
800         #fail mds will wait the failover finish then set
801         #following fail_loc to avoid interfer the recovery process.
802         fail mds${mdt_index}
803
804         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
805         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
806         ls -l $wdir/$tfile && rc=1
807         do_facet mds${mdt_index} lctl set_param fail_loc=0
808         [[ $rc -eq 0 ]] || error "stat file should fail"
809 }
810 run_test 17o "stat file with incompat LMA feature"
811
812 test_18() {
813         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
814         ls $DIR || error "Failed to ls $DIR: $?"
815 }
816 run_test 18 "touch .../f ; ls ... =============================="
817
818 test_19a() {
819         touch $DIR/$tfile
820         ls -l $DIR
821         rm $DIR/$tfile
822         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
823 }
824 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
825
826 test_19b() {
827         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
828 }
829 run_test 19b "ls -l .../f19 (should return error) =============="
830
831 test_19c() {
832         [ $RUNAS_ID -eq $UID ] &&
833                 skip_env "RUNAS_ID = UID = $UID -- skipping"
834
835         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
836 }
837 run_test 19c "$RUNAS touch .../f19 (should return error) =="
838
839 test_19d() {
840         cat $DIR/f19 && error || true
841 }
842 run_test 19d "cat .../f19 (should return error) =============="
843
844 test_20() {
845         touch $DIR/$tfile
846         rm $DIR/$tfile
847         touch $DIR/$tfile
848         rm $DIR/$tfile
849         touch $DIR/$tfile
850         rm $DIR/$tfile
851         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
852 }
853 run_test 20 "touch .../f ; ls -l ..."
854
855 test_21() {
856         test_mkdir $DIR/$tdir
857         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
858         ln -s dangle $DIR/$tdir/link
859         echo foo >> $DIR/$tdir/link
860         cat $DIR/$tdir/dangle
861         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
862         $CHECKSTAT -f -t file $DIR/$tdir/link ||
863                 error "$tdir/link not linked to a file"
864 }
865 run_test 21 "write to dangling link"
866
867 test_22() {
868         local wdir=$DIR/$tdir
869         test_mkdir $wdir
870         chown $RUNAS_ID:$RUNAS_GID $wdir
871         (cd $wdir || error "cd $wdir failed";
872                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
873                 $RUNAS tar xf -)
874         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
875         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
876         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
877                 error "checkstat -u failed"
878 }
879 run_test 22 "unpack tar archive as non-root user"
880
881 # was test_23
882 test_23a() {
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
887         openfile -f O_CREAT:O_EXCL $file &&
888                 error "$file recreate succeeded" || true
889 }
890 run_test 23a "O_CREAT|O_EXCL in subdir"
891
892 test_23b() { # bug 18988
893         test_mkdir $DIR/$tdir
894         local file=$DIR/$tdir/$tfile
895
896         rm -f $file
897         echo foo > $file || error "write filed"
898         echo bar >> $file || error "append filed"
899         $CHECKSTAT -s 8 $file || error "wrong size"
900         rm $file
901 }
902 run_test 23b "O_APPEND check"
903
904 # LU-9409, size with O_APPEND and tiny writes
905 test_23c() {
906         local file=$DIR/$tfile
907
908         # single dd
909         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
910         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
911         rm -f $file
912
913         # racing tiny writes
914         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         wait
917         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
918         rm -f $file
919
920         #racing tiny & normal writes
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
923         wait
924         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
925         rm -f $file
926
927         #racing tiny & normal writes 2, ugly numbers
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
930         wait
931         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
932         rm -f $file
933 }
934 run_test 23c "O_APPEND size checks for tiny writes"
935
936 # LU-11069 file offset is correct after appending writes
937 test_23d() {
938         local file=$DIR/$tfile
939         local offset
940
941         echo CentaurHauls > $file
942         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
943         if ((offset != 26)); then
944                 error "wrong offset, expected 26, got '$offset'"
945         fi
946 }
947 run_test 23d "file offset is correct after appending writes"
948
949 # rename sanity
950 test_24a() {
951         echo '-- same directory rename'
952         test_mkdir $DIR/$tdir
953         touch $DIR/$tdir/$tfile.1
954         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
955         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
956 }
957 run_test 24a "rename file to non-existent target"
958
959 test_24b() {
960         test_mkdir $DIR/$tdir
961         touch $DIR/$tdir/$tfile.{1,2}
962         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
963         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
964         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
965 }
966 run_test 24b "rename file to existing target"
967
968 test_24c() {
969         test_mkdir $DIR/$tdir
970         test_mkdir $DIR/$tdir/d$testnum.1
971         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24c "rename directory to non-existent target"
976
977 test_24d() {
978         test_mkdir -c1 $DIR/$tdir
979         test_mkdir -c1 $DIR/$tdir/d$testnum.1
980         test_mkdir -c1 $DIR/$tdir/d$testnum.2
981         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
982         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
983         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
984 }
985 run_test 24d "rename directory to existing target"
986
987 test_24e() {
988         echo '-- cross directory renames --'
989         test_mkdir $DIR/R5a
990         test_mkdir $DIR/R5b
991         touch $DIR/R5a/f
992         mv $DIR/R5a/f $DIR/R5b/g
993         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
994         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
995 }
996 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
997
998 test_24f() {
999         test_mkdir $DIR/R6a
1000         test_mkdir $DIR/R6b
1001         touch $DIR/R6a/f $DIR/R6b/g
1002         mv $DIR/R6a/f $DIR/R6b/g
1003         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1004         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1005 }
1006 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1007
1008 test_24g() {
1009         test_mkdir $DIR/R7a
1010         test_mkdir $DIR/R7b
1011         test_mkdir $DIR/R7a/d
1012         mv $DIR/R7a/d $DIR/R7b/e
1013         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1014         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1015 }
1016 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1017
1018 test_24h() {
1019         test_mkdir -c1 $DIR/R8a
1020         test_mkdir -c1 $DIR/R8b
1021         test_mkdir -c1 $DIR/R8a/d
1022         test_mkdir -c1 $DIR/R8b/e
1023         mrename $DIR/R8a/d $DIR/R8b/e
1024         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1025         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1026 }
1027 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1028
1029 test_24i() {
1030         echo "-- rename error cases"
1031         test_mkdir $DIR/R9
1032         test_mkdir $DIR/R9/a
1033         touch $DIR/R9/f
1034         mrename $DIR/R9/f $DIR/R9/a
1035         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1036         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1037         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1038 }
1039 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1040
1041 test_24j() {
1042         test_mkdir $DIR/R10
1043         mrename $DIR/R10/f $DIR/R10/g
1044         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1045         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1046         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1047 }
1048 run_test 24j "source does not exist ============================"
1049
1050 test_24k() {
1051         test_mkdir $DIR/R11a
1052         test_mkdir $DIR/R11a/d
1053         touch $DIR/R11a/f
1054         mv $DIR/R11a/f $DIR/R11a/d
1055         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1056         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1057 }
1058 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1059
1060 # bug 2429 - rename foo foo foo creates invalid file
1061 test_24l() {
1062         f="$DIR/f24l"
1063         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1064 }
1065 run_test 24l "Renaming a file to itself ========================"
1066
1067 test_24m() {
1068         f="$DIR/f24m"
1069         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1070         # on ext3 this does not remove either the source or target files
1071         # though the "expected" operation would be to remove the source
1072         $CHECKSTAT -t file ${f} || error "${f} missing"
1073         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1074 }
1075 run_test 24m "Renaming a file to a hard link to itself ========="
1076
1077 test_24n() {
1078     f="$DIR/f24n"
1079     # this stats the old file after it was renamed, so it should fail
1080     touch ${f}
1081     $CHECKSTAT ${f} || error "${f} missing"
1082     mv ${f} ${f}.rename
1083     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1084     $CHECKSTAT -a ${f} || error "${f} exists"
1085 }
1086 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1087
1088 test_24o() {
1089         test_mkdir $DIR/$tdir
1090         rename_many -s random -v -n 10 $DIR/$tdir
1091 }
1092 run_test 24o "rename of files during htree split"
1093
1094 test_24p() {
1095         test_mkdir $DIR/R12a
1096         test_mkdir $DIR/R12b
1097         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1098         mrename $DIR/R12a $DIR/R12b
1099         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1100         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1101         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1102         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1103 }
1104 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1105
1106 cleanup_multiop_pause() {
1107         trap 0
1108         kill -USR1 $MULTIPID
1109 }
1110
1111 test_24q() {
1112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1113
1114         test_mkdir $DIR/R13a
1115         test_mkdir $DIR/R13b
1116         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1117         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1118         MULTIPID=$!
1119
1120         trap cleanup_multiop_pause EXIT
1121         mrename $DIR/R13a $DIR/R13b
1122         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1123         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1124         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1125         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1126         cleanup_multiop_pause
1127         wait $MULTIPID || error "multiop close failed"
1128 }
1129 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1130
1131 test_24r() { #bug 3789
1132         test_mkdir $DIR/R14a
1133         test_mkdir $DIR/R14a/b
1134         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1136         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1137 }
1138 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1139
1140 test_24s() {
1141         test_mkdir $DIR/R15a
1142         test_mkdir $DIR/R15a/b
1143         test_mkdir $DIR/R15a/b/c
1144         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1145         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1146         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1147 }
1148 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1149
1150 test_24t() {
1151         test_mkdir $DIR/R16a
1152         test_mkdir $DIR/R16a/b
1153         test_mkdir $DIR/R16a/b/c
1154         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1155         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1156         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1157 }
1158 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1159
1160 test_24u() { # bug12192
1161         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1162         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1163 }
1164 run_test 24u "create stripe file"
1165
1166 simple_cleanup_common() {
1167         local createmany=$1
1168         local rc=0
1169
1170         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1171
1172         local start=$SECONDS
1173
1174         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1175         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1176         rc=$?
1177         wait_delete_completed
1178         echo "cleanup time $((SECONDS - start))"
1179         return $rc
1180 }
1181
1182 max_pages_per_rpc() {
1183         local mdtname="$(printf "MDT%04x" ${1:-0})"
1184         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1185 }
1186
1187 test_24v() {
1188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1189
1190         local nrfiles=${COUNT:-100000}
1191         local fname="$DIR/$tdir/$tfile"
1192
1193         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1194         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1195
1196         test_mkdir "$(dirname $fname)"
1197         # assume MDT0000 has the fewest inodes
1198         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1199         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1200         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1201
1202         stack_trap "simple_cleanup_common $nrfiles"
1203
1204         createmany -m "$fname" $nrfiles
1205
1206         cancel_lru_locks mdc
1207         lctl set_param mdc.*.stats clear
1208
1209         # was previously test_24D: LU-6101
1210         # readdir() returns correct number of entries after cursor reload
1211         local num_ls=$(ls $DIR/$tdir | wc -l)
1212         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1213         local num_all=$(ls -a $DIR/$tdir | wc -l)
1214         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1215                 [ $num_all -ne $((nrfiles + 2)) ]; then
1216                         error "Expected $nrfiles files, got $num_ls " \
1217                                 "($num_uniq unique $num_all .&..)"
1218         fi
1219         # LU-5 large readdir
1220         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1221         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1222         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1223         # take into account of overhead in lu_dirpage header and end mark in
1224         # each page, plus one in rpc_num calculation.
1225         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1226         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1227         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1228         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1229         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1230         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1231         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1232         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1233                 error "large readdir doesn't take effect: " \
1234                       "$mds_readpage should be about $rpc_max"
1235 }
1236 run_test 24v "list large directory (test hash collision, b=17560)"
1237
1238 test_24w() { # bug21506
1239         SZ1=234852
1240         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1241         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1242         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1243         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1244         [[ "$SZ1" -eq "$SZ2" ]] ||
1245                 error "Error reading at the end of the file $tfile"
1246 }
1247 run_test 24w "Reading a file larger than 4Gb"
1248
1249 test_24x() {
1250         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1252         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1253                 skip "Need MDS version at least 2.7.56"
1254
1255         local MDTIDX=1
1256         local remote_dir=$DIR/$tdir/remote_dir
1257
1258         test_mkdir $DIR/$tdir
1259         $LFS mkdir -i $MDTIDX $remote_dir ||
1260                 error "create remote directory failed"
1261
1262         test_mkdir $DIR/$tdir/src_dir
1263         touch $DIR/$tdir/src_file
1264         test_mkdir $remote_dir/tgt_dir
1265         touch $remote_dir/tgt_file
1266
1267         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1268                 error "rename dir cross MDT failed!"
1269
1270         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1271                 error "rename file cross MDT failed!"
1272
1273         touch $DIR/$tdir/ln_file
1274         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1275                 error "ln file cross MDT failed"
1276
1277         rm -rf $DIR/$tdir || error "Can not delete directories"
1278 }
1279 run_test 24x "cross MDT rename/link"
1280
1281 test_24y() {
1282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1284
1285         local remote_dir=$DIR/$tdir/remote_dir
1286         local mdtidx=1
1287
1288         test_mkdir $DIR/$tdir
1289         $LFS mkdir -i $mdtidx $remote_dir ||
1290                 error "create remote directory failed"
1291
1292         test_mkdir $remote_dir/src_dir
1293         touch $remote_dir/src_file
1294         test_mkdir $remote_dir/tgt_dir
1295         touch $remote_dir/tgt_file
1296
1297         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1298                 error "rename subdir in the same remote dir failed!"
1299
1300         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1301                 error "rename files in the same remote dir failed!"
1302
1303         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1304                 error "link files in the same remote dir failed!"
1305
1306         rm -rf $DIR/$tdir || error "Can not delete directories"
1307 }
1308 run_test 24y "rename/link on the same dir should succeed"
1309
1310 test_24z() {
1311         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1312         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1313                 skip "Need MDS version at least 2.12.51"
1314
1315         local index
1316
1317         for index in 0 1; do
1318                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1319                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1320         done
1321
1322         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1323
1324         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1325         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1326
1327         local mdts=$(comma_list $(mdts_nodes))
1328
1329         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1330         stack_trap "do_nodes $mdts $LCTL \
1331                 set_param mdt.*.enable_remote_rename=1" EXIT
1332
1333         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1334
1335         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1336         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1337 }
1338 run_test 24z "cross-MDT rename is done as cp"
1339
1340 test_24A() { # LU-3182
1341         local NFILES=5000
1342
1343         test_mkdir $DIR/$tdir
1344         stack_trap "simple_cleanup_common $NFILES"
1345         createmany -m $DIR/$tdir/$tfile $NFILES
1346         local t=$(ls $DIR/$tdir | wc -l)
1347         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1348         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1349
1350         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1351                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1352 }
1353 run_test 24A "readdir() returns correct number of entries."
1354
1355 test_24B() { # LU-4805
1356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1357
1358         local count
1359
1360         test_mkdir $DIR/$tdir
1361         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1362                 error "create striped dir failed"
1363
1364         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1365         [ $count -eq 2 ] || error "Expected 2, got $count"
1366
1367         touch $DIR/$tdir/striped_dir/a
1368
1369         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1370         [ $count -eq 3 ] || error "Expected 3, got $count"
1371
1372         touch $DIR/$tdir/striped_dir/.f
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 4 ] || error "Expected 4, got $count"
1376
1377         rm -rf $DIR/$tdir || error "Can not delete directories"
1378 }
1379 run_test 24B "readdir for striped dir return correct number of entries"
1380
1381 test_24C() {
1382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1383
1384         mkdir $DIR/$tdir
1385         mkdir $DIR/$tdir/d0
1386         mkdir $DIR/$tdir/d1
1387
1388         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1389                 error "create striped dir failed"
1390
1391         cd $DIR/$tdir/d0/striped_dir
1392
1393         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1394         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1395         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d0_ino" = "$parent_ino" ] ||
1398                 error ".. wrong, expect $d0_ino, get $parent_ino"
1399
1400         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1401                 error "mv striped dir failed"
1402
1403         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1404
1405         [ "$d1_ino" = "$parent_ino" ] ||
1406                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1407 }
1408 run_test 24C "check .. in striped dir"
1409
1410 test_24E() {
1411         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1413
1414         mkdir -p $DIR/$tdir
1415         mkdir $DIR/$tdir/src_dir
1416         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1417                 error "create remote source failed"
1418
1419         touch $DIR/$tdir/src_dir/src_child/a
1420
1421         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1422                 error "create remote target dir failed"
1423
1424         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1425                 error "create remote target child failed"
1426
1427         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1428                 error "rename dir cross MDT failed!"
1429
1430         find $DIR/$tdir
1431
1432         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1433                 error "src_child still exists after rename"
1434
1435         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1436                 error "missing file(a) after rename"
1437
1438         rm -rf $DIR/$tdir || error "Can not delete directories"
1439 }
1440 run_test 24E "cross MDT rename/link"
1441
1442 test_24F () {
1443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1444
1445         local repeats=1000
1446         [ "$SLOW" = "no" ] && repeats=100
1447
1448         mkdir -p $DIR/$tdir
1449
1450         echo "$repeats repeats"
1451         for ((i = 0; i < repeats; i++)); do
1452                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1453                 touch $DIR/$tdir/test/a || error "touch fails"
1454                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1455                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1456         done
1457
1458         true
1459 }
1460 run_test 24F "hash order vs readdir (LU-11330)"
1461
1462 test_24G () {
1463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1464
1465         local ino1
1466         local ino2
1467
1468         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1469         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1470         touch $DIR/$tdir-0/f1 || error "touch f1"
1471         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1472         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1473         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1474         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1475         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1476 }
1477 run_test 24G "migrate symlink in rename"
1478
1479 test_24H() {
1480         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1481         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1482                 skip "MDT1 should be on another node"
1483
1484         test_mkdir -i 1 -c 1 $DIR/$tdir
1485 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1486         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1487         touch $DIR/$tdir/$tfile || error "touch failed"
1488 }
1489 run_test 24H "repeat FLD_QUERY rpc"
1490
1491 test_25a() {
1492         echo '== symlink sanity ============================================='
1493
1494         test_mkdir $DIR/d25
1495         ln -s d25 $DIR/s25
1496         touch $DIR/s25/foo ||
1497                 error "File creation in symlinked directory failed"
1498 }
1499 run_test 25a "create file in symlinked directory ==============="
1500
1501 test_25b() {
1502         [ ! -d $DIR/d25 ] && test_25a
1503         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1504 }
1505 run_test 25b "lookup file in symlinked directory ==============="
1506
1507 test_26a() {
1508         test_mkdir $DIR/d26
1509         test_mkdir $DIR/d26/d26-2
1510         ln -s d26/d26-2 $DIR/s26
1511         touch $DIR/s26/foo || error "File creation failed"
1512 }
1513 run_test 26a "multiple component symlink ======================="
1514
1515 test_26b() {
1516         test_mkdir -p $DIR/$tdir/d26-2
1517         ln -s $tdir/d26-2/foo $DIR/s26-2
1518         touch $DIR/s26-2 || error "File creation failed"
1519 }
1520 run_test 26b "multiple component symlink at end of lookup ======"
1521
1522 test_26c() {
1523         test_mkdir $DIR/d26.2
1524         touch $DIR/d26.2/foo
1525         ln -s d26.2 $DIR/s26.2-1
1526         ln -s s26.2-1 $DIR/s26.2-2
1527         ln -s s26.2-2 $DIR/s26.2-3
1528         chmod 0666 $DIR/s26.2-3/foo
1529 }
1530 run_test 26c "chain of symlinks"
1531
1532 # recursive symlinks (bug 439)
1533 test_26d() {
1534         ln -s d26-3/foo $DIR/d26-3
1535 }
1536 run_test 26d "create multiple component recursive symlink"
1537
1538 test_26e() {
1539         [ ! -h $DIR/d26-3 ] && test_26d
1540         rm $DIR/d26-3
1541 }
1542 run_test 26e "unlink multiple component recursive symlink"
1543
1544 # recursive symlinks (bug 7022)
1545 test_26f() {
1546         test_mkdir $DIR/$tdir
1547         test_mkdir $DIR/$tdir/$tfile
1548         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1549         test_mkdir -p lndir/bar1
1550         test_mkdir $DIR/$tdir/$tfile/$tfile
1551         cd $tfile                || error "cd $tfile failed"
1552         ln -s .. dotdot          || error "ln dotdot failed"
1553         ln -s dotdot/lndir lndir || error "ln lndir failed"
1554         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1555         output=`ls $tfile/$tfile/lndir/bar1`
1556         [ "$output" = bar1 ] && error "unexpected output"
1557         rm -r $tfile             || error "rm $tfile failed"
1558         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1559 }
1560 run_test 26f "rm -r of a directory which has recursive symlink"
1561
1562 test_27a() {
1563         test_mkdir $DIR/$tdir
1564         $LFS getstripe $DIR/$tdir
1565         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1566         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1567         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1568 }
1569 run_test 27a "one stripe file"
1570
1571 test_27b() {
1572         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1573
1574         test_mkdir $DIR/$tdir
1575         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1576         $LFS getstripe -c $DIR/$tdir/$tfile
1577         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1578                 error "two-stripe file doesn't have two stripes"
1579
1580         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1581 }
1582 run_test 27b "create and write to two stripe file"
1583
1584 # 27c family tests specific striping, setstripe -o
1585 test_27ca() {
1586         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1587         test_mkdir -p $DIR/$tdir
1588         local osts="1"
1589
1590         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1591         $LFS getstripe -i $DIR/$tdir/$tfile
1592         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1593                 error "stripe not on specified OST"
1594
1595         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1596 }
1597 run_test 27ca "one stripe on specified OST"
1598
1599 test_27cb() {
1600         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1601         test_mkdir -p $DIR/$tdir
1602         local osts="1,0"
1603         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1604         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1605         echo "$getstripe"
1606
1607         # Strip getstripe output to a space separated list of OSTs
1608         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1609                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1610         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1611                 error "stripes not on specified OSTs"
1612
1613         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1614 }
1615 run_test 27cb "two stripes on specified OSTs"
1616
1617 test_27cc() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1620                 skip "server does not support overstriping"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cc "two stripes on the same OST"
1637
1638 test_27cd() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642         test_mkdir -p $DIR/$tdir
1643         local osts="0,1,1,0"
1644         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1645         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1646         echo "$getstripe"
1647
1648         # Strip getstripe output to a space separated list of OSTs
1649         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1650                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1651         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1652                 error "stripes not on specified OSTs"
1653
1654         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1655 }
1656 run_test 27cd "four stripes on two OSTs"
1657
1658 test_27ce() {
1659         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1660                 skip_env "too many osts, skipping"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         # We do one more stripe than we have OSTs
1664         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1665                 skip_env "ea_inode feature disabled"
1666
1667         test_mkdir -p $DIR/$tdir
1668         local osts=""
1669         for i in $(seq 0 $OSTCOUNT);
1670         do
1671                 osts=$osts"0"
1672                 if [ $i -ne $OSTCOUNT ]; then
1673                         osts=$osts","
1674                 fi
1675         done
1676         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1677         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1678         echo "$getstripe"
1679
1680         # Strip getstripe output to a space separated list of OSTs
1681         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1682                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1683         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1684                 error "stripes not on specified OSTs"
1685
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1687 }
1688 run_test 27ce "more stripes than OSTs with -o"
1689
1690 test_27cf() {
1691         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1692         local pid=0
1693
1694         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1695         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1696         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1697         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1698                 error "failed to set $osp_proc=0"
1699
1700         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1701         pid=$!
1702         sleep 1
1703         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1704         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1705                 error "failed to set $osp_proc=1"
1706         wait $pid
1707         [[ $pid -ne 0 ]] ||
1708                 error "should return error due to $osp_proc=0"
1709 }
1710 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1711
1712 test_27d() {
1713         test_mkdir $DIR/$tdir
1714         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1715                 error "setstripe failed"
1716         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1718 }
1719 run_test 27d "create file with default settings"
1720
1721 test_27e() {
1722         # LU-5839 adds check for existed layout before setting it
1723         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1724                 skip "Need MDS version at least 2.7.56"
1725
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1729         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1730 }
1731 run_test 27e "setstripe existing file (should return error)"
1732
1733 test_27f() {
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1736                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1737         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1738                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1739         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1740         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1741 }
1742 run_test 27f "setstripe with bad stripe size (should return error)"
1743
1744 test_27g() {
1745         test_mkdir $DIR/$tdir
1746         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1747         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1748                 error "$DIR/$tdir/$tfile has object"
1749 }
1750 run_test 27g "$LFS getstripe with no objects"
1751
1752 test_27ga() {
1753         test_mkdir $DIR/$tdir
1754         touch $DIR/$tdir/$tfile || error "touch failed"
1755         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1756         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1757         local rc=$?
1758         (( rc == 2 )) || error "getstripe did not return ENOENT"
1759 }
1760 run_test 27ga "$LFS getstripe with missing file (should return error)"
1761
1762 test_27i() {
1763         test_mkdir $DIR/$tdir
1764         touch $DIR/$tdir/$tfile || error "touch failed"
1765         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1766                 error "missing objects"
1767 }
1768 run_test 27i "$LFS getstripe with some objects"
1769
1770 test_27j() {
1771         test_mkdir $DIR/$tdir
1772         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1773                 error "setstripe failed" || true
1774 }
1775 run_test 27j "setstripe with bad stripe offset (should return error)"
1776
1777 test_27k() { # bug 2844
1778         test_mkdir $DIR/$tdir
1779         local file=$DIR/$tdir/$tfile
1780         local ll_max_blksize=$((4 * 1024 * 1024))
1781         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1782         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1783         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1784         dd if=/dev/zero of=$file bs=4k count=1
1785         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1786         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1787 }
1788 run_test 27k "limit i_blksize for broken user apps"
1789
1790 test_27l() {
1791         mcreate $DIR/$tfile || error "creating file"
1792         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1793                 error "setstripe should have failed" || true
1794 }
1795 run_test 27l "check setstripe permissions (should return error)"
1796
1797 test_27m() {
1798         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1799
1800         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1801                 skip_env "multiple clients -- skipping"
1802
1803         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1804                    head -n1)
1805         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1806                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1807         fi
1808         stack_trap simple_cleanup_common
1809         test_mkdir $DIR/$tdir
1810         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1811         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1812                 error "dd should fill OST0"
1813         i=2
1814         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1815                 i=$((i + 1))
1816                 [ $i -gt 256 ] && break
1817         done
1818         i=$((i + 1))
1819         touch $DIR/$tdir/$tfile.$i
1820         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1821             awk '{print $1}'| grep -w "0") ] &&
1822                 error "OST0 was full but new created file still use it"
1823         i=$((i + 1))
1824         touch $DIR/$tdir/$tfile.$i
1825         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1826             awk '{print $1}'| grep -w "0") ] &&
1827                 error "OST0 was full but new created file still use it" || true
1828 }
1829 run_test 27m "create file while OST0 was full"
1830
1831 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1832 # if the OST isn't full anymore.
1833 reset_enospc() {
1834         local ostidx=${1:-""}
1835         local delay
1836         local ready
1837         local get_prealloc
1838
1839         local list=$(comma_list $(osts_nodes))
1840         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1841
1842         do_nodes $list lctl set_param fail_loc=0
1843         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1844         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1845                 awk '{print $1 * 2;exit;}')
1846         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1847                         grep -v \"^0$\""
1848         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1849 }
1850
1851 test_27n() {
1852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1854         remote_mds_nodsh && skip "remote MDS with nodsh"
1855         remote_ost_nodsh && skip "remote OST with nodsh"
1856
1857         reset_enospc
1858         rm -f $DIR/$tdir/$tfile
1859         exhaust_precreations 0 0x80000215
1860         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1861         touch $DIR/$tdir/$tfile || error "touch failed"
1862         $LFS getstripe $DIR/$tdir/$tfile
1863         reset_enospc
1864 }
1865 run_test 27n "create file with some full OSTs"
1866
1867 test_27o() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1870         remote_mds_nodsh && skip "remote MDS with nodsh"
1871         remote_ost_nodsh && skip "remote OST with nodsh"
1872
1873         reset_enospc
1874         rm -f $DIR/$tdir/$tfile
1875         exhaust_all_precreations 0x215
1876
1877         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1878
1879         reset_enospc
1880         rm -rf $DIR/$tdir/*
1881 }
1882 run_test 27o "create file with all full OSTs (should error)"
1883
1884 function create_and_checktime() {
1885         local fname=$1
1886         local loops=$2
1887         local i
1888
1889         for ((i=0; i < $loops; i++)); do
1890                 local start=$SECONDS
1891                 multiop $fname-$i Oc
1892                 ((SECONDS-start < TIMEOUT)) ||
1893                         error "creation took " $((SECONDS-$start)) && return 1
1894         done
1895 }
1896
1897 test_27oo() {
1898         local mdts=$(comma_list $(mdts_nodes))
1899
1900         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1901                 skip "Need MDS version at least 2.13.57"
1902
1903         local f0=$DIR/${tfile}-0
1904         local f1=$DIR/${tfile}-1
1905
1906         wait_delete_completed
1907
1908         # refill precreated objects
1909         $LFS setstripe -i0 -c1 $f0
1910
1911         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1912         # force QoS allocation policy
1913         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1914         stack_trap "do_nodes $mdts $LCTL set_param \
1915                 lov.*.qos_threshold_rr=$saved" EXIT
1916         sleep_maxage
1917
1918         # one OST is unavailable, but still have few objects preallocated
1919         stop ost1
1920         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1921                 rm -rf $f1 $DIR/$tdir*" EXIT
1922
1923         for ((i=0; i < 7; i++)); do
1924                 mkdir $DIR/$tdir$i || error "can't create dir"
1925                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1926                         error "can't set striping"
1927         done
1928         for ((i=0; i < 7; i++)); do
1929                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1930         done
1931         wait
1932 }
1933 run_test 27oo "don't let few threads to reserve too many objects"
1934
1935 test_27p() {
1936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1938         remote_mds_nodsh && skip "remote MDS with nodsh"
1939         remote_ost_nodsh && skip "remote OST with nodsh"
1940
1941         reset_enospc
1942         rm -f $DIR/$tdir/$tfile
1943         test_mkdir $DIR/$tdir
1944
1945         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1946         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_precreations 0 0x80000215
1950         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1951         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1952         $LFS getstripe $DIR/$tdir/$tfile
1953
1954         reset_enospc
1955 }
1956 run_test 27p "append to a truncated file with some full OSTs"
1957
1958 test_27q() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966
1967         mkdir_on_mdt0 $DIR/$tdir
1968         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1969         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1970                 error "truncate $DIR/$tdir/$tfile failed"
1971         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1972
1973         exhaust_all_precreations 0x215
1974
1975         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1976         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1977
1978         reset_enospc
1979 }
1980 run_test 27q "append to truncated file with all OSTs full (should error)"
1981
1982 test_27r() {
1983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1985         remote_mds_nodsh && skip "remote MDS with nodsh"
1986         remote_ost_nodsh && skip "remote OST with nodsh"
1987
1988         reset_enospc
1989         rm -f $DIR/$tdir/$tfile
1990         exhaust_precreations 0 0x80000215
1991
1992         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1993
1994         reset_enospc
1995 }
1996 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1997
1998 test_27s() { # bug 10725
1999         test_mkdir $DIR/$tdir
2000         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2001         local stripe_count=0
2002         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2003         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2004                 error "stripe width >= 2^32 succeeded" || true
2005
2006 }
2007 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2008
2009 test_27t() { # bug 10864
2010         WDIR=$(pwd)
2011         WLFS=$(which lfs)
2012         cd $DIR
2013         touch $tfile
2014         $WLFS getstripe $tfile
2015         cd $WDIR
2016 }
2017 run_test 27t "check that utils parse path correctly"
2018
2019 test_27u() { # bug 4900
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         remote_mds_nodsh && skip "remote MDS with nodsh"
2022
2023         local index
2024         local list=$(comma_list $(mdts_nodes))
2025
2026 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2027         do_nodes $list $LCTL set_param fail_loc=0x139
2028         test_mkdir -p $DIR/$tdir
2029         stack_trap "simple_cleanup_common 1000"
2030         createmany -o $DIR/$tdir/$tfile 1000
2031         do_nodes $list $LCTL set_param fail_loc=0
2032
2033         TLOG=$TMP/$tfile.getstripe
2034         $LFS getstripe $DIR/$tdir > $TLOG
2035         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2036         [[ $OBJS -gt 0 ]] &&
2037                 error "$OBJS objects created on OST-0. See $TLOG" ||
2038                 rm -f $TLOG
2039 }
2040 run_test 27u "skip object creation on OSC w/o objects"
2041
2042 test_27v() { # bug 4900
2043         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2045         remote_mds_nodsh && skip "remote MDS with nodsh"
2046         remote_ost_nodsh && skip "remote OST with nodsh"
2047
2048         exhaust_all_precreations 0x215
2049         reset_enospc
2050
2051         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2052
2053         touch $DIR/$tdir/$tfile
2054         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2055         # all except ost1
2056         for (( i=1; i < OSTCOUNT; i++ )); do
2057                 do_facet ost$i lctl set_param fail_loc=0x705
2058         done
2059         local START=`date +%s`
2060         createmany -o $DIR/$tdir/$tfile 32
2061
2062         local FINISH=`date +%s`
2063         local TIMEOUT=`lctl get_param -n timeout`
2064         local PROCESS=$((FINISH - START))
2065         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2066                error "$FINISH - $START >= $TIMEOUT / 2"
2067         sleep $((TIMEOUT / 2 - PROCESS))
2068         reset_enospc
2069 }
2070 run_test 27v "skip object creation on slow OST"
2071
2072 test_27w() { # bug 10997
2073         test_mkdir $DIR/$tdir
2074         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2075         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2076                 error "stripe size $size != 65536" || true
2077         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2078                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2079 }
2080 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2081
2082 test_27wa() {
2083         [[ $OSTCOUNT -lt 2 ]] &&
2084                 skip_env "skipping multiple stripe count/offset test"
2085
2086         test_mkdir $DIR/$tdir
2087         for i in $(seq 1 $OSTCOUNT); do
2088                 offset=$((i - 1))
2089                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2090                         error "setstripe -c $i -i $offset failed"
2091                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2092                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2093                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2094                 [ $index -ne $offset ] &&
2095                         error "stripe offset $index != $offset" || true
2096         done
2097 }
2098 run_test 27wa "check $LFS setstripe -c -i options"
2099
2100 test_27x() {
2101         remote_ost_nodsh && skip "remote OST with nodsh"
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104
2105         OFFSET=$(($OSTCOUNT - 1))
2106         OSTIDX=0
2107         local OST=$(ostname_from_index $OSTIDX)
2108
2109         test_mkdir $DIR/$tdir
2110         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2111         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2112         sleep_maxage
2113         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2114         for i in $(seq 0 $OFFSET); do
2115                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2116                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2117                 error "OST0 was degraded but new created file still use it"
2118         done
2119         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2120 }
2121 run_test 27x "create files while OST0 is degraded"
2122
2123 test_27y() {
2124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2125         remote_mds_nodsh && skip "remote MDS with nodsh"
2126         remote_ost_nodsh && skip "remote OST with nodsh"
2127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2128
2129         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2130         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2131                 osp.$mdtosc.prealloc_last_id)
2132         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2133                 osp.$mdtosc.prealloc_next_id)
2134         local fcount=$((last_id - next_id))
2135         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2136         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2137
2138         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2139                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2140         local OST_DEACTIVE_IDX=-1
2141         local OSC
2142         local OSTIDX
2143         local OST
2144
2145         for OSC in $MDS_OSCS; do
2146                 OST=$(osc_to_ost $OSC)
2147                 OSTIDX=$(index_from_ostuuid $OST)
2148                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2149                         OST_DEACTIVE_IDX=$OSTIDX
2150                 fi
2151                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2152                         echo $OSC "is Deactivated:"
2153                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2154                 fi
2155         done
2156
2157         OSTIDX=$(index_from_ostuuid $OST)
2158         test_mkdir $DIR/$tdir
2159         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2160
2161         for OSC in $MDS_OSCS; do
2162                 OST=$(osc_to_ost $OSC)
2163                 OSTIDX=$(index_from_ostuuid $OST)
2164                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2165                         echo $OST "is degraded:"
2166                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2167                                                 obdfilter.$OST.degraded=1
2168                 fi
2169         done
2170
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $fcount
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2178                         echo $OST "is recovered from degraded:"
2179                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2180                                                 obdfilter.$OST.degraded=0
2181                 else
2182                         do_facet $SINGLEMDS lctl --device %$OSC activate
2183                 fi
2184         done
2185
2186         # all osp devices get activated, hence -1 stripe count restored
2187         local stripe_count=0
2188
2189         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2190         # devices get activated.
2191         sleep_maxage
2192         $LFS setstripe -c -1 $DIR/$tfile
2193         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2194         rm -f $DIR/$tfile
2195         [ $stripe_count -ne $OSTCOUNT ] &&
2196                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2197         return 0
2198 }
2199 run_test 27y "create files while OST0 is degraded and the rest inactive"
2200
2201 check_seq_oid()
2202 {
2203         log "check file $1"
2204
2205         lmm_count=$($LFS getstripe -c $1)
2206         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2207         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2208
2209         local old_ifs="$IFS"
2210         IFS=$'[:]'
2211         fid=($($LFS path2fid $1))
2212         IFS="$old_ifs"
2213
2214         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2215         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2216
2217         # compare lmm_seq and lu_fid->f_seq
2218         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2219         # compare lmm_object_id and lu_fid->oid
2220         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2221
2222         # check the trusted.fid attribute of the OST objects of the file
2223         local have_obdidx=false
2224         local stripe_nr=0
2225         $LFS getstripe $1 | while read obdidx oid hex seq; do
2226                 # skip lines up to and including "obdidx"
2227                 [ -z "$obdidx" ] && break
2228                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2229                 $have_obdidx || continue
2230
2231                 local ost=$((obdidx + 1))
2232                 local dev=$(ostdevname $ost)
2233                 local oid_hex
2234
2235                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2236
2237                 seq=$(echo $seq | sed -e "s/^0x//g")
2238                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2239                         oid_hex=$(echo $oid)
2240                 else
2241                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2242                 fi
2243                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2244
2245                 local ff=""
2246                 #
2247                 # Don't unmount/remount the OSTs if we don't need to do that.
2248                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2249                 # update too, until that use mount/ll_decode_filter_fid/mount.
2250                 # Re-enable when debugfs will understand new filter_fid.
2251                 #
2252                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2253                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2254                                 $dev 2>/dev/null" | grep "parent=")
2255                 fi
2256                 if [ -z "$ff" ]; then
2257                         stop ost$ost
2258                         mount_fstype ost$ost
2259                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2260                                 $(facet_mntpt ost$ost)/$obj_file)
2261                         unmount_fstype ost$ost
2262                         start ost$ost $dev $OST_MOUNT_OPTS
2263                         clients_up
2264                 fi
2265
2266                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2267
2268                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2269
2270                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2271                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2272                 #
2273                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2274                 #       stripe_size=1048576 component_id=1 component_start=0 \
2275                 #       component_end=33554432
2276                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2277                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2278                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2279                 local ff_pstripe
2280                 if grep -q 'stripe=' <<<$ff; then
2281                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2282                 else
2283                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2284                         # into f_ver in this case.  See comment on ff_parent.
2285                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2286                 fi
2287
2288                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2289                 [ $ff_pseq = $lmm_seq ] ||
2290                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2291                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2292                 [ $ff_poid = $lmm_oid ] ||
2293                         error "FF parent OID $ff_poid != $lmm_oid"
2294                 (($ff_pstripe == $stripe_nr)) ||
2295                         error "FF stripe $ff_pstripe != $stripe_nr"
2296
2297                 stripe_nr=$((stripe_nr + 1))
2298                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2299                         continue
2300                 if grep -q 'stripe_count=' <<<$ff; then
2301                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2302                                             -e 's/ .*//' <<<$ff)
2303                         [ $lmm_count = $ff_scnt ] ||
2304                                 error "FF stripe count $lmm_count != $ff_scnt"
2305                 fi
2306         done
2307 }
2308
2309 test_27z() {
2310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2311         remote_ost_nodsh && skip "remote OST with nodsh"
2312
2313         test_mkdir $DIR/$tdir
2314         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2315                 { error "setstripe -c -1 failed"; return 1; }
2316         # We need to send a write to every object to get parent FID info set.
2317         # This _should_ also work for setattr, but does not currently.
2318         # touch $DIR/$tdir/$tfile-1 ||
2319         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2320                 { error "dd $tfile-1 failed"; return 2; }
2321         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2322                 { error "setstripe -c -1 failed"; return 3; }
2323         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2324                 { error "dd $tfile-2 failed"; return 4; }
2325
2326         # make sure write RPCs have been sent to OSTs
2327         sync; sleep 5; sync
2328
2329         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2330         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2331 }
2332 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2333
2334 test_27A() { # b=19102
2335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2336
2337         save_layout_restore_at_exit $MOUNT
2338         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2339         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2340                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2341         local default_size=$($LFS getstripe -S $MOUNT)
2342         local default_offset=$($LFS getstripe -i $MOUNT)
2343         local dsize=$(do_facet $SINGLEMDS \
2344                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2345         [ $default_size -eq $dsize ] ||
2346                 error "stripe size $default_size != $dsize"
2347         [ $default_offset -eq -1 ] ||
2348                 error "stripe offset $default_offset != -1"
2349 }
2350 run_test 27A "check filesystem-wide default LOV EA values"
2351
2352 test_27B() { # LU-2523
2353         test_mkdir $DIR/$tdir
2354         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2355         touch $DIR/$tdir/f0
2356         # open f1 with O_LOV_DELAY_CREATE
2357         # rename f0 onto f1
2358         # call setstripe ioctl on open file descriptor for f1
2359         # close
2360         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2361                 $DIR/$tdir/f0
2362
2363         rm -f $DIR/$tdir/f1
2364         # open f1 with O_LOV_DELAY_CREATE
2365         # unlink f1
2366         # call setstripe ioctl on open file descriptor for f1
2367         # close
2368         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2369
2370         # Allow multiop to fail in imitation of NFS's busted semantics.
2371         true
2372 }
2373 run_test 27B "call setstripe on open unlinked file/rename victim"
2374
2375 # 27C family tests full striping and overstriping
2376 test_27Ca() { #LU-2871
2377         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2378
2379         declare -a ost_idx
2380         local index
2381         local found
2382         local i
2383         local j
2384
2385         test_mkdir $DIR/$tdir
2386         cd $DIR/$tdir
2387         for i in $(seq 0 $((OSTCOUNT - 1))); do
2388                 # set stripe across all OSTs starting from OST$i
2389                 $LFS setstripe -i $i -c -1 $tfile$i
2390                 # get striping information
2391                 ost_idx=($($LFS getstripe $tfile$i |
2392                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2393                 echo "OST Index: ${ost_idx[*]}"
2394
2395                 # check the layout
2396                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2397                         error "${#ost_idx[@]} != $OSTCOUNT"
2398
2399                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2400                         found=0
2401                         for j in "${ost_idx[@]}"; do
2402                                 if [ $index -eq $j ]; then
2403                                         found=1
2404                                         break
2405                                 fi
2406                         done
2407                         [ $found = 1 ] ||
2408                                 error "Can not find $index in ${ost_idx[*]}"
2409                 done
2410         done
2411 }
2412 run_test 27Ca "check full striping across all OSTs"
2413
2414 test_27Cb() {
2415         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2416                 skip "server does not support overstriping"
2417         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2418                 skip_env "too many osts, skipping"
2419
2420         test_mkdir -p $DIR/$tdir
2421         local setcount=$(($OSTCOUNT * 2))
2422         [ $setcount -lt 160 ] || large_xattr_enabled ||
2423                 skip_env "ea_inode feature disabled"
2424
2425         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2426                 error "setstripe failed"
2427
2428         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2429         [ $count -eq $setcount ] ||
2430                 error "stripe count $count, should be $setcount"
2431
2432         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2433                 error "overstriped should be set in pattern"
2434
2435         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2436                 error "dd failed"
2437 }
2438 run_test 27Cb "more stripes than OSTs with -C"
2439
2440 test_27Cc() {
2441         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2442                 skip "server does not support overstriping"
2443         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2444
2445         test_mkdir -p $DIR/$tdir
2446         local setcount=$(($OSTCOUNT - 1))
2447
2448         [ $setcount -lt 160 ] || large_xattr_enabled ||
2449                 skip_env "ea_inode feature disabled"
2450
2451         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2452                 error "setstripe failed"
2453
2454         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2455         [ $count -eq $setcount ] ||
2456                 error "stripe count $count, should be $setcount"
2457
2458         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2459                 error "overstriped should not be set in pattern"
2460
2461         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2462                 error "dd failed"
2463 }
2464 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2465
2466 test_27Cd() {
2467         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2468                 skip "server does not support overstriping"
2469         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2470         large_xattr_enabled || skip_env "ea_inode feature disabled"
2471
2472         test_mkdir -p $DIR/$tdir
2473         local setcount=$LOV_MAX_STRIPE_COUNT
2474
2475         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2476                 error "setstripe failed"
2477
2478         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2479         [ $count -eq $setcount ] ||
2480                 error "stripe count $count, should be $setcount"
2481
2482         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2483                 error "overstriped should be set in pattern"
2484
2485         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2486                 error "dd failed"
2487
2488         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2489 }
2490 run_test 27Cd "test maximum stripe count"
2491
2492 test_27Ce() {
2493         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2494                 skip "server does not support overstriping"
2495         test_mkdir -p $DIR/$tdir
2496
2497         pool_add $TESTNAME || error "Pool creation failed"
2498         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2499
2500         local setcount=8
2501
2502         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2503                 error "setstripe failed"
2504
2505         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2506         [ $count -eq $setcount ] ||
2507                 error "stripe count $count, should be $setcount"
2508
2509         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2510                 error "overstriped should be set in pattern"
2511
2512         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2513                 error "dd failed"
2514
2515         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2516 }
2517 run_test 27Ce "test pool with overstriping"
2518
2519 test_27Cf() {
2520         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2521                 skip "server does not support overstriping"
2522         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2523                 skip_env "too many osts, skipping"
2524
2525         test_mkdir -p $DIR/$tdir
2526
2527         local setcount=$(($OSTCOUNT * 2))
2528         [ $setcount -lt 160 ] || large_xattr_enabled ||
2529                 skip_env "ea_inode feature disabled"
2530
2531         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2532                 error "setstripe failed"
2533
2534         echo 1 > $DIR/$tdir/$tfile
2535
2536         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2537         [ $count -eq $setcount ] ||
2538                 error "stripe count $count, should be $setcount"
2539
2540         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2541                 error "overstriped should be set in pattern"
2542
2543         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2544                 error "dd failed"
2545
2546         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2547 }
2548 run_test 27Cf "test default inheritance with overstriping"
2549
2550 test_27D() {
2551         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2552         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2553         remote_mds_nodsh && skip "remote MDS with nodsh"
2554
2555         local POOL=${POOL:-testpool}
2556         local first_ost=0
2557         local last_ost=$(($OSTCOUNT - 1))
2558         local ost_step=1
2559         local ost_list=$(seq $first_ost $ost_step $last_ost)
2560         local ost_range="$first_ost $last_ost $ost_step"
2561
2562         test_mkdir $DIR/$tdir
2563         pool_add $POOL || error "pool_add failed"
2564         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2565
2566         local skip27D
2567         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2568                 skip27D+="-s 29"
2569         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2570                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2571                         skip27D+=" -s 30,31"
2572         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2573           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2574                 skip27D+=" -s 32,33"
2575         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2576                 skip27D+=" -s 34"
2577         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2578                 error "llapi_layout_test failed"
2579
2580         destroy_test_pools || error "destroy test pools failed"
2581 }
2582 run_test 27D "validate llapi_layout API"
2583
2584 # Verify that default_easize is increased from its initial value after
2585 # accessing a widely striped file.
2586 test_27E() {
2587         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2588         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2589                 skip "client does not have LU-3338 fix"
2590
2591         # 72 bytes is the minimum space required to store striping
2592         # information for a file striped across one OST:
2593         # (sizeof(struct lov_user_md_v3) +
2594         #  sizeof(struct lov_user_ost_data_v1))
2595         local min_easize=72
2596         $LCTL set_param -n llite.*.default_easize $min_easize ||
2597                 error "lctl set_param failed"
2598         local easize=$($LCTL get_param -n llite.*.default_easize)
2599
2600         [ $easize -eq $min_easize ] ||
2601                 error "failed to set default_easize"
2602
2603         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2604                 error "setstripe failed"
2605         # In order to ensure stat() call actually talks to MDS we need to
2606         # do something drastic to this file to shake off all lock, e.g.
2607         # rename it (kills lookup lock forcing cache cleaning)
2608         mv $DIR/$tfile $DIR/${tfile}-1
2609         ls -l $DIR/${tfile}-1
2610         rm $DIR/${tfile}-1
2611
2612         easize=$($LCTL get_param -n llite.*.default_easize)
2613
2614         [ $easize -gt $min_easize ] ||
2615                 error "default_easize not updated"
2616 }
2617 run_test 27E "check that default extended attribute size properly increases"
2618
2619 test_27F() { # LU-5346/LU-7975
2620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2621         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2622         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2623                 skip "Need MDS version at least 2.8.51"
2624         remote_ost_nodsh && skip "remote OST with nodsh"
2625
2626         test_mkdir $DIR/$tdir
2627         rm -f $DIR/$tdir/f0
2628         $LFS setstripe -c 2 $DIR/$tdir
2629
2630         # stop all OSTs to reproduce situation for LU-7975 ticket
2631         for num in $(seq $OSTCOUNT); do
2632                 stop ost$num
2633         done
2634
2635         # open/create f0 with O_LOV_DELAY_CREATE
2636         # truncate f0 to a non-0 size
2637         # close
2638         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2639
2640         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2641         # open/write it again to force delayed layout creation
2642         cat /etc/hosts > $DIR/$tdir/f0 &
2643         catpid=$!
2644
2645         # restart OSTs
2646         for num in $(seq $OSTCOUNT); do
2647                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2648                         error "ost$num failed to start"
2649         done
2650
2651         wait $catpid || error "cat failed"
2652
2653         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2654         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2655                 error "wrong stripecount"
2656
2657 }
2658 run_test 27F "Client resend delayed layout creation with non-zero size"
2659
2660 test_27G() { #LU-10629
2661         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2662                 skip "Need MDS version at least 2.11.51"
2663         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2664         remote_mds_nodsh && skip "remote MDS with nodsh"
2665         local POOL=${POOL:-testpool}
2666         local ostrange="0 0 1"
2667
2668         test_mkdir $DIR/$tdir
2669         touch $DIR/$tdir/$tfile.nopool
2670         pool_add $POOL || error "pool_add failed"
2671         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2672         $LFS setstripe -p $POOL $DIR/$tdir
2673
2674         local pool=$($LFS getstripe -p $DIR/$tdir)
2675
2676         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2677         touch $DIR/$tdir/$tfile.default
2678         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2679         $LFS find $DIR/$tdir -type f --pool $POOL
2680         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2681         [[ "$found" == "2" ]] ||
2682                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2683
2684         $LFS setstripe -d $DIR/$tdir
2685
2686         pool=$($LFS getstripe -p -d $DIR/$tdir)
2687
2688         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2689 }
2690 run_test 27G "Clear OST pool from stripe"
2691
2692 test_27H() {
2693         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2694                 skip "Need MDS version newer than 2.11.54"
2695         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2696         test_mkdir $DIR/$tdir
2697         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2698         touch $DIR/$tdir/$tfile
2699         $LFS getstripe -c $DIR/$tdir/$tfile
2700         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2701                 error "two-stripe file doesn't have two stripes"
2702
2703         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2704         $LFS getstripe -y $DIR/$tdir/$tfile
2705         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2706              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2707                 error "expected l_ost_idx: [02]$ not matched"
2708
2709         # make sure ost list has been cleared
2710         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2711         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2712                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2713         touch $DIR/$tdir/f3
2714         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2715 }
2716 run_test 27H "Set specific OSTs stripe"
2717
2718 test_27I() {
2719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2720         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2721         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2722                 skip "Need MDS version newer than 2.12.52"
2723         local pool=$TESTNAME
2724         local ostrange="1 1 1"
2725
2726         save_layout_restore_at_exit $MOUNT
2727         $LFS setstripe -c 2 -i 0 $MOUNT
2728         pool_add $pool || error "pool_add failed"
2729         pool_add_targets $pool $ostrange ||
2730                 error "pool_add_targets failed"
2731         test_mkdir $DIR/$tdir
2732         $LFS setstripe -p $pool $DIR/$tdir
2733         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2734         $LFS getstripe $DIR/$tdir/$tfile
2735 }
2736 run_test 27I "check that root dir striping does not break parent dir one"
2737
2738 test_27J() {
2739         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2740                 skip "Need MDS version newer than 2.12.51"
2741
2742         test_mkdir $DIR/$tdir
2743         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2744         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2745
2746         # create foreign file (raw way)
2747         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2748                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2749
2750         ! $LFS setstripe --foreign --flags foo \
2751                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2752                         error "creating $tfile with '--flags foo' should fail"
2753
2754         ! $LFS setstripe --foreign --flags 0xffffffff \
2755                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2756                         error "creating $tfile w/ 0xffffffff flags should fail"
2757
2758         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2759                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2760
2761         # verify foreign file (raw way)
2762         parse_foreign_file -f $DIR/$tdir/$tfile |
2763                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2764                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2765         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2766                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2767         parse_foreign_file -f $DIR/$tdir/$tfile |
2768                 grep "lov_foreign_size: 73" ||
2769                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2770         parse_foreign_file -f $DIR/$tdir/$tfile |
2771                 grep "lov_foreign_type: 1" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2773         parse_foreign_file -f $DIR/$tdir/$tfile |
2774                 grep "lov_foreign_flags: 0x0000DA08" ||
2775                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2776         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_value: 0x" |
2778                 sed -e 's/lov_foreign_value: 0x//')
2779         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2780         [[ $lov = ${lov2// /} ]] ||
2781                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2782
2783         # create foreign file (lfs + API)
2784         $LFS setstripe --foreign=none --flags 0xda08 \
2785                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2786                 error "$DIR/$tdir/${tfile}2: create failed"
2787
2788         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2789                 grep "lfm_magic:.*0x0BD70BD0" ||
2790                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2791         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2792         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2793                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2794         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2795                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2796         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2797                 grep "lfm_flags:.*0x0000DA08" ||
2798                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2799         $LFS getstripe $DIR/$tdir/${tfile}2 |
2800                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2802
2803         # modify striping should fail
2804         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2805                 error "$DIR/$tdir/$tfile: setstripe should fail"
2806         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2807                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2808
2809         # R/W should fail
2810         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2811         cat $DIR/$tdir/${tfile}2 &&
2812                 error "$DIR/$tdir/${tfile}2: read should fail"
2813         cat /etc/passwd > $DIR/$tdir/$tfile &&
2814                 error "$DIR/$tdir/$tfile: write should fail"
2815         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2816                 error "$DIR/$tdir/${tfile}2: write should fail"
2817
2818         # chmod should work
2819         chmod 222 $DIR/$tdir/$tfile ||
2820                 error "$DIR/$tdir/$tfile: chmod failed"
2821         chmod 222 $DIR/$tdir/${tfile}2 ||
2822                 error "$DIR/$tdir/${tfile}2: chmod failed"
2823
2824         # chown should work
2825         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2826                 error "$DIR/$tdir/$tfile: chown failed"
2827         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2828                 error "$DIR/$tdir/${tfile}2: chown failed"
2829
2830         # rename should work
2831         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2832                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2833         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2834                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2835
2836         #remove foreign file
2837         rm $DIR/$tdir/${tfile}.new ||
2838                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2839         rm $DIR/$tdir/${tfile}2.new ||
2840                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2841 }
2842 run_test 27J "basic ops on file with foreign LOV"
2843
2844 test_27K() {
2845         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2846                 skip "Need MDS version newer than 2.12.49"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign dir (raw way)
2853         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2854                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setdirstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2858                         error "creating $tdir with '--flags foo' should fail"
2859
2860         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2862                         error "creating $tdir w/ 0xffffffff flags should fail"
2863
2864         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2865                 error "create_foreign_dir FAILED"
2866
2867         # verify foreign dir (raw way)
2868         parse_foreign_dir -d $DIR/$tdir/$tdir |
2869                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2871         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2872                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2873         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2874                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2875         parse_foreign_dir -d $DIR/$tdir/$tdir |
2876                 grep "lmv_foreign_flags: 55813$" ||
2877                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2878         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2879                 grep "lmv_foreign_value: 0x" |
2880                 sed 's/lmv_foreign_value: 0x//')
2881         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2882                 sed 's/ //g')
2883         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2884
2885         # create foreign dir (lfs + API)
2886         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2887                 $DIR/$tdir/${tdir}2 ||
2888                 error "$DIR/$tdir/${tdir}2: create failed"
2889
2890         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2891
2892         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2893                 grep "lfm_magic:.*0x0CD50CD0" ||
2894                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2895         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2896         # - sizeof(lfm_type) - sizeof(lfm_flags)
2897         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2898                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2899         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2901         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2902                 grep "lfm_flags:.*0x0000DA05" ||
2903                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2904         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2905                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2907
2908         # file create in dir should fail
2909         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2910         touch $DIR/$tdir/${tdir}2/$tfile &&
2911                 error "$DIR/${tdir}2: file create should fail"
2912
2913         # chmod should work
2914         chmod 777 $DIR/$tdir/$tdir ||
2915                 error "$DIR/$tdir: chmod failed"
2916         chmod 777 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/${tdir}2: chmod failed"
2918
2919         # chown should work
2920         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chown failed"
2922         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chown failed"
2924
2925         # rename should work
2926         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2927                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2928         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2929                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2930
2931         #remove foreign dir
2932         rmdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2934         rmdir $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2936 }
2937 run_test 27K "basic ops on dir with foreign LMV"
2938
2939 test_27L() {
2940         remote_mds_nodsh && skip "remote MDS with nodsh"
2941
2942         local POOL=${POOL:-$TESTNAME}
2943
2944         pool_add $POOL || error "pool_add failed"
2945
2946         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2947                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2948                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2949 }
2950 run_test 27L "lfs pool_list gives correct pool name"
2951
2952 test_27M() {
2953         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2954                 skip "Need MDS version >= than 2.12.57"
2955         remote_mds_nodsh && skip "remote MDS with nodsh"
2956         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2957
2958         # Set default striping on directory
2959         local setcount=4
2960         local stripe_opt
2961         local mdts=$(comma_list $(mdts_nodes))
2962
2963         # if we run against a 2.12 server which lacks overstring support
2964         # then the connect_flag will not report overstriping, even if client
2965         # is 2.14+
2966         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2967                 stripe_opt="-C $setcount"
2968         elif (( $OSTCOUNT >= $setcount )); then
2969                 stripe_opt="-c $setcount"
2970         else
2971                 skip "server does not support overstriping"
2972         fi
2973
2974         test_mkdir $DIR/$tdir
2975
2976         # Validate existing append_* params and ensure restore
2977         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2978         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2980
2981         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2982         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2983         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2984
2985         $LFS setstripe $stripe_opt $DIR/$tdir
2986
2987         echo 1 > $DIR/$tdir/${tfile}.1
2988         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2989         [ $count -eq $setcount ] ||
2990                 error "(1) stripe count $count, should be $setcount"
2991
2992         local appendcount=$orig_count
2993         echo 1 >> $DIR/$tdir/${tfile}.2_append
2994         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2995         [ $count -eq $appendcount ] ||
2996                 error "(2)stripe count $count, should be $appendcount for append"
2997
2998         # Disable O_APPEND striping, verify it works
2999         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3000
3001         # Should now get the default striping, which is 4
3002         setcount=4
3003         echo 1 >> $DIR/$tdir/${tfile}.3_append
3004         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3005         [ $count -eq $setcount ] ||
3006                 error "(3) stripe count $count, should be $setcount"
3007
3008         # Try changing the stripe count for append files
3009         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3010
3011         # Append striping is now 2 (directory default is still 4)
3012         appendcount=2
3013         echo 1 >> $DIR/$tdir/${tfile}.4_append
3014         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3015         [ $count -eq $appendcount ] ||
3016                 error "(4) stripe count $count, should be $appendcount for append"
3017
3018         # Test append stripe count of -1
3019         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3020         appendcount=$OSTCOUNT
3021         echo 1 >> $DIR/$tdir/${tfile}.5
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3023         [ $count -eq $appendcount ] ||
3024                 error "(5) stripe count $count, should be $appendcount for append"
3025
3026         # Set append striping back to default of 1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3028
3029         # Try a new default striping, PFL + DOM
3030         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3031
3032         # Create normal DOM file, DOM returns stripe count == 0
3033         setcount=0
3034         touch $DIR/$tdir/${tfile}.6
3035         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3036         [ $count -eq $setcount ] ||
3037                 error "(6) stripe count $count, should be $setcount"
3038
3039         # Show
3040         appendcount=1
3041         echo 1 >> $DIR/$tdir/${tfile}.7_append
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3043         [ $count -eq $appendcount ] ||
3044                 error "(7) stripe count $count, should be $appendcount for append"
3045
3046         # Clean up DOM layout
3047         $LFS setstripe -d $DIR/$tdir
3048
3049         save_layout_restore_at_exit $MOUNT
3050         # Now test that append striping works when layout is from root
3051         $LFS setstripe -c 2 $MOUNT
3052         # Make a special directory for this
3053         mkdir $DIR/${tdir}/${tdir}.2
3054
3055         # Verify for normal file
3056         setcount=2
3057         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3058         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3059         [ $count -eq $setcount ] ||
3060                 error "(8) stripe count $count, should be $setcount"
3061
3062         appendcount=1
3063         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3064         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(9) stripe count $count, should be $appendcount for append"
3067
3068         # Now test O_APPEND striping with pools
3069         pool_add $TESTNAME || error "pool creation failed"
3070         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3071         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3072
3073         echo 1 >> $DIR/$tdir/${tfile}.10_append
3074
3075         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3076         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3077
3078         # Check that count is still correct
3079         appendcount=1
3080         echo 1 >> $DIR/$tdir/${tfile}.11_append
3081         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3082         [ $count -eq $appendcount ] ||
3083                 error "(11) stripe count $count, should be $appendcount for append"
3084
3085         # Disable O_APPEND stripe count, verify pool works separately
3086         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3087
3088         echo 1 >> $DIR/$tdir/${tfile}.12_append
3089
3090         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3091         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3092
3093         # Remove pool setting, verify it's not applied
3094         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3095
3096         echo 1 >> $DIR/$tdir/${tfile}.13_append
3097
3098         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3099         [ "$pool" = "" ] || error "(13) pool found: $pool"
3100 }
3101 run_test 27M "test O_APPEND striping"
3102
3103 test_27N() {
3104         combined_mgs_mds && skip "needs separate MGS/MDT"
3105
3106         pool_add $TESTNAME || error "pool_add failed"
3107         do_facet mgs "$LCTL pool_list $FSNAME" |
3108                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3109                 error "lctl pool_list on MGS failed"
3110 }
3111 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3112
3113 clean_foreign_symlink() {
3114         trap 0
3115         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3116         for i in $DIR/$tdir/* ; do
3117                 $LFS unlink_foreign $i || true
3118         done
3119 }
3120
3121 test_27O() {
3122         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3123                 skip "Need MDS version newer than 2.12.51"
3124
3125         test_mkdir $DIR/$tdir
3126         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3127         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3128
3129         trap clean_foreign_symlink EXIT
3130
3131         # enable foreign_symlink behaviour
3132         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3133
3134         # foreign symlink LOV format is a partial path by default
3135
3136         # create foreign file (lfs + API)
3137         $LFS setstripe --foreign=symlink --flags 0xda05 \
3138                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3139                 error "$DIR/$tdir/${tfile}: create failed"
3140
3141         $LFS getstripe -v $DIR/$tdir/${tfile} |
3142                 grep "lfm_magic:.*0x0BD70BD0" ||
3143                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3144         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3145                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3146         $LFS getstripe -v $DIR/$tdir/${tfile} |
3147                 grep "lfm_flags:.*0x0000DA05" ||
3148                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3149         $LFS getstripe $DIR/$tdir/${tfile} |
3150                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3152
3153         # modify striping should fail
3154         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3155                 error "$DIR/$tdir/$tfile: setstripe should fail"
3156
3157         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3158         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3159         cat /etc/passwd > $DIR/$tdir/$tfile &&
3160                 error "$DIR/$tdir/$tfile: write should fail"
3161
3162         # rename should succeed
3163         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3164                 error "$DIR/$tdir/$tfile: rename has failed"
3165
3166         #remove foreign_symlink file should fail
3167         rm $DIR/$tdir/${tfile}.new &&
3168                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3169
3170         #test fake symlink
3171         mkdir /tmp/${uuid1} ||
3172                 error "/tmp/${uuid1}: mkdir has failed"
3173         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3174                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3175         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3176         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3177                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3178         #read should succeed now
3179         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3180                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3181         #write should succeed now
3182         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3183                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3184         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3185                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3186         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3187                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3188
3189         #check that getstripe still works
3190         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3191                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3192
3193         # chmod should still succeed
3194         chmod 644 $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3196
3197         # chown should still succeed
3198         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3199                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3200
3201         # rename should still succeed
3202         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3203                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3204
3205         #remove foreign_symlink file should still fail
3206         rm $DIR/$tdir/${tfile} &&
3207                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3208
3209         #use special ioctl() to unlink foreign_symlink file
3210         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3211                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3212
3213 }
3214 run_test 27O "basic ops on foreign file of symlink type"
3215
3216 test_27P() {
3217         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3218                 skip "Need MDS version newer than 2.12.49"
3219
3220         test_mkdir $DIR/$tdir
3221         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3222         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3223
3224         trap clean_foreign_symlink EXIT
3225
3226         # enable foreign_symlink behaviour
3227         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3228
3229         # foreign symlink LMV format is a partial path by default
3230
3231         # create foreign dir (lfs + API)
3232         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3233                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3234                 error "$DIR/$tdir/${tdir}: create failed"
3235
3236         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3237
3238         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3239                 grep "lfm_magic:.*0x0CD50CD0" ||
3240                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3241         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3242                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3243         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3244                 grep "lfm_flags:.*0x0000DA05" ||
3245                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3246         $LFS getdirstripe $DIR/$tdir/${tdir} |
3247                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3248                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3249
3250         # file create in dir should fail
3251         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3252         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3253
3254         # rename should succeed
3255         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3256                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3257
3258         #remove foreign_symlink dir should fail
3259         rmdir $DIR/$tdir/${tdir}.new &&
3260                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3261
3262         #test fake symlink
3263         mkdir -p /tmp/${uuid1}/${uuid2} ||
3264                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3265         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3266                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3267         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3268         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3269                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3270         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3271                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3272
3273         #check that getstripe fails now that foreign_symlink enabled
3274         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3275                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3276
3277         # file create in dir should work now
3278         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3279                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3280         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3281                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3282         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3283                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3284
3285         # chmod should still succeed
3286         chmod 755 $DIR/$tdir/${tdir}.new ||
3287                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3288
3289         # chown should still succeed
3290         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3291                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3292
3293         # rename should still succeed
3294         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3295                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3296
3297         #remove foreign_symlink dir should still fail
3298         rmdir $DIR/$tdir/${tdir} &&
3299                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3300
3301         #use special ioctl() to unlink foreign_symlink file
3302         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3303                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3304
3305         #created file should still exist
3306         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3307                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3308         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3309                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3310 }
3311 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3312
3313 test_27Q() {
3314         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3315         stack_trap "rm -f $TMP/$tfile*"
3316
3317         test_mkdir $DIR/$tdir-1
3318         test_mkdir $DIR/$tdir-2
3319
3320         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3321         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3322
3323         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3324         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3325
3326         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3327         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3328
3329         # Create some bad symlinks and ensure that we don't loop
3330         # forever or something. These should return ELOOP (40) and
3331         # ENOENT (2) but I don't want to test for that because there's
3332         # always some weirdo architecture that needs to ruin
3333         # everything by defining these error numbers differently.
3334
3335         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3336         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3337
3338         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3339         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3340
3341         return 0
3342 }
3343 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3344
3345 test_27R() {
3346         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3347                 skip "need MDS 2.14.55 or later"
3348         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3349
3350         local testdir="$DIR/$tdir"
3351         test_mkdir -p $testdir
3352         stack_trap "rm -rf $testdir"
3353         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3354
3355         local f1="$testdir/f1"
3356         touch $f1 || error "failed to touch $f1"
3357         local count=$($LFS getstripe -c $f1)
3358         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3359
3360         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3361         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3362
3363         local maxcount=$(($OSTCOUNT - 1))
3364         local mdts=$(comma_list $(mdts_nodes))
3365         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3366         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3367
3368         local f2="$testdir/f2"
3369         touch $f2 || error "failed to touch $f2"
3370         local count=$($LFS getstripe -c $f2)
3371         (( $count == $maxcount )) || error "wrong stripe count"
3372 }
3373 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3374
3375 test_27T() {
3376         [ $(facet_host client) == $(facet_host ost1) ] &&
3377                 skip "need ost1 and client on different nodes"
3378
3379 #define OBD_FAIL_OSC_NO_GRANT            0x411
3380         $LCTL set_param fail_loc=0x20000411 fail_val=1
3381 #define OBD_FAIL_OST_ENOSPC              0x215
3382         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3383         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3384         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3385                 error "multiop failed"
3386 }
3387 run_test 27T "no eio on close on partial write due to enosp"
3388
3389 test_27U() {
3390         local dir=$DIR/$tdir
3391         local file=$dir/$tfile
3392         local append_pool=${TESTNAME}-append
3393         local normal_pool=${TESTNAME}-normal
3394         local pool
3395         local stripe_count
3396         local stripe_count2
3397         local mdts=$(comma_list $(mdts_nodes))
3398
3399         # FIMXE
3400         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3401         #       skip "Need MDS version at least 2.15.42"
3402
3403         # Validate existing append_* params and ensure restore
3404         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3405         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3406         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3407
3408         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3409         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3410         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3411
3412         pool_add $append_pool || error "pool creation failed"
3413         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3414
3415         pool_add $normal_pool || error "pool creation failed"
3416         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3417
3418         test_mkdir $dir
3419         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3420
3421         echo XXX >> $file.1
3422         $LFS getstripe $file.1
3423
3424         pool=$($LFS getstripe -p $file.1)
3425         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3426
3427         stripe_count2=$($LFS getstripe -c $file.1)
3428         ((stripe_count2 == stripe_count)) ||
3429                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3430
3431         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3432
3433         echo XXX >> $file.2
3434         $LFS getstripe $file.2
3435
3436         pool=$($LFS getstripe -p $file.2)
3437         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3438
3439         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3440
3441         echo XXX >> $file.3
3442         $LFS getstripe $file.3
3443
3444         stripe_count2=$($LFS getstripe -c $file.3)
3445         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3446 }
3447 run_test 27U "append pool and stripe count work with composite default layout"
3448
3449 # createtest also checks that device nodes are created and
3450 # then visible correctly (#2091)
3451 test_28() { # bug 2091
3452         test_mkdir $DIR/d28
3453         $CREATETEST $DIR/d28/ct || error "createtest failed"
3454 }
3455 run_test 28 "create/mknod/mkdir with bad file types ============"
3456
3457 test_29() {
3458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3459
3460         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3461                 disable_opencache
3462                 stack_trap "restore_opencache"
3463         }
3464
3465         sync; sleep 1; sync # flush out any dirty pages from previous tests
3466         cancel_lru_locks
3467         test_mkdir $DIR/d29
3468         touch $DIR/d29/foo
3469         log 'first d29'
3470         ls -l $DIR/d29
3471
3472         declare -i LOCKCOUNTORIG=0
3473         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3474                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3475         done
3476         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3477
3478         declare -i LOCKUNUSEDCOUNTORIG=0
3479         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3480                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3481         done
3482
3483         log 'second d29'
3484         ls -l $DIR/d29
3485         log 'done'
3486
3487         declare -i LOCKCOUNTCURRENT=0
3488         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3489                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3490         done
3491
3492         declare -i LOCKUNUSEDCOUNTCURRENT=0
3493         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3494                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3495         done
3496
3497         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3498                 $LCTL set_param -n ldlm.dump_namespaces ""
3499                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3500                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3501                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3502                 return 2
3503         fi
3504         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3505                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3506                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3507                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3508                 return 3
3509         fi
3510 }
3511 run_test 29 "IT_GETATTR regression  ============================"
3512
3513 test_30a() { # was test_30
3514         cp $(which ls) $DIR || cp /bin/ls $DIR
3515         $DIR/ls / || error "Can't execute binary from lustre"
3516         rm $DIR/ls
3517 }
3518 run_test 30a "execute binary from Lustre (execve) =============="
3519
3520 test_30b() {
3521         cp `which ls` $DIR || cp /bin/ls $DIR
3522         chmod go+rx $DIR/ls
3523         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3524         rm $DIR/ls
3525 }
3526 run_test 30b "execute binary from Lustre as non-root ==========="
3527
3528 test_30c() { # b=22376
3529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3530
3531         cp $(which ls) $DIR || cp /bin/ls $DIR
3532         chmod a-rw $DIR/ls
3533         cancel_lru_locks mdc
3534         cancel_lru_locks osc
3535         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3536         rm -f $DIR/ls
3537 }
3538 run_test 30c "execute binary from Lustre without read perms ===="
3539
3540 test_30d() {
3541         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3542
3543         for i in {1..10}; do
3544                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3545                 local PID=$!
3546                 sleep 1
3547                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3548                 wait $PID || error "executing dd from Lustre failed"
3549                 rm -f $DIR/$tfile
3550         done
3551
3552         rm -f $DIR/dd
3553 }
3554 run_test 30d "execute binary from Lustre while clear locks"
3555
3556 test_31a() {
3557         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3558         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3559 }
3560 run_test 31a "open-unlink file =================================="
3561
3562 test_31b() {
3563         touch $DIR/f31 || error "touch $DIR/f31 failed"
3564         ln $DIR/f31 $DIR/f31b || error "ln failed"
3565         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3566         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3567 }
3568 run_test 31b "unlink file with multiple links while open ======="
3569
3570 test_31c() {
3571         touch $DIR/f31 || error "touch $DIR/f31 failed"
3572         ln $DIR/f31 $DIR/f31c || error "ln failed"
3573         multiop_bg_pause $DIR/f31 O_uc ||
3574                 error "multiop_bg_pause for $DIR/f31 failed"
3575         MULTIPID=$!
3576         $MULTIOP $DIR/f31c Ouc
3577         kill -USR1 $MULTIPID
3578         wait $MULTIPID
3579 }
3580 run_test 31c "open-unlink file with multiple links ============="
3581
3582 test_31d() {
3583         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3584         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3585 }
3586 run_test 31d "remove of open directory ========================="
3587
3588 test_31e() { # bug 2904
3589         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3590 }
3591 run_test 31e "remove of open non-empty directory ==============="
3592
3593 test_31f() { # bug 4554
3594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3595
3596         set -vx
3597         test_mkdir $DIR/d31f
3598         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3599         cp /etc/hosts $DIR/d31f
3600         ls -l $DIR/d31f
3601         $LFS getstripe $DIR/d31f/hosts
3602         multiop_bg_pause $DIR/d31f D_c || return 1
3603         MULTIPID=$!
3604
3605         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3606         test_mkdir $DIR/d31f
3607         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3608         cp /etc/hosts $DIR/d31f
3609         ls -l $DIR/d31f
3610         $LFS getstripe $DIR/d31f/hosts
3611         multiop_bg_pause $DIR/d31f D_c || return 1
3612         MULTIPID2=$!
3613
3614         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3615         wait $MULTIPID || error "first opendir $MULTIPID failed"
3616
3617         sleep 6
3618
3619         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3620         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3621         set +vx
3622 }
3623 run_test 31f "remove of open directory with open-unlink file ==="
3624
3625 test_31g() {
3626         echo "-- cross directory link --"
3627         test_mkdir -c1 $DIR/${tdir}ga
3628         test_mkdir -c1 $DIR/${tdir}gb
3629         touch $DIR/${tdir}ga/f
3630         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3631         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3632         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3633         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3634         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3635 }
3636 run_test 31g "cross directory link==============="
3637
3638 test_31h() {
3639         echo "-- cross directory link --"
3640         test_mkdir -c1 $DIR/${tdir}
3641         test_mkdir -c1 $DIR/${tdir}/dir
3642         touch $DIR/${tdir}/f
3643         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3644         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3645         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3646         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3647         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3648 }
3649 run_test 31h "cross directory link under child==============="
3650
3651 test_31i() {
3652         echo "-- cross directory link --"
3653         test_mkdir -c1 $DIR/$tdir
3654         test_mkdir -c1 $DIR/$tdir/dir
3655         touch $DIR/$tdir/dir/f
3656         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3657         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3658         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3659         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3660         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3661 }
3662 run_test 31i "cross directory link under parent==============="
3663
3664 test_31j() {
3665         test_mkdir -c1 -p $DIR/$tdir
3666         test_mkdir -c1 -p $DIR/$tdir/dir1
3667         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3668         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3669         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3671         return 0
3672 }
3673 run_test 31j "link for directory==============="
3674
3675 test_31k() {
3676         test_mkdir -c1 -p $DIR/$tdir
3677         touch $DIR/$tdir/s
3678         touch $DIR/$tdir/exist
3679         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3680         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3681         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3682         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3683         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3684         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3686         return 0
3687 }
3688 run_test 31k "link to file: the same, non-existing, dir==============="
3689
3690 test_31m() {
3691         mkdir $DIR/d31m
3692         touch $DIR/d31m/s
3693         mkdir $DIR/d31m2
3694         touch $DIR/d31m2/exist
3695         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3696         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3697         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3698         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3699         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3701         return 0
3702 }
3703 run_test 31m "link to file: the same, non-existing, dir==============="
3704
3705 test_31n() {
3706         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3707         nlink=$(stat --format=%h $DIR/$tfile)
3708         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3709         local fd=$(free_fd)
3710         local cmd="exec $fd<$DIR/$tfile"
3711         eval $cmd
3712         cmd="exec $fd<&-"
3713         trap "eval $cmd" EXIT
3714         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3715         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3716         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3717         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3718         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3719         eval $cmd
3720 }
3721 run_test 31n "check link count of unlinked file"
3722
3723 link_one() {
3724         local tempfile=$(mktemp $1_XXXXXX)
3725         mlink $tempfile $1 2> /dev/null &&
3726                 echo "$BASHPID: link $tempfile to $1 succeeded"
3727         munlink $tempfile
3728 }
3729
3730 test_31o() { # LU-2901
3731         test_mkdir $DIR/$tdir
3732         for LOOP in $(seq 100); do
3733                 rm -f $DIR/$tdir/$tfile*
3734                 for THREAD in $(seq 8); do
3735                         link_one $DIR/$tdir/$tfile.$LOOP &
3736                 done
3737                 wait
3738                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3739                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3740                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3741                         break || true
3742         done
3743 }
3744 run_test 31o "duplicate hard links with same filename"
3745
3746 test_31p() {
3747         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3748
3749         test_mkdir $DIR/$tdir
3750         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3751         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3752
3753         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3754                 error "open unlink test1 failed"
3755         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3756                 error "open unlink test2 failed"
3757
3758         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3759                 error "test1 still exists"
3760         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3761                 error "test2 still exists"
3762 }
3763 run_test 31p "remove of open striped directory"
3764
3765 test_31q() {
3766         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3767
3768         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3769         index=$($LFS getdirstripe -i $DIR/$tdir)
3770         [ $index -eq 3 ] || error "first stripe index $index != 3"
3771         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3772         [ $index -eq 1 ] || error "second stripe index $index != 1"
3773
3774         # when "-c <stripe_count>" is set, the number of MDTs specified after
3775         # "-i" should equal to the stripe count
3776         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3777 }
3778 run_test 31q "create striped directory on specific MDTs"
3779
3780 #LU-14949
3781 test_31r() {
3782         touch $DIR/$tfile.target
3783         touch $DIR/$tfile.source
3784
3785         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3786         $LCTL set_param fail_loc=0x1419 fail_val=3
3787         cat $DIR/$tfile.target &
3788         CATPID=$!
3789
3790         # Guarantee open is waiting before we get here
3791         sleep 1
3792         mv $DIR/$tfile.source $DIR/$tfile.target
3793
3794         wait $CATPID
3795         RC=$?
3796         if [[ $RC -ne 0 ]]; then
3797                 error "open with cat failed, rc=$RC"
3798         fi
3799 }
3800 run_test 31r "open-rename(replace) race"
3801
3802 cleanup_test32_mount() {
3803         local rc=0
3804         trap 0
3805         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3806         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3807         losetup -d $loopdev || true
3808         rm -rf $DIR/$tdir
3809         return $rc
3810 }
3811
3812 test_32a() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         echo "== more mountpoints and symlinks ================="
3816         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3817         trap cleanup_test32_mount EXIT
3818         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3819         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3820                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3821         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3822                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3823         cleanup_test32_mount
3824 }
3825 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3826
3827 test_32b() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3836                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3837         cleanup_test32_mount
3838 }
3839 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3840
3841 test_32c() {
3842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3843
3844         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3845         trap cleanup_test32_mount EXIT
3846         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3847         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3848                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3849         test_mkdir -p $DIR/$tdir/d2/test_dir
3850         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3851                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3852         cleanup_test32_mount
3853 }
3854 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3855
3856 test_32d() {
3857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3858
3859         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3860         trap cleanup_test32_mount EXIT
3861         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3862         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3863                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3864         test_mkdir -p $DIR/$tdir/d2/test_dir
3865         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3866                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3867         cleanup_test32_mount
3868 }
3869 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3870
3871 test_32e() {
3872         rm -fr $DIR/$tdir
3873         test_mkdir -p $DIR/$tdir/tmp
3874         local tmp_dir=$DIR/$tdir/tmp
3875         ln -s $DIR/$tdir $tmp_dir/symlink11
3876         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3877         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3878         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3879 }
3880 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3881
3882 test_32f() {
3883         rm -fr $DIR/$tdir
3884         test_mkdir -p $DIR/$tdir/tmp
3885         local tmp_dir=$DIR/$tdir/tmp
3886         ln -s $DIR/$tdir $tmp_dir/symlink11
3887         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3888         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3889         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3890 }
3891 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3892
3893 test_32g() {
3894         local tmp_dir=$DIR/$tdir/tmp
3895         test_mkdir -p $tmp_dir
3896         test_mkdir $DIR/${tdir}2
3897         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3898         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3899         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3900         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3901         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3902         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3903 }
3904 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3905
3906 test_32h() {
3907         rm -fr $DIR/$tdir $DIR/${tdir}2
3908         tmp_dir=$DIR/$tdir/tmp
3909         test_mkdir -p $tmp_dir
3910         test_mkdir $DIR/${tdir}2
3911         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3912         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3913         ls $tmp_dir/symlink12 || error "listing symlink12"
3914         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3915 }
3916 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3917
3918 test_32i() {
3919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3920
3921         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3922         trap cleanup_test32_mount EXIT
3923         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3924         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3925                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3926         touch $DIR/$tdir/test_file
3927         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3928                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3929         cleanup_test32_mount
3930 }
3931 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3932
3933 test_32j() {
3934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3935
3936         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3937         trap cleanup_test32_mount EXIT
3938         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3939         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3940                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3941         touch $DIR/$tdir/test_file
3942         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3943                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3944         cleanup_test32_mount
3945 }
3946 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3947
3948 test_32k() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         rm -fr $DIR/$tdir
3952         trap cleanup_test32_mount EXIT
3953         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3954         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3955                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3956         test_mkdir -p $DIR/$tdir/d2
3957         touch $DIR/$tdir/d2/test_file || error "touch failed"
3958         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3959                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3960         cleanup_test32_mount
3961 }
3962 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3963
3964 test_32l() {
3965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3966
3967         rm -fr $DIR/$tdir
3968         trap cleanup_test32_mount EXIT
3969         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3970         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3971                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3972         test_mkdir -p $DIR/$tdir/d2
3973         touch $DIR/$tdir/d2/test_file || error "touch failed"
3974         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3975                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3976         cleanup_test32_mount
3977 }
3978 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3979
3980 test_32m() {
3981         rm -fr $DIR/d32m
3982         test_mkdir -p $DIR/d32m/tmp
3983         TMP_DIR=$DIR/d32m/tmp
3984         ln -s $DIR $TMP_DIR/symlink11
3985         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3986         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3987                 error "symlink11 not a link"
3988         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3989                 error "symlink01 not a link"
3990 }
3991 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3992
3993 test_32n() {
3994         rm -fr $DIR/d32n
3995         test_mkdir -p $DIR/d32n/tmp
3996         TMP_DIR=$DIR/d32n/tmp
3997         ln -s $DIR $TMP_DIR/symlink11
3998         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3999         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4000         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4001 }
4002 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4003
4004 test_32o() {
4005         touch $DIR/$tfile
4006         test_mkdir -p $DIR/d32o/tmp
4007         TMP_DIR=$DIR/d32o/tmp
4008         ln -s $DIR/$tfile $TMP_DIR/symlink12
4009         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4010         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4011                 error "symlink12 not a link"
4012         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4013         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4014                 error "$DIR/d32o/tmp/symlink12 not file type"
4015         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4016                 error "$DIR/d32o/symlink02 not file type"
4017 }
4018 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4019
4020 test_32p() {
4021         log 32p_1
4022         rm -fr $DIR/d32p
4023         log 32p_2
4024         rm -f $DIR/$tfile
4025         log 32p_3
4026         touch $DIR/$tfile
4027         log 32p_4
4028         test_mkdir -p $DIR/d32p/tmp
4029         log 32p_5
4030         TMP_DIR=$DIR/d32p/tmp
4031         log 32p_6
4032         ln -s $DIR/$tfile $TMP_DIR/symlink12
4033         log 32p_7
4034         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4035         log 32p_8
4036         cat $DIR/d32p/tmp/symlink12 ||
4037                 error "Can't open $DIR/d32p/tmp/symlink12"
4038         log 32p_9
4039         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4040         log 32p_10
4041 }
4042 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4043
4044 test_32q() {
4045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4046
4047         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4048         trap cleanup_test32_mount EXIT
4049         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4050         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4051         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4052                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4053         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4054         cleanup_test32_mount
4055 }
4056 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4057
4058 test_32r() {
4059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4060
4061         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4062         trap cleanup_test32_mount EXIT
4063         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4064         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4065         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4066                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4067         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4068         cleanup_test32_mount
4069 }
4070 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4071
4072 test_33aa() {
4073         rm -f $DIR/$tfile
4074         touch $DIR/$tfile
4075         chmod 444 $DIR/$tfile
4076         chown $RUNAS_ID $DIR/$tfile
4077         log 33_1
4078         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4079         log 33_2
4080 }
4081 run_test 33aa "write file with mode 444 (should return error)"
4082
4083 test_33a() {
4084         rm -fr $DIR/$tdir
4085         test_mkdir $DIR/$tdir
4086         chown $RUNAS_ID $DIR/$tdir
4087         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4088                 error "$RUNAS create $tdir/$tfile failed"
4089         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4090                 error "open RDWR" || true
4091 }
4092 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4093
4094 test_33b() {
4095         rm -fr $DIR/$tdir
4096         test_mkdir $DIR/$tdir
4097         chown $RUNAS_ID $DIR/$tdir
4098         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4099 }
4100 run_test 33b "test open file with malformed flags (No panic)"
4101
4102 test_33c() {
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104         remote_ost_nodsh && skip "remote OST with nodsh"
4105
4106         local ostnum
4107         local ostname
4108         local write_bytes
4109         local all_zeros
4110
4111         all_zeros=true
4112         test_mkdir $DIR/$tdir
4113         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4114
4115         sync
4116         for ostnum in $(seq $OSTCOUNT); do
4117                 # test-framework's OST numbering is one-based, while Lustre's
4118                 # is zero-based
4119                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4120                 # check if at least some write_bytes stats are counted
4121                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4122                               obdfilter.$ostname.stats |
4123                               awk '/^write_bytes/ {print $7}' )
4124                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4125                 if (( ${write_bytes:-0} > 0 )); then
4126                         all_zeros=false
4127                         break
4128                 fi
4129         done
4130
4131         $all_zeros || return 0
4132
4133         # Write four bytes
4134         echo foo > $DIR/$tdir/bar
4135         # Really write them
4136         sync
4137
4138         # Total up write_bytes after writing.  We'd better find non-zeros.
4139         for ostnum in $(seq $OSTCOUNT); do
4140                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4141                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4142                               obdfilter/$ostname/stats |
4143                               awk '/^write_bytes/ {print $7}' )
4144                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4145                 if (( ${write_bytes:-0} > 0 )); then
4146                         all_zeros=false
4147                         break
4148                 fi
4149         done
4150
4151         if $all_zeros; then
4152                 for ostnum in $(seq $OSTCOUNT); do
4153                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4154                         echo "Check write_bytes is in obdfilter.*.stats:"
4155                         do_facet ost$ostnum lctl get_param -n \
4156                                 obdfilter.$ostname.stats
4157                 done
4158                 error "OST not keeping write_bytes stats (b=22312)"
4159         fi
4160 }
4161 run_test 33c "test write_bytes stats"
4162
4163 test_33d() {
4164         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4166
4167         local MDTIDX=1
4168         local remote_dir=$DIR/$tdir/remote_dir
4169
4170         test_mkdir $DIR/$tdir
4171         $LFS mkdir -i $MDTIDX $remote_dir ||
4172                 error "create remote directory failed"
4173
4174         touch $remote_dir/$tfile
4175         chmod 444 $remote_dir/$tfile
4176         chown $RUNAS_ID $remote_dir/$tfile
4177
4178         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4179
4180         chown $RUNAS_ID $remote_dir
4181         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4182                                         error "create" || true
4183         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4184                                     error "open RDWR" || true
4185         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4186 }
4187 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4188
4189 test_33e() {
4190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4191
4192         mkdir $DIR/$tdir
4193
4194         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4195         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4196         mkdir $DIR/$tdir/local_dir
4197
4198         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4199         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4200         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4201
4202         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4203                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4204
4205         rmdir $DIR/$tdir/* || error "rmdir failed"
4206
4207         umask 777
4208         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4209         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4210         mkdir $DIR/$tdir/local_dir
4211
4212         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4213         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4214         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4215
4216         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4217                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4218
4219         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4220
4221         umask 000
4222         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4223         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4224         mkdir $DIR/$tdir/local_dir
4225
4226         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4227         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4228         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4229
4230         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4231                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4232 }
4233 run_test 33e "mkdir and striped directory should have same mode"
4234
4235 cleanup_33f() {
4236         trap 0
4237         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4238 }
4239
4240 test_33f() {
4241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4242         remote_mds_nodsh && skip "remote MDS with nodsh"
4243
4244         mkdir $DIR/$tdir
4245         chmod go+rwx $DIR/$tdir
4246         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4247         trap cleanup_33f EXIT
4248
4249         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4250                 error "cannot create striped directory"
4251
4252         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4253                 error "cannot create files in striped directory"
4254
4255         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4256                 error "cannot remove files in striped directory"
4257
4258         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4259                 error "cannot remove striped directory"
4260
4261         cleanup_33f
4262 }
4263 run_test 33f "nonroot user can create, access, and remove a striped directory"
4264
4265 test_33g() {
4266         mkdir -p $DIR/$tdir/dir2
4267
4268         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4269         echo $err
4270         [[ $err =~ "exists" ]] || error "Not exists error"
4271 }
4272 run_test 33g "nonroot user create already existing root created file"
4273
4274 sub_33h() {
4275         local hash_type=$1
4276         local count=250
4277
4278         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4279                 error "lfs mkdir -H $hash_type $tdir failed"
4280         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4281
4282         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4283         local index2
4284         local fname
4285
4286         for fname in $DIR/$tdir/$tfile.bak \
4287                      $DIR/$tdir/$tfile.SAV \
4288                      $DIR/$tdir/$tfile.orig \
4289                      $DIR/$tdir/$tfile~; do
4290                 touch $fname || error "touch $fname failed"
4291                 index2=$($LFS getstripe -m $fname)
4292                 (( $index == $index2 )) ||
4293                         error "$fname MDT index mismatch $index != $index2"
4294         done
4295
4296         local failed=0
4297         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4298         local pattern
4299
4300         for pattern in ${patterns[*]}; do
4301                 echo "pattern $pattern"
4302                 fname=$DIR/$tdir/$pattern
4303                 for (( i = 0; i < $count; i++ )); do
4304                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4305                                 error "mktemp $DIR/$tdir/$pattern failed"
4306                         index2=$($LFS getstripe -m $fname)
4307                         (( $index == $index2 )) && continue
4308
4309                         failed=$((failed + 1))
4310                         echo "$fname MDT index mismatch $index != $index2"
4311                 done
4312         done
4313
4314         echo "$failed/$count MDT index mismatches, expect ~2-4"
4315         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4316
4317         local same=0
4318         local expect
4319
4320         # verify that "crush" is still broken with all files on same MDT,
4321         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4322         [[ "$hash_type" == "crush" ]] && expect=$count ||
4323                 expect=$((count / MDSCOUNT))
4324
4325         # crush2 doesn't put all-numeric suffixes on the same MDT,
4326         # filename like $tfile.12345678 should *not* be considered temp
4327         for pattern in ${patterns[*]}; do
4328                 local base=${pattern%%X*}
4329                 local suff=${pattern#$base}
4330
4331                 echo "pattern $pattern"
4332                 for (( i = 0; i < $count; i++ )); do
4333                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4334                         touch $fname || error "touch $fname failed"
4335                         index2=$($LFS getstripe -m $fname)
4336                         (( $index != $index2 )) && continue
4337
4338                         same=$((same + 1))
4339                 done
4340         done
4341
4342         # the number of "bad" hashes is random, as it depends on the random
4343         # filenames generated by "mktemp".  Allow some margin in the results.
4344         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4345         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4346            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4347                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4348         same=0
4349
4350         # crush2 doesn't put suffixes with special characters on the same MDT
4351         # filename like $tfile.txt.1234 should *not* be considered temp
4352         for pattern in ${patterns[*]}; do
4353                 local base=${pattern%%X*}
4354                 local suff=${pattern#$base}
4355
4356                 pattern=$base...${suff/XXX}
4357                 echo "pattern=$pattern"
4358                 for (( i = 0; i < $count; i++ )); do
4359                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4360                                 error "touch $fname failed"
4361                         index2=$($LFS getstripe -m $fname)
4362                         (( $index != $index2 )) && continue
4363
4364                         same=$((same + 1))
4365                 done
4366         done
4367
4368         # the number of "bad" hashes is random, as it depends on the random
4369         # filenames generated by "mktemp".  Allow some margin in the results.
4370         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4371         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4372            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4373                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4374 }
4375
4376 test_33h() {
4377         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4378         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4379                 skip "Need MDS version at least 2.13.50"
4380
4381         sub_33h crush
4382 }
4383 run_test 33h "temp file is located on the same MDT as target (crush)"
4384
4385 test_33hh() {
4386         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4387         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4388         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4389                 skip "Need MDS version at least 2.15.0 for crush2"
4390
4391         sub_33h crush2
4392 }
4393 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4394
4395 test_33i()
4396 {
4397         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4398
4399         local FNAME=$(str_repeat 'f' 250)
4400
4401         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4402         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4403
4404         local count
4405         local total
4406
4407         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4408
4409         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4410
4411         lctl --device %$MDC deactivate
4412         stack_trap "lctl --device %$MDC activate"
4413         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4414         total=$(\ls -l $DIR/$tdir | wc -l)
4415         # "ls -l" will list total in the first line
4416         total=$((total - 1))
4417         (( total + count == 1000 )) ||
4418                 error "ls list $total files, $count files on MDT1"
4419 }
4420 run_test 33i "striped directory can be accessed when one MDT is down"
4421
4422 test_33j() {
4423         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4424
4425         mkdir -p $DIR/$tdir/
4426
4427         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4428                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4429
4430         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4431                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4432
4433         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4434                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4435
4436         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4437                 error "-D was not specified, but still failed"
4438 }
4439 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4440
4441 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4442 test_34a() {
4443         rm -f $DIR/f34
4444         $MCREATE $DIR/f34 || error "mcreate failed"
4445         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4446                 error "getstripe failed"
4447         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4448         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4449                 error "getstripe failed"
4450         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4451                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4452 }
4453 run_test 34a "truncate file that has not been opened ==========="
4454
4455 test_34b() {
4456         [ ! -f $DIR/f34 ] && test_34a
4457         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4458                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4459         $OPENFILE -f O_RDONLY $DIR/f34
4460         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4461                 error "getstripe failed"
4462         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4463                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4464 }
4465 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4466
4467 test_34c() {
4468         [ ! -f $DIR/f34 ] && test_34a
4469         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4470                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4471         $OPENFILE -f O_RDWR $DIR/f34
4472         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4473                 error "$LFS getstripe failed"
4474         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4475                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4476 }
4477 run_test 34c "O_RDWR opening file-with-size works =============="
4478
4479 test_34d() {
4480         [ ! -f $DIR/f34 ] && test_34a
4481         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4482                 error "dd failed"
4483         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4484                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4485         rm $DIR/f34
4486 }
4487 run_test 34d "write to sparse file ============================="
4488
4489 test_34e() {
4490         rm -f $DIR/f34e
4491         $MCREATE $DIR/f34e || error "mcreate failed"
4492         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4493         $CHECKSTAT -s 1000 $DIR/f34e ||
4494                 error "Size of $DIR/f34e not equal to 1000 bytes"
4495         $OPENFILE -f O_RDWR $DIR/f34e
4496         $CHECKSTAT -s 1000 $DIR/f34e ||
4497                 error "Size of $DIR/f34e not equal to 1000 bytes"
4498 }
4499 run_test 34e "create objects, some with size and some without =="
4500
4501 test_34f() { # bug 6242, 6243
4502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4503
4504         SIZE34F=48000
4505         rm -f $DIR/f34f
4506         $MCREATE $DIR/f34f || error "mcreate failed"
4507         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4508         dd if=$DIR/f34f of=$TMP/f34f
4509         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4510         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4511         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4512         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4513         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4514 }
4515 run_test 34f "read from a file with no objects until EOF ======="
4516
4517 test_34g() {
4518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4519
4520         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4521                 error "dd failed"
4522         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4523         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4524                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4525         cancel_lru_locks osc
4526         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4527                 error "wrong size after lock cancel"
4528
4529         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4530         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4531                 error "expanding truncate failed"
4532         cancel_lru_locks osc
4533         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4534                 error "wrong expanded size after lock cancel"
4535 }
4536 run_test 34g "truncate long file ==============================="
4537
4538 test_34h() {
4539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4540
4541         local gid=10
4542         local sz=1000
4543
4544         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4545         sync # Flush the cache so that multiop below does not block on cache
4546              # flush when getting the group lock
4547         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4548         MULTIPID=$!
4549
4550         # Since just timed wait is not good enough, let's do a sync write
4551         # that way we are sure enough time for a roundtrip + processing
4552         # passed + 2 seconds of extra margin.
4553         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4554         rm $DIR/${tfile}-1
4555         sleep 2
4556
4557         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4558                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4559                 kill -9 $MULTIPID
4560         fi
4561         wait $MULTIPID
4562         local nsz=`stat -c %s $DIR/$tfile`
4563         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4564 }
4565 run_test 34h "ftruncate file under grouplock should not block"
4566
4567 test_35a() {
4568         cp /bin/sh $DIR/f35a
4569         chmod 444 $DIR/f35a
4570         chown $RUNAS_ID $DIR/f35a
4571         $RUNAS $DIR/f35a && error || true
4572         rm $DIR/f35a
4573 }
4574 run_test 35a "exec file with mode 444 (should return and not leak)"
4575
4576 test_36a() {
4577         rm -f $DIR/f36
4578         utime $DIR/f36 || error "utime failed for MDS"
4579 }
4580 run_test 36a "MDS utime check (mknod, utime)"
4581
4582 test_36b() {
4583         echo "" > $DIR/f36
4584         utime $DIR/f36 || error "utime failed for OST"
4585 }
4586 run_test 36b "OST utime check (open, utime)"
4587
4588 test_36c() {
4589         rm -f $DIR/d36/f36
4590         test_mkdir $DIR/d36
4591         chown $RUNAS_ID $DIR/d36
4592         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4593 }
4594 run_test 36c "non-root MDS utime check (mknod, utime)"
4595
4596 test_36d() {
4597         [ ! -d $DIR/d36 ] && test_36c
4598         echo "" > $DIR/d36/f36
4599         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4600 }
4601 run_test 36d "non-root OST utime check (open, utime)"
4602
4603 test_36e() {
4604         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4605
4606         test_mkdir $DIR/$tdir
4607         touch $DIR/$tdir/$tfile
4608         $RUNAS utime $DIR/$tdir/$tfile &&
4609                 error "utime worked, expected failure" || true
4610 }
4611 run_test 36e "utime on non-owned file (should return error)"
4612
4613 subr_36fh() {
4614         local fl="$1"
4615         local LANG_SAVE=$LANG
4616         local LC_LANG_SAVE=$LC_LANG
4617         export LANG=C LC_LANG=C # for date language
4618
4619         DATESTR="Dec 20  2000"
4620         test_mkdir $DIR/$tdir
4621         lctl set_param fail_loc=$fl
4622         date; date +%s
4623         cp /etc/hosts $DIR/$tdir/$tfile
4624         sync & # write RPC generated with "current" inode timestamp, but delayed
4625         sleep 1
4626         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4627         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4628         cancel_lru_locks $OSC
4629         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4630         date; date +%s
4631         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4632                 echo "BEFORE: $LS_BEFORE" && \
4633                 echo "AFTER : $LS_AFTER" && \
4634                 echo "WANT  : $DATESTR" && \
4635                 error "$DIR/$tdir/$tfile timestamps changed" || true
4636
4637         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4638 }
4639
4640 test_36f() {
4641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4642
4643         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4644         subr_36fh "0x80000214"
4645 }
4646 run_test 36f "utime on file racing with OST BRW write =========="
4647
4648 test_36g() {
4649         remote_ost_nodsh && skip "remote OST with nodsh"
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4652                 skip "Need MDS version at least 2.12.51"
4653
4654         local fmd_max_age
4655         local fmd
4656         local facet="ost1"
4657         local tgt="obdfilter"
4658
4659         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4660
4661         test_mkdir $DIR/$tdir
4662         fmd_max_age=$(do_facet $facet \
4663                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4664                 head -n 1")
4665
4666         echo "FMD max age: ${fmd_max_age}s"
4667         touch $DIR/$tdir/$tfile
4668         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4669                 gawk '{cnt=cnt+$1}  END{print cnt}')
4670         echo "FMD before: $fmd"
4671         [[ $fmd == 0 ]] &&
4672                 error "FMD wasn't create by touch"
4673         sleep $((fmd_max_age + 12))
4674         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4675                 gawk '{cnt=cnt+$1}  END{print cnt}')
4676         echo "FMD after: $fmd"
4677         [[ $fmd == 0 ]] ||
4678                 error "FMD wasn't expired by ping"
4679 }
4680 run_test 36g "FMD cache expiry ====================="
4681
4682 test_36h() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4686         subr_36fh "0x80000227"
4687 }
4688 run_test 36h "utime on file racing with OST BRW write =========="
4689
4690 test_36i() {
4691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4692
4693         test_mkdir $DIR/$tdir
4694         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4695
4696         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4697         local new_mtime=$((mtime + 200))
4698
4699         #change Modify time of striped dir
4700         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4701                         error "change mtime failed"
4702
4703         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4704
4705         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4706 }
4707 run_test 36i "change mtime on striped directory"
4708
4709 # test_37 - duplicate with tests 32q 32r
4710
4711 test_38() {
4712         local file=$DIR/$tfile
4713         touch $file
4714         openfile -f O_DIRECTORY $file
4715         local RC=$?
4716         local ENOTDIR=20
4717         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4718         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4719 }
4720 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4721
4722 test_39a() { # was test_39
4723         touch $DIR/$tfile
4724         touch $DIR/${tfile}2
4725 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4726 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4727 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4728         sleep 2
4729         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4730         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4731                 echo "mtime"
4732                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4733                 echo "atime"
4734                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4735                 echo "ctime"
4736                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4737                 error "O_TRUNC didn't change timestamps"
4738         fi
4739 }
4740 run_test 39a "mtime changed on create"
4741
4742 test_39b() {
4743         test_mkdir -c1 $DIR/$tdir
4744         cp -p /etc/passwd $DIR/$tdir/fopen
4745         cp -p /etc/passwd $DIR/$tdir/flink
4746         cp -p /etc/passwd $DIR/$tdir/funlink
4747         cp -p /etc/passwd $DIR/$tdir/frename
4748         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4749
4750         sleep 1
4751         echo "aaaaaa" >> $DIR/$tdir/fopen
4752         echo "aaaaaa" >> $DIR/$tdir/flink
4753         echo "aaaaaa" >> $DIR/$tdir/funlink
4754         echo "aaaaaa" >> $DIR/$tdir/frename
4755
4756         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4757         local link_new=`stat -c %Y $DIR/$tdir/flink`
4758         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4759         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4760
4761         cat $DIR/$tdir/fopen > /dev/null
4762         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4763         rm -f $DIR/$tdir/funlink2
4764         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4765
4766         for (( i=0; i < 2; i++ )) ; do
4767                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4768                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4769                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4770                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4771
4772                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4773                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4774                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4775                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4776
4777                 cancel_lru_locks $OSC
4778                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4779         done
4780 }
4781 run_test 39b "mtime change on open, link, unlink, rename  ======"
4782
4783 # this should be set to past
4784 TEST_39_MTIME=`date -d "1 year ago" +%s`
4785
4786 # bug 11063
4787 test_39c() {
4788         touch $DIR1/$tfile
4789         sleep 2
4790         local mtime0=`stat -c %Y $DIR1/$tfile`
4791
4792         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4793         local mtime1=`stat -c %Y $DIR1/$tfile`
4794         [ "$mtime1" = $TEST_39_MTIME ] || \
4795                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4796
4797         local d1=`date +%s`
4798         echo hello >> $DIR1/$tfile
4799         local d2=`date +%s`
4800         local mtime2=`stat -c %Y $DIR1/$tfile`
4801         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4802                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4803
4804         mv $DIR1/$tfile $DIR1/$tfile-1
4805
4806         for (( i=0; i < 2; i++ )) ; do
4807                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4808                 [ "$mtime2" = "$mtime3" ] || \
4809                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4810
4811                 cancel_lru_locks $OSC
4812                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4813         done
4814 }
4815 run_test 39c "mtime change on rename ==========================="
4816
4817 # bug 21114
4818 test_39d() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         touch $DIR1/$tfile
4822         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local mtime=`stat -c %Y $DIR1/$tfile`
4826                 [ $mtime = $TEST_39_MTIME ] || \
4827                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4828
4829                 cancel_lru_locks $OSC
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832 }
4833 run_test 39d "create, utime, stat =============================="
4834
4835 # bug 21114
4836 test_39e() {
4837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4838
4839         touch $DIR1/$tfile
4840         local mtime1=`stat -c %Y $DIR1/$tfile`
4841
4842         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4843
4844         for (( i=0; i < 2; i++ )) ; do
4845                 local mtime2=`stat -c %Y $DIR1/$tfile`
4846                 [ $mtime2 = $TEST_39_MTIME ] || \
4847                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4848
4849                 cancel_lru_locks $OSC
4850                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4851         done
4852 }
4853 run_test 39e "create, stat, utime, stat ========================"
4854
4855 # bug 21114
4856 test_39f() {
4857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4858
4859         touch $DIR1/$tfile
4860         mtime1=`stat -c %Y $DIR1/$tfile`
4861
4862         sleep 2
4863         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4864
4865         for (( i=0; i < 2; i++ )) ; do
4866                 local mtime2=`stat -c %Y $DIR1/$tfile`
4867                 [ $mtime2 = $TEST_39_MTIME ] || \
4868                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4869
4870                 cancel_lru_locks $OSC
4871                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4872         done
4873 }
4874 run_test 39f "create, stat, sleep, utime, stat ================="
4875
4876 # bug 11063
4877 test_39g() {
4878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4879
4880         echo hello >> $DIR1/$tfile
4881         local mtime1=`stat -c %Y $DIR1/$tfile`
4882
4883         sleep 2
4884         chmod o+r $DIR1/$tfile
4885
4886         for (( i=0; i < 2; i++ )) ; do
4887                 local mtime2=`stat -c %Y $DIR1/$tfile`
4888                 [ "$mtime1" = "$mtime2" ] || \
4889                         error "lost mtime: $mtime2, should be $mtime1"
4890
4891                 cancel_lru_locks $OSC
4892                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4893         done
4894 }
4895 run_test 39g "write, chmod, stat ==============================="
4896
4897 # bug 11063
4898 test_39h() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         touch $DIR1/$tfile
4902         sleep 1
4903
4904         local d1=`date`
4905         echo hello >> $DIR1/$tfile
4906         local mtime1=`stat -c %Y $DIR1/$tfile`
4907
4908         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4909         local d2=`date`
4910         if [ "$d1" != "$d2" ]; then
4911                 echo "write and touch not within one second"
4912         else
4913                 for (( i=0; i < 2; i++ )) ; do
4914                         local mtime2=`stat -c %Y $DIR1/$tfile`
4915                         [ "$mtime2" = $TEST_39_MTIME ] || \
4916                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4917
4918                         cancel_lru_locks $OSC
4919                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4920                 done
4921         fi
4922 }
4923 run_test 39h "write, utime within one second, stat ============="
4924
4925 test_39i() {
4926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4927
4928         touch $DIR1/$tfile
4929         sleep 1
4930
4931         echo hello >> $DIR1/$tfile
4932         local mtime1=`stat -c %Y $DIR1/$tfile`
4933
4934         mv $DIR1/$tfile $DIR1/$tfile-1
4935
4936         for (( i=0; i < 2; i++ )) ; do
4937                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4938
4939                 [ "$mtime1" = "$mtime2" ] || \
4940                         error "lost mtime: $mtime2, should be $mtime1"
4941
4942                 cancel_lru_locks $OSC
4943                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4944         done
4945 }
4946 run_test 39i "write, rename, stat =============================="
4947
4948 test_39j() {
4949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4950
4951         start_full_debug_logging
4952         touch $DIR1/$tfile
4953         sleep 1
4954
4955         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4956         lctl set_param fail_loc=0x80000412
4957         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4958                 error "multiop failed"
4959         local multipid=$!
4960         local mtime1=`stat -c %Y $DIR1/$tfile`
4961
4962         mv $DIR1/$tfile $DIR1/$tfile-1
4963
4964         kill -USR1 $multipid
4965         wait $multipid || error "multiop close failed"
4966
4967         for (( i=0; i < 2; i++ )) ; do
4968                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4969                 [ "$mtime1" = "$mtime2" ] ||
4970                         error "mtime is lost on close: $mtime2, " \
4971                               "should be $mtime1"
4972
4973                 cancel_lru_locks
4974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4975         done
4976         lctl set_param fail_loc=0
4977         stop_full_debug_logging
4978 }
4979 run_test 39j "write, rename, close, stat ======================="
4980
4981 test_39k() {
4982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4983
4984         touch $DIR1/$tfile
4985         sleep 1
4986
4987         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4988         local multipid=$!
4989         local mtime1=`stat -c %Y $DIR1/$tfile`
4990
4991         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4992
4993         kill -USR1 $multipid
4994         wait $multipid || error "multiop close failed"
4995
4996         for (( i=0; i < 2; i++ )) ; do
4997                 local mtime2=`stat -c %Y $DIR1/$tfile`
4998
4999                 [ "$mtime2" = $TEST_39_MTIME ] || \
5000                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5001
5002                 cancel_lru_locks
5003                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5004         done
5005 }
5006 run_test 39k "write, utime, close, stat ========================"
5007
5008 # this should be set to future
5009 TEST_39_ATIME=`date -d "1 year" +%s`
5010
5011 test_39l() {
5012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5013         remote_mds_nodsh && skip "remote MDS with nodsh"
5014
5015         local atime_diff=$(do_facet $SINGLEMDS \
5016                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5017         rm -rf $DIR/$tdir
5018         mkdir_on_mdt0 $DIR/$tdir
5019
5020         # test setting directory atime to future
5021         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5022         local atime=$(stat -c %X $DIR/$tdir)
5023         [ "$atime" = $TEST_39_ATIME ] ||
5024                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5025
5026         # test setting directory atime from future to now
5027         local now=$(date +%s)
5028         touch -a -d @$now $DIR/$tdir
5029
5030         atime=$(stat -c %X $DIR/$tdir)
5031         [ "$atime" -eq "$now"  ] ||
5032                 error "atime is not updated from future: $atime, $now"
5033
5034         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5035         sleep 3
5036
5037         # test setting directory atime when now > dir atime + atime_diff
5038         local d1=$(date +%s)
5039         ls $DIR/$tdir
5040         local d2=$(date +%s)
5041         cancel_lru_locks mdc
5042         atime=$(stat -c %X $DIR/$tdir)
5043         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5044                 error "atime is not updated  : $atime, should be $d2"
5045
5046         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5047         sleep 3
5048
5049         # test not setting directory atime when now < dir atime + atime_diff
5050         ls $DIR/$tdir
5051         cancel_lru_locks mdc
5052         atime=$(stat -c %X $DIR/$tdir)
5053         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5054                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5055
5056         do_facet $SINGLEMDS \
5057                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5058 }
5059 run_test 39l "directory atime update ==========================="
5060
5061 test_39m() {
5062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5063
5064         touch $DIR1/$tfile
5065         sleep 2
5066         local far_past_mtime=$(date -d "May 29 1953" +%s)
5067         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5068
5069         touch -m -d @$far_past_mtime $DIR1/$tfile
5070         touch -a -d @$far_past_atime $DIR1/$tfile
5071
5072         for (( i=0; i < 2; i++ )) ; do
5073                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5074                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5075                         error "atime or mtime set incorrectly"
5076
5077                 cancel_lru_locks $OSC
5078                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5079         done
5080 }
5081 run_test 39m "test atime and mtime before 1970"
5082
5083 test_39n() { # LU-3832
5084         remote_mds_nodsh && skip "remote MDS with nodsh"
5085
5086         local atime_diff=$(do_facet $SINGLEMDS \
5087                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5088         local atime0
5089         local atime1
5090         local atime2
5091
5092         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5093
5094         rm -rf $DIR/$tfile
5095         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5096         atime0=$(stat -c %X $DIR/$tfile)
5097
5098         sleep 5
5099         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5100         atime1=$(stat -c %X $DIR/$tfile)
5101
5102         sleep 5
5103         cancel_lru_locks mdc
5104         cancel_lru_locks osc
5105         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5106         atime2=$(stat -c %X $DIR/$tfile)
5107
5108         do_facet $SINGLEMDS \
5109                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5110
5111         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5112         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5113 }
5114 run_test 39n "check that O_NOATIME is honored"
5115
5116 test_39o() {
5117         TESTDIR=$DIR/$tdir/$tfile
5118         [ -e $TESTDIR ] && rm -rf $TESTDIR
5119         mkdir -p $TESTDIR
5120         cd $TESTDIR
5121         links1=2
5122         ls
5123         mkdir a b
5124         ls
5125         links2=$(stat -c %h .)
5126         [ $(($links1 + 2)) != $links2 ] &&
5127                 error "wrong links count $(($links1 + 2)) != $links2"
5128         rmdir b
5129         links3=$(stat -c %h .)
5130         [ $(($links1 + 1)) != $links3 ] &&
5131                 error "wrong links count $links1 != $links3"
5132         return 0
5133 }
5134 run_test 39o "directory cached attributes updated after create"
5135
5136 test_39p() {
5137         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5138
5139         local MDTIDX=1
5140         TESTDIR=$DIR/$tdir/$tdir
5141         [ -e $TESTDIR ] && rm -rf $TESTDIR
5142         test_mkdir -p $TESTDIR
5143         cd $TESTDIR
5144         links1=2
5145         ls
5146         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5147         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5148         ls
5149         links2=$(stat -c %h .)
5150         [ $(($links1 + 2)) != $links2 ] &&
5151                 error "wrong links count $(($links1 + 2)) != $links2"
5152         rmdir remote_dir2
5153         links3=$(stat -c %h .)
5154         [ $(($links1 + 1)) != $links3 ] &&
5155                 error "wrong links count $links1 != $links3"
5156         return 0
5157 }
5158 run_test 39p "remote directory cached attributes updated after create ========"
5159
5160 test_39r() {
5161         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5162                 skip "no atime update on old OST"
5163         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5164                 skip_env "ldiskfs only test"
5165         fi
5166
5167         local saved_adiff
5168         saved_adiff=$(do_facet ost1 \
5169                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5170         stack_trap "do_facet ost1 \
5171                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5172
5173         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5174
5175         $LFS setstripe -i 0 $DIR/$tfile
5176         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5177                 error "can't write initial file"
5178         cancel_lru_locks osc
5179
5180         # exceed atime_diff and access file
5181         sleep 10
5182         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5183                 error "can't udpate atime"
5184
5185         local atime_cli=$(stat -c %X $DIR/$tfile)
5186         echo "client atime: $atime_cli"
5187         # allow atime update to be written to device
5188         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5189         sleep 5
5190
5191         local ostdev=$(ostdevname 1)
5192         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5193         local seq=${fid[3]#0x}
5194         local oid=${fid[1]}
5195         local oid_hex
5196
5197         if [ $seq == 0 ]; then
5198                 oid_hex=${fid[1]}
5199         else
5200                 oid_hex=${fid[2]#0x}
5201         fi
5202         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5203         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5204
5205         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5206         local atime_ost=$(do_facet ost1 "$cmd" |&
5207                           awk -F'[: ]' '/atime:/ { print $4 }')
5208         (( atime_cli == atime_ost )) ||
5209                 error "atime on client $atime_cli != ost $atime_ost"
5210 }
5211 run_test 39r "lazy atime update on OST"
5212
5213 test_39q() { # LU-8041
5214         local testdir=$DIR/$tdir
5215         mkdir -p $testdir
5216         multiop_bg_pause $testdir D_c || error "multiop failed"
5217         local multipid=$!
5218         cancel_lru_locks mdc
5219         kill -USR1 $multipid
5220         local atime=$(stat -c %X $testdir)
5221         [ "$atime" -ne 0 ] || error "atime is zero"
5222 }
5223 run_test 39q "close won't zero out atime"
5224
5225 test_40() {
5226         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5227         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5228                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5229         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5230                 error "$tfile is not 4096 bytes in size"
5231 }
5232 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5233
5234 test_41() {
5235         # bug 1553
5236         small_write $DIR/f41 18
5237 }
5238 run_test 41 "test small file write + fstat ====================="
5239
5240 count_ost_writes() {
5241         lctl get_param -n ${OSC}.*.stats |
5242                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5243                         END { printf("%0.0f", writes) }'
5244 }
5245
5246 # decent default
5247 WRITEBACK_SAVE=500
5248 DIRTY_RATIO_SAVE=40
5249 MAX_DIRTY_RATIO=50
5250 BG_DIRTY_RATIO_SAVE=10
5251 MAX_BG_DIRTY_RATIO=25
5252
5253 start_writeback() {
5254         trap 0
5255         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5256         # dirty_ratio, dirty_background_ratio
5257         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5258                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5259                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5260                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5261         else
5262                 # if file not here, we are a 2.4 kernel
5263                 kill -CONT `pidof kupdated`
5264         fi
5265 }
5266
5267 stop_writeback() {
5268         # setup the trap first, so someone cannot exit the test at the
5269         # exact wrong time and mess up a machine
5270         trap start_writeback EXIT
5271         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5272         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5273                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5274                 sysctl -w vm.dirty_writeback_centisecs=0
5275                 sysctl -w vm.dirty_writeback_centisecs=0
5276                 # save and increase /proc/sys/vm/dirty_ratio
5277                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5278                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5279                 # save and increase /proc/sys/vm/dirty_background_ratio
5280                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5281                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5282         else
5283                 # if file not here, we are a 2.4 kernel
5284                 kill -STOP `pidof kupdated`
5285         fi
5286 }
5287
5288 # ensure that all stripes have some grant before we test client-side cache
5289 setup_test42() {
5290         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5291                 dd if=/dev/zero of=$i bs=4k count=1
5292                 rm $i
5293         done
5294 }
5295
5296 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5297 # file truncation, and file removal.
5298 test_42a() {
5299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5300
5301         setup_test42
5302         cancel_lru_locks $OSC
5303         stop_writeback
5304         sync; sleep 1; sync # just to be safe
5305         BEFOREWRITES=`count_ost_writes`
5306         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5307         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5308         AFTERWRITES=`count_ost_writes`
5309         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5310                 error "$BEFOREWRITES < $AFTERWRITES"
5311         start_writeback
5312 }
5313 run_test 42a "ensure that we don't flush on close"
5314
5315 test_42b() {
5316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5317
5318         setup_test42
5319         cancel_lru_locks $OSC
5320         stop_writeback
5321         sync
5322         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5323         BEFOREWRITES=$(count_ost_writes)
5324         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5325         AFTERWRITES=$(count_ost_writes)
5326         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5327                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5328         fi
5329         BEFOREWRITES=$(count_ost_writes)
5330         sync || error "sync: $?"
5331         AFTERWRITES=$(count_ost_writes)
5332         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5333                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5334         fi
5335         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5336         start_writeback
5337         return 0
5338 }
5339 run_test 42b "test destroy of file with cached dirty data ======"
5340
5341 # if these tests just want to test the effect of truncation,
5342 # they have to be very careful.  consider:
5343 # - the first open gets a {0,EOF}PR lock
5344 # - the first write conflicts and gets a {0, count-1}PW
5345 # - the rest of the writes are under {count,EOF}PW
5346 # - the open for truncate tries to match a {0,EOF}PR
5347 #   for the filesize and cancels the PWs.
5348 # any number of fixes (don't get {0,EOF} on open, match
5349 # composite locks, do smarter file size management) fix
5350 # this, but for now we want these tests to verify that
5351 # the cancellation with truncate intent works, so we
5352 # start the file with a full-file pw lock to match against
5353 # until the truncate.
5354 trunc_test() {
5355         test=$1
5356         file=$DIR/$test
5357         offset=$2
5358         cancel_lru_locks $OSC
5359         stop_writeback
5360         # prime the file with 0,EOF PW to match
5361         touch $file
5362         $TRUNCATE $file 0
5363         sync; sync
5364         # now the real test..
5365         dd if=/dev/zero of=$file bs=1024 count=100
5366         BEFOREWRITES=`count_ost_writes`
5367         $TRUNCATE $file $offset
5368         cancel_lru_locks $OSC
5369         AFTERWRITES=`count_ost_writes`
5370         start_writeback
5371 }
5372
5373 test_42c() {
5374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5375
5376         trunc_test 42c 1024
5377         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5378                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5379         rm $file
5380 }
5381 run_test 42c "test partial truncate of file with cached dirty data"
5382
5383 test_42d() {
5384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5385
5386         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5387         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5388         $LCTL set_param debug=+cache
5389
5390         trunc_test 42d 0
5391         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5392                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5393         rm $file
5394 }
5395 run_test 42d "test complete truncate of file with cached dirty data"
5396
5397 test_42e() { # bug22074
5398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5399
5400         local TDIR=$DIR/${tdir}e
5401         local pages=16 # hardcoded 16 pages, don't change it.
5402         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5403         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5404         local max_dirty_mb
5405         local warmup_files
5406
5407         test_mkdir $DIR/${tdir}e
5408         $LFS setstripe -c 1 $TDIR
5409         createmany -o $TDIR/f $files
5410
5411         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5412
5413         # we assume that with $OSTCOUNT files, at least one of them will
5414         # be allocated on OST0.
5415         warmup_files=$((OSTCOUNT * max_dirty_mb))
5416         createmany -o $TDIR/w $warmup_files
5417
5418         # write a large amount of data into one file and sync, to get good
5419         # avail_grant number from OST.
5420         for ((i=0; i<$warmup_files; i++)); do
5421                 idx=$($LFS getstripe -i $TDIR/w$i)
5422                 [ $idx -ne 0 ] && continue
5423                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5424                 break
5425         done
5426         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5427         sync
5428         $LCTL get_param $proc_osc0/cur_dirty_bytes
5429         $LCTL get_param $proc_osc0/cur_grant_bytes
5430
5431         # create as much dirty pages as we can while not to trigger the actual
5432         # RPCs directly. but depends on the env, VFS may trigger flush during this
5433         # period, hopefully we are good.
5434         for ((i=0; i<$warmup_files; i++)); do
5435                 idx=$($LFS getstripe -i $TDIR/w$i)
5436                 [ $idx -ne 0 ] && continue
5437                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5438         done
5439         $LCTL get_param $proc_osc0/cur_dirty_bytes
5440         $LCTL get_param $proc_osc0/cur_grant_bytes
5441
5442         # perform the real test
5443         $LCTL set_param $proc_osc0/rpc_stats 0
5444         for ((;i<$files; i++)); do
5445                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5446                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5447         done
5448         sync
5449         $LCTL get_param $proc_osc0/rpc_stats
5450
5451         local percent=0
5452         local have_ppr=false
5453         $LCTL get_param $proc_osc0/rpc_stats |
5454                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5455                         # skip lines until we are at the RPC histogram data
5456                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5457                         $have_ppr || continue
5458
5459                         # we only want the percent stat for < 16 pages
5460                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5461
5462                         percent=$((percent + WPCT))
5463                         if [[ $percent -gt 15 ]]; then
5464                                 error "less than 16-pages write RPCs" \
5465                                       "$percent% > 15%"
5466                                 break
5467                         fi
5468                 done
5469         rm -rf $TDIR
5470 }
5471 run_test 42e "verify sub-RPC writes are not done synchronously"
5472
5473 test_43A() { # was test_43
5474         test_mkdir $DIR/$tdir
5475         cp -p /bin/ls $DIR/$tdir/$tfile
5476         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5477         pid=$!
5478         # give multiop a chance to open
5479         sleep 1
5480
5481         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5482         kill -USR1 $pid
5483         # Wait for multiop to exit
5484         wait $pid
5485 }
5486 run_test 43A "execution of file opened for write should return -ETXTBSY"
5487
5488 test_43a() {
5489         test_mkdir $DIR/$tdir
5490         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5491         $DIR/$tdir/sleep 60 &
5492         SLEEP_PID=$!
5493         # Make sure exec of $tdir/sleep wins race with truncate
5494         sleep 1
5495         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5496         kill $SLEEP_PID
5497 }
5498 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5499
5500 test_43b() {
5501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5502
5503         test_mkdir $DIR/$tdir
5504         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5505         $DIR/$tdir/sleep 60 &
5506         SLEEP_PID=$!
5507         # Make sure exec of $tdir/sleep wins race with truncate
5508         sleep 1
5509         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5510         kill $SLEEP_PID
5511 }
5512 run_test 43b "truncate of file being executed should return -ETXTBSY"
5513
5514 test_43c() {
5515         local testdir="$DIR/$tdir"
5516         test_mkdir $testdir
5517         cp $SHELL $testdir/
5518         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5519                 ( cd $testdir && md5sum -c )
5520 }
5521 run_test 43c "md5sum of copy into lustre"
5522
5523 test_44A() { # was test_44
5524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5525
5526         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5527         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5528 }
5529 run_test 44A "zero length read from a sparse stripe"
5530
5531 test_44a() {
5532         local nstripe=$($LFS getstripe -c -d $DIR)
5533         [ -z "$nstripe" ] && skip "can't get stripe info"
5534         [[ $nstripe -gt $OSTCOUNT ]] &&
5535                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5536
5537         local stride=$($LFS getstripe -S -d $DIR)
5538         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5539                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5540         fi
5541
5542         OFFSETS="0 $((stride/2)) $((stride-1))"
5543         for offset in $OFFSETS; do
5544                 for i in $(seq 0 $((nstripe-1))); do
5545                         local GLOBALOFFSETS=""
5546                         # size in Bytes
5547                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5548                         local myfn=$DIR/d44a-$size
5549                         echo "--------writing $myfn at $size"
5550                         ll_sparseness_write $myfn $size ||
5551                                 error "ll_sparseness_write"
5552                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5553                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5554                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5555
5556                         for j in $(seq 0 $((nstripe-1))); do
5557                                 # size in Bytes
5558                                 size=$((((j + $nstripe )*$stride + $offset)))
5559                                 ll_sparseness_write $myfn $size ||
5560                                         error "ll_sparseness_write"
5561                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5562                         done
5563                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5564                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5565                         rm -f $myfn
5566                 done
5567         done
5568 }
5569 run_test 44a "test sparse pwrite ==============================="
5570
5571 dirty_osc_total() {
5572         tot=0
5573         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5574                 tot=$(($tot + $d))
5575         done
5576         echo $tot
5577 }
5578 do_dirty_record() {
5579         before=`dirty_osc_total`
5580         echo executing "\"$*\""
5581         eval $*
5582         after=`dirty_osc_total`
5583         echo before $before, after $after
5584 }
5585 test_45() {
5586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5587
5588         f="$DIR/f45"
5589         # Obtain grants from OST if it supports it
5590         echo blah > ${f}_grant
5591         stop_writeback
5592         sync
5593         do_dirty_record "echo blah > $f"
5594         [[ $before -eq $after ]] && error "write wasn't cached"
5595         do_dirty_record "> $f"
5596         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5597         do_dirty_record "echo blah > $f"
5598         [[ $before -eq $after ]] && error "write wasn't cached"
5599         do_dirty_record "sync"
5600         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5601         do_dirty_record "echo blah > $f"
5602         [[ $before -eq $after ]] && error "write wasn't cached"
5603         do_dirty_record "cancel_lru_locks osc"
5604         [[ $before -gt $after ]] ||
5605                 error "lock cancellation didn't lower dirty count"
5606         start_writeback
5607 }
5608 run_test 45 "osc io page accounting ============================"
5609
5610 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5611 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5612 # objects offset and an assert hit when an rpc was built with 1023's mapped
5613 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5614 test_46() {
5615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5616
5617         f="$DIR/f46"
5618         stop_writeback
5619         sync
5620         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5621         sync
5622         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5623         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5624         sync
5625         start_writeback
5626 }
5627 run_test 46 "dirtying a previously written page ================"
5628
5629 # test_47 is removed "Device nodes check" is moved to test_28
5630
5631 test_48a() { # bug 2399
5632         [ "$mds1_FSTYPE" = "zfs" ] &&
5633         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5634                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5635
5636         test_mkdir $DIR/$tdir
5637         cd $DIR/$tdir
5638         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5639         test_mkdir $DIR/$tdir
5640         touch foo || error "'touch foo' failed after recreating cwd"
5641         test_mkdir bar
5642         touch .foo || error "'touch .foo' failed after recreating cwd"
5643         test_mkdir .bar
5644         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5645         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5646         cd . || error "'cd .' failed after recreating cwd"
5647         mkdir . && error "'mkdir .' worked after recreating cwd"
5648         rmdir . && error "'rmdir .' worked after recreating cwd"
5649         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5650         cd .. || error "'cd ..' failed after recreating cwd"
5651 }
5652 run_test 48a "Access renamed working dir (should return errors)="
5653
5654 test_48b() { # bug 2399
5655         rm -rf $DIR/$tdir
5656         test_mkdir $DIR/$tdir
5657         cd $DIR/$tdir
5658         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5659         touch foo && error "'touch foo' worked after removing cwd"
5660         mkdir foo && error "'mkdir foo' worked after removing cwd"
5661         touch .foo && error "'touch .foo' worked after removing cwd"
5662         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5663         ls . > /dev/null && error "'ls .' worked after removing cwd"
5664         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5665         mkdir . && error "'mkdir .' worked after removing cwd"
5666         rmdir . && error "'rmdir .' worked after removing cwd"
5667         ln -s . foo && error "'ln -s .' worked after removing cwd"
5668         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5669 }
5670 run_test 48b "Access removed working dir (should return errors)="
5671
5672 test_48c() { # bug 2350
5673         #lctl set_param debug=-1
5674         #set -vx
5675         rm -rf $DIR/$tdir
5676         test_mkdir -p $DIR/$tdir/dir
5677         cd $DIR/$tdir/dir
5678         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5679         $TRACE touch foo && error "touch foo worked after removing cwd"
5680         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5681         touch .foo && error "touch .foo worked after removing cwd"
5682         mkdir .foo && error "mkdir .foo worked after removing cwd"
5683         $TRACE ls . && error "'ls .' worked after removing cwd"
5684         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5685         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5686         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5687         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5688         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5689 }
5690 run_test 48c "Access removed working subdir (should return errors)"
5691
5692 test_48d() { # bug 2350
5693         #lctl set_param debug=-1
5694         #set -vx
5695         rm -rf $DIR/$tdir
5696         test_mkdir -p $DIR/$tdir/dir
5697         cd $DIR/$tdir/dir
5698         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5699         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5700         $TRACE touch foo && error "'touch foo' worked after removing parent"
5701         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5702         touch .foo && error "'touch .foo' worked after removing parent"
5703         mkdir .foo && error "mkdir .foo worked after removing parent"
5704         $TRACE ls . && error "'ls .' worked after removing parent"
5705         $TRACE ls .. && error "'ls ..' worked after removing parent"
5706         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5707         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5708         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5709         true
5710 }
5711 run_test 48d "Access removed parent subdir (should return errors)"
5712
5713 test_48e() { # bug 4134
5714         #lctl set_param debug=-1
5715         #set -vx
5716         rm -rf $DIR/$tdir
5717         test_mkdir -p $DIR/$tdir/dir
5718         cd $DIR/$tdir/dir
5719         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5720         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5721         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5722         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5723         # On a buggy kernel addition of "touch foo" after cd .. will
5724         # produce kernel oops in lookup_hash_it
5725         touch ../foo && error "'cd ..' worked after recreate parent"
5726         cd $DIR
5727         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5728 }
5729 run_test 48e "Access to recreated parent subdir (should return errors)"
5730
5731 test_48f() {
5732         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5733                 skip "need MDS >= 2.13.55"
5734         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5735         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5736                 skip "needs different host for mdt1 mdt2"
5737         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5738
5739         $LFS mkdir -i0 $DIR/$tdir
5740         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5741
5742         for d in sub1 sub2 sub3; do
5743                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5744                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5745                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5746         done
5747
5748         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5749 }
5750 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5751
5752 test_49() { # LU-1030
5753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5754         remote_ost_nodsh && skip "remote OST with nodsh"
5755
5756         # get ost1 size - $FSNAME-OST0000
5757         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5758                 awk '{ print $4 }')
5759         # write 800M at maximum
5760         [[ $ost1_size -lt 2 ]] && ost1_size=2
5761         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5762
5763         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5764         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5765         local dd_pid=$!
5766
5767         # change max_pages_per_rpc while writing the file
5768         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5769         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5770         # loop until dd process exits
5771         while ps ax -opid | grep -wq $dd_pid; do
5772                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5773                 sleep $((RANDOM % 5 + 1))
5774         done
5775         # restore original max_pages_per_rpc
5776         $LCTL set_param $osc1_mppc=$orig_mppc
5777         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5778 }
5779 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5780
5781 test_50() {
5782         # bug 1485
5783         test_mkdir $DIR/$tdir
5784         cd $DIR/$tdir
5785         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5786 }
5787 run_test 50 "special situations: /proc symlinks  ==============="
5788
5789 test_51a() {    # was test_51
5790         # bug 1516 - create an empty entry right after ".." then split dir
5791         test_mkdir -c1 $DIR/$tdir
5792         touch $DIR/$tdir/foo
5793         $MCREATE $DIR/$tdir/bar
5794         rm $DIR/$tdir/foo
5795         createmany -m $DIR/$tdir/longfile 201
5796         FNUM=202
5797         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5798                 $MCREATE $DIR/$tdir/longfile$FNUM
5799                 FNUM=$(($FNUM + 1))
5800                 echo -n "+"
5801         done
5802         echo
5803         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5804 }
5805 run_test 51a "special situations: split htree with empty entry =="
5806
5807 cleanup_print_lfs_df () {
5808         trap 0
5809         $LFS df
5810         $LFS df -i
5811 }
5812
5813 test_51b() {
5814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5815
5816         local dir=$DIR/$tdir
5817         local nrdirs=$((65536 + 100))
5818
5819         # cleanup the directory
5820         rm -fr $dir
5821
5822         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5823
5824         $LFS df
5825         $LFS df -i
5826         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5827         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5828         [[ $numfree -lt $nrdirs ]] &&
5829                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5830
5831         # need to check free space for the directories as well
5832         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5833         numfree=$(( blkfree / $(fs_inode_ksize) ))
5834         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5835
5836         trap cleanup_print_lfs_df EXIT
5837
5838         # create files
5839         createmany -d $dir/d $nrdirs || {
5840                 unlinkmany $dir/d $nrdirs
5841                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5842         }
5843
5844         # really created :
5845         nrdirs=$(ls -U $dir | wc -l)
5846
5847         # unlink all but 100 subdirectories, then check it still works
5848         local left=100
5849         local delete=$((nrdirs - left))
5850
5851         $LFS df
5852         $LFS df -i
5853
5854         # for ldiskfs the nlink count should be 1, but this is OSD specific
5855         # and so this is listed for informational purposes only
5856         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5857         unlinkmany -d $dir/d $delete ||
5858                 error "unlink of first $delete subdirs failed"
5859
5860         echo "nlink between: $(stat -c %h $dir)"
5861         local found=$(ls -U $dir | wc -l)
5862         [ $found -ne $left ] &&
5863                 error "can't find subdirs: found only $found, expected $left"
5864
5865         unlinkmany -d $dir/d $delete $left ||
5866                 error "unlink of second $left subdirs failed"
5867         # regardless of whether the backing filesystem tracks nlink accurately
5868         # or not, the nlink count shouldn't be more than "." and ".." here
5869         local after=$(stat -c %h $dir)
5870         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5871                 echo "nlink after: $after"
5872
5873         cleanup_print_lfs_df
5874 }
5875 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5876
5877 test_51d_sub() {
5878         local stripecount=$1
5879         local nfiles=$2
5880
5881         log "create files with stripecount=$stripecount"
5882         $LFS setstripe -C $stripecount $DIR/$tdir
5883         createmany -o $DIR/$tdir/t- $nfiles
5884         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5885         for ((n = 0; n < $OSTCOUNT; n++)); do
5886                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5887                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5888                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5889                             '($1 == '$n') { objs += 1 } \
5890                             END { printf("%0.0f", objs) }')
5891                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5892         done
5893         unlinkmany $DIR/$tdir/t- $nfiles
5894         rm  -f $TMP/$tfile
5895
5896         local nlast
5897         local min=4
5898         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5899
5900         # For some combinations of stripecount and OSTCOUNT current code
5901         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5902         # than others. Rather than skipping this test entirely, check that
5903         # and keep testing to ensure imbalance does not get worse. LU-15282
5904         (( (OSTCOUNT == 6 && stripecount == 4) ||
5905            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5906            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5907         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5908                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5909                         { $LFS df && $LFS df -i &&
5910                         error "stripecount=$stripecount: " \
5911                               "OST $n has fewer objects vs. OST $nlast " \
5912                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5913                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5914                         { $LFS df && $LFS df -i &&
5915                         error "stripecount=$stripecount: " \
5916                               "OST $n has more objects vs. OST $nlast " \
5917                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5918
5919                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5920                         { $LFS df && $LFS df -i &&
5921                         error "stripecount=$stripecount: " \
5922                               "OST $n has fewer #0 objects vs. OST $nlast " \
5923                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5924                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5925                         { $LFS df && $LFS df -i &&
5926                         error "stripecount=$stripecount: " \
5927                               "OST $n has more #0 objects vs. OST $nlast " \
5928                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5929         done
5930 }
5931
5932 test_51d() {
5933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5934         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5935
5936         local stripecount
5937         local per_ost=100
5938         local nfiles=$((per_ost * OSTCOUNT))
5939         local mdts=$(comma_list $(mdts_nodes))
5940         local param="osp.*.create_count"
5941         local qos_old=$(do_facet mds1 \
5942                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5943
5944         do_nodes $mdts \
5945                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5946         stack_trap "do_nodes $mdts \
5947                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5948
5949         test_mkdir $DIR/$tdir
5950         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5951         (( dirstripes > 0 )) || dirstripes=1
5952
5953         # Ensure enough OST objects precreated for tests to pass without
5954         # running out of objects.  This is an LOV r-r OST algorithm test,
5955         # not an OST object precreation test.
5956         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5957         (( old >= nfiles )) ||
5958         {
5959                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5960
5961                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5962                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5963
5964                 # trigger precreation from all MDTs for all OSTs
5965                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5966                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5967                 done
5968         }
5969
5970         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5971                 sleep 8  # allow object precreation to catch up
5972                 test_51d_sub $stripecount $nfiles
5973         done
5974 }
5975 run_test 51d "check LOV round-robin OST object distribution"
5976
5977 test_51e() {
5978         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5979                 skip_env "ldiskfs only test"
5980         fi
5981
5982         test_mkdir -c1 $DIR/$tdir
5983         test_mkdir -c1 $DIR/$tdir/d0
5984
5985         touch $DIR/$tdir/d0/foo
5986         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5987                 error "file exceed 65000 nlink limit!"
5988         unlinkmany $DIR/$tdir/d0/f- 65001
5989         return 0
5990 }
5991 run_test 51e "check file nlink limit"
5992
5993 test_51f() {
5994         test_mkdir $DIR/$tdir
5995
5996         local max=100000
5997         local ulimit_old=$(ulimit -n)
5998         local spare=20 # number of spare fd's for scripts/libraries, etc.
5999         local mdt=$($LFS getstripe -m $DIR/$tdir)
6000         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6001
6002         echo "MDT$mdt numfree=$numfree, max=$max"
6003         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6004         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6005                 while ! ulimit -n $((numfree + spare)); do
6006                         numfree=$((numfree * 3 / 4))
6007                 done
6008                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6009         else
6010                 echo "left ulimit at $ulimit_old"
6011         fi
6012
6013         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6014                 unlinkmany $DIR/$tdir/f $numfree
6015                 error "create+open $numfree files in $DIR/$tdir failed"
6016         }
6017         ulimit -n $ulimit_old
6018
6019         # if createmany exits at 120s there will be fewer than $numfree files
6020         unlinkmany $DIR/$tdir/f $numfree || true
6021 }
6022 run_test 51f "check many open files limit"
6023
6024 test_52a() {
6025         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6026         test_mkdir $DIR/$tdir
6027         touch $DIR/$tdir/foo
6028         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6029         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6030         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6031         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6032         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6033                                         error "link worked"
6034         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6035         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6036         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6037                                                      error "lsattr"
6038         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6039         cp -r $DIR/$tdir $TMP/
6040         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6041 }
6042 run_test 52a "append-only flag test (should return errors)"
6043
6044 test_52b() {
6045         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6046         test_mkdir $DIR/$tdir
6047         touch $DIR/$tdir/foo
6048         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6049         cat test > $DIR/$tdir/foo && error "cat test worked"
6050         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6051         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6052         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6053                                         error "link worked"
6054         echo foo >> $DIR/$tdir/foo && error "echo worked"
6055         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6056         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6057         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6058         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6059                                                         error "lsattr"
6060         chattr -i $DIR/$tdir/foo || error "chattr failed"
6061
6062         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6063 }
6064 run_test 52b "immutable flag test (should return errors) ======="
6065
6066 test_53() {
6067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6068         remote_mds_nodsh && skip "remote MDS with nodsh"
6069         remote_ost_nodsh && skip "remote OST with nodsh"
6070
6071         local param
6072         local param_seq
6073         local ostname
6074         local mds_last
6075         local mds_last_seq
6076         local ost_last
6077         local ost_last_seq
6078         local ost_last_id
6079         local ostnum
6080         local node
6081         local found=false
6082         local support_last_seq=true
6083
6084         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6085                 support_last_seq=false
6086
6087         # only test MDT0000
6088         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6089         local value
6090         for value in $(do_facet $SINGLEMDS \
6091                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6092                 param=$(echo ${value[0]} | cut -d "=" -f1)
6093                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6094
6095                 if $support_last_seq; then
6096                         param_seq=$(echo $param |
6097                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6098                         mds_last_seq=$(do_facet $SINGLEMDS \
6099                                        $LCTL get_param -n $param_seq)
6100                 fi
6101                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6102
6103                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6104                 node=$(facet_active_host ost$((ostnum+1)))
6105                 param="obdfilter.$ostname.last_id"
6106                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6107                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6108                         ost_last_id=$ost_last
6109
6110                         if $support_last_seq; then
6111                                 ost_last_id=$(echo $ost_last |
6112                                               awk -F':' '{print $2}' |
6113                                               sed -e "s/^0x//g")
6114                                 ost_last_seq=$(echo $ost_last |
6115                                                awk -F':' '{print $1}')
6116                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6117                         fi
6118
6119                         if [[ $ost_last_id != $mds_last ]]; then
6120                                 error "$ost_last_id != $mds_last"
6121                         else
6122                                 found=true
6123                                 break
6124                         fi
6125                 done
6126         done
6127         $found || error "can not match last_seq/last_id for $mdtosc"
6128         return 0
6129 }
6130 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6131
6132 test_54a() {
6133         perl -MSocket -e ';' || skip "no Socket perl module installed"
6134
6135         $SOCKETSERVER $DIR/socket ||
6136                 error "$SOCKETSERVER $DIR/socket failed: $?"
6137         $SOCKETCLIENT $DIR/socket ||
6138                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6139         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6140 }
6141 run_test 54a "unix domain socket test =========================="
6142
6143 test_54b() {
6144         f="$DIR/f54b"
6145         mknod $f c 1 3
6146         chmod 0666 $f
6147         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6148 }
6149 run_test 54b "char device works in lustre ======================"
6150
6151 find_loop_dev() {
6152         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6153         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6154         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6155
6156         for i in $(seq 3 7); do
6157                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6158                 LOOPDEV=$LOOPBASE$i
6159                 LOOPNUM=$i
6160                 break
6161         done
6162 }
6163
6164 cleanup_54c() {
6165         local rc=0
6166         loopdev="$DIR/loop54c"
6167
6168         trap 0
6169         $UMOUNT $DIR/$tdir || rc=$?
6170         losetup -d $loopdev || true
6171         losetup -d $LOOPDEV || true
6172         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6173         return $rc
6174 }
6175
6176 test_54c() {
6177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6178
6179         loopdev="$DIR/loop54c"
6180
6181         find_loop_dev
6182         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6183         trap cleanup_54c EXIT
6184         mknod $loopdev b 7 $LOOPNUM
6185         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6186         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6187         losetup $loopdev $DIR/$tfile ||
6188                 error "can't set up $loopdev for $DIR/$tfile"
6189         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6190         test_mkdir $DIR/$tdir
6191         mount -t ext2 $loopdev $DIR/$tdir ||
6192                 error "error mounting $loopdev on $DIR/$tdir"
6193         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6194                 error "dd write"
6195         df $DIR/$tdir
6196         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6197                 error "dd read"
6198         cleanup_54c
6199 }
6200 run_test 54c "block device works in lustre ====================="
6201
6202 test_54d() {
6203         local pipe="$DIR/$tfile.pipe"
6204         local string="aaaaaa"
6205
6206         mknod $pipe p
6207         echo -n "$string" > $pipe &
6208         local result=$(cat $pipe)
6209         [[ "$result" == "$string" ]] || error "$result != $string"
6210 }
6211 run_test 54d "fifo device works in lustre ======================"
6212
6213 test_54e() {
6214         f="$DIR/f54e"
6215         string="aaaaaa"
6216         cp -aL /dev/console $f
6217         echo $string > $f || error "echo $string to $f failed"
6218 }
6219 run_test 54e "console/tty device works in lustre ======================"
6220
6221 test_56a() {
6222         local numfiles=3
6223         local numdirs=2
6224         local dir=$DIR/$tdir
6225
6226         rm -rf $dir
6227         test_mkdir -p $dir/dir
6228         for i in $(seq $numfiles); do
6229                 touch $dir/file$i
6230                 touch $dir/dir/file$i
6231         done
6232
6233         local numcomp=$($LFS getstripe --component-count $dir)
6234
6235         [[ $numcomp == 0 ]] && numcomp=1
6236
6237         # test lfs getstripe with --recursive
6238         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6239
6240         [[ $filenum -eq $((numfiles * 2)) ]] ||
6241                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6242         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6243         [[ $filenum -eq $numfiles ]] ||
6244                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6245         echo "$LFS getstripe showed obdidx or l_ost_idx"
6246
6247         # test lfs getstripe with file instead of dir
6248         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6249         [[ $filenum -eq 1 ]] ||
6250                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6251         echo "$LFS getstripe file1 passed"
6252
6253         #test lfs getstripe with --verbose
6254         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6255         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6256                 error "$LFS getstripe --verbose $dir: "\
6257                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6258         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6259                 error "$LFS getstripe $dir: showed lmm_magic"
6260
6261         #test lfs getstripe with -v prints lmm_fid
6262         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6263         local countfids=$((numdirs + numfiles * numcomp))
6264         [[ $filenum -eq $countfids ]] ||
6265                 error "$LFS getstripe -v $dir: "\
6266                       "got $filenum want $countfids lmm_fid"
6267         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6268                 error "$LFS getstripe $dir: showed lmm_fid by default"
6269         echo "$LFS getstripe --verbose passed"
6270
6271         #check for FID information
6272         local fid1=$($LFS getstripe --fid $dir/file1)
6273         local fid2=$($LFS getstripe --verbose $dir/file1 |
6274                      awk '/lmm_fid: / { print $2; exit; }')
6275         local fid3=$($LFS path2fid $dir/file1)
6276
6277         [ "$fid1" != "$fid2" ] &&
6278                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6279         [ "$fid1" != "$fid3" ] &&
6280                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6281         echo "$LFS getstripe --fid passed"
6282
6283         #test lfs getstripe with --obd
6284         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6285                 error "$LFS getstripe --obd wrong_uuid: should return error"
6286
6287         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6288
6289         local ostidx=1
6290         local obduuid=$(ostuuid_from_index $ostidx)
6291         local found=$($LFS getstripe -r --obd $obduuid $dir |
6292                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6293
6294         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6295         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6296                 ((filenum--))
6297         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6298                 ((filenum--))
6299
6300         [[ $found -eq $filenum ]] ||
6301                 error "$LFS getstripe --obd: found $found expect $filenum"
6302         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6303                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6304                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6305                 error "$LFS getstripe --obd: should not show file on other obd"
6306         echo "$LFS getstripe --obd passed"
6307 }
6308 run_test 56a "check $LFS getstripe"
6309
6310 test_56b() {
6311         local dir=$DIR/$tdir
6312         local numdirs=3
6313
6314         test_mkdir $dir
6315         for i in $(seq $numdirs); do
6316                 test_mkdir $dir/dir$i
6317         done
6318
6319         # test lfs getdirstripe default mode is non-recursion, which is
6320         # different from lfs getstripe
6321         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6322
6323         [[ $dircnt -eq 1 ]] ||
6324                 error "$LFS getdirstripe: found $dircnt, not 1"
6325         dircnt=$($LFS getdirstripe --recursive $dir |
6326                 grep -c lmv_stripe_count)
6327         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6328                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6329 }
6330 run_test 56b "check $LFS getdirstripe"
6331
6332 test_56c() {
6333         remote_ost_nodsh && skip "remote OST with nodsh"
6334
6335         local ost_idx=0
6336         local ost_name=$(ostname_from_index $ost_idx)
6337         local old_status=$(ost_dev_status $ost_idx)
6338         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6339
6340         [[ -z "$old_status" ]] ||
6341                 skip_env "OST $ost_name is in $old_status status"
6342
6343         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6344         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6345                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6346         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6347                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6348                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6349         fi
6350
6351         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6352                 error "$LFS df -v showing inactive devices"
6353         sleep_maxage
6354
6355         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6356
6357         [[ "$new_status" =~ "D" ]] ||
6358                 error "$ost_name status is '$new_status', missing 'D'"
6359         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6360                 [[ "$new_status" =~ "N" ]] ||
6361                         error "$ost_name status is '$new_status', missing 'N'"
6362         fi
6363         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6364                 [[ "$new_status" =~ "f" ]] ||
6365                         error "$ost_name status is '$new_status', missing 'f'"
6366         fi
6367
6368         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6369         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6370                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6371         [[ -z "$p" ]] && restore_lustre_params < $p || true
6372         sleep_maxage
6373
6374         new_status=$(ost_dev_status $ost_idx)
6375         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6376                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6377         # can't check 'f' as devices may actually be on flash
6378 }
6379 run_test 56c "check 'lfs df' showing device status"
6380
6381 test_56d() {
6382         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6383         local osts=$($LFS df -v $MOUNT | grep -c OST)
6384
6385         $LFS df $MOUNT
6386
6387         (( mdts == MDSCOUNT )) ||
6388                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6389         (( osts == OSTCOUNT )) ||
6390                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6391 }
6392 run_test 56d "'lfs df -v' prints only configured devices"
6393
6394 test_56e() {
6395         err_enoent=2 # No such file or directory
6396         err_eopnotsupp=95 # Operation not supported
6397
6398         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6399         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6400
6401         # Check for handling of path not exists
6402         output=$($LFS df $enoent_mnt 2>&1)
6403         ret=$?
6404
6405         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6406         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6407                 error "expect failure $err_enoent, not $ret"
6408
6409         # Check for handling of non-Lustre FS
6410         output=$($LFS df $notsup_mnt)
6411         ret=$?
6412
6413         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6414         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6415                 error "expect success $err_eopnotsupp, not $ret"
6416
6417         # Check for multiple LustreFS argument
6418         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6419         ret=$?
6420
6421         [[ $output -eq 3 && $ret -eq 0 ]] ||
6422                 error "expect success 3, not $output, rc = $ret"
6423
6424         # Check for correct non-Lustre FS handling among multiple
6425         # LustreFS argument
6426         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6427                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6428         ret=$?
6429
6430         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6431                 error "expect success 2, not $output, rc = $ret"
6432 }
6433 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6434
6435 NUMFILES=3
6436 NUMDIRS=3
6437 setup_56() {
6438         local local_tdir="$1"
6439         local local_numfiles="$2"
6440         local local_numdirs="$3"
6441         local dir_params="$4"
6442         local dir_stripe_params="$5"
6443
6444         if [ ! -d "$local_tdir" ] ; then
6445                 test_mkdir -p $dir_stripe_params $local_tdir
6446                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6447                 for i in $(seq $local_numfiles) ; do
6448                         touch $local_tdir/file$i
6449                 done
6450                 for i in $(seq $local_numdirs) ; do
6451                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6452                         for j in $(seq $local_numfiles) ; do
6453                                 touch $local_tdir/dir$i/file$j
6454                         done
6455                 done
6456         fi
6457 }
6458
6459 setup_56_special() {
6460         local local_tdir=$1
6461         local local_numfiles=$2
6462         local local_numdirs=$3
6463
6464         setup_56 $local_tdir $local_numfiles $local_numdirs
6465
6466         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6467                 for i in $(seq $local_numfiles) ; do
6468                         mknod $local_tdir/loop${i}b b 7 $i
6469                         mknod $local_tdir/null${i}c c 1 3
6470                         ln -s $local_tdir/file1 $local_tdir/link${i}
6471                 done
6472                 for i in $(seq $local_numdirs) ; do
6473                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6474                         mknod $local_tdir/dir$i/null${i}c c 1 3
6475                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6476                 done
6477         fi
6478 }
6479
6480 test_56g() {
6481         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6482         local expected=$(($NUMDIRS + 2))
6483
6484         setup_56 $dir $NUMFILES $NUMDIRS
6485
6486         # test lfs find with -name
6487         for i in $(seq $NUMFILES) ; do
6488                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6489
6490                 [ $nums -eq $expected ] ||
6491                         error "lfs find -name '*$i' $dir wrong: "\
6492                               "found $nums, expected $expected"
6493         done
6494 }
6495 run_test 56g "check lfs find -name"
6496
6497 test_56h() {
6498         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6499         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6500
6501         setup_56 $dir $NUMFILES $NUMDIRS
6502
6503         # test lfs find with ! -name
6504         for i in $(seq $NUMFILES) ; do
6505                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6506
6507                 [ $nums -eq $expected ] ||
6508                         error "lfs find ! -name '*$i' $dir wrong: "\
6509                               "found $nums, expected $expected"
6510         done
6511 }
6512 run_test 56h "check lfs find ! -name"
6513
6514 test_56i() {
6515         local dir=$DIR/$tdir
6516
6517         test_mkdir $dir
6518
6519         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6520         local out=$($cmd)
6521
6522         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6523 }
6524 run_test 56i "check 'lfs find -ost UUID' skips directories"
6525
6526 test_56j() {
6527         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6528
6529         setup_56_special $dir $NUMFILES $NUMDIRS
6530
6531         local expected=$((NUMDIRS + 1))
6532         local cmd="$LFS find -type d $dir"
6533         local nums=$($cmd | wc -l)
6534
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537 }
6538 run_test 56j "check lfs find -type d"
6539
6540 test_56k() {
6541         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6542
6543         setup_56_special $dir $NUMFILES $NUMDIRS
6544
6545         local expected=$(((NUMDIRS + 1) * NUMFILES))
6546         local cmd="$LFS find -type f $dir"
6547         local nums=$($cmd | wc -l)
6548
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551 }
6552 run_test 56k "check lfs find -type f"
6553
6554 test_56l() {
6555         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6556
6557         setup_56_special $dir $NUMFILES $NUMDIRS
6558
6559         local expected=$((NUMDIRS + NUMFILES))
6560         local cmd="$LFS find -type b $dir"
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565 }
6566 run_test 56l "check lfs find -type b"
6567
6568 test_56m() {
6569         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6570
6571         setup_56_special $dir $NUMFILES $NUMDIRS
6572
6573         local expected=$((NUMDIRS + NUMFILES))
6574         local cmd="$LFS find -type c $dir"
6575         local nums=$($cmd | wc -l)
6576         [ $nums -eq $expected ] ||
6577                 error "'$cmd' wrong: found $nums, expected $expected"
6578 }
6579 run_test 56m "check lfs find -type c"
6580
6581 test_56n() {
6582         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6583         setup_56_special $dir $NUMFILES $NUMDIRS
6584
6585         local expected=$((NUMDIRS + NUMFILES))
6586         local cmd="$LFS find -type l $dir"
6587         local nums=$($cmd | wc -l)
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591 }
6592 run_test 56n "check lfs find -type l"
6593
6594 test_56o() {
6595         local dir=$DIR/$tdir
6596
6597         setup_56 $dir $NUMFILES $NUMDIRS
6598         utime $dir/file1 > /dev/null || error "utime (1)"
6599         utime $dir/file2 > /dev/null || error "utime (2)"
6600         utime $dir/dir1 > /dev/null || error "utime (3)"
6601         utime $dir/dir2 > /dev/null || error "utime (4)"
6602         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6603         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6604
6605         local expected=4
6606         local nums=$($LFS find -mtime +0 $dir | wc -l)
6607
6608         [ $nums -eq $expected ] ||
6609                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6610
6611         expected=12
6612         cmd="$LFS find -mtime 0 $dir"
6613         nums=$($cmd | wc -l)
6614         [ $nums -eq $expected ] ||
6615                 error "'$cmd' wrong: found $nums, expected $expected"
6616 }
6617 run_test 56o "check lfs find -mtime for old files"
6618
6619 test_56ob() {
6620         local dir=$DIR/$tdir
6621         local expected=1
6622         local count=0
6623
6624         # just to make sure there is something that won't be found
6625         test_mkdir $dir
6626         touch $dir/$tfile.now
6627
6628         for age in year week day hour min; do
6629                 count=$((count + 1))
6630
6631                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6632                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6633                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6634
6635                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6636                 local nums=$($cmd | wc -l)
6637                 [ $nums -eq $expected ] ||
6638                         error "'$cmd' wrong: found $nums, expected $expected"
6639
6640                 cmd="$LFS find $dir -atime $count${age:0:1}"
6641                 nums=$($cmd | wc -l)
6642                 [ $nums -eq $expected ] ||
6643                         error "'$cmd' wrong: found $nums, expected $expected"
6644         done
6645
6646         sleep 2
6647         cmd="$LFS find $dir -ctime +1s -type f"
6648         nums=$($cmd | wc -l)
6649         (( $nums == $count * 2 + 1)) ||
6650                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6651 }
6652 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6653
6654 test_newerXY_base() {
6655         local x=$1
6656         local y=$2
6657         local dir=$DIR/$tdir
6658         local ref
6659         local negref
6660
6661         if [ $y == "t" ]; then
6662                 if [ $x == "b" ]; then
6663                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6664                 else
6665                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6666                 fi
6667         else
6668                 ref=$DIR/$tfile.newer.$x$y
6669                 touch $ref || error "touch $ref failed"
6670         fi
6671
6672         echo "before = $ref"
6673         sleep 2
6674         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6675         sleep 2
6676         if [ $y == "t" ]; then
6677                 if [ $x == "b" ]; then
6678                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6679                 else
6680                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6681                 fi
6682         else
6683                 negref=$DIR/$tfile.negnewer.$x$y
6684                 touch $negref || error "touch $negref failed"
6685         fi
6686
6687         echo "after = $negref"
6688         local cmd="$LFS find $dir -newer$x$y $ref"
6689         local nums=$(eval $cmd | wc -l)
6690         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6691
6692         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6693                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6694
6695         cmd="$LFS find $dir ! -newer$x$y $negref"
6696         nums=$(eval $cmd | wc -l)
6697         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6698                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6699
6700         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6701         nums=$(eval $cmd | wc -l)
6702         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6703                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6704
6705         rm -rf $DIR/*
6706 }
6707
6708 test_56oc() {
6709         test_newerXY_base "a" "a"
6710         test_newerXY_base "a" "m"
6711         test_newerXY_base "a" "c"
6712         test_newerXY_base "m" "a"
6713         test_newerXY_base "m" "m"
6714         test_newerXY_base "m" "c"
6715         test_newerXY_base "c" "a"
6716         test_newerXY_base "c" "m"
6717         test_newerXY_base "c" "c"
6718
6719         test_newerXY_base "a" "t"
6720         test_newerXY_base "m" "t"
6721         test_newerXY_base "c" "t"
6722
6723         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6724            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6725                 ! btime_supported && echo "btime unsupported" && return 0
6726
6727         test_newerXY_base "b" "b"
6728         test_newerXY_base "b" "t"
6729 }
6730 run_test 56oc "check lfs find -newerXY work"
6731
6732 btime_supported() {
6733         local dir=$DIR/$tdir
6734         local rc
6735
6736         mkdir -p $dir
6737         touch $dir/$tfile
6738         $LFS find $dir -btime -1d -type f
6739         rc=$?
6740         rm -rf $dir
6741         return $rc
6742 }
6743
6744 test_56od() {
6745         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6746                 ! btime_supported && skip "btime unsupported on MDS"
6747
6748         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6749                 ! btime_supported && skip "btime unsupported on clients"
6750
6751         local dir=$DIR/$tdir
6752         local ref=$DIR/$tfile.ref
6753         local negref=$DIR/$tfile.negref
6754
6755         mkdir $dir || error "mkdir $dir failed"
6756         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6757         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6758         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6759         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6760         touch $ref || error "touch $ref failed"
6761         # sleep 3 seconds at least
6762         sleep 3
6763
6764         local before=$(do_facet mds1 date +%s)
6765         local skew=$(($(date +%s) - before + 1))
6766
6767         if (( skew < 0 && skew > -5 )); then
6768                 sleep $((0 - skew + 1))
6769                 skew=0
6770         fi
6771
6772         # Set the dir stripe params to limit files all on MDT0,
6773         # otherwise we need to calc the max clock skew between
6774         # the client and MDTs.
6775         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6776         sleep 2
6777         touch $negref || error "touch $negref failed"
6778
6779         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6780         local nums=$($cmd | wc -l)
6781         local expected=$(((NUMFILES + 1) * NUMDIRS))
6782
6783         [ $nums -eq $expected ] ||
6784                 error "'$cmd' wrong: found $nums, expected $expected"
6785
6786         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6787         nums=$($cmd | wc -l)
6788         expected=$((NUMFILES + 1))
6789         [ $nums -eq $expected ] ||
6790                 error "'$cmd' wrong: found $nums, expected $expected"
6791
6792         [ $skew -lt 0 ] && return
6793
6794         local after=$(do_facet mds1 date +%s)
6795         local age=$((after - before + 1 + skew))
6796
6797         cmd="$LFS find $dir -btime -${age}s -type f"
6798         nums=$($cmd | wc -l)
6799         expected=$(((NUMFILES + 1) * NUMDIRS))
6800
6801         echo "Clock skew between client and server: $skew, age:$age"
6802         [ $nums -eq $expected ] ||
6803                 error "'$cmd' wrong: found $nums, expected $expected"
6804
6805         expected=$(($NUMDIRS + 1))
6806         cmd="$LFS find $dir -btime -${age}s -type d"
6807         nums=$($cmd | wc -l)
6808         [ $nums -eq $expected ] ||
6809                 error "'$cmd' wrong: found $nums, expected $expected"
6810         rm -f $ref $negref || error "Failed to remove $ref $negref"
6811 }
6812 run_test 56od "check lfs find -btime with units"
6813
6814 test_56p() {
6815         [ $RUNAS_ID -eq $UID ] &&
6816                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6817
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS
6821         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6822
6823         local expected=$NUMFILES
6824         local cmd="$LFS find -uid $RUNAS_ID $dir"
6825         local nums=$($cmd | wc -l)
6826
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829
6830         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6831         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6832         nums=$($cmd | wc -l)
6833         [ $nums -eq $expected ] ||
6834                 error "'$cmd' wrong: found $nums, expected $expected"
6835 }
6836 run_test 56p "check lfs find -uid and ! -uid"
6837
6838 test_56q() {
6839         [ $RUNAS_ID -eq $UID ] &&
6840                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6841
6842         local dir=$DIR/$tdir
6843
6844         setup_56 $dir $NUMFILES $NUMDIRS
6845         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6846
6847         local expected=$NUMFILES
6848         local cmd="$LFS find -gid $RUNAS_GID $dir"
6849         local nums=$($cmd | wc -l)
6850
6851         [ $nums -eq $expected ] ||
6852                 error "'$cmd' wrong: found $nums, expected $expected"
6853
6854         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6855         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6856         nums=$($cmd | wc -l)
6857         [ $nums -eq $expected ] ||
6858                 error "'$cmd' wrong: found $nums, expected $expected"
6859 }
6860 run_test 56q "check lfs find -gid and ! -gid"
6861
6862 test_56r() {
6863         local dir=$DIR/$tdir
6864
6865         setup_56 $dir $NUMFILES $NUMDIRS
6866
6867         local expected=12
6868         local cmd="$LFS find -size 0 -type f -lazy $dir"
6869         local nums=$($cmd | wc -l)
6870
6871         [ $nums -eq $expected ] ||
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873         cmd="$LFS find -size 0 -type f $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877
6878         expected=0
6879         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6880         nums=$($cmd | wc -l)
6881         [ $nums -eq $expected ] ||
6882                 error "'$cmd' wrong: found $nums, expected $expected"
6883         cmd="$LFS find ! -size 0 -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         echo "test" > $dir/$tfile
6889         echo "test2" > $dir/$tfile.2 && sync
6890         expected=1
6891         cmd="$LFS find -size 5 -type f -lazy $dir"
6892         nums=$($cmd | wc -l)
6893         [ $nums -eq $expected ] ||
6894                 error "'$cmd' wrong: found $nums, expected $expected"
6895         cmd="$LFS find -size 5 -type f $dir"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] ||
6898                 error "'$cmd' wrong: found $nums, expected $expected"
6899
6900         expected=1
6901         cmd="$LFS find -size +5 -type f -lazy $dir"
6902         nums=$($cmd | wc -l)
6903         [ $nums -eq $expected ] ||
6904                 error "'$cmd' wrong: found $nums, expected $expected"
6905         cmd="$LFS find -size +5 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         expected=2
6911         cmd="$LFS find -size +0 -type f -lazy $dir"
6912         nums=$($cmd | wc -l)
6913         [ $nums -eq $expected ] ||
6914                 error "'$cmd' wrong: found $nums, expected $expected"
6915         cmd="$LFS find -size +0 -type f $dir"
6916         nums=$($cmd | wc -l)
6917         [ $nums -eq $expected ] ||
6918                 error "'$cmd' wrong: found $nums, expected $expected"
6919
6920         expected=2
6921         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6922         nums=$($cmd | wc -l)
6923         [ $nums -eq $expected ] ||
6924                 error "'$cmd' wrong: found $nums, expected $expected"
6925         cmd="$LFS find ! -size -5 -type f $dir"
6926         nums=$($cmd | wc -l)
6927         [ $nums -eq $expected ] ||
6928                 error "'$cmd' wrong: found $nums, expected $expected"
6929
6930         expected=12
6931         cmd="$LFS find -size -5 -type f -lazy $dir"
6932         nums=$($cmd | wc -l)
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935         cmd="$LFS find -size -5 -type f $dir"
6936         nums=$($cmd | wc -l)
6937         [ $nums -eq $expected ] ||
6938                 error "'$cmd' wrong: found $nums, expected $expected"
6939 }
6940 run_test 56r "check lfs find -size works"
6941
6942 test_56ra_sub() {
6943         local expected=$1
6944         local glimpses=$2
6945         local cmd="$3"
6946
6947         cancel_lru_locks $OSC
6948
6949         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6950         local nums=$($cmd | wc -l)
6951
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6956
6957         if (( rpcs_before + glimpses != rpcs_after )); then
6958                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6959                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6960
6961                 if [[ $glimpses == 0 ]]; then
6962                         error "'$cmd' should not send glimpse RPCs to OST"
6963                 else
6964                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6965                 fi
6966         fi
6967 }
6968
6969 test_56ra() {
6970         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6971                 skip "MDS < 2.12.58 doesn't return LSOM data"
6972         local dir=$DIR/$tdir
6973         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6974
6975         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6976
6977         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6978         $LCTL set_param -n llite.*.statahead_agl=0
6979         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6980
6981         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6982         # open and close all files to ensure LSOM is updated
6983         cancel_lru_locks $OSC
6984         find $dir -type f | xargs cat > /dev/null
6985
6986         #   expect_found  glimpse_rpcs  command_to_run
6987         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6988         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6989         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6990         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6991
6992         echo "test" > $dir/$tfile
6993         echo "test2" > $dir/$tfile.2 && sync
6994         cancel_lru_locks $OSC
6995         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6996
6997         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6998         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6999         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7000         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7001
7002         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7003         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7004         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7005         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7006         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7007         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7008 }
7009 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7010
7011 test_56rb() {
7012         local dir=$DIR/$tdir
7013         local tmp=$TMP/$tfile.log
7014         local mdt_idx;
7015
7016         test_mkdir -p $dir || error "failed to mkdir $dir"
7017         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7018                 error "failed to setstripe $dir/$tfile"
7019         mdt_idx=$($LFS getdirstripe -i $dir)
7020         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7021
7022         stack_trap "rm -f $tmp" EXIT
7023         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7024         ! grep -q obd_uuid $tmp ||
7025                 error "failed to find --size +100K --ost 0 $dir"
7026         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7027         ! grep -q obd_uuid $tmp ||
7028                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7029 }
7030 run_test 56rb "check lfs find --size --ost/--mdt works"
7031
7032 test_56rc() {
7033         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7034         local dir=$DIR/$tdir
7035         local found
7036
7037         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7038         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7039         (( $MDSCOUNT > 2 )) &&
7040                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7041         mkdir $dir/$tdir-{1..10}
7042         touch $dir/$tfile-{1..10}
7043
7044         found=$($LFS find $dir --mdt-count 2 | wc -l)
7045         expect=11
7046         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7047
7048         found=$($LFS find $dir -T +1 | wc -l)
7049         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7050         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7051
7052         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7053         expect=11
7054         (( $found == $expect )) || error "found $found all_char, expect $expect"
7055
7056         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7057         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7058         (( $found == $expect )) || error "found $found all_char, expect $expect"
7059 }
7060 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7061
7062 test_56s() { # LU-611 #LU-9369
7063         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7064
7065         local dir=$DIR/$tdir
7066         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7067
7068         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7069         for i in $(seq $NUMDIRS); do
7070                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7071         done
7072
7073         local expected=$NUMDIRS
7074         local cmd="$LFS find -c $OSTCOUNT $dir"
7075         local nums=$($cmd | wc -l)
7076
7077         [ $nums -eq $expected ] || {
7078                 $LFS getstripe -R $dir
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080         }
7081
7082         expected=$((NUMDIRS + onestripe))
7083         cmd="$LFS find -stripe-count +0 -type f $dir"
7084         nums=$($cmd | wc -l)
7085         [ $nums -eq $expected ] || {
7086                 $LFS getstripe -R $dir
7087                 error "'$cmd' wrong: found $nums, expected $expected"
7088         }
7089
7090         expected=$onestripe
7091         cmd="$LFS find -stripe-count 1 -type f $dir"
7092         nums=$($cmd | wc -l)
7093         [ $nums -eq $expected ] || {
7094                 $LFS getstripe -R $dir
7095                 error "'$cmd' wrong: found $nums, expected $expected"
7096         }
7097
7098         cmd="$LFS find -stripe-count -2 -type f $dir"
7099         nums=$($cmd | wc -l)
7100         [ $nums -eq $expected ] || {
7101                 $LFS getstripe -R $dir
7102                 error "'$cmd' wrong: found $nums, expected $expected"
7103         }
7104
7105         expected=0
7106         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] || {
7109                 $LFS getstripe -R $dir
7110                 error "'$cmd' wrong: found $nums, expected $expected"
7111         }
7112 }
7113 run_test 56s "check lfs find -stripe-count works"
7114
7115 test_56t() { # LU-611 #LU-9369
7116         local dir=$DIR/$tdir
7117
7118         setup_56 $dir 0 $NUMDIRS
7119         for i in $(seq $NUMDIRS); do
7120                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7121         done
7122
7123         local expected=$NUMDIRS
7124         local cmd="$LFS find -S 8M $dir"
7125         local nums=$($cmd | wc -l)
7126
7127         [ $nums -eq $expected ] || {
7128                 $LFS getstripe -R $dir
7129                 error "'$cmd' wrong: found $nums, expected $expected"
7130         }
7131         rm -rf $dir
7132
7133         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7134
7135         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7136
7137         expected=$(((NUMDIRS + 1) * NUMFILES))
7138         cmd="$LFS find -stripe-size 512k -type f $dir"
7139         nums=$($cmd | wc -l)
7140         [ $nums -eq $expected ] ||
7141                 error "'$cmd' wrong: found $nums, expected $expected"
7142
7143         cmd="$LFS find -stripe-size +320k -type f $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147
7148         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7149         cmd="$LFS find -stripe-size +200k -type f $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153
7154         cmd="$LFS find -stripe-size -640k -type f $dir"
7155         nums=$($cmd | wc -l)
7156         [ $nums -eq $expected ] ||
7157                 error "'$cmd' wrong: found $nums, expected $expected"
7158
7159         expected=4
7160         cmd="$LFS find -stripe-size 256k -type f $dir"
7161         nums=$($cmd | wc -l)
7162         [ $nums -eq $expected ] ||
7163                 error "'$cmd' wrong: found $nums, expected $expected"
7164
7165         cmd="$LFS find -stripe-size -320k -type f $dir"
7166         nums=$($cmd | wc -l)
7167         [ $nums -eq $expected ] ||
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169
7170         expected=0
7171         cmd="$LFS find -stripe-size 1024k -type f $dir"
7172         nums=$($cmd | wc -l)
7173         [ $nums -eq $expected ] ||
7174                 error "'$cmd' wrong: found $nums, expected $expected"
7175 }
7176 run_test 56t "check lfs find -stripe-size works"
7177
7178 test_56u() { # LU-611
7179         local dir=$DIR/$tdir
7180
7181         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7182
7183         if [[ $OSTCOUNT -gt 1 ]]; then
7184                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7185                 onestripe=4
7186         else
7187                 onestripe=0
7188         fi
7189
7190         local expected=$(((NUMDIRS + 1) * NUMFILES))
7191         local cmd="$LFS find -stripe-index 0 -type f $dir"
7192         local nums=$($cmd | wc -l)
7193
7194         [ $nums -eq $expected ] ||
7195                 error "'$cmd' wrong: found $nums, expected $expected"
7196
7197         expected=$onestripe
7198         cmd="$LFS find -stripe-index 1 -type f $dir"
7199         nums=$($cmd | wc -l)
7200         [ $nums -eq $expected ] ||
7201                 error "'$cmd' wrong: found $nums, expected $expected"
7202
7203         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7204         nums=$($cmd | wc -l)
7205         [ $nums -eq $expected ] ||
7206                 error "'$cmd' wrong: found $nums, expected $expected"
7207
7208         expected=0
7209         # This should produce an error and not return any files
7210         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7211         nums=$($cmd 2>/dev/null | wc -l)
7212         [ $nums -eq $expected ] ||
7213                 error "'$cmd' wrong: found $nums, expected $expected"
7214
7215         if [[ $OSTCOUNT -gt 1 ]]; then
7216                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7217                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7218                 nums=$($cmd | wc -l)
7219                 [ $nums -eq $expected ] ||
7220                         error "'$cmd' wrong: found $nums, expected $expected"
7221         fi
7222 }
7223 run_test 56u "check lfs find -stripe-index works"
7224
7225 test_56v() {
7226         local mdt_idx=0
7227         local dir=$DIR/$tdir
7228
7229         setup_56 $dir $NUMFILES $NUMDIRS
7230
7231         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7232         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7233
7234         for file in $($LFS find -m $UUID $dir); do
7235                 file_midx=$($LFS getstripe -m $file)
7236                 [ $file_midx -eq $mdt_idx ] ||
7237                         error "lfs find -m $UUID != getstripe -m $file_midx"
7238         done
7239 }
7240 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7241
7242 test_56w() {
7243         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7245
7246         local dir=$DIR/$tdir
7247
7248         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7249
7250         local stripe_size=$($LFS getstripe -S -d $dir) ||
7251                 error "$LFS getstripe -S -d $dir failed"
7252         stripe_size=${stripe_size%% *}
7253
7254         local file_size=$((stripe_size * OSTCOUNT))
7255         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7256         local required_space=$((file_num * file_size))
7257         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7258                            head -n1)
7259         [[ $free_space -le $((required_space / 1024)) ]] &&
7260                 skip_env "need $required_space, have $free_space kbytes"
7261
7262         local dd_bs=65536
7263         local dd_count=$((file_size / dd_bs))
7264
7265         # write data into the files
7266         local i
7267         local j
7268         local file
7269
7270         for i in $(seq $NUMFILES); do
7271                 file=$dir/file$i
7272                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7273                         error "write data into $file failed"
7274         done
7275         for i in $(seq $NUMDIRS); do
7276                 for j in $(seq $NUMFILES); do
7277                         file=$dir/dir$i/file$j
7278                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7279                                 error "write data into $file failed"
7280                 done
7281         done
7282
7283         # $LFS_MIGRATE will fail if hard link migration is unsupported
7284         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7285                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7286                         error "creating links to $dir/dir1/file1 failed"
7287         fi
7288
7289         local expected=-1
7290
7291         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7292
7293         # lfs_migrate file
7294         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7295
7296         echo "$cmd"
7297         eval $cmd || error "$cmd failed"
7298
7299         check_stripe_count $dir/file1 $expected
7300
7301         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7302         then
7303                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7304                 # OST 1 if it is on OST 0. This file is small enough to
7305                 # be on only one stripe.
7306                 file=$dir/migr_1_ost
7307                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7308                         error "write data into $file failed"
7309                 local obdidx=$($LFS getstripe -i $file)
7310                 local oldmd5=$(md5sum $file)
7311                 local newobdidx=0
7312
7313                 [[ $obdidx -eq 0 ]] && newobdidx=1
7314                 cmd="$LFS migrate -i $newobdidx $file"
7315                 echo $cmd
7316                 eval $cmd || error "$cmd failed"
7317
7318                 local realobdix=$($LFS getstripe -i $file)
7319                 local newmd5=$(md5sum $file)
7320
7321                 [[ $newobdidx -ne $realobdix ]] &&
7322                         error "new OST is different (was=$obdidx, "\
7323                               "wanted=$newobdidx, got=$realobdix)"
7324                 [[ "$oldmd5" != "$newmd5" ]] &&
7325                         error "md5sum differ: $oldmd5, $newmd5"
7326         fi
7327
7328         # lfs_migrate dir
7329         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7330         echo "$cmd"
7331         eval $cmd || error "$cmd failed"
7332
7333         for j in $(seq $NUMFILES); do
7334                 check_stripe_count $dir/dir1/file$j $expected
7335         done
7336
7337         # lfs_migrate works with lfs find
7338         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7339              $LFS_MIGRATE -y -c $expected"
7340         echo "$cmd"
7341         eval $cmd || error "$cmd failed"
7342
7343         for i in $(seq 2 $NUMFILES); do
7344                 check_stripe_count $dir/file$i $expected
7345         done
7346         for i in $(seq 2 $NUMDIRS); do
7347                 for j in $(seq $NUMFILES); do
7348                 check_stripe_count $dir/dir$i/file$j $expected
7349                 done
7350         done
7351 }
7352 run_test 56w "check lfs_migrate -c stripe_count works"
7353
7354 test_56wb() {
7355         local file1=$DIR/$tdir/file1
7356         local create_pool=false
7357         local initial_pool=$($LFS getstripe -p $DIR)
7358         local pool_list=()
7359         local pool=""
7360
7361         echo -n "Creating test dir..."
7362         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7363         echo "done."
7364
7365         echo -n "Creating test file..."
7366         touch $file1 || error "cannot create file"
7367         echo "done."
7368
7369         echo -n "Detecting existing pools..."
7370         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7371
7372         if [ ${#pool_list[@]} -gt 0 ]; then
7373                 echo "${pool_list[@]}"
7374                 for thispool in "${pool_list[@]}"; do
7375                         if [[ -z "$initial_pool" ||
7376                               "$initial_pool" != "$thispool" ]]; then
7377                                 pool="$thispool"
7378                                 echo "Using existing pool '$pool'"
7379                                 break
7380                         fi
7381                 done
7382         else
7383                 echo "none detected."
7384         fi
7385         if [ -z "$pool" ]; then
7386                 pool=${POOL:-testpool}
7387                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7388                 echo -n "Creating pool '$pool'..."
7389                 create_pool=true
7390                 pool_add $pool &> /dev/null ||
7391                         error "pool_add failed"
7392                 echo "done."
7393
7394                 echo -n "Adding target to pool..."
7395                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7396                         error "pool_add_targets failed"
7397                 echo "done."
7398         fi
7399
7400         echo -n "Setting pool using -p option..."
7401         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7402                 error "migrate failed rc = $?"
7403         echo "done."
7404
7405         echo -n "Verifying test file is in pool after migrating..."
7406         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7407                 error "file was not migrated to pool $pool"
7408         echo "done."
7409
7410         echo -n "Removing test file from pool '$pool'..."
7411         # "lfs migrate $file" won't remove the file from the pool
7412         # until some striping information is changed.
7413         $LFS migrate -c 1 $file1 &> /dev/null ||
7414                 error "cannot remove from pool"
7415         [ "$($LFS getstripe -p $file1)" ] &&
7416                 error "pool still set"
7417         echo "done."
7418
7419         echo -n "Setting pool using --pool option..."
7420         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7421                 error "migrate failed rc = $?"
7422         echo "done."
7423
7424         # Clean up
7425         rm -f $file1
7426         if $create_pool; then
7427                 destroy_test_pools 2> /dev/null ||
7428                         error "destroy test pools failed"
7429         fi
7430 }
7431 run_test 56wb "check lfs_migrate pool support"
7432
7433 test_56wc() {
7434         local file1="$DIR/$tdir/file1"
7435         local parent_ssize
7436         local parent_scount
7437         local cur_ssize
7438         local cur_scount
7439         local orig_ssize
7440
7441         echo -n "Creating test dir..."
7442         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7443         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7444                 error "cannot set stripe by '-S 1M -c 1'"
7445         echo "done"
7446
7447         echo -n "Setting initial stripe for test file..."
7448         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7449                 error "cannot set stripe"
7450         cur_ssize=$($LFS getstripe -S "$file1")
7451         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7452         echo "done."
7453
7454         # File currently set to -S 512K -c 1
7455
7456         # Ensure -c and -S options are rejected when -R is set
7457         echo -n "Verifying incompatible options are detected..."
7458         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7459                 error "incompatible -c and -R options not detected"
7460         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7461                 error "incompatible -S and -R options not detected"
7462         echo "done."
7463
7464         # Ensure unrecognized options are passed through to 'lfs migrate'
7465         echo -n "Verifying -S option is passed through to lfs migrate..."
7466         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7467                 error "migration failed"
7468         cur_ssize=$($LFS getstripe -S "$file1")
7469         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7470         echo "done."
7471
7472         # File currently set to -S 1M -c 1
7473
7474         # Ensure long options are supported
7475         echo -n "Verifying long options supported..."
7476         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7477                 error "long option without argument not supported"
7478         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7479                 error "long option with argument not supported"
7480         cur_ssize=$($LFS getstripe -S "$file1")
7481         [ $cur_ssize -eq 524288 ] ||
7482                 error "migrate --stripe-size $cur_ssize != 524288"
7483         echo "done."
7484
7485         # File currently set to -S 512K -c 1
7486
7487         if [ "$OSTCOUNT" -gt 1 ]; then
7488                 echo -n "Verifying explicit stripe count can be set..."
7489                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7490                         error "migrate failed"
7491                 cur_scount=$($LFS getstripe -c "$file1")
7492                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7493                 echo "done."
7494         fi
7495
7496         # File currently set to -S 512K -c 1 or -S 512K -c 2
7497
7498         # Ensure parent striping is used if -R is set, and no stripe
7499         # count or size is specified
7500         echo -n "Setting stripe for parent directory..."
7501         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7502                 error "cannot set stripe '-S 2M -c 1'"
7503         echo "done."
7504
7505         echo -n "Verifying restripe option uses parent stripe settings..."
7506         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7507         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7508         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7509                 error "migrate failed"
7510         cur_ssize=$($LFS getstripe -S "$file1")
7511         [ $cur_ssize -eq $parent_ssize ] ||
7512                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7513         cur_scount=$($LFS getstripe -c "$file1")
7514         [ $cur_scount -eq $parent_scount ] ||
7515                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7516         echo "done."
7517
7518         # File currently set to -S 1M -c 1
7519
7520         # Ensure striping is preserved if -R is not set, and no stripe
7521         # count or size is specified
7522         echo -n "Verifying striping size preserved when not specified..."
7523         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7524         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7525                 error "cannot set stripe on parent directory"
7526         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7527                 error "migrate failed"
7528         cur_ssize=$($LFS getstripe -S "$file1")
7529         [ $cur_ssize -eq $orig_ssize ] ||
7530                 error "migrate by default $cur_ssize != $orig_ssize"
7531         echo "done."
7532
7533         # Ensure file name properly detected when final option has no argument
7534         echo -n "Verifying file name properly detected..."
7535         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7536                 error "file name interpreted as option argument"
7537         echo "done."
7538
7539         # Clean up
7540         rm -f "$file1"
7541 }
7542 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7543
7544 test_56wd() {
7545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7546
7547         local file1=$DIR/$tdir/file1
7548
7549         echo -n "Creating test dir..."
7550         test_mkdir $DIR/$tdir || error "cannot create dir"
7551         echo "done."
7552
7553         echo -n "Creating test file..."
7554         touch $file1
7555         echo "done."
7556
7557         # Ensure 'lfs migrate' will fail by using a non-existent option,
7558         # and make sure rsync is not called to recover
7559         echo -n "Make sure --no-rsync option works..."
7560         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7561                 grep -q 'refusing to fall back to rsync' ||
7562                 error "rsync was called with --no-rsync set"
7563         echo "done."
7564
7565         # Ensure rsync is called without trying 'lfs migrate' first
7566         echo -n "Make sure --rsync option works..."
7567         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7568                 grep -q 'falling back to rsync' &&
7569                 error "lfs migrate was called with --rsync set"
7570         echo "done."
7571
7572         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7573         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7574                 grep -q 'at the same time' ||
7575                 error "--rsync and --no-rsync accepted concurrently"
7576         echo "done."
7577
7578         # Clean up
7579         rm -f $file1
7580 }
7581 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7582
7583 test_56we() {
7584         local td=$DIR/$tdir
7585         local tf=$td/$tfile
7586
7587         test_mkdir $td || error "cannot create $td"
7588         touch $tf || error "cannot touch $tf"
7589
7590         echo -n "Make sure --non-direct|-D works..."
7591         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7592                 grep -q "lfs migrate --non-direct" ||
7593                 error "--non-direct option cannot work correctly"
7594         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7595                 grep -q "lfs migrate -D" ||
7596                 error "-D option cannot work correctly"
7597         echo "done."
7598 }
7599 run_test 56we "check lfs_migrate --non-direct|-D support"
7600
7601 test_56x() {
7602         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7603         check_swap_layouts_support
7604
7605         local dir=$DIR/$tdir
7606         local ref1=/etc/passwd
7607         local file1=$dir/file1
7608
7609         test_mkdir $dir || error "creating dir $dir"
7610         $LFS setstripe -c 2 $file1
7611         cp $ref1 $file1
7612         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7613         stripe=$($LFS getstripe -c $file1)
7614         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7615         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7616
7617         # clean up
7618         rm -f $file1
7619 }
7620 run_test 56x "lfs migration support"
7621
7622 test_56xa() {
7623         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7624         check_swap_layouts_support
7625
7626         local dir=$DIR/$tdir/$testnum
7627
7628         test_mkdir -p $dir
7629
7630         local ref1=/etc/passwd
7631         local file1=$dir/file1
7632
7633         $LFS setstripe -c 2 $file1
7634         cp $ref1 $file1
7635         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7636
7637         local stripe=$($LFS getstripe -c $file1)
7638
7639         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7640         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7641
7642         # clean up
7643         rm -f $file1
7644 }
7645 run_test 56xa "lfs migration --block support"
7646
7647 check_migrate_links() {
7648         local dir="$1"
7649         local file1="$dir/file1"
7650         local begin="$2"
7651         local count="$3"
7652         local runas="$4"
7653         local total_count=$(($begin + $count - 1))
7654         local symlink_count=10
7655         local uniq_count=10
7656
7657         if [ ! -f "$file1" ]; then
7658                 echo -n "creating initial file..."
7659                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7660                         error "cannot setstripe initial file"
7661                 echo "done"
7662
7663                 echo -n "creating symlinks..."
7664                 for s in $(seq 1 $symlink_count); do
7665                         ln -s "$file1" "$dir/slink$s" ||
7666                                 error "cannot create symlinks"
7667                 done
7668                 echo "done"
7669
7670                 echo -n "creating nonlinked files..."
7671                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7672                         error "cannot create nonlinked files"
7673                 echo "done"
7674         fi
7675
7676         # create hard links
7677         if [ ! -f "$dir/file$total_count" ]; then
7678                 echo -n "creating hard links $begin:$total_count..."
7679                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7680                         /dev/null || error "cannot create hard links"
7681                 echo "done"
7682         fi
7683
7684         echo -n "checking number of hard links listed in xattrs..."
7685         local fid=$($LFS getstripe -F "$file1")
7686         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7687
7688         echo "${#paths[*]}"
7689         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7690                         skip "hard link list has unexpected size, skipping test"
7691         fi
7692         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7693                         error "link names should exceed xattrs size"
7694         fi
7695
7696         echo -n "migrating files..."
7697         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7698         local rc=$?
7699         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7700         echo "done"
7701
7702         # make sure all links have been properly migrated
7703         echo -n "verifying files..."
7704         fid=$($LFS getstripe -F "$file1") ||
7705                 error "cannot get fid for file $file1"
7706         for i in $(seq 2 $total_count); do
7707                 local fid2=$($LFS getstripe -F $dir/file$i)
7708
7709                 [ "$fid2" == "$fid" ] ||
7710                         error "migrated hard link has mismatched FID"
7711         done
7712
7713         # make sure hard links were properly detected, and migration was
7714         # performed only once for the entire link set; nonlinked files should
7715         # also be migrated
7716         local actual=$(grep -c 'done' <<< "$migrate_out")
7717         local expected=$(($uniq_count + 1))
7718
7719         [ "$actual" -eq  "$expected" ] ||
7720                 error "hard links individually migrated ($actual != $expected)"
7721
7722         # make sure the correct number of hard links are present
7723         local hardlinks=$(stat -c '%h' "$file1")
7724
7725         [ $hardlinks -eq $total_count ] ||
7726                 error "num hard links $hardlinks != $total_count"
7727         echo "done"
7728
7729         return 0
7730 }
7731
7732 test_56xb() {
7733         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7734                 skip "Need MDS version at least 2.10.55"
7735
7736         local dir="$DIR/$tdir"
7737
7738         test_mkdir "$dir" || error "cannot create dir $dir"
7739
7740         echo "testing lfs migrate mode when all links fit within xattrs"
7741         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7742
7743         echo "testing rsync mode when all links fit within xattrs"
7744         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7745
7746         echo "testing lfs migrate mode when all links do not fit within xattrs"
7747         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7748
7749         echo "testing rsync mode when all links do not fit within xattrs"
7750         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7751
7752         chown -R $RUNAS_ID $dir
7753         echo "testing non-root lfs migrate mode when not all links are in xattr"
7754         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7755
7756         # clean up
7757         rm -rf $dir
7758 }
7759 run_test 56xb "lfs migration hard link support"
7760
7761 test_56xc() {
7762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7763
7764         local dir="$DIR/$tdir"
7765
7766         test_mkdir "$dir" || error "cannot create dir $dir"
7767
7768         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7769         echo -n "Setting initial stripe for 20MB test file..."
7770         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7771                 error "cannot setstripe 20MB file"
7772         echo "done"
7773         echo -n "Sizing 20MB test file..."
7774         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7775         echo "done"
7776         echo -n "Verifying small file autostripe count is 1..."
7777         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7778                 error "cannot migrate 20MB file"
7779         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7780                 error "cannot get stripe for $dir/20mb"
7781         [ $stripe_count -eq 1 ] ||
7782                 error "unexpected stripe count $stripe_count for 20MB file"
7783         rm -f "$dir/20mb"
7784         echo "done"
7785
7786         # Test 2: File is small enough to fit within the available space on
7787         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7788         # have at least an additional 1KB for each desired stripe for test 3
7789         echo -n "Setting stripe for 1GB test file..."
7790         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7791         echo "done"
7792         echo -n "Sizing 1GB test file..."
7793         # File size is 1GB + 3KB
7794         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7795         echo "done"
7796
7797         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7798         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7799         if (( avail > 524288 * OSTCOUNT )); then
7800                 echo -n "Migrating 1GB file..."
7801                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7802                         error "cannot migrate 1GB file"
7803                 echo "done"
7804                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7805                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7806                         error "cannot getstripe for 1GB file"
7807                 [ $stripe_count -eq 2 ] ||
7808                         error "unexpected stripe count $stripe_count != 2"
7809                 echo "done"
7810         fi
7811
7812         # Test 3: File is too large to fit within the available space on
7813         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7814         if [ $OSTCOUNT -ge 3 ]; then
7815                 # The required available space is calculated as
7816                 # file size (1GB + 3KB) / OST count (3).
7817                 local kb_per_ost=349526
7818
7819                 echo -n "Migrating 1GB file with limit..."
7820                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7821                         error "cannot migrate 1GB file with limit"
7822                 echo "done"
7823
7824                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7825                 echo -n "Verifying 1GB autostripe count with limited space..."
7826                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7827                         error "unexpected stripe count $stripe_count (min 3)"
7828                 echo "done"
7829         fi
7830
7831         # clean up
7832         rm -rf $dir
7833 }
7834 run_test 56xc "lfs migration autostripe"
7835
7836 test_56xd() {
7837         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7838
7839         local dir=$DIR/$tdir
7840         local f_mgrt=$dir/$tfile.mgrt
7841         local f_yaml=$dir/$tfile.yaml
7842         local f_copy=$dir/$tfile.copy
7843         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7844         local layout_copy="-c 2 -S 2M -i 1"
7845         local yamlfile=$dir/yamlfile
7846         local layout_before;
7847         local layout_after;
7848
7849         test_mkdir "$dir" || error "cannot create dir $dir"
7850         $LFS setstripe $layout_yaml $f_yaml ||
7851                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7852         $LFS getstripe --yaml $f_yaml > $yamlfile
7853         $LFS setstripe $layout_copy $f_copy ||
7854                 error "cannot setstripe $f_copy with layout $layout_copy"
7855         touch $f_mgrt
7856         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7857
7858         # 1. test option --yaml
7859         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7860                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7861         layout_before=$(get_layout_param $f_yaml)
7862         layout_after=$(get_layout_param $f_mgrt)
7863         [ "$layout_after" == "$layout_before" ] ||
7864                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7865
7866         # 2. test option --copy
7867         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7868                 error "cannot migrate $f_mgrt with --copy $f_copy"
7869         layout_before=$(get_layout_param $f_copy)
7870         layout_after=$(get_layout_param $f_mgrt)
7871         [ "$layout_after" == "$layout_before" ] ||
7872                 error "lfs_migrate --copy: $layout_after != $layout_before"
7873 }
7874 run_test 56xd "check lfs_migrate --yaml and --copy support"
7875
7876 test_56xe() {
7877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7878
7879         local dir=$DIR/$tdir
7880         local f_comp=$dir/$tfile
7881         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7882         local layout_before=""
7883         local layout_after=""
7884
7885         test_mkdir "$dir" || error "cannot create dir $dir"
7886         $LFS setstripe $layout $f_comp ||
7887                 error "cannot setstripe $f_comp with layout $layout"
7888         layout_before=$(get_layout_param $f_comp)
7889         dd if=/dev/zero of=$f_comp bs=1M count=4
7890
7891         # 1. migrate a comp layout file by lfs_migrate
7892         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7893         layout_after=$(get_layout_param $f_comp)
7894         [ "$layout_before" == "$layout_after" ] ||
7895                 error "lfs_migrate: $layout_before != $layout_after"
7896
7897         # 2. migrate a comp layout file by lfs migrate
7898         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7899         layout_after=$(get_layout_param $f_comp)
7900         [ "$layout_before" == "$layout_after" ] ||
7901                 error "lfs migrate: $layout_before != $layout_after"
7902 }
7903 run_test 56xe "migrate a composite layout file"
7904
7905 test_56xf() {
7906         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7907
7908         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7909                 skip "Need server version at least 2.13.53"
7910
7911         local dir=$DIR/$tdir
7912         local f_comp=$dir/$tfile
7913         local layout="-E 1M -c1 -E -1 -c2"
7914         local fid_before=""
7915         local fid_after=""
7916
7917         test_mkdir "$dir" || error "cannot create dir $dir"
7918         $LFS setstripe $layout $f_comp ||
7919                 error "cannot setstripe $f_comp with layout $layout"
7920         fid_before=$($LFS getstripe --fid $f_comp)
7921         dd if=/dev/zero of=$f_comp bs=1M count=4
7922
7923         # 1. migrate a comp layout file to a comp layout
7924         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7925         fid_after=$($LFS getstripe --fid $f_comp)
7926         [ "$fid_before" == "$fid_after" ] ||
7927                 error "comp-to-comp migrate: $fid_before != $fid_after"
7928
7929         # 2. migrate a comp layout file to a plain layout
7930         $LFS migrate -c2 $f_comp ||
7931                 error "cannot migrate $f_comp by lfs migrate"
7932         fid_after=$($LFS getstripe --fid $f_comp)
7933         [ "$fid_before" == "$fid_after" ] ||
7934                 error "comp-to-plain migrate: $fid_before != $fid_after"
7935
7936         # 3. migrate a plain layout file to a comp layout
7937         $LFS migrate $layout $f_comp ||
7938                 error "cannot migrate $f_comp by lfs migrate"
7939         fid_after=$($LFS getstripe --fid $f_comp)
7940         [ "$fid_before" == "$fid_after" ] ||
7941                 error "plain-to-comp migrate: $fid_before != $fid_after"
7942 }
7943 run_test 56xf "FID is not lost during migration of a composite layout file"
7944
7945 check_file_ost_range() {
7946         local file="$1"
7947         shift
7948         local range="$*"
7949         local -a file_range
7950         local idx
7951
7952         file_range=($($LFS getstripe -y "$file" |
7953                 awk '/l_ost_idx:/ { print $NF }'))
7954
7955         if [[ "${#file_range[@]}" = 0 ]]; then
7956                 echo "No osts found for $file"
7957                 return 1
7958         fi
7959
7960         for idx in "${file_range[@]}"; do
7961                 [[ " $range " =~ " $idx " ]] ||
7962                         return 1
7963         done
7964
7965         return 0
7966 }
7967
7968 sub_test_56xg() {
7969         local stripe_opt="$1"
7970         local pool="$2"
7971         shift 2
7972         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7973
7974         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7975                 error "Fail to migrate $tfile on $pool"
7976         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7977                 error "$tfile is not in pool $pool"
7978         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7979                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7980 }
7981
7982 test_56xg() {
7983         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7984         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7985         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7986                 skip "Need MDS version newer than 2.14.52"
7987
7988         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7989         local -a pool_ranges=("0 0" "1 1" "0 1")
7990
7991         # init pools
7992         for i in "${!pool_names[@]}"; do
7993                 pool_add ${pool_names[$i]} ||
7994                         error "pool_add failed (pool: ${pool_names[$i]})"
7995                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7996                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7997         done
7998
7999         # init the file to migrate
8000         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8001                 error "Unable to create $tfile on OST1"
8002         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8003                 error "Unable to write on $tfile"
8004
8005         echo "1. migrate $tfile on pool ${pool_names[0]}"
8006         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8007
8008         echo "2. migrate $tfile on pool ${pool_names[2]}"
8009         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8010
8011         echo "3. migrate $tfile on pool ${pool_names[1]}"
8012         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8013
8014         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8015         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8016         echo
8017
8018         # Clean pools
8019         destroy_test_pools ||
8020                 error "pool_destroy failed"
8021 }
8022 run_test 56xg "lfs migrate pool support"
8023
8024 test_56y() {
8025         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8026                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8027
8028         local res=""
8029         local dir=$DIR/$tdir
8030         local f1=$dir/file1
8031         local f2=$dir/file2
8032
8033         test_mkdir -p $dir || error "creating dir $dir"
8034         touch $f1 || error "creating std file $f1"
8035         $MULTIOP $f2 H2c || error "creating released file $f2"
8036
8037         # a directory can be raid0, so ask only for files
8038         res=$($LFS find $dir -L raid0 -type f | wc -l)
8039         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8040
8041         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8042         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8043
8044         # only files can be released, so no need to force file search
8045         res=$($LFS find $dir -L released)
8046         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8047
8048         res=$($LFS find $dir -type f \! -L released)
8049         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8050 }
8051 run_test 56y "lfs find -L raid0|released"
8052
8053 test_56z() { # LU-4824
8054         # This checks to make sure 'lfs find' continues after errors
8055         # There are two classes of errors that should be caught:
8056         # - If multiple paths are provided, all should be searched even if one
8057         #   errors out
8058         # - If errors are encountered during the search, it should not terminate
8059         #   early
8060         local dir=$DIR/$tdir
8061         local i
8062
8063         test_mkdir $dir
8064         for i in d{0..9}; do
8065                 test_mkdir $dir/$i
8066                 touch $dir/$i/$tfile
8067         done
8068         $LFS find $DIR/non_existent_dir $dir &&
8069                 error "$LFS find did not return an error"
8070         # Make a directory unsearchable. This should NOT be the last entry in
8071         # directory order.  Arbitrarily pick the 6th entry
8072         chmod 700 $($LFS find $dir -type d | sed '6!d')
8073
8074         $RUNAS $LFS find $DIR/non_existent $dir
8075         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8076
8077         # The user should be able to see 10 directories and 9 files
8078         (( count == 19 )) ||
8079                 error "$LFS find found $count != 19 entries after error"
8080 }
8081 run_test 56z "lfs find should continue after an error"
8082
8083 test_56aa() { # LU-5937
8084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8085
8086         local dir=$DIR/$tdir
8087
8088         mkdir $dir
8089         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8090
8091         createmany -o $dir/striped_dir/${tfile}- 1024
8092         local dirs=$($LFS find --size +8k $dir/)
8093
8094         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8095 }
8096 run_test 56aa "lfs find --size under striped dir"
8097
8098 test_56ab() { # LU-10705
8099         test_mkdir $DIR/$tdir
8100         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8101         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8102         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8103         # Flush writes to ensure valid blocks.  Need to be more thorough for
8104         # ZFS, since blocks are not allocated/returned to client immediately.
8105         sync_all_data
8106         wait_zfs_commit ost1 2
8107         cancel_lru_locks osc
8108         ls -ls $DIR/$tdir
8109
8110         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8111
8112         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8113
8114         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8115         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8116
8117         rm -f $DIR/$tdir/$tfile.[123]
8118 }
8119 run_test 56ab "lfs find --blocks"
8120
8121 # LU-11188
8122 test_56aca() {
8123         local dir="$DIR/$tdir"
8124         local perms=(001 002 003 004 005 006 007
8125                      010 020 030 040 050 060 070
8126                      100 200 300 400 500 600 700
8127                      111 222 333 444 555 666 777)
8128         local perm_minus=(8 8 4 8 4 4 2
8129                           8 8 4 8 4 4 2
8130                           8 8 4 8 4 4 2
8131                           4 4 2 4 2 2 1)
8132         local perm_slash=(8  8 12  8 12 12 14
8133                           8  8 12  8 12 12 14
8134                           8  8 12  8 12 12 14
8135                          16 16 24 16 24 24 28)
8136
8137         test_mkdir "$dir"
8138         for perm in ${perms[*]}; do
8139                 touch "$dir/$tfile.$perm"
8140                 chmod $perm "$dir/$tfile.$perm"
8141         done
8142
8143         for ((i = 0; i < ${#perms[*]}; i++)); do
8144                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8145                 (( $num == 1 )) ||
8146                         error "lfs find -perm ${perms[i]}:"\
8147                               "$num != 1"
8148
8149                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8150                 (( $num == ${perm_minus[i]} )) ||
8151                         error "lfs find -perm -${perms[i]}:"\
8152                               "$num != ${perm_minus[i]}"
8153
8154                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8155                 (( $num == ${perm_slash[i]} )) ||
8156                         error "lfs find -perm /${perms[i]}:"\
8157                               "$num != ${perm_slash[i]}"
8158         done
8159 }
8160 run_test 56aca "check lfs find -perm with octal representation"
8161
8162 test_56acb() {
8163         local dir=$DIR/$tdir
8164         # p is the permission of write and execute for user, group and other
8165         # without the umask. It is used to test +wx.
8166         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8167         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8168         local symbolic=(+t  a+t u+t g+t o+t
8169                         g+s u+s o+s +s o+sr
8170                         o=r,ug+o,u+w
8171                         u+ g+ o+ a+ ugo+
8172                         u- g- o- a- ugo-
8173                         u= g= o= a= ugo=
8174                         o=r,ug+o,u+w u=r,a+u,u+w
8175                         g=r,ugo=g,u+w u+x,+X +X
8176                         u+x,u+X u+X u+x,g+X o+r,+X
8177                         u+x,go+X +wx +rwx)
8178
8179         test_mkdir $dir
8180         for perm in ${perms[*]}; do
8181                 touch "$dir/$tfile.$perm"
8182                 chmod $perm "$dir/$tfile.$perm"
8183         done
8184
8185         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8186                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8187
8188                 (( $num == 1 )) ||
8189                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8190         done
8191 }
8192 run_test 56acb "check lfs find -perm with symbolic representation"
8193
8194 test_56acc() {
8195         local dir=$DIR/$tdir
8196         local tests="17777 787 789 abcd
8197                 ug=uu ug=a ug=gu uo=ou urw
8198                 u+xg+x a=r,u+x,"
8199
8200         test_mkdir $dir
8201         for err in $tests; do
8202                 if $LFS find $dir -perm $err 2>/dev/null; then
8203                         error "lfs find -perm $err: parsing should have failed"
8204                 fi
8205         done
8206 }
8207 run_test 56acc "check parsing error for lfs find -perm"
8208
8209 test_56ba() {
8210         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8211                 skip "Need MDS version at least 2.10.50"
8212
8213         # Create composite files with one component
8214         local dir=$DIR/$tdir
8215
8216         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8217         # Create composite files with three components
8218         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8219         # Create non-composite files
8220         createmany -o $dir/${tfile}- 10
8221
8222         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8223
8224         [[ $nfiles == 10 ]] ||
8225                 error "lfs find -E 1M found $nfiles != 10 files"
8226
8227         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8228         [[ $nfiles == 25 ]] ||
8229                 error "lfs find ! -E 1M found $nfiles != 25 files"
8230
8231         # All files have a component that starts at 0
8232         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8233         [[ $nfiles == 35 ]] ||
8234                 error "lfs find --component-start 0 - $nfiles != 35 files"
8235
8236         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8237         [[ $nfiles == 15 ]] ||
8238                 error "lfs find --component-start 2M - $nfiles != 15 files"
8239
8240         # All files created here have a componenet that does not starts at 2M
8241         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8242         [[ $nfiles == 35 ]] ||
8243                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8244
8245         # Find files with a specified number of components
8246         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8247         [[ $nfiles == 15 ]] ||
8248                 error "lfs find --component-count 3 - $nfiles != 15 files"
8249
8250         # Remember non-composite files have a component count of zero
8251         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8252         [[ $nfiles == 10 ]] ||
8253                 error "lfs find --component-count 0 - $nfiles != 10 files"
8254
8255         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8256         [[ $nfiles == 20 ]] ||
8257                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8258
8259         # All files have a flag called "init"
8260         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8261         [[ $nfiles == 35 ]] ||
8262                 error "lfs find --component-flags init - $nfiles != 35 files"
8263
8264         # Multi-component files will have a component not initialized
8265         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8266         [[ $nfiles == 15 ]] ||
8267                 error "lfs find !--component-flags init - $nfiles != 15 files"
8268
8269         rm -rf $dir
8270
8271 }
8272 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8273
8274 test_56ca() {
8275         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8276                 skip "Need MDS version at least 2.10.57"
8277
8278         local td=$DIR/$tdir
8279         local tf=$td/$tfile
8280         local dir
8281         local nfiles
8282         local cmd
8283         local i
8284         local j
8285
8286         # create mirrored directories and mirrored files
8287         mkdir $td || error "mkdir $td failed"
8288         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8289         createmany -o $tf- 10 || error "create $tf- failed"
8290
8291         for i in $(seq 2); do
8292                 dir=$td/dir$i
8293                 mkdir $dir || error "mkdir $dir failed"
8294                 $LFS mirror create -N$((3 + i)) $dir ||
8295                         error "create mirrored dir $dir failed"
8296                 createmany -o $dir/$tfile- 10 ||
8297                         error "create $dir/$tfile- failed"
8298         done
8299
8300         # change the states of some mirrored files
8301         echo foo > $tf-6
8302         for i in $(seq 2); do
8303                 dir=$td/dir$i
8304                 for j in $(seq 4 9); do
8305                         echo foo > $dir/$tfile-$j
8306                 done
8307         done
8308
8309         # find mirrored files with specific mirror count
8310         cmd="$LFS find --mirror-count 3 --type f $td"
8311         nfiles=$($cmd | wc -l)
8312         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8313
8314         cmd="$LFS find ! --mirror-count 3 --type f $td"
8315         nfiles=$($cmd | wc -l)
8316         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8317
8318         cmd="$LFS find --mirror-count +2 --type f $td"
8319         nfiles=$($cmd | wc -l)
8320         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8321
8322         cmd="$LFS find --mirror-count -6 --type f $td"
8323         nfiles=$($cmd | wc -l)
8324         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8325
8326         # find mirrored files with specific file state
8327         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8328         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8329
8330         cmd="$LFS find --mirror-state=ro --type f $td"
8331         nfiles=$($cmd | wc -l)
8332         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8333
8334         cmd="$LFS find ! --mirror-state=ro --type f $td"
8335         nfiles=$($cmd | wc -l)
8336         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8337
8338         cmd="$LFS find --mirror-state=wp --type f $td"
8339         nfiles=$($cmd | wc -l)
8340         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8341
8342         cmd="$LFS find ! --mirror-state=sp --type f $td"
8343         nfiles=$($cmd | wc -l)
8344         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8345 }
8346 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8347
8348 test_56da() { # LU-14179
8349         local path=$DIR/$tdir
8350
8351         test_mkdir $path
8352         cd $path
8353
8354         local longdir=$(str_repeat 'a' 255)
8355
8356         for i in {1..15}; do
8357                 path=$path/$longdir
8358                 test_mkdir $longdir
8359                 cd $longdir
8360         done
8361
8362         local len=${#path}
8363         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8364
8365         test_mkdir $lastdir
8366         cd $lastdir
8367         # PATH_MAX-1
8368         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8369
8370         # NAME_MAX
8371         touch $(str_repeat 'f' 255)
8372
8373         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8374                 error "lfs find reported an error"
8375
8376         rm -rf $DIR/$tdir
8377 }
8378 run_test 56da "test lfs find with long paths"
8379
8380 test_56ea() { #LU-10378
8381         local path=$DIR/$tdir
8382         local pool=$TESTNAME
8383
8384         # Create ost pool
8385         pool_add $pool || error "pool_add $pool failed"
8386         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8387                 error "adding targets to $pool failed"
8388
8389         # Set default pool on directory before creating file
8390         mkdir $path || error "mkdir $path failed"
8391         $LFS setstripe -p $pool $path ||
8392                 error "set OST pool on $pool failed"
8393         touch $path/$tfile || error "touch $path/$tfile failed"
8394
8395         # Compare basic file attributes from -printf and stat
8396         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8397         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8398
8399         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8400                 error "Attrs from lfs find and stat don't match"
8401
8402         # Compare Lustre attributes from lfs find and lfs getstripe
8403         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8404         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8405         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8406         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8407         local fpool=$($LFS getstripe --pool $path/$tfile)
8408         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8409
8410         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8411                 error "Attrs from lfs find and lfs getstripe don't match"
8412
8413         # Verify behavior for unknown escape/format sequences
8414         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8415
8416         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8417                 error "Escape/format codes don't match"
8418 }
8419 run_test 56ea "test lfs find -printf option"
8420
8421 test_56eb() {
8422         local dir=$DIR/$tdir
8423         local subdir_1=$dir/subdir_1
8424
8425         test_mkdir -p $subdir_1
8426         ln -s subdir_1 $dir/link_1
8427
8428         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8429                 error "symlink is not followed"
8430
8431         $LFS getstripe --no-follow $dir |
8432                 grep "^$dir/link_1 has no stripe info$" ||
8433                 error "symlink should not have stripe info"
8434
8435         touch $dir/testfile
8436         ln -s testfile $dir/file_link_2
8437
8438         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8439                 error "symlink is not followed"
8440
8441         $LFS getstripe --no-follow $dir |
8442                 grep "^$dir/file_link_2 has no stripe info$" ||
8443                 error "symlink should not have stripe info"
8444 }
8445 run_test 56eb "check lfs getstripe on symlink"
8446
8447 test_57a() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449         # note test will not do anything if MDS is not local
8450         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8451                 skip_env "ldiskfs only test"
8452         fi
8453         remote_mds_nodsh && skip "remote MDS with nodsh"
8454
8455         local MNTDEV="osd*.*MDT*.mntdev"
8456         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8457         [ -z "$DEV" ] && error "can't access $MNTDEV"
8458         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8459                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8460                         error "can't access $DEV"
8461                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8462                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8463                 rm $TMP/t57a.dump
8464         done
8465 }
8466 run_test 57a "verify MDS filesystem created with large inodes =="
8467
8468 test_57b() {
8469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8470         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8471                 skip_env "ldiskfs only test"
8472         fi
8473         remote_mds_nodsh && skip "remote MDS with nodsh"
8474
8475         local dir=$DIR/$tdir
8476         local filecount=100
8477         local file1=$dir/f1
8478         local fileN=$dir/f$filecount
8479
8480         rm -rf $dir || error "removing $dir"
8481         test_mkdir -c1 $dir
8482         local mdtidx=$($LFS getstripe -m $dir)
8483         local mdtname=MDT$(printf %04x $mdtidx)
8484         local facet=mds$((mdtidx + 1))
8485
8486         echo "mcreating $filecount files"
8487         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8488
8489         # verify that files do not have EAs yet
8490         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8491                 error "$file1 has an EA"
8492         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8493                 error "$fileN has an EA"
8494
8495         sync
8496         sleep 1
8497         df $dir  #make sure we get new statfs data
8498         local mdsfree=$(do_facet $facet \
8499                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8500         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8501         local file
8502
8503         echo "opening files to create objects/EAs"
8504         for file in $(seq -f $dir/f%g 1 $filecount); do
8505                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8506                         error "opening $file"
8507         done
8508
8509         # verify that files have EAs now
8510         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8511         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8512
8513         sleep 1  #make sure we get new statfs data
8514         df $dir
8515         local mdsfree2=$(do_facet $facet \
8516                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8517         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8518
8519         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8520                 if [ "$mdsfree" != "$mdsfree2" ]; then
8521                         error "MDC before $mdcfree != after $mdcfree2"
8522                 else
8523                         echo "MDC before $mdcfree != after $mdcfree2"
8524                         echo "unable to confirm if MDS has large inodes"
8525                 fi
8526         fi
8527         rm -rf $dir
8528 }
8529 run_test 57b "default LOV EAs are stored inside large inodes ==="
8530
8531 test_58() {
8532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8533         [ -z "$(which wiretest 2>/dev/null)" ] &&
8534                         skip_env "could not find wiretest"
8535
8536         wiretest
8537 }
8538 run_test 58 "verify cross-platform wire constants =============="
8539
8540 test_59() {
8541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8542
8543         echo "touch 130 files"
8544         createmany -o $DIR/f59- 130
8545         echo "rm 130 files"
8546         unlinkmany $DIR/f59- 130
8547         sync
8548         # wait for commitment of removal
8549         wait_delete_completed
8550 }
8551 run_test 59 "verify cancellation of llog records async ========="
8552
8553 TEST60_HEAD="test_60 run $RANDOM"
8554 test_60a() {
8555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8556         remote_mgs_nodsh && skip "remote MGS with nodsh"
8557         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8558                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8559                         skip_env "missing subtest run-llog.sh"
8560
8561         log "$TEST60_HEAD - from kernel mode"
8562         do_facet mgs "$LCTL dk > /dev/null"
8563         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8564         do_facet mgs $LCTL dk > $TMP/$tfile
8565
8566         # LU-6388: test llog_reader
8567         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8568         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8569         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8570                         skip_env "missing llog_reader"
8571         local fstype=$(facet_fstype mgs)
8572         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8573                 skip_env "Only for ldiskfs or zfs type mgs"
8574
8575         local mntpt=$(facet_mntpt mgs)
8576         local mgsdev=$(mgsdevname 1)
8577         local fid_list
8578         local fid
8579         local rec_list
8580         local rec
8581         local rec_type
8582         local obj_file
8583         local path
8584         local seq
8585         local oid
8586         local pass=true
8587
8588         #get fid and record list
8589         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8590                 tail -n 4))
8591         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8592                 tail -n 4))
8593         #remount mgs as ldiskfs or zfs type
8594         stop mgs || error "stop mgs failed"
8595         mount_fstype mgs || error "remount mgs failed"
8596         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8597                 fid=${fid_list[i]}
8598                 rec=${rec_list[i]}
8599                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8600                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8601                 oid=$((16#$oid))
8602
8603                 case $fstype in
8604                         ldiskfs )
8605                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8606                         zfs )
8607                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8608                 esac
8609                 echo "obj_file is $obj_file"
8610                 do_facet mgs $llog_reader $obj_file
8611
8612                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8613                         awk '{ print $3 }' | sed -e "s/^type=//g")
8614                 if [ $rec_type != $rec ]; then
8615                         echo "FAILED test_60a wrong record type $rec_type," \
8616                               "should be $rec"
8617                         pass=false
8618                         break
8619                 fi
8620
8621                 #check obj path if record type is LLOG_LOGID_MAGIC
8622                 if [ "$rec" == "1064553b" ]; then
8623                         path=$(do_facet mgs $llog_reader $obj_file |
8624                                 grep "path=" | awk '{ print $NF }' |
8625                                 sed -e "s/^path=//g")
8626                         if [ $obj_file != $mntpt/$path ]; then
8627                                 echo "FAILED test_60a wrong obj path" \
8628                                       "$montpt/$path, should be $obj_file"
8629                                 pass=false
8630                                 break
8631                         fi
8632                 fi
8633         done
8634         rm -f $TMP/$tfile
8635         #restart mgs before "error", otherwise it will block the next test
8636         stop mgs || error "stop mgs failed"
8637         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8638         $pass || error "test failed, see FAILED test_60a messages for specifics"
8639 }
8640 run_test 60a "llog_test run from kernel module and test llog_reader"
8641
8642 test_60b() { # bug 6411
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644
8645         dmesg > $DIR/$tfile
8646         LLOG_COUNT=$(do_facet mgs dmesg |
8647                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8648                           /llog_[a-z]*.c:[0-9]/ {
8649                                 if (marker)
8650                                         from_marker++
8651                                 from_begin++
8652                           }
8653                           END {
8654                                 if (marker)
8655                                         print from_marker
8656                                 else
8657                                         print from_begin
8658                           }")
8659
8660         [[ $LLOG_COUNT -gt 120 ]] &&
8661                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8662 }
8663 run_test 60b "limit repeated messages from CERROR/CWARN"
8664
8665 test_60c() {
8666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8667
8668         echo "create 5000 files"
8669         createmany -o $DIR/f60c- 5000
8670 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8671         lctl set_param fail_loc=0x80000137
8672         unlinkmany $DIR/f60c- 5000
8673         lctl set_param fail_loc=0
8674 }
8675 run_test 60c "unlink file when mds full"
8676
8677 test_60d() {
8678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8679
8680         SAVEPRINTK=$(lctl get_param -n printk)
8681         # verify "lctl mark" is even working"
8682         MESSAGE="test message ID $RANDOM $$"
8683         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8684         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8685
8686         lctl set_param printk=0 || error "set lnet.printk failed"
8687         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8688         MESSAGE="new test message ID $RANDOM $$"
8689         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8690         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8691         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8692
8693         lctl set_param -n printk="$SAVEPRINTK"
8694 }
8695 run_test 60d "test printk console message masking"
8696
8697 test_60e() {
8698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8699         remote_mds_nodsh && skip "remote MDS with nodsh"
8700
8701         touch $DIR/$tfile
8702 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8703         do_facet mds1 lctl set_param fail_loc=0x15b
8704         rm $DIR/$tfile
8705 }
8706 run_test 60e "no space while new llog is being created"
8707
8708 test_60f() {
8709         local old_path=$($LCTL get_param -n debug_path)
8710
8711         stack_trap "$LCTL set_param debug_path=$old_path"
8712         stack_trap "rm -f $TMP/$tfile*"
8713         rm -f $TMP/$tfile* 2> /dev/null
8714         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8715         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8716         test_mkdir $DIR/$tdir
8717         # retry in case the open is cached and not released
8718         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8719                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8720                 sleep 0.1
8721         done
8722         ls $TMP/$tfile*
8723         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8724 }
8725 run_test 60f "change debug_path works"
8726
8727 test_60g() {
8728         local pid
8729         local i
8730
8731         test_mkdir -c $MDSCOUNT $DIR/$tdir
8732
8733         (
8734                 local index=0
8735                 while true; do
8736                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8737                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8738                                 2>/dev/null
8739                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8740                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8741                         index=$((index + 1))
8742                 done
8743         ) &
8744
8745         pid=$!
8746
8747         for i in {0..100}; do
8748                 # define OBD_FAIL_OSD_TXN_START    0x19a
8749                 local index=$((i % MDSCOUNT + 1))
8750
8751                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8752                         > /dev/null
8753                 sleep 0.01
8754         done
8755
8756         kill -9 $pid
8757
8758         for i in $(seq $MDSCOUNT); do
8759                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8760         done
8761
8762         mkdir $DIR/$tdir/new || error "mkdir failed"
8763         rmdir $DIR/$tdir/new || error "rmdir failed"
8764
8765         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8766                 -t namespace
8767         for i in $(seq $MDSCOUNT); do
8768                 wait_update_facet mds$i "$LCTL get_param -n \
8769                         mdd.$(facet_svc mds$i).lfsck_namespace |
8770                         awk '/^status/ { print \\\$2 }'" "completed"
8771         done
8772
8773         ls -R $DIR/$tdir
8774         rm -rf $DIR/$tdir || error "rmdir failed"
8775 }
8776 run_test 60g "transaction abort won't cause MDT hung"
8777
8778 test_60h() {
8779         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8780                 skip "Need MDS version at least 2.12.52"
8781         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8782
8783         local f
8784
8785         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8786         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8787         for fail_loc in 0x80000188 0x80000189; do
8788                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8789                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8790                         error "mkdir $dir-$fail_loc failed"
8791                 for i in {0..10}; do
8792                         # create may fail on missing stripe
8793                         echo $i > $DIR/$tdir-$fail_loc/$i
8794                 done
8795                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8796                         error "getdirstripe $tdir-$fail_loc failed"
8797                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8798                         error "migrate $tdir-$fail_loc failed"
8799                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8800                         error "getdirstripe $tdir-$fail_loc failed"
8801                 pushd $DIR/$tdir-$fail_loc
8802                 for f in *; do
8803                         echo $f | cmp $f - || error "$f data mismatch"
8804                 done
8805                 popd
8806                 rm -rf $DIR/$tdir-$fail_loc
8807         done
8808 }
8809 run_test 60h "striped directory with missing stripes can be accessed"
8810
8811 function t60i_load() {
8812         mkdir $DIR/$tdir
8813         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8814         $LCTL set_param fail_loc=0x131c fail_val=1
8815         for ((i=0; i<5000; i++)); do
8816                 touch $DIR/$tdir/f$i
8817         done
8818 }
8819
8820 test_60i() {
8821         changelog_register || error "changelog_register failed"
8822         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8823         changelog_users $SINGLEMDS | grep -q $cl_user ||
8824                 error "User $cl_user not found in changelog_users"
8825         changelog_chmask "ALL"
8826         t60i_load &
8827         local PID=$!
8828         for((i=0; i<100; i++)); do
8829                 changelog_dump >/dev/null ||
8830                         error "can't read changelog"
8831         done
8832         kill $PID
8833         wait $PID
8834         changelog_deregister || error "changelog_deregister failed"
8835         $LCTL set_param fail_loc=0
8836 }
8837 run_test 60i "llog: new record vs reader race"
8838
8839 test_60j() {
8840         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8841                 skip "need MDS version at least 2.15.50"
8842         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8843         remote_mds_nodsh && skip "remote MDS with nodsh"
8844         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8845
8846         changelog_users $SINGLEMDS | grep "^cl" &&
8847                 skip "active changelog user"
8848
8849         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8850
8851         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8852                 skip_env "missing llog_reader"
8853
8854         mkdir_on_mdt0 $DIR/$tdir
8855
8856         local f=$DIR/$tdir/$tfile
8857         local mdt_dev
8858         local tmpfile
8859         local plain
8860
8861         changelog_register || error "cannot register changelog user"
8862
8863         # set changelog_mask to ALL
8864         changelog_chmask "ALL"
8865         changelog_clear
8866
8867         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8868         unlinkmany ${f}- 100 || error "unlinkmany failed"
8869
8870         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8871         mdt_dev=$(facet_device $SINGLEMDS)
8872
8873         do_facet $SINGLEMDS sync
8874         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8875                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8876                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8877
8878         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8879
8880         # if $tmpfile is not on EXT3 filesystem for some reason
8881         [[ ${plain:0:1} == 'O' ]] ||
8882                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8883
8884         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8885                 $mdt_dev; stat -c %s $tmpfile")
8886         echo "Truncate llog from $size to $((size - size % 8192))"
8887         size=$((size - size % 8192))
8888         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8889         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8890                 grep -c 'in bitmap only')
8891         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8892
8893         size=$((size - 9000))
8894         echo "Corrupt llog in the middle at $size"
8895         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8896                 count=333 conv=notrunc
8897         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8898                 grep -c 'next chunk')
8899         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
8900 }
8901 run_test 60j "llog_reader reports corruptions"
8902
8903 test_61a() {
8904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8905
8906         f="$DIR/f61"
8907         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8908         cancel_lru_locks osc
8909         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8910         sync
8911 }
8912 run_test 61a "mmap() writes don't make sync hang ================"
8913
8914 test_61b() {
8915         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8916 }
8917 run_test 61b "mmap() of unstriped file is successful"
8918
8919 # bug 2330 - insufficient obd_match error checking causes LBUG
8920 test_62() {
8921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8922
8923         f="$DIR/f62"
8924         echo foo > $f
8925         cancel_lru_locks osc
8926         lctl set_param fail_loc=0x405
8927         cat $f && error "cat succeeded, expect -EIO"
8928         lctl set_param fail_loc=0
8929 }
8930 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8931 # match every page all of the time.
8932 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8933
8934 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8935 # Though this test is irrelevant anymore, it helped to reveal some
8936 # other grant bugs (LU-4482), let's keep it.
8937 test_63a() {   # was test_63
8938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8939
8940         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8941
8942         for i in `seq 10` ; do
8943                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8944                 sleep 5
8945                 kill $!
8946                 sleep 1
8947         done
8948
8949         rm -f $DIR/f63 || true
8950 }
8951 run_test 63a "Verify oig_wait interruption does not crash ======="
8952
8953 # bug 2248 - async write errors didn't return to application on sync
8954 # bug 3677 - async write errors left page locked
8955 test_63b() {
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957
8958         debugsave
8959         lctl set_param debug=-1
8960
8961         # ensure we have a grant to do async writes
8962         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8963         rm $DIR/$tfile
8964
8965         sync    # sync lest earlier test intercept the fail_loc
8966
8967         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8968         lctl set_param fail_loc=0x80000406
8969         $MULTIOP $DIR/$tfile Owy && \
8970                 error "sync didn't return ENOMEM"
8971         sync; sleep 2; sync     # do a real sync this time to flush page
8972         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8973                 error "locked page left in cache after async error" || true
8974         debugrestore
8975 }
8976 run_test 63b "async write errors should be returned to fsync ==="
8977
8978 test_64a () {
8979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8980
8981         lfs df $DIR
8982         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8983 }
8984 run_test 64a "verify filter grant calculations (in kernel) ====="
8985
8986 test_64b () {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988
8989         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8990 }
8991 run_test 64b "check out-of-space detection on client"
8992
8993 test_64c() {
8994         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8995 }
8996 run_test 64c "verify grant shrink"
8997
8998 import_param() {
8999         local tgt=$1
9000         local param=$2
9001
9002         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9003 }
9004
9005 # this does exactly what osc_request.c:osc_announce_cached() does in
9006 # order to calculate max amount of grants to ask from server
9007 want_grant() {
9008         local tgt=$1
9009
9010         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9011         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9012
9013         ((rpc_in_flight++));
9014         nrpages=$((nrpages * rpc_in_flight))
9015
9016         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9017
9018         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9019
9020         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9021         local undirty=$((nrpages * PAGE_SIZE))
9022
9023         local max_extent_pages
9024         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9025         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9026         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9027         local grant_extent_tax
9028         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9029
9030         undirty=$((undirty + nrextents * grant_extent_tax))
9031
9032         echo $undirty
9033 }
9034
9035 # this is size of unit for grant allocation. It should be equal to
9036 # what tgt_grant.c:tgt_grant_chunk() calculates
9037 grant_chunk() {
9038         local tgt=$1
9039         local max_brw_size
9040         local grant_extent_tax
9041
9042         max_brw_size=$(import_param $tgt max_brw_size)
9043
9044         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9045
9046         echo $(((max_brw_size + grant_extent_tax) * 2))
9047 }
9048
9049 test_64d() {
9050         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9051                 skip "OST < 2.10.55 doesn't limit grants enough"
9052
9053         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9054
9055         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9056                 skip "no grant_param connect flag"
9057
9058         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9059
9060         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9061         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9062
9063
9064         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9065         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9066
9067         $LFS setstripe $DIR/$tfile -i 0 -c 1
9068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9069         ddpid=$!
9070
9071         while kill -0 $ddpid; do
9072                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9073
9074                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9075                         kill $ddpid
9076                         error "cur_grant $cur_grant > $max_cur_granted"
9077                 fi
9078
9079                 sleep 1
9080         done
9081 }
9082 run_test 64d "check grant limit exceed"
9083
9084 check_grants() {
9085         local tgt=$1
9086         local expected=$2
9087         local msg=$3
9088         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9089
9090         ((cur_grants == expected)) ||
9091                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9092 }
9093
9094 round_up_p2() {
9095         echo $((($1 + $2 - 1) & ~($2 - 1)))
9096 }
9097
9098 test_64e() {
9099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9100         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9101                 skip "Need OSS version at least 2.11.56"
9102
9103         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9104         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9105         $LCTL set_param debug=+cache
9106
9107         # Remount client to reset grant
9108         remount_client $MOUNT || error "failed to remount client"
9109         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9110
9111         local init_grants=$(import_param $osc_tgt initial_grant)
9112
9113         check_grants $osc_tgt $init_grants "init grants"
9114
9115         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9116         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9117         local gbs=$(import_param $osc_tgt grant_block_size)
9118
9119         # write random number of bytes from max_brw_size / 4 to max_brw_size
9120         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9121         # align for direct io
9122         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9123         # round to grant consumption unit
9124         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9125
9126         local grants=$((wb_round_up + extent_tax))
9127
9128         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9129
9130         # define OBD_FAIL_TGT_NO_GRANT 0x725
9131         # make the server not grant more back
9132         do_facet ost1 $LCTL set_param fail_loc=0x725
9133         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9134
9135         do_facet ost1 $LCTL set_param fail_loc=0
9136
9137         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9138
9139         rm -f $DIR/$tfile || error "rm failed"
9140
9141         # Remount client to reset grant
9142         remount_client $MOUNT || error "failed to remount client"
9143         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9144
9145         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9146
9147         # define OBD_FAIL_TGT_NO_GRANT 0x725
9148         # make the server not grant more back
9149         do_facet ost1 $LCTL set_param fail_loc=0x725
9150         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9151         do_facet ost1 $LCTL set_param fail_loc=0
9152
9153         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9154 }
9155 run_test 64e "check grant consumption (no grant allocation)"
9156
9157 test_64f() {
9158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9159
9160         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9161         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9162         $LCTL set_param debug=+cache
9163
9164         # Remount client to reset grant
9165         remount_client $MOUNT || error "failed to remount client"
9166         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9167
9168         local init_grants=$(import_param $osc_tgt initial_grant)
9169         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9170         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9171         local gbs=$(import_param $osc_tgt grant_block_size)
9172         local chunk=$(grant_chunk $osc_tgt)
9173
9174         # write random number of bytes from max_brw_size / 4 to max_brw_size
9175         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9176         # align for direct io
9177         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9178         # round to grant consumption unit
9179         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9180
9181         local grants=$((wb_round_up + extent_tax))
9182
9183         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9184         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9185                 error "error writing to $DIR/$tfile"
9186
9187         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9188                 "direct io with grant allocation"
9189
9190         rm -f $DIR/$tfile || error "rm failed"
9191
9192         # Remount client to reset grant
9193         remount_client $MOUNT || error "failed to remount client"
9194         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9195
9196         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9197
9198         local cmd="oO_WRONLY:w${write_bytes}_yc"
9199
9200         $MULTIOP $DIR/$tfile $cmd &
9201         MULTIPID=$!
9202         sleep 1
9203
9204         check_grants $osc_tgt $((init_grants - grants)) \
9205                 "buffered io, not write rpc"
9206
9207         kill -USR1 $MULTIPID
9208         wait
9209
9210         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9211                 "buffered io, one RPC"
9212 }
9213 run_test 64f "check grant consumption (with grant allocation)"
9214
9215 test_64g() {
9216         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9217                 skip "Need MDS version at least 2.14.56"
9218
9219         local mdts=$(comma_list $(mdts_nodes))
9220
9221         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9222                         tr '\n' ' ')
9223         stack_trap "$LCTL set_param $old"
9224
9225         # generate dirty pages and increase dirty granted on MDT
9226         stack_trap "rm -f $DIR/$tfile-*"
9227         for (( i = 0; i < 10; i++)); do
9228                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9229                         error "can't set stripe"
9230                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9231                         error "can't dd"
9232                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9233                         $LFS getstripe $DIR/$tfile-$i
9234                         error "not DoM file"
9235                 }
9236         done
9237
9238         # flush dirty pages
9239         sync
9240
9241         # wait until grant shrink reset grant dirty on MDTs
9242         for ((i = 0; i < 120; i++)); do
9243                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9244                         awk '{sum=sum+$1} END {print sum}')
9245                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9246                 echo "$grant_dirty grants, $vm_dirty pages"
9247                 (( grant_dirty + vm_dirty == 0 )) && break
9248                 (( i == 3 )) && sync &&
9249                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9250                 sleep 1
9251         done
9252
9253         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9254                 awk '{sum=sum+$1} END {print sum}')
9255         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9256 }
9257 run_test 64g "grant shrink on MDT"
9258
9259 test_64h() {
9260         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9261                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9262
9263         local instance=$($LFS getname -i $DIR)
9264         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9265         local num_exps=$(do_facet ost1 \
9266             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9267         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9268         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9269         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9270
9271         # 10MiB is for file to be written, max_brw_size * 16 *
9272         # num_exps is space reserve so that tgt_grant_shrink() decided
9273         # to not shrink
9274         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9275         (( avail * 1024 < expect )) &&
9276                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9277
9278         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9279         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9280         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9281         $LCTL set_param osc.*OST0000*.grant_shrink=1
9282         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9283
9284         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9285         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9286
9287         # drop cache so that coming read would do rpc
9288         cancel_lru_locks osc
9289
9290         # shrink interval is set to 10, pause for 7 seconds so that
9291         # grant thread did not wake up yet but coming read entered
9292         # shrink mode for rpc (osc_should_shrink_grant())
9293         sleep 7
9294
9295         declare -a cur_grant_bytes
9296         declare -a tot_granted
9297         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9298         tot_granted[0]=$(do_facet ost1 \
9299             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9300
9301         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9302
9303         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9304         tot_granted[1]=$(do_facet ost1 \
9305             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9306
9307         # grant change should be equal on both sides
9308         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9309                 tot_granted[0] - tot_granted[1])) ||
9310                 error "grant change mismatch, "                                \
9311                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9312                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9313 }
9314 run_test 64h "grant shrink on read"
9315
9316 test_64i() {
9317         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9318                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9319
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321         remote_ost_nodsh && skip "remote OSTs with nodsh"
9322
9323         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9324
9325         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9326
9327         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9328         local instance=$($LFS getname -i $DIR)
9329
9330         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9331         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9332
9333         # shrink grants and simulate rpc loss
9334         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9335         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9336         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9337
9338         fail ost1
9339
9340         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9341
9342         local testid=$(echo $TESTNAME | tr '_' ' ')
9343
9344         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9345                 grep "GRANT, real grant" &&
9346                 error "client has more grants then it owns" || true
9347 }
9348 run_test 64i "shrink on reconnect"
9349
9350 # bug 1414 - set/get directories' stripe info
9351 test_65a() {
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         test_mkdir $DIR/$tdir
9355         touch $DIR/$tdir/f1
9356         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9357 }
9358 run_test 65a "directory with no stripe info"
9359
9360 test_65b() {
9361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9362
9363         test_mkdir $DIR/$tdir
9364         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9365
9366         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9367                                                 error "setstripe"
9368         touch $DIR/$tdir/f2
9369         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9370 }
9371 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9372
9373 test_65c() {
9374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9375         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9376
9377         test_mkdir $DIR/$tdir
9378         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9379
9380         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9381                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9382         touch $DIR/$tdir/f3
9383         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9384 }
9385 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9386
9387 test_65d() {
9388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9389
9390         test_mkdir $DIR/$tdir
9391         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9392         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9393
9394         if [[ $STRIPECOUNT -le 0 ]]; then
9395                 sc=1
9396         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9397                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9398                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9399         else
9400                 sc=$(($STRIPECOUNT - 1))
9401         fi
9402         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9403         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9404         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9405                 error "lverify failed"
9406 }
9407 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9408
9409 test_65e() {
9410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9411
9412         test_mkdir $DIR/$tdir
9413
9414         $LFS setstripe $DIR/$tdir || error "setstripe"
9415         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9416                                         error "no stripe info failed"
9417         touch $DIR/$tdir/f6
9418         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9419 }
9420 run_test 65e "directory setstripe defaults"
9421
9422 test_65f() {
9423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9424
9425         test_mkdir $DIR/${tdir}f
9426         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9427                 error "setstripe succeeded" || true
9428 }
9429 run_test 65f "dir setstripe permission (should return error) ==="
9430
9431 test_65g() {
9432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9433
9434         test_mkdir $DIR/$tdir
9435         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9436
9437         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9438                 error "setstripe -S failed"
9439         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9440         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9441                 error "delete default stripe failed"
9442 }
9443 run_test 65g "directory setstripe -d"
9444
9445 test_65h() {
9446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9447
9448         test_mkdir $DIR/$tdir
9449         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9450
9451         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9452                 error "setstripe -S failed"
9453         test_mkdir $DIR/$tdir/dd1
9454         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9455                 error "stripe info inherit failed"
9456 }
9457 run_test 65h "directory stripe info inherit ===================="
9458
9459 test_65i() {
9460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9461
9462         save_layout_restore_at_exit $MOUNT
9463
9464         # bug6367: set non-default striping on root directory
9465         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9466
9467         # bug12836: getstripe on -1 default directory striping
9468         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9469
9470         # bug12836: getstripe -v on -1 default directory striping
9471         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9472
9473         # bug12836: new find on -1 default directory striping
9474         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9475 }
9476 run_test 65i "various tests to set root directory striping"
9477
9478 test_65j() { # bug6367
9479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9480
9481         sync; sleep 1
9482
9483         # if we aren't already remounting for each test, do so for this test
9484         if [ "$I_MOUNTED" = "yes" ]; then
9485                 cleanup || error "failed to unmount"
9486                 setup
9487         fi
9488
9489         save_layout_restore_at_exit $MOUNT
9490
9491         $LFS setstripe -d $MOUNT || error "setstripe failed"
9492 }
9493 run_test 65j "set default striping on root directory (bug 6367)="
9494
9495 cleanup_65k() {
9496         rm -rf $DIR/$tdir
9497         wait_delete_completed
9498         do_facet $SINGLEMDS "lctl set_param -n \
9499                 osp.$ost*MDT0000.max_create_count=$max_count"
9500         do_facet $SINGLEMDS "lctl set_param -n \
9501                 osp.$ost*MDT0000.create_count=$count"
9502         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9503         echo $INACTIVE_OSC "is Activate"
9504
9505         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9506 }
9507
9508 test_65k() { # bug11679
9509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9510         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9511         remote_mds_nodsh && skip "remote MDS with nodsh"
9512
9513         local disable_precreate=true
9514         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9515                 disable_precreate=false
9516
9517         echo "Check OST status: "
9518         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9519                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9520
9521         for OSC in $MDS_OSCS; do
9522                 echo $OSC "is active"
9523                 do_facet $SINGLEMDS lctl --device %$OSC activate
9524         done
9525
9526         for INACTIVE_OSC in $MDS_OSCS; do
9527                 local ost=$(osc_to_ost $INACTIVE_OSC)
9528                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9529                                lov.*md*.target_obd |
9530                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9531
9532                 mkdir -p $DIR/$tdir
9533                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9534                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9535
9536                 echo "Deactivate: " $INACTIVE_OSC
9537                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9538
9539                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9540                               osp.$ost*MDT0000.create_count")
9541                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9542                                   osp.$ost*MDT0000.max_create_count")
9543                 $disable_precreate &&
9544                         do_facet $SINGLEMDS "lctl set_param -n \
9545                                 osp.$ost*MDT0000.max_create_count=0"
9546
9547                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9548                         [ -f $DIR/$tdir/$idx ] && continue
9549                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9550                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9551                                 { cleanup_65k;
9552                                   error "setstripe $idx should succeed"; }
9553                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9554                 done
9555                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9556                 rmdir $DIR/$tdir
9557
9558                 do_facet $SINGLEMDS "lctl set_param -n \
9559                         osp.$ost*MDT0000.max_create_count=$max_count"
9560                 do_facet $SINGLEMDS "lctl set_param -n \
9561                         osp.$ost*MDT0000.create_count=$count"
9562                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9563                 echo $INACTIVE_OSC "is Activate"
9564
9565                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9566         done
9567 }
9568 run_test 65k "validate manual striping works properly with deactivated OSCs"
9569
9570 test_65l() { # bug 12836
9571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9572
9573         test_mkdir -p $DIR/$tdir/test_dir
9574         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9575         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9576 }
9577 run_test 65l "lfs find on -1 stripe dir ========================"
9578
9579 test_65m() {
9580         local layout=$(save_layout $MOUNT)
9581         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9582                 restore_layout $MOUNT $layout
9583                 error "setstripe should fail by non-root users"
9584         }
9585         true
9586 }
9587 run_test 65m "normal user can't set filesystem default stripe"
9588
9589 test_65n() {
9590         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9591         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9592                 skip "Need MDS version at least 2.12.50"
9593         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9594
9595         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9596         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9597         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9598
9599         save_layout_restore_at_exit $MOUNT
9600
9601         # new subdirectory under root directory should not inherit
9602         # the default layout from root
9603         local dir1=$MOUNT/$tdir-1
9604         mkdir $dir1 || error "mkdir $dir1 failed"
9605         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9606                 error "$dir1 shouldn't have LOV EA"
9607
9608         # delete the default layout on root directory
9609         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9610
9611         local dir2=$MOUNT/$tdir-2
9612         mkdir $dir2 || error "mkdir $dir2 failed"
9613         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9614                 error "$dir2 shouldn't have LOV EA"
9615
9616         # set a new striping pattern on root directory
9617         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9618         local new_def_stripe_size=$((def_stripe_size * 2))
9619         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9620                 error "set stripe size on $MOUNT failed"
9621
9622         # new file created in $dir2 should inherit the new stripe size from
9623         # the filesystem default
9624         local file2=$dir2/$tfile-2
9625         touch $file2 || error "touch $file2 failed"
9626
9627         local file2_stripe_size=$($LFS getstripe -S $file2)
9628         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9629         {
9630                 echo "file2_stripe_size: '$file2_stripe_size'"
9631                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9632                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9633         }
9634
9635         local dir3=$MOUNT/$tdir-3
9636         mkdir $dir3 || error "mkdir $dir3 failed"
9637         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9638         # the root layout, which is the actual default layout that will be used
9639         # when new files are created in $dir3.
9640         local dir3_layout=$(get_layout_param $dir3)
9641         local root_dir_layout=$(get_layout_param $MOUNT)
9642         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9643         {
9644                 echo "dir3_layout: '$dir3_layout'"
9645                 echo "root_dir_layout: '$root_dir_layout'"
9646                 error "$dir3 should show the default layout from $MOUNT"
9647         }
9648
9649         # set OST pool on root directory
9650         local pool=$TESTNAME
9651         pool_add $pool || error "add $pool failed"
9652         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9653                 error "add targets to $pool failed"
9654
9655         $LFS setstripe -p $pool $MOUNT ||
9656                 error "set OST pool on $MOUNT failed"
9657
9658         # new file created in $dir3 should inherit the pool from
9659         # the filesystem default
9660         local file3=$dir3/$tfile-3
9661         touch $file3 || error "touch $file3 failed"
9662
9663         local file3_pool=$($LFS getstripe -p $file3)
9664         [[ "$file3_pool" = "$pool" ]] ||
9665                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9666
9667         local dir4=$MOUNT/$tdir-4
9668         mkdir $dir4 || error "mkdir $dir4 failed"
9669         local dir4_layout=$(get_layout_param $dir4)
9670         root_dir_layout=$(get_layout_param $MOUNT)
9671         echo "$LFS getstripe -d $dir4"
9672         $LFS getstripe -d $dir4
9673         echo "$LFS getstripe -d $MOUNT"
9674         $LFS getstripe -d $MOUNT
9675         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9676         {
9677                 echo "dir4_layout: '$dir4_layout'"
9678                 echo "root_dir_layout: '$root_dir_layout'"
9679                 error "$dir4 should show the default layout from $MOUNT"
9680         }
9681
9682         # new file created in $dir4 should inherit the pool from
9683         # the filesystem default
9684         local file4=$dir4/$tfile-4
9685         touch $file4 || error "touch $file4 failed"
9686
9687         local file4_pool=$($LFS getstripe -p $file4)
9688         [[ "$file4_pool" = "$pool" ]] ||
9689                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9690
9691         # new subdirectory under non-root directory should inherit
9692         # the default layout from its parent directory
9693         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9694                 error "set directory layout on $dir4 failed"
9695
9696         local dir5=$dir4/$tdir-5
9697         mkdir $dir5 || error "mkdir $dir5 failed"
9698
9699         dir4_layout=$(get_layout_param $dir4)
9700         local dir5_layout=$(get_layout_param $dir5)
9701         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9702         {
9703                 echo "dir4_layout: '$dir4_layout'"
9704                 echo "dir5_layout: '$dir5_layout'"
9705                 error "$dir5 should inherit the default layout from $dir4"
9706         }
9707
9708         # though subdir under ROOT doesn't inherit default layout, but
9709         # its sub dir/file should be created with default layout.
9710         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9711         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9712                 skip "Need MDS version at least 2.12.59"
9713
9714         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9715         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9716         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9717
9718         if [ $default_lmv_hash == "none" ]; then
9719                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9720         else
9721                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9722                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9723         fi
9724
9725         $LFS setdirstripe -D -c 2 $MOUNT ||
9726                 error "setdirstripe -D -c 2 failed"
9727         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9728         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9729         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9730
9731         # $dir4 layout includes pool
9732         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9733         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9734                 error "pool lost on setstripe"
9735         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9736         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9737                 error "pool lost on compound layout setstripe"
9738 }
9739 run_test 65n "don't inherit default layout from root for new subdirectories"
9740
9741 test_65o() {
9742         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9743                 skip "need MDS version at least 2.14.57"
9744
9745         # set OST pool on root directory
9746         local pool=$TESTNAME
9747
9748         pool_add $pool || error "add $pool failed"
9749         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9750                 error "add targets to $pool failed"
9751
9752         local dir1=$MOUNT/$tdir
9753
9754         mkdir $dir1 || error "mkdir $dir1 failed"
9755
9756         # set a new striping pattern on root directory
9757         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9758
9759         $LFS setstripe -p $pool $dir1 ||
9760                 error "set directory layout on $dir1 failed"
9761
9762         # $dir1 layout includes pool
9763         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9764         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9765                 error "pool lost on setstripe"
9766         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9767         $LFS getstripe $dir1
9768         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9769                 error "pool lost on compound layout setstripe"
9770
9771         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9772                 error "setdirstripe failed on sub-dir with inherited pool"
9773         $LFS getstripe $dir1/dir2
9774         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9775                 error "pool lost on compound layout setdirstripe"
9776
9777         $LFS setstripe -E -1 -c 1 $dir1
9778         $LFS getstripe -d $dir1
9779         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9780                 error "pool lost on setstripe"
9781 }
9782 run_test 65o "pool inheritance for mdt component"
9783
9784 test_65p () { # LU-16152
9785         local src_dir=$DIR/$tdir/src_dir
9786         local dst_dir=$DIR/$tdir/dst_dir
9787         local yaml_file=$DIR/$tdir/layout.yaml
9788         local border
9789
9790         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9791                 skip "Need at least version 2.15.51"
9792
9793         test_mkdir -p $src_dir
9794         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9795                 error "failed to setstripe"
9796         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9797                 error "failed to getstripe"
9798
9799         test_mkdir -p $dst_dir
9800         $LFS setstripe --yaml $yaml_file $dst_dir ||
9801                 error "failed to setstripe with yaml file"
9802         border=$($LFS getstripe -d $dst_dir |
9803                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9804                 error "failed to getstripe"
9805
9806         # 2048M is 0x80000000, or 2147483648
9807         (( $border == 2147483648 )) ||
9808                 error "failed to handle huge number in yaml layout"
9809 }
9810 run_test 65p "setstripe with yaml file and huge number"
9811
9812 # bug 2543 - update blocks count on client
9813 test_66() {
9814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9815
9816         local COUNT=${COUNT:-8}
9817         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9818         sync; sync_all_data; sync; sync_all_data
9819         cancel_lru_locks osc
9820         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9821         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9822 }
9823 run_test 66 "update inode blocks count on client ==============="
9824
9825 meminfo() {
9826         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9827 }
9828
9829 swap_used() {
9830         swapon -s | awk '($1 == "'$1'") { print $4 }'
9831 }
9832
9833 # bug5265, obdfilter oa2dentry return -ENOENT
9834 # #define OBD_FAIL_SRV_ENOENT 0x217
9835 test_69() {
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837         remote_ost_nodsh && skip "remote OST with nodsh"
9838
9839         f="$DIR/$tfile"
9840         $LFS setstripe -c 1 -i 0 $f
9841
9842         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9843
9844         do_facet ost1 lctl set_param fail_loc=0x217
9845         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9846         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9847
9848         do_facet ost1 lctl set_param fail_loc=0
9849         $DIRECTIO write $f 0 2 || error "write error"
9850
9851         cancel_lru_locks osc
9852         $DIRECTIO read $f 0 1 || error "read error"
9853
9854         do_facet ost1 lctl set_param fail_loc=0x217
9855         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9856
9857         do_facet ost1 lctl set_param fail_loc=0
9858         rm -f $f
9859 }
9860 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9861
9862 test_71() {
9863         test_mkdir $DIR/$tdir
9864         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9865         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9866 }
9867 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9868
9869 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9871         [ "$RUNAS_ID" = "$UID" ] &&
9872                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9873         # Check that testing environment is properly set up. Skip if not
9874         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9875                 skip_env "User $RUNAS_ID does not exist - skipping"
9876
9877         touch $DIR/$tfile
9878         chmod 777 $DIR/$tfile
9879         chmod ug+s $DIR/$tfile
9880         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9881                 error "$RUNAS dd $DIR/$tfile failed"
9882         # See if we are still setuid/sgid
9883         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9884                 error "S/gid is not dropped on write"
9885         # Now test that MDS is updated too
9886         cancel_lru_locks mdc
9887         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9888                 error "S/gid is not dropped on MDS"
9889         rm -f $DIR/$tfile
9890 }
9891 run_test 72a "Test that remove suid works properly (bug5695) ===="
9892
9893 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9894         local perm
9895
9896         [ "$RUNAS_ID" = "$UID" ] &&
9897                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9898         [ "$RUNAS_ID" -eq 0 ] &&
9899                 skip_env "RUNAS_ID = 0 -- skipping"
9900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9901         # Check that testing environment is properly set up. Skip if not
9902         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9903                 skip_env "User $RUNAS_ID does not exist - skipping"
9904
9905         touch $DIR/${tfile}-f{g,u}
9906         test_mkdir $DIR/${tfile}-dg
9907         test_mkdir $DIR/${tfile}-du
9908         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9909         chmod g+s $DIR/${tfile}-{f,d}g
9910         chmod u+s $DIR/${tfile}-{f,d}u
9911         for perm in 777 2777 4777; do
9912                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9913                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9914                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9915                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9916         done
9917         true
9918 }
9919 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9920
9921 # bug 3462 - multiple simultaneous MDC requests
9922 test_73() {
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924
9925         test_mkdir $DIR/d73-1
9926         test_mkdir $DIR/d73-2
9927         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9928         pid1=$!
9929
9930         lctl set_param fail_loc=0x80000129
9931         $MULTIOP $DIR/d73-1/f73-2 Oc &
9932         sleep 1
9933         lctl set_param fail_loc=0
9934
9935         $MULTIOP $DIR/d73-2/f73-3 Oc &
9936         pid3=$!
9937
9938         kill -USR1 $pid1
9939         wait $pid1 || return 1
9940
9941         sleep 25
9942
9943         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9944         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9945         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9946
9947         rm -rf $DIR/d73-*
9948 }
9949 run_test 73 "multiple MDC requests (should not deadlock)"
9950
9951 test_74a() { # bug 6149, 6184
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953
9954         touch $DIR/f74a
9955         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9956         #
9957         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9958         # will spin in a tight reconnection loop
9959         $LCTL set_param fail_loc=0x8000030e
9960         # get any lock that won't be difficult - lookup works.
9961         ls $DIR/f74a
9962         $LCTL set_param fail_loc=0
9963         rm -f $DIR/f74a
9964         true
9965 }
9966 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9967
9968 test_74b() { # bug 13310
9969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9970
9971         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9972         #
9973         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9974         # will spin in a tight reconnection loop
9975         $LCTL set_param fail_loc=0x8000030e
9976         # get a "difficult" lock
9977         touch $DIR/f74b
9978         $LCTL set_param fail_loc=0
9979         rm -f $DIR/f74b
9980         true
9981 }
9982 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9983
9984 test_74c() {
9985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9986
9987         #define OBD_FAIL_LDLM_NEW_LOCK
9988         $LCTL set_param fail_loc=0x319
9989         touch $DIR/$tfile && error "touch successful"
9990         $LCTL set_param fail_loc=0
9991         true
9992 }
9993 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9994
9995 slab_lic=/sys/kernel/slab/lustre_inode_cache
9996 num_objects() {
9997         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9998         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9999                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10000 }
10001
10002 test_76a() { # Now for b=20433, added originally in b=1443
10003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10004
10005         cancel_lru_locks osc
10006         # there may be some slab objects cached per core
10007         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10008         local before=$(num_objects)
10009         local count=$((512 * cpus))
10010         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10011         local margin=$((count / 10))
10012         if [[ -f $slab_lic/aliases ]]; then
10013                 local aliases=$(cat $slab_lic/aliases)
10014                 (( aliases > 0 )) && margin=$((margin * aliases))
10015         fi
10016
10017         echo "before slab objects: $before"
10018         for i in $(seq $count); do
10019                 touch $DIR/$tfile
10020                 rm -f $DIR/$tfile
10021         done
10022         cancel_lru_locks osc
10023         local after=$(num_objects)
10024         echo "created: $count, after slab objects: $after"
10025         # shared slab counts are not very accurate, allow significant margin
10026         # the main goal is that the cache growth is not permanently > $count
10027         while (( after > before + margin )); do
10028                 sleep 1
10029                 after=$(num_objects)
10030                 wait=$((wait + 1))
10031                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10032                 if (( wait > 60 )); then
10033                         error "inode slab grew from $before+$margin to $after"
10034                 fi
10035         done
10036 }
10037 run_test 76a "confirm clients recycle inodes properly ===="
10038
10039 test_76b() {
10040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10041         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10042
10043         local count=512
10044         local before=$(num_objects)
10045
10046         for i in $(seq $count); do
10047                 mkdir $DIR/$tdir
10048                 rmdir $DIR/$tdir
10049         done
10050
10051         local after=$(num_objects)
10052         local wait=0
10053
10054         while (( after > before )); do
10055                 sleep 1
10056                 after=$(num_objects)
10057                 wait=$((wait + 1))
10058                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10059                 if (( wait > 60 )); then
10060                         error "inode slab grew from $before to $after"
10061                 fi
10062         done
10063
10064         echo "slab objects before: $before, after: $after"
10065 }
10066 run_test 76b "confirm clients recycle directory inodes properly ===="
10067
10068 export ORIG_CSUM=""
10069 set_checksums()
10070 {
10071         # Note: in sptlrpc modes which enable its own bulk checksum, the
10072         # original crc32_le bulk checksum will be automatically disabled,
10073         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10074         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10075         # In this case set_checksums() will not be no-op, because sptlrpc
10076         # bulk checksum will be enabled all through the test.
10077
10078         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10079         lctl set_param -n osc.*.checksums $1
10080         return 0
10081 }
10082
10083 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10084                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10085 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10086                              tr -d [] | head -n1)}
10087 set_checksum_type()
10088 {
10089         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10090         rc=$?
10091         log "set checksum type to $1, rc = $rc"
10092         return $rc
10093 }
10094
10095 get_osc_checksum_type()
10096 {
10097         # arugment 1: OST name, like OST0000
10098         ost=$1
10099         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10100                         sed 's/.*\[\(.*\)\].*/\1/g')
10101         rc=$?
10102         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10103         echo $checksum_type
10104 }
10105
10106 F77_TMP=$TMP/f77-temp
10107 F77SZ=8
10108 setup_f77() {
10109         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10110                 error "error writing to $F77_TMP"
10111 }
10112
10113 test_77a() { # bug 10889
10114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10115         $GSS && skip_env "could not run with gss"
10116
10117         [ ! -f $F77_TMP ] && setup_f77
10118         set_checksums 1
10119         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10120         set_checksums 0
10121         rm -f $DIR/$tfile
10122 }
10123 run_test 77a "normal checksum read/write operation"
10124
10125 test_77b() { # bug 10889
10126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10127         $GSS && skip_env "could not run with gss"
10128
10129         [ ! -f $F77_TMP ] && setup_f77
10130         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10131         $LCTL set_param fail_loc=0x80000409
10132         set_checksums 1
10133
10134         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10135                 error "dd error: $?"
10136         $LCTL set_param fail_loc=0
10137
10138         for algo in $CKSUM_TYPES; do
10139                 cancel_lru_locks osc
10140                 set_checksum_type $algo
10141                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10142                 $LCTL set_param fail_loc=0x80000408
10143                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10144                 $LCTL set_param fail_loc=0
10145         done
10146         set_checksums 0
10147         set_checksum_type $ORIG_CSUM_TYPE
10148         rm -f $DIR/$tfile
10149 }
10150 run_test 77b "checksum error on client write, read"
10151
10152 cleanup_77c() {
10153         trap 0
10154         set_checksums 0
10155         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10156         $check_ost &&
10157                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10158         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10159         $check_ost && [ -n "$ost_file_prefix" ] &&
10160                 do_facet ost1 rm -f ${ost_file_prefix}\*
10161 }
10162
10163 test_77c() {
10164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10165         $GSS && skip_env "could not run with gss"
10166         remote_ost_nodsh && skip "remote OST with nodsh"
10167
10168         local bad1
10169         local osc_file_prefix
10170         local osc_file
10171         local check_ost=false
10172         local ost_file_prefix
10173         local ost_file
10174         local orig_cksum
10175         local dump_cksum
10176         local fid
10177
10178         # ensure corruption will occur on first OSS/OST
10179         $LFS setstripe -i 0 $DIR/$tfile
10180
10181         [ ! -f $F77_TMP ] && setup_f77
10182         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10183                 error "dd write error: $?"
10184         fid=$($LFS path2fid $DIR/$tfile)
10185
10186         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10187         then
10188                 check_ost=true
10189                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10190                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10191         else
10192                 echo "OSS do not support bulk pages dump upon error"
10193         fi
10194
10195         osc_file_prefix=$($LCTL get_param -n debug_path)
10196         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10197
10198         trap cleanup_77c EXIT
10199
10200         set_checksums 1
10201         # enable bulk pages dump upon error on Client
10202         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10203         # enable bulk pages dump upon error on OSS
10204         $check_ost &&
10205                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10206
10207         # flush Client cache to allow next read to reach OSS
10208         cancel_lru_locks osc
10209
10210         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10211         $LCTL set_param fail_loc=0x80000408
10212         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10213         $LCTL set_param fail_loc=0
10214
10215         rm -f $DIR/$tfile
10216
10217         # check cksum dump on Client
10218         osc_file=$(ls ${osc_file_prefix}*)
10219         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10220         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10221         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10222         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10223         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10224                      cksum)
10225         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10226         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10227                 error "dump content does not match on Client"
10228
10229         $check_ost || skip "No need to check cksum dump on OSS"
10230
10231         # check cksum dump on OSS
10232         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10233         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10234         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10235         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10236         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10237                 error "dump content does not match on OSS"
10238
10239         cleanup_77c
10240 }
10241 run_test 77c "checksum error on client read with debug"
10242
10243 test_77d() { # bug 10889
10244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10245         $GSS && skip_env "could not run with gss"
10246
10247         stack_trap "rm -f $DIR/$tfile"
10248         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10249         $LCTL set_param fail_loc=0x80000409
10250         set_checksums 1
10251         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10252                 error "direct write: rc=$?"
10253         $LCTL set_param fail_loc=0
10254         set_checksums 0
10255
10256         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10257         $LCTL set_param fail_loc=0x80000408
10258         set_checksums 1
10259         cancel_lru_locks osc
10260         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10261                 error "direct read: rc=$?"
10262         $LCTL set_param fail_loc=0
10263         set_checksums 0
10264 }
10265 run_test 77d "checksum error on OST direct write, read"
10266
10267 test_77f() { # bug 10889
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         $GSS && skip_env "could not run with gss"
10270
10271         set_checksums 1
10272         stack_trap "rm -f $DIR/$tfile"
10273         for algo in $CKSUM_TYPES; do
10274                 cancel_lru_locks osc
10275                 set_checksum_type $algo
10276                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10277                 $LCTL set_param fail_loc=0x409
10278                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10279                         error "direct write succeeded"
10280                 $LCTL set_param fail_loc=0
10281         done
10282         set_checksum_type $ORIG_CSUM_TYPE
10283         set_checksums 0
10284 }
10285 run_test 77f "repeat checksum error on write (expect error)"
10286
10287 test_77g() { # bug 10889
10288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10289         $GSS && skip_env "could not run with gss"
10290         remote_ost_nodsh && skip "remote OST with nodsh"
10291
10292         [ ! -f $F77_TMP ] && setup_f77
10293
10294         local file=$DIR/$tfile
10295         stack_trap "rm -f $file" EXIT
10296
10297         $LFS setstripe -c 1 -i 0 $file
10298         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10299         do_facet ost1 lctl set_param fail_loc=0x8000021a
10300         set_checksums 1
10301         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10302                 error "write error: rc=$?"
10303         do_facet ost1 lctl set_param fail_loc=0
10304         set_checksums 0
10305
10306         cancel_lru_locks osc
10307         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10308         do_facet ost1 lctl set_param fail_loc=0x8000021b
10309         set_checksums 1
10310         cmp $F77_TMP $file || error "file compare failed"
10311         do_facet ost1 lctl set_param fail_loc=0
10312         set_checksums 0
10313 }
10314 run_test 77g "checksum error on OST write, read"
10315
10316 test_77k() { # LU-10906
10317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10318         $GSS && skip_env "could not run with gss"
10319
10320         local cksum_param="osc.$FSNAME*.checksums"
10321         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10322         local checksum
10323         local i
10324
10325         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10326         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10327         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10328
10329         for i in 0 1; do
10330                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10331                         error "failed to set checksum=$i on MGS"
10332                 wait_update $HOSTNAME "$get_checksum" $i
10333                 #remount
10334                 echo "remount client, checksum should be $i"
10335                 remount_client $MOUNT || error "failed to remount client"
10336                 checksum=$(eval $get_checksum)
10337                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10338         done
10339         # remove persistent param to avoid races with checksum mountopt below
10340         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10341                 error "failed to delete checksum on MGS"
10342
10343         for opt in "checksum" "nochecksum"; do
10344                 #remount with mount option
10345                 echo "remount client with option $opt, checksum should be $i"
10346                 umount_client $MOUNT || error "failed to umount client"
10347                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10348                         error "failed to mount client with option '$opt'"
10349                 checksum=$(eval $get_checksum)
10350                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10351                 i=$((i - 1))
10352         done
10353
10354         remount_client $MOUNT || error "failed to remount client"
10355 }
10356 run_test 77k "enable/disable checksum correctly"
10357
10358 test_77l() {
10359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10360         $GSS && skip_env "could not run with gss"
10361
10362         set_checksums 1
10363         stack_trap "set_checksums $ORIG_CSUM" EXIT
10364         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10365
10366         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10367
10368         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10369         for algo in $CKSUM_TYPES; do
10370                 set_checksum_type $algo || error "fail to set checksum type $algo"
10371                 osc_algo=$(get_osc_checksum_type OST0000)
10372                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10373
10374                 # no locks, no reqs to let the connection idle
10375                 cancel_lru_locks osc
10376                 lru_resize_disable osc
10377                 wait_osc_import_state client ost1 IDLE
10378
10379                 # ensure ost1 is connected
10380                 stat $DIR/$tfile >/dev/null || error "can't stat"
10381                 wait_osc_import_state client ost1 FULL
10382
10383                 osc_algo=$(get_osc_checksum_type OST0000)
10384                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10385         done
10386         return 0
10387 }
10388 run_test 77l "preferred checksum type is remembered after reconnected"
10389
10390 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10391 rm -f $F77_TMP
10392 unset F77_TMP
10393
10394 test_77m() {
10395         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10396                 skip "Need at least version 2.14.52"
10397         local param=checksum_speed
10398
10399         $LCTL get_param $param || error "reading $param failed"
10400
10401         csum_speeds=$($LCTL get_param -n $param)
10402
10403         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10404                 error "known checksum types are missing"
10405 }
10406 run_test 77m "Verify checksum_speed is correctly read"
10407
10408 check_filefrag_77n() {
10409         local nr_ext=0
10410         local starts=()
10411         local ends=()
10412
10413         while read extidx a b start end rest; do
10414                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10415                         nr_ext=$(( $nr_ext + 1 ))
10416                         starts+=( ${start%..} )
10417                         ends+=( ${end%:} )
10418                 fi
10419         done < <( filefrag -sv $1 )
10420
10421         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10422         return 1
10423 }
10424
10425 test_77n() {
10426         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10427
10428         touch $DIR/$tfile
10429         $TRUNCATE $DIR/$tfile 0
10430         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10431         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10432         check_filefrag_77n $DIR/$tfile ||
10433                 skip "$tfile blocks not contiguous around hole"
10434
10435         set_checksums 1
10436         stack_trap "set_checksums $ORIG_CSUM" EXIT
10437         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10438         stack_trap "rm -f $DIR/$tfile"
10439
10440         for algo in $CKSUM_TYPES; do
10441                 if [[ "$algo" =~ ^t10 ]]; then
10442                         set_checksum_type $algo ||
10443                                 error "fail to set checksum type $algo"
10444                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10445                                 error "fail to read $tfile with $algo"
10446                 fi
10447         done
10448         rm -f $DIR/$tfile
10449         return 0
10450 }
10451 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10452
10453 test_77o() {
10454         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10455                 skip "Need MDS version at least 2.14.55"
10456         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10457                 skip "Need OST version at least 2.14.55"
10458         local ofd=obdfilter
10459         local mdt=mdt
10460
10461         # print OST checksum_type
10462         echo "$ofd.$FSNAME-*.checksum_type:"
10463         do_nodes $(comma_list $(osts_nodes)) \
10464                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10465
10466         # print MDT checksum_type
10467         echo "$mdt.$FSNAME-*.checksum_type:"
10468         do_nodes $(comma_list $(mdts_nodes)) \
10469                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10470
10471         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10472                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10473
10474         (( $o_count == $OSTCOUNT )) ||
10475                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10476
10477         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10478                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10479
10480         (( $m_count == $MDSCOUNT )) ||
10481                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10482 }
10483 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10484
10485 cleanup_test_78() {
10486         trap 0
10487         rm -f $DIR/$tfile
10488 }
10489
10490 test_78() { # bug 10901
10491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10492         remote_ost || skip_env "local OST"
10493
10494         NSEQ=5
10495         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10496         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10497         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10498         echo "MemTotal: $MEMTOTAL"
10499
10500         # reserve 256MB of memory for the kernel and other running processes,
10501         # and then take 1/2 of the remaining memory for the read/write buffers.
10502         if [ $MEMTOTAL -gt 512 ] ;then
10503                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10504         else
10505                 # for those poor memory-starved high-end clusters...
10506                 MEMTOTAL=$((MEMTOTAL / 2))
10507         fi
10508         echo "Mem to use for directio: $MEMTOTAL"
10509
10510         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10511         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10512         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10513         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10514                 head -n1)
10515         echo "Smallest OST: $SMALLESTOST"
10516         [[ $SMALLESTOST -lt 10240 ]] &&
10517                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10518
10519         trap cleanup_test_78 EXIT
10520
10521         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10522                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10523
10524         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10525         echo "File size: $F78SIZE"
10526         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10527         for i in $(seq 1 $NSEQ); do
10528                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10529                 echo directIO rdwr round $i of $NSEQ
10530                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10531         done
10532
10533         cleanup_test_78
10534 }
10535 run_test 78 "handle large O_DIRECT writes correctly ============"
10536
10537 test_79() { # bug 12743
10538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10539
10540         wait_delete_completed
10541
10542         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10543         BKFREE=$(calc_osc_kbytes kbytesfree)
10544         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10545
10546         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10547         DFTOTAL=`echo $STRING | cut -d, -f1`
10548         DFUSED=`echo $STRING  | cut -d, -f2`
10549         DFAVAIL=`echo $STRING | cut -d, -f3`
10550         DFFREE=$(($DFTOTAL - $DFUSED))
10551
10552         ALLOWANCE=$((64 * $OSTCOUNT))
10553
10554         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10555            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10556                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10557         fi
10558         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10559            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10560                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10561         fi
10562         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10563            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10564                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10565         fi
10566 }
10567 run_test 79 "df report consistency check ======================="
10568
10569 test_80() { # bug 10718
10570         remote_ost_nodsh && skip "remote OST with nodsh"
10571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10572
10573         # relax strong synchronous semantics for slow backends like ZFS
10574         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10575                 local soc="obdfilter.*.sync_lock_cancel"
10576                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10577
10578                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10579                 if [ -z "$save" ]; then
10580                         soc="obdfilter.*.sync_on_lock_cancel"
10581                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10582                 fi
10583
10584                 if [ "$save" != "never" ]; then
10585                         local hosts=$(comma_list $(osts_nodes))
10586
10587                         do_nodes $hosts $LCTL set_param $soc=never
10588                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10589                 fi
10590         fi
10591
10592         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10593         sync; sleep 1; sync
10594         local before=$(date +%s)
10595         cancel_lru_locks osc
10596         local after=$(date +%s)
10597         local diff=$((after - before))
10598         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10599
10600         rm -f $DIR/$tfile
10601 }
10602 run_test 80 "Page eviction is equally fast at high offsets too"
10603
10604 test_81a() { # LU-456
10605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10606         remote_ost_nodsh && skip "remote OST with nodsh"
10607
10608         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10609         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10610         do_facet ost1 lctl set_param fail_loc=0x80000228
10611
10612         # write should trigger a retry and success
10613         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10614         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10615         RC=$?
10616         if [ $RC -ne 0 ] ; then
10617                 error "write should success, but failed for $RC"
10618         fi
10619 }
10620 run_test 81a "OST should retry write when get -ENOSPC ==============="
10621
10622 test_81b() { # LU-456
10623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10624         remote_ost_nodsh && skip "remote OST with nodsh"
10625
10626         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10627         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10628         do_facet ost1 lctl set_param fail_loc=0x228
10629
10630         # write should retry several times and return -ENOSPC finally
10631         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10632         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10633         RC=$?
10634         ENOSPC=28
10635         if [ $RC -ne $ENOSPC ] ; then
10636                 error "dd should fail for -ENOSPC, but succeed."
10637         fi
10638 }
10639 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10640
10641 test_99() {
10642         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10643
10644         test_mkdir $DIR/$tdir.cvsroot
10645         chown $RUNAS_ID $DIR/$tdir.cvsroot
10646
10647         cd $TMP
10648         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10649
10650         cd /etc/init.d
10651         # some versions of cvs import exit(1) when asked to import links or
10652         # files they can't read.  ignore those files.
10653         local toignore=$(find . -type l -printf '-I %f\n' -o \
10654                          ! -perm /4 -printf '-I %f\n')
10655         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10656                 $tdir.reposname vtag rtag
10657
10658         cd $DIR
10659         test_mkdir $DIR/$tdir.reposname
10660         chown $RUNAS_ID $DIR/$tdir.reposname
10661         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10662
10663         cd $DIR/$tdir.reposname
10664         $RUNAS touch foo99
10665         $RUNAS cvs add -m 'addmsg' foo99
10666         $RUNAS cvs update
10667         $RUNAS cvs commit -m 'nomsg' foo99
10668         rm -fr $DIR/$tdir.cvsroot
10669 }
10670 run_test 99 "cvs strange file/directory operations"
10671
10672 test_100() {
10673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10674         [[ "$NETTYPE" =~ tcp ]] ||
10675                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10676         remote_ost_nodsh && skip "remote OST with nodsh"
10677         remote_mds_nodsh && skip "remote MDS with nodsh"
10678         remote_servers ||
10679                 skip "useless for local single node setup"
10680
10681         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10682                 [ "$PROT" != "tcp" ] && continue
10683                 RPORT=$(echo $REMOTE | cut -d: -f2)
10684                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10685
10686                 rc=0
10687                 LPORT=`echo $LOCAL | cut -d: -f2`
10688                 if [ $LPORT -ge 1024 ]; then
10689                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10690                         netstat -tna
10691                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10692                 fi
10693         done
10694         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10695 }
10696 run_test 100 "check local port using privileged port ==========="
10697
10698 function get_named_value()
10699 {
10700     local tag=$1
10701
10702     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10703 }
10704
10705 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10706                    awk '/^max_cached_mb/ { print $2 }')
10707
10708 cleanup_101a() {
10709         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10710         trap 0
10711 }
10712
10713 test_101a() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715
10716         local s
10717         local discard
10718         local nreads=10000
10719         local cache_limit=32
10720
10721         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10722         trap cleanup_101a EXIT
10723         $LCTL set_param -n llite.*.read_ahead_stats=0
10724         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10725
10726         #
10727         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10728         #
10729         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10730         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10731
10732         discard=0
10733         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10734                    get_named_value 'read.but.discarded'); do
10735                         discard=$(($discard + $s))
10736         done
10737         cleanup_101a
10738
10739         $LCTL get_param osc.*-osc*.rpc_stats
10740         $LCTL get_param llite.*.read_ahead_stats
10741
10742         # Discard is generally zero, but sometimes a few random reads line up
10743         # and trigger larger readahead, which is wasted & leads to discards.
10744         if [[ $(($discard)) -gt $nreads ]]; then
10745                 error "too many ($discard) discarded pages"
10746         fi
10747         rm -f $DIR/$tfile || true
10748 }
10749 run_test 101a "check read-ahead for random reads"
10750
10751 setup_test101bc() {
10752         test_mkdir $DIR/$tdir
10753         local ssize=$1
10754         local FILE_LENGTH=$2
10755         STRIPE_OFFSET=0
10756
10757         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10758
10759         local list=$(comma_list $(osts_nodes))
10760         set_osd_param $list '' read_cache_enable 0
10761         set_osd_param $list '' writethrough_cache_enable 0
10762
10763         trap cleanup_test101bc EXIT
10764         # prepare the read-ahead file
10765         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10766
10767         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10768                                 count=$FILE_SIZE_MB 2> /dev/null
10769
10770 }
10771
10772 cleanup_test101bc() {
10773         trap 0
10774         rm -rf $DIR/$tdir
10775         rm -f $DIR/$tfile
10776
10777         local list=$(comma_list $(osts_nodes))
10778         set_osd_param $list '' read_cache_enable 1
10779         set_osd_param $list '' writethrough_cache_enable 1
10780 }
10781
10782 calc_total() {
10783         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10784 }
10785
10786 ra_check_101() {
10787         local read_size=$1
10788         local stripe_size=$2
10789         local stride_length=$((stripe_size / read_size))
10790         local stride_width=$((stride_length * OSTCOUNT))
10791         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10792                                 (stride_width - stride_length) ))
10793         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10794                   get_named_value 'read.but.discarded' | calc_total)
10795
10796         if [[ $discard -gt $discard_limit ]]; then
10797                 $LCTL get_param llite.*.read_ahead_stats
10798                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10799         else
10800                 echo "Read-ahead success for size ${read_size}"
10801         fi
10802 }
10803
10804 test_101b() {
10805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10807
10808         local STRIPE_SIZE=1048576
10809         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10810
10811         if [ $SLOW == "yes" ]; then
10812                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10813         else
10814                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10815         fi
10816
10817         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10818
10819         # prepare the read-ahead file
10820         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10821         cancel_lru_locks osc
10822         for BIDX in 2 4 8 16 32 64 128 256
10823         do
10824                 local BSIZE=$((BIDX*4096))
10825                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10826                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10827                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10828                 $LCTL set_param -n llite.*.read_ahead_stats=0
10829                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10830                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10831                 cancel_lru_locks osc
10832                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10833         done
10834         cleanup_test101bc
10835         true
10836 }
10837 run_test 101b "check stride-io mode read-ahead ================="
10838
10839 test_101c() {
10840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10841
10842         local STRIPE_SIZE=1048576
10843         local FILE_LENGTH=$((STRIPE_SIZE*100))
10844         local nreads=10000
10845         local rsize=65536
10846         local osc_rpc_stats
10847
10848         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10849
10850         cancel_lru_locks osc
10851         $LCTL set_param osc.*.rpc_stats=0
10852         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10853         $LCTL get_param osc.*.rpc_stats
10854         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10855                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10856                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10857                 local size
10858
10859                 if [ $lines -le 20 ]; then
10860                         echo "continue debug"
10861                         continue
10862                 fi
10863                 for size in 1 2 4 8; do
10864                         local rpc=$(echo "$stats" |
10865                                     awk '($1 == "'$size':") {print $2; exit; }')
10866                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10867                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10868                 done
10869                 echo "$osc_rpc_stats check passed!"
10870         done
10871         cleanup_test101bc
10872         true
10873 }
10874 run_test 101c "check stripe_size aligned read-ahead"
10875
10876 test_101d() {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878
10879         local file=$DIR/$tfile
10880         local sz_MB=${FILESIZE_101d:-80}
10881         local ra_MB=${READAHEAD_MB:-40}
10882
10883         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10884         [ $free_MB -lt $sz_MB ] &&
10885                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10886
10887         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10888         $LFS setstripe -c -1 $file || error "setstripe failed"
10889
10890         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10891         echo Cancel LRU locks on lustre client to flush the client cache
10892         cancel_lru_locks osc
10893
10894         echo Disable read-ahead
10895         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10896         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10897         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10898         $LCTL get_param -n llite.*.max_read_ahead_mb
10899
10900         echo "Reading the test file $file with read-ahead disabled"
10901         local sz_KB=$((sz_MB * 1024 / 4))
10902         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10903         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10904         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10905                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10906
10907         echo "Cancel LRU locks on lustre client to flush the client cache"
10908         cancel_lru_locks osc
10909         echo Enable read-ahead with ${ra_MB}MB
10910         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10911
10912         echo "Reading the test file $file with read-ahead enabled"
10913         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10914                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10915
10916         echo "read-ahead disabled time read $raOFF"
10917         echo "read-ahead enabled time read $raON"
10918
10919         rm -f $file
10920         wait_delete_completed
10921
10922         # use awk for this check instead of bash because it handles decimals
10923         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10924                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10925 }
10926 run_test 101d "file read with and without read-ahead enabled"
10927
10928 test_101e() {
10929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10930
10931         local file=$DIR/$tfile
10932         local size_KB=500  #KB
10933         local count=100
10934         local bsize=1024
10935
10936         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10937         local need_KB=$((count * size_KB))
10938         [[ $free_KB -le $need_KB ]] &&
10939                 skip_env "Need free space $need_KB, have $free_KB"
10940
10941         echo "Creating $count ${size_KB}K test files"
10942         for ((i = 0; i < $count; i++)); do
10943                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10944         done
10945
10946         echo "Cancel LRU locks on lustre client to flush the client cache"
10947         cancel_lru_locks $OSC
10948
10949         echo "Reset readahead stats"
10950         $LCTL set_param -n llite.*.read_ahead_stats=0
10951
10952         for ((i = 0; i < $count; i++)); do
10953                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10954         done
10955
10956         $LCTL get_param llite.*.max_cached_mb
10957         $LCTL get_param llite.*.read_ahead_stats
10958         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10959                      get_named_value 'misses' | calc_total)
10960
10961         for ((i = 0; i < $count; i++)); do
10962                 rm -rf $file.$i 2>/dev/null
10963         done
10964
10965         #10000 means 20% reads are missing in readahead
10966         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10967 }
10968 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10969
10970 test_101f() {
10971         which iozone || skip_env "no iozone installed"
10972
10973         local old_debug=$($LCTL get_param debug)
10974         old_debug=${old_debug#*=}
10975         $LCTL set_param debug="reada mmap"
10976
10977         # create a test file
10978         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10979
10980         echo Cancel LRU locks on lustre client to flush the client cache
10981         cancel_lru_locks osc
10982
10983         echo Reset readahead stats
10984         $LCTL set_param -n llite.*.read_ahead_stats=0
10985
10986         echo mmap read the file with small block size
10987         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10988                 > /dev/null 2>&1
10989
10990         echo checking missing pages
10991         $LCTL get_param llite.*.read_ahead_stats
10992         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10993                         get_named_value 'misses' | calc_total)
10994
10995         $LCTL set_param debug="$old_debug"
10996         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10997         rm -f $DIR/$tfile
10998 }
10999 run_test 101f "check mmap read performance"
11000
11001 test_101g_brw_size_test() {
11002         local mb=$1
11003         local pages=$((mb * 1048576 / PAGE_SIZE))
11004         local file=$DIR/$tfile
11005
11006         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11007                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11008         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11009                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11010                         return 2
11011         done
11012
11013         stack_trap "rm -f $file" EXIT
11014         $LCTL set_param -n osc.*.rpc_stats=0
11015
11016         # 10 RPCs should be enough for the test
11017         local count=10
11018         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11019                 { error "dd write ${mb} MB blocks failed"; return 3; }
11020         cancel_lru_locks osc
11021         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11022                 { error "dd write ${mb} MB blocks failed"; return 4; }
11023
11024         # calculate number of full-sized read and write RPCs
11025         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11026                 sed -n '/pages per rpc/,/^$/p' |
11027                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11028                 END { print reads,writes }'))
11029         # allow one extra full-sized read RPC for async readahead
11030         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11031                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11032         [[ ${rpcs[1]} == $count ]] ||
11033                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11034 }
11035
11036 test_101g() {
11037         remote_ost_nodsh && skip "remote OST with nodsh"
11038
11039         local rpcs
11040         local osts=$(get_facets OST)
11041         local list=$(comma_list $(osts_nodes))
11042         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11043         local brw_size="obdfilter.*.brw_size"
11044
11045         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11046
11047         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11048
11049         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11050                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11051                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11052            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11053                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11054                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11055
11056                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11057                         suffix="M"
11058
11059                 if [[ $orig_mb -lt 16 ]]; then
11060                         save_lustre_params $osts "$brw_size" > $p
11061                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11062                                 error "set 16MB RPC size failed"
11063
11064                         echo "remount client to enable new RPC size"
11065                         remount_client $MOUNT || error "remount_client failed"
11066                 fi
11067
11068                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11069                 # should be able to set brw_size=12, but no rpc_stats for that
11070                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11071         fi
11072
11073         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11074
11075         if [[ $orig_mb -lt 16 ]]; then
11076                 restore_lustre_params < $p
11077                 remount_client $MOUNT || error "remount_client restore failed"
11078         fi
11079
11080         rm -f $p $DIR/$tfile
11081 }
11082 run_test 101g "Big bulk(4/16 MiB) readahead"
11083
11084 test_101h() {
11085         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11086
11087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11088                 error "dd 70M file failed"
11089         echo Cancel LRU locks on lustre client to flush the client cache
11090         cancel_lru_locks osc
11091
11092         echo "Reset readahead stats"
11093         $LCTL set_param -n llite.*.read_ahead_stats 0
11094
11095         echo "Read 10M of data but cross 64M bundary"
11096         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11097         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11098                      get_named_value 'misses' | calc_total)
11099         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11100         rm -f $p $DIR/$tfile
11101 }
11102 run_test 101h "Readahead should cover current read window"
11103
11104 test_101i() {
11105         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11106                 error "dd 10M file failed"
11107
11108         local max_per_file_mb=$($LCTL get_param -n \
11109                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11110         cancel_lru_locks osc
11111         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11112         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11113                 error "set max_read_ahead_per_file_mb to 1 failed"
11114
11115         echo "Reset readahead stats"
11116         $LCTL set_param llite.*.read_ahead_stats=0
11117
11118         dd if=$DIR/$tfile of=/dev/null bs=2M
11119
11120         $LCTL get_param llite.*.read_ahead_stats
11121         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11122                      awk '/misses/ { print $2 }')
11123         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11124         rm -f $DIR/$tfile
11125 }
11126 run_test 101i "allow current readahead to exceed reservation"
11127
11128 test_101j() {
11129         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11130                 error "setstripe $DIR/$tfile failed"
11131         local file_size=$((1048576 * 16))
11132         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11133         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11134
11135         echo Disable read-ahead
11136         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11137
11138         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11139         for blk in $PAGE_SIZE 1048576 $file_size; do
11140                 cancel_lru_locks osc
11141                 echo "Reset readahead stats"
11142                 $LCTL set_param -n llite.*.read_ahead_stats=0
11143                 local count=$(($file_size / $blk))
11144                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11145                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11146                              get_named_value 'failed.to.fast.read' | calc_total)
11147                 $LCTL get_param -n llite.*.read_ahead_stats
11148                 [ $miss -eq $count ] || error "expected $count got $miss"
11149         done
11150
11151         rm -f $p $DIR/$tfile
11152 }
11153 run_test 101j "A complete read block should be submitted when no RA"
11154
11155 setup_test102() {
11156         test_mkdir $DIR/$tdir
11157         chown $RUNAS_ID $DIR/$tdir
11158         STRIPE_SIZE=65536
11159         STRIPE_OFFSET=1
11160         STRIPE_COUNT=$OSTCOUNT
11161         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11162
11163         trap cleanup_test102 EXIT
11164         cd $DIR
11165         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11166         cd $DIR/$tdir
11167         for num in 1 2 3 4; do
11168                 for count in $(seq 1 $STRIPE_COUNT); do
11169                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11170                                 local size=`expr $STRIPE_SIZE \* $num`
11171                                 local file=file"$num-$idx-$count"
11172                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11173                         done
11174                 done
11175         done
11176
11177         cd $DIR
11178         $1 tar cf $TMP/f102.tar $tdir --xattrs
11179 }
11180
11181 cleanup_test102() {
11182         trap 0
11183         rm -f $TMP/f102.tar
11184         rm -rf $DIR/d0.sanity/d102
11185 }
11186
11187 test_102a() {
11188         [ "$UID" != 0 ] && skip "must run as root"
11189         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11190                 skip_env "must have user_xattr"
11191
11192         [ -z "$(which setfattr 2>/dev/null)" ] &&
11193                 skip_env "could not find setfattr"
11194
11195         local testfile=$DIR/$tfile
11196
11197         touch $testfile
11198         echo "set/get xattr..."
11199         setfattr -n trusted.name1 -v value1 $testfile ||
11200                 error "setfattr -n trusted.name1=value1 $testfile failed"
11201         getfattr -n trusted.name1 $testfile 2> /dev/null |
11202           grep "trusted.name1=.value1" ||
11203                 error "$testfile missing trusted.name1=value1"
11204
11205         setfattr -n user.author1 -v author1 $testfile ||
11206                 error "setfattr -n user.author1=author1 $testfile failed"
11207         getfattr -n user.author1 $testfile 2> /dev/null |
11208           grep "user.author1=.author1" ||
11209                 error "$testfile missing trusted.author1=author1"
11210
11211         echo "listxattr..."
11212         setfattr -n trusted.name2 -v value2 $testfile ||
11213                 error "$testfile unable to set trusted.name2"
11214         setfattr -n trusted.name3 -v value3 $testfile ||
11215                 error "$testfile unable to set trusted.name3"
11216         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11217             grep "trusted.name" | wc -l) -eq 3 ] ||
11218                 error "$testfile missing 3 trusted.name xattrs"
11219
11220         setfattr -n user.author2 -v author2 $testfile ||
11221                 error "$testfile unable to set user.author2"
11222         setfattr -n user.author3 -v author3 $testfile ||
11223                 error "$testfile unable to set user.author3"
11224         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11225             grep "user.author" | wc -l) -eq 3 ] ||
11226                 error "$testfile missing 3 user.author xattrs"
11227
11228         echo "remove xattr..."
11229         setfattr -x trusted.name1 $testfile ||
11230                 error "$testfile error deleting trusted.name1"
11231         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11232                 error "$testfile did not delete trusted.name1 xattr"
11233
11234         setfattr -x user.author1 $testfile ||
11235                 error "$testfile error deleting user.author1"
11236         echo "set lustre special xattr ..."
11237         $LFS setstripe -c1 $testfile
11238         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11239                 awk -F "=" '/trusted.lov/ { print $2 }' )
11240         setfattr -n "trusted.lov" -v $lovea $testfile ||
11241                 error "$testfile doesn't ignore setting trusted.lov again"
11242         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11243                 error "$testfile allow setting invalid trusted.lov"
11244         rm -f $testfile
11245 }
11246 run_test 102a "user xattr test =================================="
11247
11248 check_102b_layout() {
11249         local layout="$*"
11250         local testfile=$DIR/$tfile
11251
11252         echo "test layout '$layout'"
11253         $LFS setstripe $layout $testfile || error "setstripe failed"
11254         $LFS getstripe -y $testfile
11255
11256         echo "get/set/list trusted.lov xattr ..." # b=10930
11257         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11258         [[ "$value" =~ "trusted.lov" ]] ||
11259                 error "can't get trusted.lov from $testfile"
11260         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11261                 error "getstripe failed"
11262
11263         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11264
11265         value=$(cut -d= -f2 <<<$value)
11266         # LU-13168: truncated xattr should fail if short lov_user_md header
11267         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11268                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11269         for len in $lens; do
11270                 echo "setfattr $len $testfile.2"
11271                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11272                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11273         done
11274         local stripe_size=$($LFS getstripe -S $testfile.2)
11275         local stripe_count=$($LFS getstripe -c $testfile.2)
11276         [[ $stripe_size -eq 65536 ]] ||
11277                 error "stripe size $stripe_size != 65536"
11278         [[ $stripe_count -eq $stripe_count_orig ]] ||
11279                 error "stripe count $stripe_count != $stripe_count_orig"
11280         rm $testfile $testfile.2
11281 }
11282
11283 test_102b() {
11284         [ -z "$(which setfattr 2>/dev/null)" ] &&
11285                 skip_env "could not find setfattr"
11286         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11287
11288         # check plain layout
11289         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11290
11291         # and also check composite layout
11292         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11293
11294 }
11295 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11296
11297 test_102c() {
11298         [ -z "$(which setfattr 2>/dev/null)" ] &&
11299                 skip_env "could not find setfattr"
11300         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11301
11302         # b10930: get/set/list lustre.lov xattr
11303         echo "get/set/list lustre.lov xattr ..."
11304         test_mkdir $DIR/$tdir
11305         chown $RUNAS_ID $DIR/$tdir
11306         local testfile=$DIR/$tdir/$tfile
11307         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11308                 error "setstripe failed"
11309         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11310                 error "getstripe failed"
11311         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11312         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11313
11314         local testfile2=${testfile}2
11315         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11316                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11317
11318         $RUNAS $MCREATE $testfile2
11319         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11320         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11321         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11322         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11323         [ $stripe_count -eq $STRIPECOUNT ] ||
11324                 error "stripe count $stripe_count != $STRIPECOUNT"
11325 }
11326 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11327
11328 compare_stripe_info1() {
11329         local stripe_index_all_zero=true
11330
11331         for num in 1 2 3 4; do
11332                 for count in $(seq 1 $STRIPE_COUNT); do
11333                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11334                                 local size=$((STRIPE_SIZE * num))
11335                                 local file=file"$num-$offset-$count"
11336                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11337                                 [[ $stripe_size -ne $size ]] &&
11338                                     error "$file: size $stripe_size != $size"
11339                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11340                                 # allow fewer stripes to be created, ORI-601
11341                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11342                                     error "$file: count $stripe_count != $count"
11343                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11344                                 [[ $stripe_index -ne 0 ]] &&
11345                                         stripe_index_all_zero=false
11346                         done
11347                 done
11348         done
11349         $stripe_index_all_zero &&
11350                 error "all files are being extracted starting from OST index 0"
11351         return 0
11352 }
11353
11354 have_xattrs_include() {
11355         tar --help | grep -q xattrs-include &&
11356                 echo --xattrs-include="lustre.*"
11357 }
11358
11359 test_102d() {
11360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11361         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11362
11363         XINC=$(have_xattrs_include)
11364         setup_test102
11365         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11366         cd $DIR/$tdir/$tdir
11367         compare_stripe_info1
11368 }
11369 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11370
11371 test_102f() {
11372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11373         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11374
11375         XINC=$(have_xattrs_include)
11376         setup_test102
11377         test_mkdir $DIR/$tdir.restore
11378         cd $DIR
11379         tar cf - --xattrs $tdir | tar xf - \
11380                 -C $DIR/$tdir.restore --xattrs $XINC
11381         cd $DIR/$tdir.restore/$tdir
11382         compare_stripe_info1
11383 }
11384 run_test 102f "tar copy files, not keep osts"
11385
11386 grow_xattr() {
11387         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11388                 skip "must have user_xattr"
11389         [ -z "$(which setfattr 2>/dev/null)" ] &&
11390                 skip_env "could not find setfattr"
11391         [ -z "$(which getfattr 2>/dev/null)" ] &&
11392                 skip_env "could not find getfattr"
11393
11394         local xsize=${1:-1024}  # in bytes
11395         local file=$DIR/$tfile
11396         local value="$(generate_string $xsize)"
11397         local xbig=trusted.big
11398         local toobig=$2
11399
11400         touch $file
11401         log "save $xbig on $file"
11402         if [ -z "$toobig" ]
11403         then
11404                 setfattr -n $xbig -v $value $file ||
11405                         error "saving $xbig on $file failed"
11406         else
11407                 setfattr -n $xbig -v $value $file &&
11408                         error "saving $xbig on $file succeeded"
11409                 return 0
11410         fi
11411
11412         local orig=$(get_xattr_value $xbig $file)
11413         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11414
11415         local xsml=trusted.sml
11416         log "save $xsml on $file"
11417         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11418
11419         local new=$(get_xattr_value $xbig $file)
11420         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11421
11422         log "grow $xsml on $file"
11423         setfattr -n $xsml -v "$value" $file ||
11424                 error "growing $xsml on $file failed"
11425
11426         new=$(get_xattr_value $xbig $file)
11427         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11428         log "$xbig still valid after growing $xsml"
11429
11430         rm -f $file
11431 }
11432
11433 test_102h() { # bug 15777
11434         grow_xattr 1024
11435 }
11436 run_test 102h "grow xattr from inside inode to external block"
11437
11438 test_102ha() {
11439         large_xattr_enabled || skip_env "ea_inode feature disabled"
11440
11441         echo "setting xattr of max xattr size: $(max_xattr_size)"
11442         grow_xattr $(max_xattr_size)
11443
11444         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11445         echo "This should fail:"
11446         grow_xattr $(($(max_xattr_size) + 10)) 1
11447 }
11448 run_test 102ha "grow xattr from inside inode to external inode"
11449
11450 test_102i() { # bug 17038
11451         [ -z "$(which getfattr 2>/dev/null)" ] &&
11452                 skip "could not find getfattr"
11453
11454         touch $DIR/$tfile
11455         ln -s $DIR/$tfile $DIR/${tfile}link
11456         getfattr -n trusted.lov $DIR/$tfile ||
11457                 error "lgetxattr on $DIR/$tfile failed"
11458         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11459                 grep -i "no such attr" ||
11460                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11461         rm -f $DIR/$tfile $DIR/${tfile}link
11462 }
11463 run_test 102i "lgetxattr test on symbolic link ============"
11464
11465 test_102j() {
11466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11467         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11468
11469         XINC=$(have_xattrs_include)
11470         setup_test102 "$RUNAS"
11471         chown $RUNAS_ID $DIR/$tdir
11472         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11473         cd $DIR/$tdir/$tdir
11474         compare_stripe_info1 "$RUNAS"
11475 }
11476 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11477
11478 test_102k() {
11479         [ -z "$(which setfattr 2>/dev/null)" ] &&
11480                 skip "could not find setfattr"
11481
11482         touch $DIR/$tfile
11483         # b22187 just check that does not crash for regular file.
11484         setfattr -n trusted.lov $DIR/$tfile
11485         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11486         local test_kdir=$DIR/$tdir
11487         test_mkdir $test_kdir
11488         local default_size=$($LFS getstripe -S $test_kdir)
11489         local default_count=$($LFS getstripe -c $test_kdir)
11490         local default_offset=$($LFS getstripe -i $test_kdir)
11491         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11492                 error 'dir setstripe failed'
11493         setfattr -n trusted.lov $test_kdir
11494         local stripe_size=$($LFS getstripe -S $test_kdir)
11495         local stripe_count=$($LFS getstripe -c $test_kdir)
11496         local stripe_offset=$($LFS getstripe -i $test_kdir)
11497         [ $stripe_size -eq $default_size ] ||
11498                 error "stripe size $stripe_size != $default_size"
11499         [ $stripe_count -eq $default_count ] ||
11500                 error "stripe count $stripe_count != $default_count"
11501         [ $stripe_offset -eq $default_offset ] ||
11502                 error "stripe offset $stripe_offset != $default_offset"
11503         rm -rf $DIR/$tfile $test_kdir
11504 }
11505 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11506
11507 test_102l() {
11508         [ -z "$(which getfattr 2>/dev/null)" ] &&
11509                 skip "could not find getfattr"
11510
11511         # LU-532 trusted. xattr is invisible to non-root
11512         local testfile=$DIR/$tfile
11513
11514         touch $testfile
11515
11516         echo "listxattr as user..."
11517         chown $RUNAS_ID $testfile
11518         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11519             grep -q "trusted" &&
11520                 error "$testfile trusted xattrs are user visible"
11521
11522         return 0;
11523 }
11524 run_test 102l "listxattr size test =================================="
11525
11526 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11527         local path=$DIR/$tfile
11528         touch $path
11529
11530         listxattr_size_check $path || error "listattr_size_check $path failed"
11531 }
11532 run_test 102m "Ensure listxattr fails on small bufffer ========"
11533
11534 cleanup_test102
11535
11536 getxattr() { # getxattr path name
11537         # Return the base64 encoding of the value of xattr name on path.
11538         local path=$1
11539         local name=$2
11540
11541         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11542         # file: $path
11543         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11544         #
11545         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11546
11547         getfattr --absolute-names --encoding=base64 --name=$name $path |
11548                 awk -F= -v name=$name '$1 == name {
11549                         print substr($0, index($0, "=") + 1);
11550         }'
11551 }
11552
11553 test_102n() { # LU-4101 mdt: protect internal xattrs
11554         [ -z "$(which setfattr 2>/dev/null)" ] &&
11555                 skip "could not find setfattr"
11556         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11557         then
11558                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11559         fi
11560
11561         local file0=$DIR/$tfile.0
11562         local file1=$DIR/$tfile.1
11563         local xattr0=$TMP/$tfile.0
11564         local xattr1=$TMP/$tfile.1
11565         local namelist="lov lma lmv link fid version som hsm"
11566         local name
11567         local value
11568
11569         rm -rf $file0 $file1 $xattr0 $xattr1
11570         touch $file0 $file1
11571
11572         # Get 'before' xattrs of $file1.
11573         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11574
11575         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11576                 namelist+=" lfsck_namespace"
11577         for name in $namelist; do
11578                 # Try to copy xattr from $file0 to $file1.
11579                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11580
11581                 setfattr --name=trusted.$name --value="$value" $file1 ||
11582                         error "setxattr 'trusted.$name' failed"
11583
11584                 # Try to set a garbage xattr.
11585                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11586
11587                 if [[ x$name == "xlov" ]]; then
11588                         setfattr --name=trusted.lov --value="$value" $file1 &&
11589                         error "setxattr invalid 'trusted.lov' success"
11590                 else
11591                         setfattr --name=trusted.$name --value="$value" $file1 ||
11592                                 error "setxattr invalid 'trusted.$name' failed"
11593                 fi
11594
11595                 # Try to remove the xattr from $file1. We don't care if this
11596                 # appears to succeed or fail, we just don't want there to be
11597                 # any changes or crashes.
11598                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11599         done
11600
11601         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11602         then
11603                 name="lfsck_ns"
11604                 # Try to copy xattr from $file0 to $file1.
11605                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11606
11607                 setfattr --name=trusted.$name --value="$value" $file1 ||
11608                         error "setxattr 'trusted.$name' failed"
11609
11610                 # Try to set a garbage xattr.
11611                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11612
11613                 setfattr --name=trusted.$name --value="$value" $file1 ||
11614                         error "setxattr 'trusted.$name' failed"
11615
11616                 # Try to remove the xattr from $file1. We don't care if this
11617                 # appears to succeed or fail, we just don't want there to be
11618                 # any changes or crashes.
11619                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11620         fi
11621
11622         # Get 'after' xattrs of file1.
11623         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11624
11625         if ! diff $xattr0 $xattr1; then
11626                 error "before and after xattrs of '$file1' differ"
11627         fi
11628
11629         rm -rf $file0 $file1 $xattr0 $xattr1
11630
11631         return 0
11632 }
11633 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11634
11635 test_102p() { # LU-4703 setxattr did not check ownership
11636         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11637                 skip "MDS needs to be at least 2.5.56"
11638
11639         local testfile=$DIR/$tfile
11640
11641         touch $testfile
11642
11643         echo "setfacl as user..."
11644         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11645         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11646
11647         echo "setfattr as user..."
11648         setfacl -m "u:$RUNAS_ID:---" $testfile
11649         $RUNAS setfattr -x system.posix_acl_access $testfile
11650         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11651 }
11652 run_test 102p "check setxattr(2) correctly fails without permission"
11653
11654 test_102q() {
11655         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11656                 skip "MDS needs to be at least 2.6.92"
11657
11658         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11659 }
11660 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11661
11662 test_102r() {
11663         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11664                 skip "MDS needs to be at least 2.6.93"
11665
11666         touch $DIR/$tfile || error "touch"
11667         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11668         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11669         rm $DIR/$tfile || error "rm"
11670
11671         #normal directory
11672         mkdir -p $DIR/$tdir || error "mkdir"
11673         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11674         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11675         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11676                 error "$testfile error deleting user.author1"
11677         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11678                 grep "user.$(basename $tdir)" &&
11679                 error "$tdir did not delete user.$(basename $tdir)"
11680         rmdir $DIR/$tdir || error "rmdir"
11681
11682         #striped directory
11683         test_mkdir $DIR/$tdir
11684         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11685         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11686         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11687                 error "$testfile error deleting user.author1"
11688         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11689                 grep "user.$(basename $tdir)" &&
11690                 error "$tdir did not delete user.$(basename $tdir)"
11691         rmdir $DIR/$tdir || error "rm striped dir"
11692 }
11693 run_test 102r "set EAs with empty values"
11694
11695 test_102s() {
11696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11697                 skip "MDS needs to be at least 2.11.52"
11698
11699         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11700
11701         save_lustre_params client "llite.*.xattr_cache" > $save
11702
11703         for cache in 0 1; do
11704                 lctl set_param llite.*.xattr_cache=$cache
11705
11706                 rm -f $DIR/$tfile
11707                 touch $DIR/$tfile || error "touch"
11708                 for prefix in lustre security system trusted user; do
11709                         # Note getxattr() may fail with 'Operation not
11710                         # supported' or 'No such attribute' depending
11711                         # on prefix and cache.
11712                         getfattr -n $prefix.n102s $DIR/$tfile &&
11713                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11714                 done
11715         done
11716
11717         restore_lustre_params < $save
11718 }
11719 run_test 102s "getting nonexistent xattrs should fail"
11720
11721 test_102t() {
11722         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11723                 skip "MDS needs to be at least 2.11.52"
11724
11725         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11726
11727         save_lustre_params client "llite.*.xattr_cache" > $save
11728
11729         for cache in 0 1; do
11730                 lctl set_param llite.*.xattr_cache=$cache
11731
11732                 for buf_size in 0 256; do
11733                         rm -f $DIR/$tfile
11734                         touch $DIR/$tfile || error "touch"
11735                         setfattr -n user.multiop $DIR/$tfile
11736                         $MULTIOP $DIR/$tfile oa$buf_size ||
11737                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11738                 done
11739         done
11740
11741         restore_lustre_params < $save
11742 }
11743 run_test 102t "zero length xattr values handled correctly"
11744
11745 run_acl_subtest()
11746 {
11747         local test=$LUSTRE/tests/acl/$1.test
11748         local tmp=$(mktemp -t $1-XXXXXX).test
11749         local bin=$2
11750         local dmn=$3
11751         local grp=$4
11752         local nbd=$5
11753         export LANG=C
11754
11755
11756         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11757         local sedgroups="-e s/:users/:$grp/g"
11758         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11759
11760         sed $sedusers $sedgroups < $test > $tmp
11761         stack_trap "rm -f $tmp"
11762         [[ -s $tmp ]] || error "sed failed to create test script"
11763
11764         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11765         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11766 }
11767
11768 test_103a() {
11769         [ "$UID" != 0 ] && skip "must run as root"
11770         $GSS && skip_env "could not run under gss"
11771         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11772                 skip_env "must have acl enabled"
11773         which setfacl || skip_env "could not find setfacl"
11774         remote_mds_nodsh && skip "remote MDS with nodsh"
11775
11776         ACLBIN=${ACLBIN:-"bin"}
11777         ACLDMN=${ACLDMN:-"daemon"}
11778         ACLGRP=${ACLGRP:-"users"}
11779         ACLNBD=${ACLNBD:-"nobody"}
11780
11781         if ! id $ACLBIN ||
11782            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11783                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11784                 ACLBIN=$USER0
11785                 if ! id $ACLBIN ; then
11786                         cat /etc/passwd
11787                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11788                 fi
11789         fi
11790         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11791            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11792                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11793                 ACLDMN=$USER1
11794                 if ! id $ACLDMN ; then
11795                         cat /etc/passwd
11796                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11797                 fi
11798         fi
11799         if ! getent group $ACLGRP; then
11800                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11801                 ACLGRP="$TSTUSR"
11802                 if ! getent group $ACLGRP; then
11803                         echo "cannot find group '$ACLGRP', adding it"
11804                         cat /etc/group
11805                         add_group 60000 $ACLGRP
11806                 fi
11807         fi
11808
11809         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11810         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11811         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11812
11813         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11814                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11815                 ACLGRP="$TSTUSR"
11816                 if ! getent group $ACLGRP; then
11817                         echo "cannot find group '$ACLGRP', adding it"
11818                         cat /etc/group
11819                         add_group 60000 $ACLGRP
11820                 fi
11821                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11822                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11823                         cat /etc/group
11824                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11825                 fi
11826         fi
11827
11828         gpasswd -a $ACLDMN $ACLBIN ||
11829                 error "setting client group failed"             # LU-5641
11830         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11831                 error "setting MDS group failed"                # LU-5641
11832
11833         declare -a identity_old
11834
11835         for num in $(seq $MDSCOUNT); do
11836                 switch_identity $num true || identity_old[$num]=$?
11837         done
11838
11839         SAVE_UMASK=$(umask)
11840         umask 0022
11841         mkdir -p $DIR/$tdir
11842         cd $DIR/$tdir
11843
11844         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11845         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11846         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11847         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11848         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11849         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11850         if ! id -u $ACLNBD ||
11851            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11852                 ACLNBD="nfsnobody"
11853                 if ! id -u $ACLNBD; then
11854                         ACLNBD=""
11855                 fi
11856         fi
11857         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11858                 add_group $(id -u $ACLNBD) $ACLNBD
11859                 if ! getent group $ACLNBD; then
11860                         ACLNBD=""
11861                 fi
11862         fi
11863         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11864            [[ -n "$ACLNBD" ]] && which setfattr; then
11865                 run_acl_subtest permissions_xattr \
11866                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11867         elif [[ -z "$ACLNBD" ]]; then
11868                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11869         else
11870                 echo "skip 'permission_xattr' test - missing setfattr command"
11871         fi
11872         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11873
11874         # inheritance test got from HP
11875         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11876         chmod +x make-tree || error "chmod +x failed"
11877         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11878         rm -f make-tree
11879
11880         echo "LU-974 ignore umask when acl is enabled..."
11881         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11882         if [ $MDSCOUNT -ge 2 ]; then
11883                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
11884         fi
11885
11886         echo "LU-2561 newly created file is same size as directory..."
11887         if [ "$mds1_FSTYPE" != "zfs" ]; then
11888                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
11889         else
11890                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
11891         fi
11892
11893         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
11894
11895         cd $SAVE_PWD
11896         umask $SAVE_UMASK
11897
11898         for num in $(seq $MDSCOUNT); do
11899                 if [ "${identity_old[$num]}" = 1 ]; then
11900                         switch_identity $num false || identity_old[$num]=$?
11901                 fi
11902         done
11903 }
11904 run_test 103a "acl test"
11905
11906 test_103b() {
11907         declare -a pids
11908         local U
11909
11910         for U in {0..511}; do
11911                 {
11912                 local O=$(printf "%04o" $U)
11913
11914                 umask $(printf "%04o" $((511 ^ $O)))
11915                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11916                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11917
11918                 (( $S == ($O & 0666) )) ||
11919                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11920
11921                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11922                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11923                 (( $S == ($O & 0666) )) ||
11924                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11925
11926                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11927                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11928                 (( $S == ($O & 0666) )) ||
11929                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11930                 rm -f $DIR/$tfile.[smp]$0
11931                 } &
11932                 local pid=$!
11933
11934                 # limit the concurrently running threads to 64. LU-11878
11935                 local idx=$((U % 64))
11936                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11937                 pids[idx]=$pid
11938         done
11939         wait
11940 }
11941 run_test 103b "umask lfs setstripe"
11942
11943 test_103c() {
11944         mkdir -p $DIR/$tdir
11945         cp -rp $DIR/$tdir $DIR/$tdir.bak
11946
11947         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11948                 error "$DIR/$tdir shouldn't contain default ACL"
11949         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11950                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11951         true
11952 }
11953 run_test 103c "'cp -rp' won't set empty acl"
11954
11955 test_103e() {
11956         local numacl
11957         local fileacl
11958         local saved_debug=$($LCTL get_param -n debug)
11959
11960         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
11961                 skip "MDS needs to be at least 2.14.52"
11962
11963         large_xattr_enabled || skip_env "ea_inode feature disabled"
11964
11965         mkdir -p $DIR/$tdir
11966         # add big LOV EA to cause reply buffer overflow earlier
11967         $LFS setstripe -C 1000 $DIR/$tdir
11968         lctl set_param mdc.*-mdc*.stats=clear
11969
11970         $LCTL set_param debug=0
11971         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11972         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11973
11974         # add a large number of default ACLs (expect 8000+ for 2.13+)
11975         for U in {2..7000}; do
11976                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11977                         error "Able to add just $U default ACLs"
11978         done
11979         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11980         echo "$numacl default ACLs created"
11981
11982         stat $DIR/$tdir || error "Cannot stat directory"
11983         # check file creation
11984         touch $DIR/$tdir/$tfile ||
11985                 error "failed to create $tfile with $numacl default ACLs"
11986         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11987         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11988         echo "$fileacl ACLs were inherited"
11989         (( $fileacl == $numacl )) ||
11990                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11991         # check that new ACLs creation adds new ACLs to inherited ACLs
11992         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11993                 error "Cannot set new ACL"
11994         numacl=$((numacl + 1))
11995         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11996         (( $fileacl == $numacl )) ||
11997                 error "failed to add new ACL: $fileacl != $numacl as expected"
11998         # adds more ACLs to a file to reach their maximum at 8000+
11999         numacl=0
12000         for U in {20000..25000}; do
12001                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12002                 numacl=$((numacl + 1))
12003         done
12004         echo "Added $numacl more ACLs to the file"
12005         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12006         echo "Total $fileacl ACLs in file"
12007         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12008         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12009         rmdir $DIR/$tdir || error "Cannot remove directory"
12010 }
12011 run_test 103e "inheritance of big amount of default ACLs"
12012
12013 test_103f() {
12014         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12015                 skip "MDS needs to be at least 2.14.51"
12016
12017         large_xattr_enabled || skip_env "ea_inode feature disabled"
12018
12019         # enable changelog to consume more internal MDD buffers
12020         changelog_register
12021
12022         mkdir -p $DIR/$tdir
12023         # add big LOV EA
12024         $LFS setstripe -C 1000 $DIR/$tdir
12025         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12026         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12027         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12028         rmdir $DIR/$tdir || error "Cannot remove directory"
12029 }
12030 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12031
12032 test_104a() {
12033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12034
12035         touch $DIR/$tfile
12036         lfs df || error "lfs df failed"
12037         lfs df -ih || error "lfs df -ih failed"
12038         lfs df -h $DIR || error "lfs df -h $DIR failed"
12039         lfs df -i $DIR || error "lfs df -i $DIR failed"
12040         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12041         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12042
12043         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12044         lctl --device %$OSC deactivate
12045         lfs df || error "lfs df with deactivated OSC failed"
12046         lctl --device %$OSC activate
12047         # wait the osc back to normal
12048         wait_osc_import_ready client ost
12049
12050         lfs df || error "lfs df with reactivated OSC failed"
12051         rm -f $DIR/$tfile
12052 }
12053 run_test 104a "lfs df [-ih] [path] test ========================="
12054
12055 test_104b() {
12056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12057         [ $RUNAS_ID -eq $UID ] &&
12058                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12059
12060         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12061                         grep "Permission denied" | wc -l)))
12062         if [ $denied_cnt -ne 0 ]; then
12063                 error "lfs check servers test failed"
12064         fi
12065 }
12066 run_test 104b "$RUNAS lfs check servers test ===================="
12067
12068 #
12069 # Verify $1 is within range of $2.
12070 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12071 # $1 is <= 2% of $2. Else Fail.
12072 #
12073 value_in_range() {
12074         # Strip all units (M, G, T)
12075         actual=$(echo $1 | tr -d A-Z)
12076         expect=$(echo $2 | tr -d A-Z)
12077
12078         expect_lo=$(($expect * 98 / 100)) # 2% below
12079         expect_hi=$(($expect * 102 / 100)) # 2% above
12080
12081         # permit 2% drift above and below
12082         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12083 }
12084
12085 test_104c() {
12086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12087         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12088
12089         local ost_param="osd-zfs.$FSNAME-OST0000."
12090         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12091         local ofacets=$(get_facets OST)
12092         local mfacets=$(get_facets MDS)
12093         local saved_ost_blocks=
12094         local saved_mdt_blocks=
12095
12096         echo "Before recordsize change"
12097         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12098         df=($(df -h | grep "$MOUNT"$))
12099
12100         # For checking.
12101         echo "lfs output : ${lfs_df[*]}"
12102         echo "df  output : ${df[*]}"
12103
12104         for facet in ${ofacets//,/ }; do
12105                 if [ -z $saved_ost_blocks ]; then
12106                         saved_ost_blocks=$(do_facet $facet \
12107                                 lctl get_param -n $ost_param.blocksize)
12108                         echo "OST Blocksize: $saved_ost_blocks"
12109                 fi
12110                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12111                 do_facet $facet zfs set recordsize=32768 $ost
12112         done
12113
12114         # BS too small. Sufficient for functional testing.
12115         for facet in ${mfacets//,/ }; do
12116                 if [ -z $saved_mdt_blocks ]; then
12117                         saved_mdt_blocks=$(do_facet $facet \
12118                                 lctl get_param -n $mdt_param.blocksize)
12119                         echo "MDT Blocksize: $saved_mdt_blocks"
12120                 fi
12121                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12122                 do_facet $facet zfs set recordsize=32768 $mdt
12123         done
12124
12125         # Give new values chance to reflect change
12126         sleep 2
12127
12128         echo "After recordsize change"
12129         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12130         df_after=($(df -h | grep "$MOUNT"$))
12131
12132         # For checking.
12133         echo "lfs output : ${lfs_df_after[*]}"
12134         echo "df  output : ${df_after[*]}"
12135
12136         # Verify lfs df
12137         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12138                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12139         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12140                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12141         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12142                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12143
12144         # Verify df
12145         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12146                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12147         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12148                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12149         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12150                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12151
12152         # Restore MDT recordize back to original
12153         for facet in ${mfacets//,/ }; do
12154                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12155                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12156         done
12157
12158         # Restore OST recordize back to original
12159         for facet in ${ofacets//,/ }; do
12160                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12161                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12162         done
12163
12164         return 0
12165 }
12166 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12167
12168 test_104d() {
12169         (( $RUNAS_ID != $UID )) ||
12170                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12171
12172         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12173                 skip "lustre version doesn't support lctl dl with non-root"
12174
12175         # debugfs only allows root users to access files, so the
12176         # previous move of the "devices" file to debugfs broke
12177         # "lctl dl" for non-root users. The LU-9680 Netlink
12178         # interface again allows non-root users to list devices.
12179         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12180                 error "lctl dl doesn't work for non root"
12181
12182         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12183         [ "$ost_count" -eq $OSTCOUNT ]  ||
12184                 error "lctl dl reports wrong number of OST devices"
12185
12186         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12187         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12188                 error "lctl dl reports wrong number of MDT devices"
12189 }
12190 run_test 104d "$RUNAS lctl dl test"
12191
12192 test_105a() {
12193         # doesn't work on 2.4 kernels
12194         touch $DIR/$tfile
12195         if $(flock_is_enabled); then
12196                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12197         else
12198                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12199         fi
12200         rm -f $DIR/$tfile
12201 }
12202 run_test 105a "flock when mounted without -o flock test ========"
12203
12204 test_105b() {
12205         touch $DIR/$tfile
12206         if $(flock_is_enabled); then
12207                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12208         else
12209                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12210         fi
12211         rm -f $DIR/$tfile
12212 }
12213 run_test 105b "fcntl when mounted without -o flock test ========"
12214
12215 test_105c() {
12216         touch $DIR/$tfile
12217         if $(flock_is_enabled); then
12218                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12219         else
12220                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12221         fi
12222         rm -f $DIR/$tfile
12223 }
12224 run_test 105c "lockf when mounted without -o flock test"
12225
12226 test_105d() { # bug 15924
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228
12229         test_mkdir $DIR/$tdir
12230         flock_is_enabled || skip_env "mount w/o flock enabled"
12231         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12232         $LCTL set_param fail_loc=0x80000315
12233         flocks_test 2 $DIR/$tdir
12234 }
12235 run_test 105d "flock race (should not freeze) ========"
12236
12237 test_105e() { # bug 22660 && 22040
12238         flock_is_enabled || skip_env "mount w/o flock enabled"
12239
12240         touch $DIR/$tfile
12241         flocks_test 3 $DIR/$tfile
12242 }
12243 run_test 105e "Two conflicting flocks from same process"
12244
12245 test_106() { #bug 10921
12246         test_mkdir $DIR/$tdir
12247         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12248         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12249 }
12250 run_test 106 "attempt exec of dir followed by chown of that dir"
12251
12252 test_107() {
12253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12254
12255         CDIR=`pwd`
12256         local file=core
12257
12258         cd $DIR
12259         rm -f $file
12260
12261         local save_pattern=$(sysctl -n kernel.core_pattern)
12262         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12263         sysctl -w kernel.core_pattern=$file
12264         sysctl -w kernel.core_uses_pid=0
12265
12266         ulimit -c unlimited
12267         sleep 60 &
12268         SLEEPPID=$!
12269
12270         sleep 1
12271
12272         kill -s 11 $SLEEPPID
12273         wait $SLEEPPID
12274         if [ -e $file ]; then
12275                 size=`stat -c%s $file`
12276                 [ $size -eq 0 ] && error "Fail to create core file $file"
12277         else
12278                 error "Fail to create core file $file"
12279         fi
12280         rm -f $file
12281         sysctl -w kernel.core_pattern=$save_pattern
12282         sysctl -w kernel.core_uses_pid=$save_uses_pid
12283         cd $CDIR
12284 }
12285 run_test 107 "Coredump on SIG"
12286
12287 test_110() {
12288         test_mkdir $DIR/$tdir
12289         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12290         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12291                 error "mkdir with 256 char should fail, but did not"
12292         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12293                 error "create with 255 char failed"
12294         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12295                 error "create with 256 char should fail, but did not"
12296
12297         ls -l $DIR/$tdir
12298         rm -rf $DIR/$tdir
12299 }
12300 run_test 110 "filename length checking"
12301
12302 test_116a() { # was previously test_116()
12303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12304         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12305         remote_mds_nodsh && skip "remote MDS with nodsh"
12306
12307         echo -n "Free space priority "
12308         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12309                 head -n1
12310         declare -a AVAIL
12311         free_min_max
12312
12313         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12314         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12315         stack_trap simple_cleanup_common
12316
12317         # Check if we need to generate uneven OSTs
12318         test_mkdir -p $DIR/$tdir/OST${MINI}
12319         local FILL=$((MINV / 4))
12320         local DIFF=$((MAXV - MINV))
12321         local DIFF2=$((DIFF * 100 / MINV))
12322
12323         local threshold=$(do_facet $SINGLEMDS \
12324                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12325         threshold=${threshold%%%}
12326         echo -n "Check for uneven OSTs: "
12327         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12328
12329         if [[ $DIFF2 -gt $threshold ]]; then
12330                 echo "ok"
12331                 echo "Don't need to fill OST$MINI"
12332         else
12333                 # generate uneven OSTs. Write 2% over the QOS threshold value
12334                 echo "no"
12335                 DIFF=$((threshold - DIFF2 + 2))
12336                 DIFF2=$((MINV * DIFF / 100))
12337                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12338                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12339                         error "setstripe failed"
12340                 DIFF=$((DIFF2 / 2048))
12341                 i=0
12342                 while [ $i -lt $DIFF ]; do
12343                         i=$((i + 1))
12344                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12345                                 bs=2M count=1 2>/dev/null
12346                         echo -n .
12347                 done
12348                 echo .
12349                 sync
12350                 sleep_maxage
12351                 free_min_max
12352         fi
12353
12354         DIFF=$((MAXV - MINV))
12355         DIFF2=$((DIFF * 100 / MINV))
12356         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12357         if [ $DIFF2 -gt $threshold ]; then
12358                 echo "ok"
12359         else
12360                 skip "QOS imbalance criteria not met"
12361         fi
12362
12363         MINI1=$MINI
12364         MINV1=$MINV
12365         MAXI1=$MAXI
12366         MAXV1=$MAXV
12367
12368         # now fill using QOS
12369         $LFS setstripe -c 1 $DIR/$tdir
12370         FILL=$((FILL / 200))
12371         if [ $FILL -gt 600 ]; then
12372                 FILL=600
12373         fi
12374         echo "writing $FILL files to QOS-assigned OSTs"
12375         i=0
12376         while [ $i -lt $FILL ]; do
12377                 i=$((i + 1))
12378                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12379                         count=1 2>/dev/null
12380                 echo -n .
12381         done
12382         echo "wrote $i 200k files"
12383         sync
12384         sleep_maxage
12385
12386         echo "Note: free space may not be updated, so measurements might be off"
12387         free_min_max
12388         DIFF2=$((MAXV - MINV))
12389         echo "free space delta: orig $DIFF final $DIFF2"
12390         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12391         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12392         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12393         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12394         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12395         if [[ $DIFF -gt 0 ]]; then
12396                 FILL=$((DIFF2 * 100 / DIFF - 100))
12397                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12398         fi
12399
12400         # Figure out which files were written where
12401         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12402                awk '/'$MINI1': / {print $2; exit}')
12403         echo $UUID
12404         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12405         echo "$MINC files created on smaller OST $MINI1"
12406         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12407                awk '/'$MAXI1': / {print $2; exit}')
12408         echo $UUID
12409         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12410         echo "$MAXC files created on larger OST $MAXI1"
12411         if [[ $MINC -gt 0 ]]; then
12412                 FILL=$((MAXC * 100 / MINC - 100))
12413                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12414         fi
12415         [[ $MAXC -gt $MINC ]] ||
12416                 error_ignore LU-9 "stripe QOS didn't balance free space"
12417 }
12418 run_test 116a "stripe QOS: free space balance ==================="
12419
12420 test_116b() { # LU-2093
12421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12422         remote_mds_nodsh && skip "remote MDS with nodsh"
12423
12424 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12425         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12426                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12427         [ -z "$old_rr" ] && skip "no QOS"
12428         do_facet $SINGLEMDS lctl set_param \
12429                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12430         mkdir -p $DIR/$tdir
12431         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12432         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12433         do_facet $SINGLEMDS lctl set_param fail_loc=0
12434         rm -rf $DIR/$tdir
12435         do_facet $SINGLEMDS lctl set_param \
12436                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12437 }
12438 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12439
12440 test_117() # bug 10891
12441 {
12442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12443
12444         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12445         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12446         lctl set_param fail_loc=0x21e
12447         > $DIR/$tfile || error "truncate failed"
12448         lctl set_param fail_loc=0
12449         echo "Truncate succeeded."
12450         rm -f $DIR/$tfile
12451 }
12452 run_test 117 "verify osd extend =========="
12453
12454 NO_SLOW_RESENDCOUNT=4
12455 export OLD_RESENDCOUNT=""
12456 set_resend_count () {
12457         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12458         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12459         lctl set_param -n $PROC_RESENDCOUNT $1
12460         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12461 }
12462
12463 # for reduce test_118* time (b=14842)
12464 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12465
12466 # Reset async IO behavior after error case
12467 reset_async() {
12468         FILE=$DIR/reset_async
12469
12470         # Ensure all OSCs are cleared
12471         $LFS setstripe -c -1 $FILE
12472         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12473         sync
12474         rm $FILE
12475 }
12476
12477 test_118a() #bug 11710
12478 {
12479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12480
12481         reset_async
12482
12483         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12484         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12485         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12486
12487         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12488                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12489                 return 1;
12490         fi
12491         rm -f $DIR/$tfile
12492 }
12493 run_test 118a "verify O_SYNC works =========="
12494
12495 test_118b()
12496 {
12497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12498         remote_ost_nodsh && skip "remote OST with nodsh"
12499
12500         reset_async
12501
12502         #define OBD_FAIL_SRV_ENOENT 0x217
12503         set_nodes_failloc "$(osts_nodes)" 0x217
12504         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12505         RC=$?
12506         set_nodes_failloc "$(osts_nodes)" 0
12507         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12508         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12509                     grep -c writeback)
12510
12511         if [[ $RC -eq 0 ]]; then
12512                 error "Must return error due to dropped pages, rc=$RC"
12513                 return 1;
12514         fi
12515
12516         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12517                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12518                 return 1;
12519         fi
12520
12521         echo "Dirty pages not leaked on ENOENT"
12522
12523         # Due to the above error the OSC will issue all RPCs syncronously
12524         # until a subsequent RPC completes successfully without error.
12525         $MULTIOP $DIR/$tfile Ow4096yc
12526         rm -f $DIR/$tfile
12527
12528         return 0
12529 }
12530 run_test 118b "Reclaim dirty pages on fatal error =========="
12531
12532 test_118c()
12533 {
12534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12535
12536         # for 118c, restore the original resend count, LU-1940
12537         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12538                                 set_resend_count $OLD_RESENDCOUNT
12539         remote_ost_nodsh && skip "remote OST with nodsh"
12540
12541         reset_async
12542
12543         #define OBD_FAIL_OST_EROFS               0x216
12544         set_nodes_failloc "$(osts_nodes)" 0x216
12545
12546         # multiop should block due to fsync until pages are written
12547         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12548         MULTIPID=$!
12549         sleep 1
12550
12551         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12552                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12553         fi
12554
12555         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12556                     grep -c writeback)
12557         if [[ $WRITEBACK -eq 0 ]]; then
12558                 error "No page in writeback, writeback=$WRITEBACK"
12559         fi
12560
12561         set_nodes_failloc "$(osts_nodes)" 0
12562         wait $MULTIPID
12563         RC=$?
12564         if [[ $RC -ne 0 ]]; then
12565                 error "Multiop fsync failed, rc=$RC"
12566         fi
12567
12568         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12569         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12570                     grep -c writeback)
12571         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12572                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12573         fi
12574
12575         rm -f $DIR/$tfile
12576         echo "Dirty pages flushed via fsync on EROFS"
12577         return 0
12578 }
12579 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12580
12581 # continue to use small resend count to reduce test_118* time (b=14842)
12582 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12583
12584 test_118d()
12585 {
12586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12587         remote_ost_nodsh && skip "remote OST with nodsh"
12588
12589         reset_async
12590
12591         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12592         set_nodes_failloc "$(osts_nodes)" 0x214
12593         # multiop should block due to fsync until pages are written
12594         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12595         MULTIPID=$!
12596         sleep 1
12597
12598         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12599                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12600         fi
12601
12602         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12603                     grep -c writeback)
12604         if [[ $WRITEBACK -eq 0 ]]; then
12605                 error "No page in writeback, writeback=$WRITEBACK"
12606         fi
12607
12608         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12609         set_nodes_failloc "$(osts_nodes)" 0
12610
12611         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12612         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12613                     grep -c writeback)
12614         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12615                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12616         fi
12617
12618         rm -f $DIR/$tfile
12619         echo "Dirty pages gaurenteed flushed via fsync"
12620         return 0
12621 }
12622 run_test 118d "Fsync validation inject a delay of the bulk =========="
12623
12624 test_118f() {
12625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12626
12627         reset_async
12628
12629         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12630         lctl set_param fail_loc=0x8000040a
12631
12632         # Should simulate EINVAL error which is fatal
12633         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12634         RC=$?
12635         if [[ $RC -eq 0 ]]; then
12636                 error "Must return error due to dropped pages, rc=$RC"
12637         fi
12638
12639         lctl set_param fail_loc=0x0
12640
12641         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12642         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12643         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12644                     grep -c writeback)
12645         if [[ $LOCKED -ne 0 ]]; then
12646                 error "Locked pages remain in cache, locked=$LOCKED"
12647         fi
12648
12649         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12650                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12651         fi
12652
12653         rm -f $DIR/$tfile
12654         echo "No pages locked after fsync"
12655
12656         reset_async
12657         return 0
12658 }
12659 run_test 118f "Simulate unrecoverable OSC side error =========="
12660
12661 test_118g() {
12662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12663
12664         reset_async
12665
12666         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12667         lctl set_param fail_loc=0x406
12668
12669         # simulate local -ENOMEM
12670         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12671         RC=$?
12672
12673         lctl set_param fail_loc=0
12674         if [[ $RC -eq 0 ]]; then
12675                 error "Must return error due to dropped pages, rc=$RC"
12676         fi
12677
12678         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12679         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12680         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12681                         grep -c writeback)
12682         if [[ $LOCKED -ne 0 ]]; then
12683                 error "Locked pages remain in cache, locked=$LOCKED"
12684         fi
12685
12686         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12687                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12688         fi
12689
12690         rm -f $DIR/$tfile
12691         echo "No pages locked after fsync"
12692
12693         reset_async
12694         return 0
12695 }
12696 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12697
12698 test_118h() {
12699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12700         remote_ost_nodsh && skip "remote OST with nodsh"
12701
12702         reset_async
12703
12704         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12705         set_nodes_failloc "$(osts_nodes)" 0x20e
12706         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12707         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12708         RC=$?
12709
12710         set_nodes_failloc "$(osts_nodes)" 0
12711         if [[ $RC -eq 0 ]]; then
12712                 error "Must return error due to dropped pages, rc=$RC"
12713         fi
12714
12715         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12716         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12717         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12718                     grep -c writeback)
12719         if [[ $LOCKED -ne 0 ]]; then
12720                 error "Locked pages remain in cache, locked=$LOCKED"
12721         fi
12722
12723         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12724                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12725         fi
12726
12727         rm -f $DIR/$tfile
12728         echo "No pages locked after fsync"
12729
12730         return 0
12731 }
12732 run_test 118h "Verify timeout in handling recoverables errors  =========="
12733
12734 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12735
12736 test_118i() {
12737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12738         remote_ost_nodsh && skip "remote OST with nodsh"
12739
12740         reset_async
12741
12742         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12743         set_nodes_failloc "$(osts_nodes)" 0x20e
12744
12745         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12747         PID=$!
12748         sleep 5
12749         set_nodes_failloc "$(osts_nodes)" 0
12750
12751         wait $PID
12752         RC=$?
12753         if [[ $RC -ne 0 ]]; then
12754                 error "got error, but should be not, rc=$RC"
12755         fi
12756
12757         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12758         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12759         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12760         if [[ $LOCKED -ne 0 ]]; then
12761                 error "Locked pages remain in cache, locked=$LOCKED"
12762         fi
12763
12764         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12765                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12766         fi
12767
12768         rm -f $DIR/$tfile
12769         echo "No pages locked after fsync"
12770
12771         return 0
12772 }
12773 run_test 118i "Fix error before timeout in recoverable error  =========="
12774
12775 [ "$SLOW" = "no" ] && set_resend_count 4
12776
12777 test_118j() {
12778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12779         remote_ost_nodsh && skip "remote OST with nodsh"
12780
12781         reset_async
12782
12783         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12784         set_nodes_failloc "$(osts_nodes)" 0x220
12785
12786         # return -EIO from OST
12787         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12788         RC=$?
12789         set_nodes_failloc "$(osts_nodes)" 0x0
12790         if [[ $RC -eq 0 ]]; then
12791                 error "Must return error due to dropped pages, rc=$RC"
12792         fi
12793
12794         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12795         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12796         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12797         if [[ $LOCKED -ne 0 ]]; then
12798                 error "Locked pages remain in cache, locked=$LOCKED"
12799         fi
12800
12801         # in recoverable error on OST we want resend and stay until it finished
12802         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12803                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12804         fi
12805
12806         rm -f $DIR/$tfile
12807         echo "No pages locked after fsync"
12808
12809         return 0
12810 }
12811 run_test 118j "Simulate unrecoverable OST side error =========="
12812
12813 test_118k()
12814 {
12815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12816         remote_ost_nodsh && skip "remote OSTs with nodsh"
12817
12818         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12819         set_nodes_failloc "$(osts_nodes)" 0x20e
12820         test_mkdir $DIR/$tdir
12821
12822         for ((i=0;i<10;i++)); do
12823                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12824                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12825                 SLEEPPID=$!
12826                 sleep 0.500s
12827                 kill $SLEEPPID
12828                 wait $SLEEPPID
12829         done
12830
12831         set_nodes_failloc "$(osts_nodes)" 0
12832         rm -rf $DIR/$tdir
12833 }
12834 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12835
12836 test_118l() # LU-646
12837 {
12838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12839
12840         test_mkdir $DIR/$tdir
12841         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12842         rm -rf $DIR/$tdir
12843 }
12844 run_test 118l "fsync dir"
12845
12846 test_118m() # LU-3066
12847 {
12848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12849
12850         test_mkdir $DIR/$tdir
12851         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12852         rm -rf $DIR/$tdir
12853 }
12854 run_test 118m "fdatasync dir ========="
12855
12856 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12857
12858 test_118n()
12859 {
12860         local begin
12861         local end
12862
12863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12864         remote_ost_nodsh && skip "remote OSTs with nodsh"
12865
12866         # Sleep to avoid a cached response.
12867         #define OBD_STATFS_CACHE_SECONDS 1
12868         sleep 2
12869
12870         # Inject a 10 second delay in the OST_STATFS handler.
12871         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12872         set_nodes_failloc "$(osts_nodes)" 0x242
12873
12874         begin=$SECONDS
12875         stat --file-system $MOUNT > /dev/null
12876         end=$SECONDS
12877
12878         set_nodes_failloc "$(osts_nodes)" 0
12879
12880         if ((end - begin > 20)); then
12881             error "statfs took $((end - begin)) seconds, expected 10"
12882         fi
12883 }
12884 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12885
12886 test_119a() # bug 11737
12887 {
12888         BSIZE=$((512 * 1024))
12889         directio write $DIR/$tfile 0 1 $BSIZE
12890         # We ask to read two blocks, which is more than a file size.
12891         # directio will indicate an error when requested and actual
12892         # sizes aren't equeal (a normal situation in this case) and
12893         # print actual read amount.
12894         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12895         if [ "$NOB" != "$BSIZE" ]; then
12896                 error "read $NOB bytes instead of $BSIZE"
12897         fi
12898         rm -f $DIR/$tfile
12899 }
12900 run_test 119a "Short directIO read must return actual read amount"
12901
12902 test_119b() # bug 11737
12903 {
12904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12905
12906         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12907         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12908         sync
12909         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12910                 error "direct read failed"
12911         rm -f $DIR/$tfile
12912 }
12913 run_test 119b "Sparse directIO read must return actual read amount"
12914
12915 test_119c() # bug 13099
12916 {
12917         BSIZE=1048576
12918         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12919         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12920         rm -f $DIR/$tfile
12921 }
12922 run_test 119c "Testing for direct read hitting hole"
12923
12924 test_119d() # bug 15950
12925 {
12926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12927
12928         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12929         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12930         BSIZE=1048576
12931         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12932         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12933         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12934         lctl set_param fail_loc=0x40d
12935         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12936         pid_dio=$!
12937         sleep 1
12938         cat $DIR/$tfile > /dev/null &
12939         lctl set_param fail_loc=0
12940         pid_reads=$!
12941         wait $pid_dio
12942         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12943         sleep 2
12944         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12945         error "the read rpcs have not completed in 2s"
12946         rm -f $DIR/$tfile
12947         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12948 }
12949 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12950
12951 test_120a() {
12952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12953         remote_mds_nodsh && skip "remote MDS with nodsh"
12954         test_mkdir -i0 -c1 $DIR/$tdir
12955         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12956                 skip_env "no early lock cancel on server"
12957
12958         lru_resize_disable mdc
12959         lru_resize_disable osc
12960         cancel_lru_locks mdc
12961         # asynchronous object destroy at MDT could cause bl ast to client
12962         cancel_lru_locks osc
12963
12964         stat $DIR/$tdir > /dev/null
12965         can1=$(do_facet mds1 \
12966                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12967                awk '/ldlm_cancel/ {print $2}')
12968         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12969                awk '/ldlm_bl_callback/ {print $2}')
12970         test_mkdir -i0 -c1 $DIR/$tdir/d1
12971         can2=$(do_facet mds1 \
12972                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12973                awk '/ldlm_cancel/ {print $2}')
12974         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12975                awk '/ldlm_bl_callback/ {print $2}')
12976         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12977         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12978         lru_resize_enable mdc
12979         lru_resize_enable osc
12980 }
12981 run_test 120a "Early Lock Cancel: mkdir test"
12982
12983 test_120b() {
12984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12985         remote_mds_nodsh && skip "remote MDS with nodsh"
12986         test_mkdir $DIR/$tdir
12987         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12988                 skip_env "no early lock cancel on server"
12989
12990         lru_resize_disable mdc
12991         lru_resize_disable osc
12992         cancel_lru_locks mdc
12993         stat $DIR/$tdir > /dev/null
12994         can1=$(do_facet $SINGLEMDS \
12995                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12996                awk '/ldlm_cancel/ {print $2}')
12997         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12998                awk '/ldlm_bl_callback/ {print $2}')
12999         touch $DIR/$tdir/f1
13000         can2=$(do_facet $SINGLEMDS \
13001                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13002                awk '/ldlm_cancel/ {print $2}')
13003         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13004                awk '/ldlm_bl_callback/ {print $2}')
13005         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13006         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13007         lru_resize_enable mdc
13008         lru_resize_enable osc
13009 }
13010 run_test 120b "Early Lock Cancel: create test"
13011
13012 test_120c() {
13013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13014         remote_mds_nodsh && skip "remote MDS with nodsh"
13015         test_mkdir -i0 -c1 $DIR/$tdir
13016         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13017                 skip "no early lock cancel on server"
13018
13019         lru_resize_disable mdc
13020         lru_resize_disable osc
13021         test_mkdir -i0 -c1 $DIR/$tdir/d1
13022         test_mkdir -i0 -c1 $DIR/$tdir/d2
13023         touch $DIR/$tdir/d1/f1
13024         cancel_lru_locks mdc
13025         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13026         can1=$(do_facet mds1 \
13027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13028                awk '/ldlm_cancel/ {print $2}')
13029         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13030                awk '/ldlm_bl_callback/ {print $2}')
13031         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13032         can2=$(do_facet mds1 \
13033                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13034                awk '/ldlm_cancel/ {print $2}')
13035         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13036                awk '/ldlm_bl_callback/ {print $2}')
13037         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13038         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13039         lru_resize_enable mdc
13040         lru_resize_enable osc
13041 }
13042 run_test 120c "Early Lock Cancel: link test"
13043
13044 test_120d() {
13045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13046         remote_mds_nodsh && skip "remote MDS with nodsh"
13047         test_mkdir -i0 -c1 $DIR/$tdir
13048         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13049                 skip_env "no early lock cancel on server"
13050
13051         lru_resize_disable mdc
13052         lru_resize_disable osc
13053         touch $DIR/$tdir
13054         cancel_lru_locks mdc
13055         stat $DIR/$tdir > /dev/null
13056         can1=$(do_facet mds1 \
13057                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13058                awk '/ldlm_cancel/ {print $2}')
13059         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13060                awk '/ldlm_bl_callback/ {print $2}')
13061         chmod a+x $DIR/$tdir
13062         can2=$(do_facet mds1 \
13063                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13064                awk '/ldlm_cancel/ {print $2}')
13065         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13066                awk '/ldlm_bl_callback/ {print $2}')
13067         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13068         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13069         lru_resize_enable mdc
13070         lru_resize_enable osc
13071 }
13072 run_test 120d "Early Lock Cancel: setattr test"
13073
13074 test_120e() {
13075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13076         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13077                 skip_env "no early lock cancel on server"
13078         remote_mds_nodsh && skip "remote MDS with nodsh"
13079
13080         local dlmtrace_set=false
13081
13082         test_mkdir -i0 -c1 $DIR/$tdir
13083         lru_resize_disable mdc
13084         lru_resize_disable osc
13085         ! $LCTL get_param debug | grep -q dlmtrace &&
13086                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13087         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13088         cancel_lru_locks mdc
13089         cancel_lru_locks osc
13090         dd if=$DIR/$tdir/f1 of=/dev/null
13091         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13092         # XXX client can not do early lock cancel of OST lock
13093         # during unlink (LU-4206), so cancel osc lock now.
13094         sleep 2
13095         cancel_lru_locks osc
13096         can1=$(do_facet mds1 \
13097                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13098                awk '/ldlm_cancel/ {print $2}')
13099         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13100                awk '/ldlm_bl_callback/ {print $2}')
13101         unlink $DIR/$tdir/f1
13102         sleep 5
13103         can2=$(do_facet mds1 \
13104                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13105                awk '/ldlm_cancel/ {print $2}')
13106         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13107                awk '/ldlm_bl_callback/ {print $2}')
13108         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13109                 $LCTL dk $TMP/cancel.debug.txt
13110         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13111                 $LCTL dk $TMP/blocking.debug.txt
13112         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13113         lru_resize_enable mdc
13114         lru_resize_enable osc
13115 }
13116 run_test 120e "Early Lock Cancel: unlink test"
13117
13118 test_120f() {
13119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13120         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13121                 skip_env "no early lock cancel on server"
13122         remote_mds_nodsh && skip "remote MDS with nodsh"
13123
13124         test_mkdir -i0 -c1 $DIR/$tdir
13125         lru_resize_disable mdc
13126         lru_resize_disable osc
13127         test_mkdir -i0 -c1 $DIR/$tdir/d1
13128         test_mkdir -i0 -c1 $DIR/$tdir/d2
13129         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13130         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13131         cancel_lru_locks mdc
13132         cancel_lru_locks osc
13133         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13134         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13135         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13136         # XXX client can not do early lock cancel of OST lock
13137         # during rename (LU-4206), so cancel osc lock now.
13138         sleep 2
13139         cancel_lru_locks osc
13140         can1=$(do_facet mds1 \
13141                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13142                awk '/ldlm_cancel/ {print $2}')
13143         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13144                awk '/ldlm_bl_callback/ {print $2}')
13145         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13146         sleep 5
13147         can2=$(do_facet mds1 \
13148                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13149                awk '/ldlm_cancel/ {print $2}')
13150         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13151                awk '/ldlm_bl_callback/ {print $2}')
13152         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13153         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13154         lru_resize_enable mdc
13155         lru_resize_enable osc
13156 }
13157 run_test 120f "Early Lock Cancel: rename test"
13158
13159 test_120g() {
13160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13161         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13162                 skip_env "no early lock cancel on server"
13163         remote_mds_nodsh && skip "remote MDS with nodsh"
13164
13165         lru_resize_disable mdc
13166         lru_resize_disable osc
13167         count=10000
13168         echo create $count files
13169         test_mkdir $DIR/$tdir
13170         cancel_lru_locks mdc
13171         cancel_lru_locks osc
13172         t0=$(date +%s)
13173
13174         can0=$(do_facet $SINGLEMDS \
13175                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13176                awk '/ldlm_cancel/ {print $2}')
13177         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13178                awk '/ldlm_bl_callback/ {print $2}')
13179         createmany -o $DIR/$tdir/f $count
13180         sync
13181         can1=$(do_facet $SINGLEMDS \
13182                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13183                awk '/ldlm_cancel/ {print $2}')
13184         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13185                awk '/ldlm_bl_callback/ {print $2}')
13186         t1=$(date +%s)
13187         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13188         echo rm $count files
13189         rm -r $DIR/$tdir
13190         sync
13191         can2=$(do_facet $SINGLEMDS \
13192                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13193                awk '/ldlm_cancel/ {print $2}')
13194         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13195                awk '/ldlm_bl_callback/ {print $2}')
13196         t2=$(date +%s)
13197         echo total: $count removes in $((t2-t1))
13198         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13199         sleep 2
13200         # wait for commitment of removal
13201         lru_resize_enable mdc
13202         lru_resize_enable osc
13203 }
13204 run_test 120g "Early Lock Cancel: performance test"
13205
13206 test_121() { #bug #10589
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208
13209         rm -rf $DIR/$tfile
13210         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13211 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13212         lctl set_param fail_loc=0x310
13213         cancel_lru_locks osc > /dev/null
13214         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13215         lctl set_param fail_loc=0
13216         [[ $reads -eq $writes ]] ||
13217                 error "read $reads blocks, must be $writes blocks"
13218 }
13219 run_test 121 "read cancel race ========="
13220
13221 test_123a_base() { # was test 123, statahead(bug 11401)
13222         local lsx="$1"
13223
13224         SLOWOK=0
13225         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13226                 log "testing UP system. Performance may be lower than expected."
13227                 SLOWOK=1
13228         fi
13229         running_in_vm && SLOWOK=1
13230
13231         rm -rf $DIR/$tdir
13232         test_mkdir $DIR/$tdir
13233         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13234         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13235         MULT=10
13236         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13237                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13238
13239                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13240                 lctl set_param -n llite.*.statahead_max 0
13241                 lctl get_param llite.*.statahead_max
13242                 cancel_lru_locks mdc
13243                 cancel_lru_locks osc
13244                 stime=$(date +%s)
13245                 time $lsx $DIR/$tdir | wc -l
13246                 etime=$(date +%s)
13247                 delta=$((etime - stime))
13248                 log "$lsx $i files without statahead: $delta sec"
13249                 lctl set_param llite.*.statahead_max=$max
13250
13251                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13252                          awk '/statahead.wrong:/ { print $NF }')
13253                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13254                 cancel_lru_locks mdc
13255                 cancel_lru_locks osc
13256                 stime=$(date +%s)
13257                 time $lsx $DIR/$tdir | wc -l
13258                 etime=$(date +%s)
13259                 delta_sa=$((etime - stime))
13260                 log "$lsx $i files with statahead: $delta_sa sec"
13261                 lctl get_param -n llite.*.statahead_stats
13262                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13263                          awk '/statahead.wrong:/ { print $NF }')
13264
13265                 [[ $swrong -lt $ewrong ]] &&
13266                         log "statahead was stopped, maybe too many locks held!"
13267                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13268
13269                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13270                         max=$(lctl get_param -n llite.*.statahead_max |
13271                                 head -n 1)
13272                         lctl set_param -n llite.*.statahead_max 0
13273                         lctl get_param llite.*.statahead_max
13274                         cancel_lru_locks mdc
13275                         cancel_lru_locks osc
13276                         stime=$(date +%s)
13277                         time $lsx $DIR/$tdir | wc -l
13278                         etime=$(date +%s)
13279                         delta=$((etime - stime))
13280                         log "$lsx $i files again without statahead: $delta sec"
13281                         lctl set_param llite.*.statahead_max=$max
13282                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13283                                 if [ $SLOWOK -eq 0 ]; then
13284                                         error "$lsx $i files is slower with statahead!"
13285                                 else
13286                                         log "$lsx $i files is slower with statahead!"
13287                                 fi
13288                                 break
13289                         fi
13290                 fi
13291
13292                 [ $delta -gt 20 ] && break
13293                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13294                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13295         done
13296         log "$lsx done"
13297
13298         stime=$(date +%s)
13299         rm -r $DIR/$tdir
13300         sync
13301         etime=$(date +%s)
13302         delta=$((etime - stime))
13303         log "rm -r $DIR/$tdir/: $delta seconds"
13304         log "rm done"
13305         lctl get_param -n llite.*.statahead_stats
13306 }
13307
13308 test_123aa() {
13309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13310
13311         test_123a_base "ls -l"
13312 }
13313 run_test 123aa "verify statahead work"
13314
13315 test_123ab() {
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317
13318         statx_supported || skip_env "Test must be statx() syscall supported"
13319
13320         test_123a_base "$STATX -l"
13321 }
13322 run_test 123ab "verify statahead work by using statx"
13323
13324 test_123ac() {
13325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13326
13327         statx_supported || skip_env "Test must be statx() syscall supported"
13328
13329         local rpcs_before
13330         local rpcs_after
13331         local agl_before
13332         local agl_after
13333
13334         cancel_lru_locks $OSC
13335         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13336         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13337                      awk '/agl.total:/ { print $NF }')
13338         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13339         test_123a_base "$STATX --cached=always -D"
13340         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13341                     awk '/agl.total:/ { print $NF }')
13342         [ $agl_before -eq $agl_after ] ||
13343                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13344         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13345         [ $rpcs_after -eq $rpcs_before ] ||
13346                 error "$STATX should not send glimpse RPCs to $OSC"
13347 }
13348 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13349
13350 test_123b () { # statahead(bug 15027)
13351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13352
13353         test_mkdir $DIR/$tdir
13354         createmany -o $DIR/$tdir/$tfile-%d 1000
13355
13356         cancel_lru_locks mdc
13357         cancel_lru_locks osc
13358
13359 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13360         lctl set_param fail_loc=0x80000803
13361         ls -lR $DIR/$tdir > /dev/null
13362         log "ls done"
13363         lctl set_param fail_loc=0x0
13364         lctl get_param -n llite.*.statahead_stats
13365         rm -r $DIR/$tdir
13366         sync
13367
13368 }
13369 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13370
13371 test_123c() {
13372         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13373
13374         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13375         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13376         touch $DIR/$tdir.1/{1..3}
13377         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13378
13379         remount_client $MOUNT
13380
13381         $MULTIOP $DIR/$tdir.0 Q
13382
13383         # let statahead to complete
13384         ls -l $DIR/$tdir.0 > /dev/null
13385
13386         testid=$(echo $TESTNAME | tr '_' ' ')
13387         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13388                 error "statahead warning" || true
13389 }
13390 run_test 123c "Can not initialize inode warning on DNE statahead"
13391
13392 test_123d() {
13393         local num=100
13394         local swrong
13395         local ewrong
13396
13397         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13398         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13399                 error "setdirstripe $DIR/$tdir failed"
13400         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13401         remount_client $MOUNT
13402         $LCTL get_param llite.*.statahead_max
13403         $LCTL set_param llite.*.statahead_stats=0 ||
13404                 error "clear statahead_stats failed"
13405         swrong=$(lctl get_param -n llite.*.statahead_stats |
13406                  awk '/statahead.wrong:/ { print $NF }')
13407         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13408         # wait for statahead thread finished to update hit/miss stats.
13409         sleep 1
13410         $LCTL get_param -n llite.*.statahead_stats
13411         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13412                  awk '/statahead.wrong:/ { print $NF }')
13413         (( $swrong == $ewrong )) ||
13414                 log "statahead was stopped, maybe too many locks held!"
13415 }
13416 run_test 123d "Statahead on striped directories works correctly"
13417
13418 test_124a() {
13419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13420         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13421                 skip_env "no lru resize on server"
13422
13423         local NR=2000
13424
13425         test_mkdir $DIR/$tdir
13426
13427         log "create $NR files at $DIR/$tdir"
13428         createmany -o $DIR/$tdir/f $NR ||
13429                 error "failed to create $NR files in $DIR/$tdir"
13430
13431         cancel_lru_locks mdc
13432         ls -l $DIR/$tdir > /dev/null
13433
13434         local NSDIR=""
13435         local LRU_SIZE=0
13436         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13437                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13438                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13439                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13440                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13441                         log "NSDIR=$NSDIR"
13442                         log "NS=$(basename $NSDIR)"
13443                         break
13444                 fi
13445         done
13446
13447         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13448                 skip "Not enough cached locks created!"
13449         fi
13450         log "LRU=$LRU_SIZE"
13451
13452         local SLEEP=30
13453
13454         # We know that lru resize allows one client to hold $LIMIT locks
13455         # for 10h. After that locks begin to be killed by client.
13456         local MAX_HRS=10
13457         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13458         log "LIMIT=$LIMIT"
13459         if [ $LIMIT -lt $LRU_SIZE ]; then
13460                 skip "Limit is too small $LIMIT"
13461         fi
13462
13463         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13464         # killing locks. Some time was spent for creating locks. This means
13465         # that up to the moment of sleep finish we must have killed some of
13466         # them (10-100 locks). This depends on how fast ther were created.
13467         # Many of them were touched in almost the same moment and thus will
13468         # be killed in groups.
13469         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13470
13471         # Use $LRU_SIZE_B here to take into account real number of locks
13472         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13473         local LRU_SIZE_B=$LRU_SIZE
13474         log "LVF=$LVF"
13475         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13476         log "OLD_LVF=$OLD_LVF"
13477         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13478
13479         # Let's make sure that we really have some margin. Client checks
13480         # cached locks every 10 sec.
13481         SLEEP=$((SLEEP+20))
13482         log "Sleep ${SLEEP} sec"
13483         local SEC=0
13484         while ((SEC<$SLEEP)); do
13485                 echo -n "..."
13486                 sleep 5
13487                 SEC=$((SEC+5))
13488                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13489                 echo -n "$LRU_SIZE"
13490         done
13491         echo ""
13492         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13493         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13494
13495         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13496                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13497                 unlinkmany $DIR/$tdir/f $NR
13498                 return
13499         }
13500
13501         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13502         log "unlink $NR files at $DIR/$tdir"
13503         unlinkmany $DIR/$tdir/f $NR
13504 }
13505 run_test 124a "lru resize ======================================="
13506
13507 get_max_pool_limit()
13508 {
13509         local limit=$($LCTL get_param \
13510                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13511         local max=0
13512         for l in $limit; do
13513                 if [[ $l -gt $max ]]; then
13514                         max=$l
13515                 fi
13516         done
13517         echo $max
13518 }
13519
13520 test_124b() {
13521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13522         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13523                 skip_env "no lru resize on server"
13524
13525         LIMIT=$(get_max_pool_limit)
13526
13527         NR=$(($(default_lru_size)*20))
13528         if [[ $NR -gt $LIMIT ]]; then
13529                 log "Limit lock number by $LIMIT locks"
13530                 NR=$LIMIT
13531         fi
13532
13533         IFree=$(mdsrate_inodes_available)
13534         if [ $IFree -lt $NR ]; then
13535                 log "Limit lock number by $IFree inodes"
13536                 NR=$IFree
13537         fi
13538
13539         lru_resize_disable mdc
13540         test_mkdir -p $DIR/$tdir/disable_lru_resize
13541
13542         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13543         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13544         cancel_lru_locks mdc
13545         stime=`date +%s`
13546         PID=""
13547         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13548         PID="$PID $!"
13549         sleep 2
13550         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13551         PID="$PID $!"
13552         sleep 2
13553         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13554         PID="$PID $!"
13555         wait $PID
13556         etime=`date +%s`
13557         nolruresize_delta=$((etime-stime))
13558         log "ls -la time: $nolruresize_delta seconds"
13559         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13560         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13561
13562         lru_resize_enable mdc
13563         test_mkdir -p $DIR/$tdir/enable_lru_resize
13564
13565         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13566         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13567         cancel_lru_locks mdc
13568         stime=`date +%s`
13569         PID=""
13570         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13571         PID="$PID $!"
13572         sleep 2
13573         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13574         PID="$PID $!"
13575         sleep 2
13576         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13577         PID="$PID $!"
13578         wait $PID
13579         etime=`date +%s`
13580         lruresize_delta=$((etime-stime))
13581         log "ls -la time: $lruresize_delta seconds"
13582         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13583
13584         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13585                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13586         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13587                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13588         else
13589                 log "lru resize performs the same with no lru resize"
13590         fi
13591         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13592 }
13593 run_test 124b "lru resize (performance test) ======================="
13594
13595 test_124c() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13598                 skip_env "no lru resize on server"
13599
13600         # cache ununsed locks on client
13601         local nr=100
13602         cancel_lru_locks mdc
13603         test_mkdir $DIR/$tdir
13604         createmany -o $DIR/$tdir/f $nr ||
13605                 error "failed to create $nr files in $DIR/$tdir"
13606         ls -l $DIR/$tdir > /dev/null
13607
13608         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13609         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13610         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13611         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13612         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13613
13614         # set lru_max_age to 1 sec
13615         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13616         echo "sleep $((recalc_p * 2)) seconds..."
13617         sleep $((recalc_p * 2))
13618
13619         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13620         # restore lru_max_age
13621         $LCTL set_param -n $nsdir.lru_max_age $max_age
13622         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13623         unlinkmany $DIR/$tdir/f $nr
13624 }
13625 run_test 124c "LRUR cancel very aged locks"
13626
13627 test_124d() {
13628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13629         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13630                 skip_env "no lru resize on server"
13631
13632         # cache ununsed locks on client
13633         local nr=100
13634
13635         lru_resize_disable mdc
13636         stack_trap "lru_resize_enable mdc" EXIT
13637
13638         cancel_lru_locks mdc
13639
13640         # asynchronous object destroy at MDT could cause bl ast to client
13641         test_mkdir $DIR/$tdir
13642         createmany -o $DIR/$tdir/f $nr ||
13643                 error "failed to create $nr files in $DIR/$tdir"
13644         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13645
13646         ls -l $DIR/$tdir > /dev/null
13647
13648         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13649         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13650         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13651         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13652
13653         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13654
13655         # set lru_max_age to 1 sec
13656         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13657         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13658
13659         echo "sleep $((recalc_p * 2)) seconds..."
13660         sleep $((recalc_p * 2))
13661
13662         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13663
13664         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13665 }
13666 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13667
13668 test_125() { # 13358
13669         $LCTL get_param -n llite.*.client_type | grep -q local ||
13670                 skip "must run as local client"
13671         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13672                 skip_env "must have acl enabled"
13673         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13674
13675         test_mkdir $DIR/$tdir
13676         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13677         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13678                 error "setfacl $DIR/$tdir failed"
13679         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13680 }
13681 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13682
13683 test_126() { # bug 12829/13455
13684         $GSS && skip_env "must run as gss disabled"
13685         $LCTL get_param -n llite.*.client_type | grep -q local ||
13686                 skip "must run as local client"
13687         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13688
13689         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13690         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13691         rm -f $DIR/$tfile
13692         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13693 }
13694 run_test 126 "check that the fsgid provided by the client is taken into account"
13695
13696 test_127a() { # bug 15521
13697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13698         local name count samp unit min max sum sumsq
13699         local tmpfile=$TMP/$tfile.tmp
13700
13701         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13702         echo "stats before reset"
13703         stack_trap "rm -f $tmpfile"
13704         local now=$(date +%s)
13705
13706         $LCTL get_param osc.*.stats | tee $tmpfile
13707
13708         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13709         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13710         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13711         local uptime=$(awk '{ print $1 }' /proc/uptime)
13712
13713         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13714         (( ${snapshot_time%\.*} >= $now - 5 &&
13715            ${snapshot_time%\.*} <= $now + 5 )) ||
13716                 error "snapshot_time=$snapshot_time != now=$now"
13717         # elapsed _should_ be from mount, but at least less than uptime
13718         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13719                 error "elapsed=$elapsed > uptime=$uptime"
13720         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13721            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13722                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13723
13724         $LCTL set_param osc.*.stats=0
13725         local reset=$(date +%s)
13726         local fsize=$((2048 * 1024))
13727
13728         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13729         cancel_lru_locks osc
13730         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13731
13732         now=$(date +%s)
13733         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13734         while read name count samp unit min max sum sumsq; do
13735                 [[ "$samp" == "samples" ]] || continue
13736
13737                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13738                 [ ! $min ] && error "Missing min value for $name proc entry"
13739                 eval $name=$count || error "Wrong proc format"
13740
13741                 case $name in
13742                 read_bytes|write_bytes)
13743                         [[ "$unit" =~ "bytes" ]] ||
13744                                 error "unit is not 'bytes': $unit"
13745                         (( $min >= 4096 )) || error "min is too small: $min"
13746                         (( $min <= $fsize )) || error "min is too big: $min"
13747                         (( $max >= 4096 )) || error "max is too small: $max"
13748                         (( $max <= $fsize )) || error "max is too big: $max"
13749                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13750                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13751                                 error "sumsquare is too small: $sumsq"
13752                         (( $sumsq <= $fsize * $fsize )) ||
13753                                 error "sumsquare is too big: $sumsq"
13754                         ;;
13755                 ost_read|ost_write)
13756                         [[ "$unit" =~ "usec" ]] ||
13757                                 error "unit is not 'usec': $unit"
13758                         ;;
13759                 *)      ;;
13760                 esac
13761         done < $tmpfile
13762
13763         #check that we actually got some stats
13764         [ "$read_bytes" ] || error "Missing read_bytes stats"
13765         [ "$write_bytes" ] || error "Missing write_bytes stats"
13766         [ "$read_bytes" != 0 ] || error "no read done"
13767         [ "$write_bytes" != 0 ] || error "no write done"
13768
13769         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13770         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13771         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13772
13773         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13774         (( ${snapshot_time%\.*} >= $now - 5 &&
13775            ${snapshot_time%\.*} <= $now + 5 )) ||
13776                 error "reset snapshot_time=$snapshot_time != now=$now"
13777         # elapsed should be from time of stats reset
13778         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13779            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13780                 error "reset elapsed=$elapsed > $now - $reset"
13781         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13782            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13783                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13784 }
13785 run_test 127a "verify the client stats are sane"
13786
13787 test_127b() { # bug LU-333
13788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13789         local name count samp unit min max sum sumsq
13790
13791         echo "stats before reset"
13792         $LCTL get_param llite.*.stats
13793         $LCTL set_param llite.*.stats=0
13794
13795         # perform 2 reads and writes so MAX is different from SUM.
13796         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13797         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13798         cancel_lru_locks osc
13799         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13800         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13801
13802         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13803         stack_trap "rm -f $TMP/$tfile.tmp"
13804         while read name count samp unit min max sum sumsq; do
13805                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13806                 eval $name=$count || error "Wrong proc format"
13807
13808                 case $name in
13809                 read_bytes|write_bytes)
13810                         [[ "$unit" =~ "bytes" ]] ||
13811                                 error "unit is not 'bytes': $unit"
13812                         (( $count == 2 )) || error "count is not 2: $count"
13813                         (( $min == $PAGE_SIZE )) ||
13814                                 error "min is not $PAGE_SIZE: $min"
13815                         (( $max == $PAGE_SIZE )) ||
13816                                 error "max is not $PAGE_SIZE: $max"
13817                         (( $sum == $PAGE_SIZE * 2 )) ||
13818                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13819                         ;;
13820                 read|write)
13821                         [[ "$unit" =~ "usec" ]] ||
13822                                 error "unit is not 'usec': $unit"
13823                         ;;
13824                 *)      ;;
13825                 esac
13826         done < $TMP/$tfile.tmp
13827
13828         #check that we actually got some stats
13829         [ "$read_bytes" ] || error "Missing read_bytes stats"
13830         [ "$write_bytes" ] || error "Missing write_bytes stats"
13831         [ "$read_bytes" != 0 ] || error "no read done"
13832         [ "$write_bytes" != 0 ] || error "no write done"
13833 }
13834 run_test 127b "verify the llite client stats are sane"
13835
13836 test_127c() { # LU-12394
13837         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13838         local size
13839         local bsize
13840         local reads
13841         local writes
13842         local count
13843
13844         $LCTL set_param llite.*.extents_stats=1
13845         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13846
13847         # Use two stripes so there is enough space in default config
13848         $LFS setstripe -c 2 $DIR/$tfile
13849
13850         # Extent stats start at 0-4K and go in power of two buckets
13851         # LL_HIST_START = 12 --> 2^12 = 4K
13852         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13853         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13854         # small configs
13855         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13856                 do
13857                 # Write and read, 2x each, second time at a non-zero offset
13858                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13859                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13860                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13861                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13862                 rm -f $DIR/$tfile
13863         done
13864
13865         $LCTL get_param llite.*.extents_stats
13866
13867         count=2
13868         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13869                 do
13870                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13871                                 grep -m 1 $bsize)
13872                 reads=$(echo $bucket | awk '{print $5}')
13873                 writes=$(echo $bucket | awk '{print $9}')
13874                 [ "$reads" -eq $count ] ||
13875                         error "$reads reads in < $bsize bucket, expect $count"
13876                 [ "$writes" -eq $count ] ||
13877                         error "$writes writes in < $bsize bucket, expect $count"
13878         done
13879
13880         # Test mmap write and read
13881         $LCTL set_param llite.*.extents_stats=c
13882         size=512
13883         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13884         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13885         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13886
13887         $LCTL get_param llite.*.extents_stats
13888
13889         count=$(((size*1024) / PAGE_SIZE))
13890
13891         bsize=$((2 * PAGE_SIZE / 1024))K
13892
13893         bucket=$($LCTL get_param -n llite.*.extents_stats |
13894                         grep -m 1 $bsize)
13895         reads=$(echo $bucket | awk '{print $5}')
13896         writes=$(echo $bucket | awk '{print $9}')
13897         # mmap writes fault in the page first, creating an additonal read
13898         [ "$reads" -eq $((2 * count)) ] ||
13899                 error "$reads reads in < $bsize bucket, expect $count"
13900         [ "$writes" -eq $count ] ||
13901                 error "$writes writes in < $bsize bucket, expect $count"
13902 }
13903 run_test 127c "test llite extent stats with regular & mmap i/o"
13904
13905 test_128() { # bug 15212
13906         touch $DIR/$tfile
13907         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13908                 find $DIR/$tfile
13909                 find $DIR/$tfile
13910         EOF
13911
13912         result=$(grep error $TMP/$tfile.log)
13913         rm -f $DIR/$tfile $TMP/$tfile.log
13914         [ -z "$result" ] ||
13915                 error "consecutive find's under interactive lfs failed"
13916 }
13917 run_test 128 "interactive lfs for 2 consecutive find's"
13918
13919 set_dir_limits () {
13920         local mntdev
13921         local canondev
13922         local node
13923
13924         local ldproc=/proc/fs/ldiskfs
13925         local facets=$(get_facets MDS)
13926
13927         for facet in ${facets//,/ }; do
13928                 canondev=$(ldiskfs_canon \
13929                            *.$(convert_facet2label $facet).mntdev $facet)
13930                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13931                         ldproc=/sys/fs/ldiskfs
13932                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13933                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13934         done
13935 }
13936
13937 check_mds_dmesg() {
13938         local facets=$(get_facets MDS)
13939         for facet in ${facets//,/ }; do
13940                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13941         done
13942         return 1
13943 }
13944
13945 test_129() {
13946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13947         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13948                 skip "Need MDS version with at least 2.5.56"
13949         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13950                 skip_env "ldiskfs only test"
13951         fi
13952         remote_mds_nodsh && skip "remote MDS with nodsh"
13953
13954         local ENOSPC=28
13955         local has_warning=false
13956
13957         rm -rf $DIR/$tdir
13958         mkdir -p $DIR/$tdir
13959
13960         # block size of mds1
13961         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13962         set_dir_limits $maxsize $((maxsize * 6 / 8))
13963         stack_trap "set_dir_limits 0 0"
13964         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13965         local dirsize=$(stat -c%s "$DIR/$tdir")
13966         local nfiles=0
13967         while (( $dirsize <= $maxsize )); do
13968                 $MCREATE $DIR/$tdir/file_base_$nfiles
13969                 rc=$?
13970                 # check two errors:
13971                 # ENOSPC for ext4 max_dir_size, which has been used since
13972                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13973                 if (( rc == ENOSPC )); then
13974                         set_dir_limits 0 0
13975                         echo "rc=$rc returned as expected after $nfiles files"
13976
13977                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13978                                 error "create failed w/o dir size limit"
13979
13980                         # messages may be rate limited if test is run repeatedly
13981                         check_mds_dmesg '"is approaching max"' ||
13982                                 echo "warning message should be output"
13983                         check_mds_dmesg '"has reached max"' ||
13984                                 echo "reached message should be output"
13985
13986                         dirsize=$(stat -c%s "$DIR/$tdir")
13987
13988                         [[ $dirsize -ge $maxsize ]] && return 0
13989                         error "dirsize $dirsize < $maxsize after $nfiles files"
13990                 elif (( rc != 0 )); then
13991                         break
13992                 fi
13993                 nfiles=$((nfiles + 1))
13994                 dirsize=$(stat -c%s "$DIR/$tdir")
13995         done
13996
13997         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13998 }
13999 run_test 129 "test directory size limit ========================"
14000
14001 OLDIFS="$IFS"
14002 cleanup_130() {
14003         trap 0
14004         IFS="$OLDIFS"
14005 }
14006
14007 test_130a() {
14008         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14009         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14010
14011         trap cleanup_130 EXIT RETURN
14012
14013         local fm_file=$DIR/$tfile
14014         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14015         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14016                 error "dd failed for $fm_file"
14017
14018         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14019         filefrag -ves $fm_file
14020         local rc=$?
14021         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14022                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14023         (( $rc == 0 )) || error "filefrag $fm_file failed"
14024
14025         filefrag_op=$(filefrag -ve -k $fm_file |
14026                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14027         local lun=$($LFS getstripe -i $fm_file)
14028
14029         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14030         IFS=$'\n'
14031         local tot_len=0
14032         for line in $filefrag_op; do
14033                 local frag_lun=$(echo $line | cut -d: -f5)
14034                 local ext_len=$(echo $line | cut -d: -f4)
14035
14036                 if (( $frag_lun != $lun )); then
14037                         error "FIEMAP on 1-stripe file($fm_file) failed"
14038                         return
14039                 fi
14040                 (( tot_len += ext_len ))
14041         done
14042
14043         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14044                 error "FIEMAP on 1-stripe file($fm_file) failed"
14045                 return
14046         fi
14047
14048         echo "FIEMAP on single striped file succeeded"
14049 }
14050 run_test 130a "FIEMAP (1-stripe file)"
14051
14052 test_130b() {
14053         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14054
14055         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14056         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14057         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14058                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14059
14060         trap cleanup_130 EXIT RETURN
14061
14062         local fm_file=$DIR/$tfile
14063         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14064                 error "setstripe on $fm_file"
14065
14066         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14067                 error "dd failed on $fm_file"
14068
14069         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14070         filefrag_op=$(filefrag -ve -k $fm_file |
14071                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14072
14073         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14074                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14075
14076         IFS=$'\n'
14077         local tot_len=0
14078         local num_luns=1
14079
14080         for line in $filefrag_op; do
14081                 local frag_lun=$(echo $line | cut -d: -f5 |
14082                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14083                 local ext_len=$(echo $line | cut -d: -f4)
14084                 if (( $frag_lun != $last_lun )); then
14085                         if (( tot_len != 1024 )); then
14086                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14087                                 return
14088                         else
14089                                 (( num_luns += 1 ))
14090                                 tot_len=0
14091                         fi
14092                 fi
14093                 (( tot_len += ext_len ))
14094                 last_lun=$frag_lun
14095         done
14096         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14097                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14098                 return
14099         fi
14100
14101         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14102 }
14103 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14104
14105 test_130c() {
14106         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14107
14108         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14109         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14110         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14111                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14112
14113         trap cleanup_130 EXIT RETURN
14114
14115         local fm_file=$DIR/$tfile
14116         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14117
14118         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14119                 error "dd failed on $fm_file"
14120
14121         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14122         filefrag_op=$(filefrag -ve -k $fm_file |
14123                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14124
14125         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14126                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14127
14128         IFS=$'\n'
14129         local tot_len=0
14130         local num_luns=1
14131         for line in $filefrag_op; do
14132                 local frag_lun=$(echo $line | cut -d: -f5 |
14133                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14134                 local ext_len=$(echo $line | cut -d: -f4)
14135                 if (( $frag_lun != $last_lun )); then
14136                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14137                         if (( logical != 512 )); then
14138                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14139                                 return
14140                         fi
14141                         if (( tot_len != 512 )); then
14142                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14143                                 return
14144                         else
14145                                 (( num_luns += 1 ))
14146                                 tot_len=0
14147                         fi
14148                 fi
14149                 (( tot_len += ext_len ))
14150                 last_lun=$frag_lun
14151         done
14152         if (( num_luns != 2 || tot_len != 512 )); then
14153                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14154                 return
14155         fi
14156
14157         echo "FIEMAP on 2-stripe file with hole succeeded"
14158 }
14159 run_test 130c "FIEMAP (2-stripe file with hole)"
14160
14161 test_130d() {
14162         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14163
14164         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14165         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14166         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14167                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14168
14169         trap cleanup_130 EXIT RETURN
14170
14171         local fm_file=$DIR/$tfile
14172         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14173                         error "setstripe on $fm_file"
14174
14175         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14176         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14177                 error "dd failed on $fm_file"
14178
14179         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14180         filefrag_op=$(filefrag -ve -k $fm_file |
14181                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14182
14183         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14184                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14185
14186         IFS=$'\n'
14187         local tot_len=0
14188         local num_luns=1
14189         for line in $filefrag_op; do
14190                 local frag_lun=$(echo $line | cut -d: -f5 |
14191                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14192                 local ext_len=$(echo $line | cut -d: -f4)
14193                 if (( $frag_lun != $last_lun )); then
14194                         if (( tot_len != 1024 )); then
14195                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14196                                 return
14197                         else
14198                                 (( num_luns += 1 ))
14199                                 local tot_len=0
14200                         fi
14201                 fi
14202                 (( tot_len += ext_len ))
14203                 last_lun=$frag_lun
14204         done
14205         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14206                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14207                 return
14208         fi
14209
14210         echo "FIEMAP on N-stripe file succeeded"
14211 }
14212 run_test 130d "FIEMAP (N-stripe file)"
14213
14214 test_130e() {
14215         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14216
14217         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14218         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14219         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14220                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14221
14222         trap cleanup_130 EXIT RETURN
14223
14224         local fm_file=$DIR/$tfile
14225         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14226
14227         local num_blks=512
14228         local expected_len=$(( (num_blks / 2) * 64 ))
14229         for ((i = 0; i < $num_blks; i++)); do
14230                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14231                         conv=notrunc > /dev/null 2>&1
14232         done
14233
14234         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14235         filefrag_op=$(filefrag -ve -k $fm_file |
14236                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14237
14238         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14239
14240         IFS=$'\n'
14241         local tot_len=0
14242         local num_luns=1
14243         for line in $filefrag_op; do
14244                 local frag_lun=$(echo $line | cut -d: -f5)
14245                 local ext_len=$(echo $line | cut -d: -f4)
14246                 if (( $frag_lun != $last_lun )); then
14247                         if (( tot_len != $expected_len )); then
14248                                 error "OST$last_lun $tot_len != $expected_len"
14249                         else
14250                                 (( num_luns += 1 ))
14251                                 tot_len=0
14252                         fi
14253                 fi
14254                 (( tot_len += ext_len ))
14255                 last_lun=$frag_lun
14256         done
14257         if (( num_luns != 2 || tot_len != $expected_len )); then
14258                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14259         fi
14260
14261         echo "FIEMAP with continuation calls succeeded"
14262 }
14263 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14264
14265 test_130f() {
14266         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14267         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14268         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14269                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14270
14271         local fm_file=$DIR/$tfile
14272         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14273                 error "multiop create with lov_delay_create on $fm_file"
14274
14275         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14276         filefrag_extents=$(filefrag -vek $fm_file |
14277                            awk '/extents? found/ { print $2 }')
14278         if (( $filefrag_extents != 0 )); then
14279                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14280         fi
14281
14282         rm -f $fm_file
14283 }
14284 run_test 130f "FIEMAP (unstriped file)"
14285
14286 test_130g() {
14287         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14288                 skip "Need MDS version with at least 2.12.53 for overstriping"
14289         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14290         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14291         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14292                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14293
14294         local file=$DIR/$tfile
14295         local nr=$((OSTCOUNT * 100))
14296
14297         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14298
14299         stack_trap "rm -f $file"
14300         dd if=/dev/zero of=$file count=$nr bs=1M
14301         sync
14302         nr=$($LFS getstripe -c $file)
14303
14304         local extents=$(filefrag -v $file |
14305                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14306
14307         echo "filefrag list $extents extents in file with stripecount $nr"
14308         if (( extents < nr )); then
14309                 $LFS getstripe $file
14310                 filefrag -v $file
14311                 error "filefrag printed $extents < $nr extents"
14312         fi
14313 }
14314 run_test 130g "FIEMAP (overstripe file)"
14315
14316 # Test for writev/readv
14317 test_131a() {
14318         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14319                 error "writev test failed"
14320         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14321                 error "readv failed"
14322         rm -f $DIR/$tfile
14323 }
14324 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14325
14326 test_131b() {
14327         local fsize=$((524288 + 1048576 + 1572864))
14328         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14329                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14330                         error "append writev test failed"
14331
14332         ((fsize += 1572864 + 1048576))
14333         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14334                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14335                         error "append writev test failed"
14336         rm -f $DIR/$tfile
14337 }
14338 run_test 131b "test append writev"
14339
14340 test_131c() {
14341         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14342         error "NOT PASS"
14343 }
14344 run_test 131c "test read/write on file w/o objects"
14345
14346 test_131d() {
14347         rwv -f $DIR/$tfile -w -n 1 1572864
14348         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14349         if [ "$NOB" != 1572864 ]; then
14350                 error "Short read filed: read $NOB bytes instead of 1572864"
14351         fi
14352         rm -f $DIR/$tfile
14353 }
14354 run_test 131d "test short read"
14355
14356 test_131e() {
14357         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14358         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14359         error "read hitting hole failed"
14360         rm -f $DIR/$tfile
14361 }
14362 run_test 131e "test read hitting hole"
14363
14364 check_stats() {
14365         local facet=$1
14366         local op=$2
14367         local want=${3:-0}
14368         local res
14369
14370         # open             11 samples [usecs] 468 4793 13658 35791898
14371         case $facet in
14372         mds*) res=($(do_facet $facet \
14373                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14374                  ;;
14375         ost*) res=($(do_facet $facet \
14376                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14377                  ;;
14378         *) error "Wrong facet '$facet'" ;;
14379         esac
14380         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14381         # if $want is zero, it means any stat increment is ok.
14382         if (( $want > 0 )); then
14383                 local count=${res[1]}
14384
14385                 if (( $count != $want )); then
14386                         if [[ $facet =~ "mds" ]]; then
14387                                 do_nodes $(comma_list $(mdts_nodes)) \
14388                                         $LCTL get_param mdt.*.md_stats
14389                         else
14390                                 do_nodes $(comma_list $(osts-nodes)) \
14391                                         $LCTL get_param obdfilter.*.stats
14392                         fi
14393                         error "The $op counter on $facet is $count, not $want"
14394                 fi
14395         fi
14396 }
14397
14398 test_133a() {
14399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14400         remote_ost_nodsh && skip "remote OST with nodsh"
14401         remote_mds_nodsh && skip "remote MDS with nodsh"
14402         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14403                 skip_env "MDS doesn't support rename stats"
14404
14405         local testdir=$DIR/${tdir}/stats_testdir
14406
14407         mkdir -p $DIR/${tdir}
14408
14409         # clear stats.
14410         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14411         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14412
14413         # verify mdt stats first.
14414         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14415         check_stats $SINGLEMDS "mkdir" 1
14416
14417         # clear "open" from "lfs mkdir" above
14418         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14419         touch ${testdir}/${tfile} || error "touch failed"
14420         check_stats $SINGLEMDS "open" 1
14421         check_stats $SINGLEMDS "close" 1
14422         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14423                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14424                 check_stats $SINGLEMDS "mknod" 2
14425         }
14426         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14427         check_stats $SINGLEMDS "unlink" 1
14428         rm -f ${testdir}/${tfile} || error "file remove failed"
14429         check_stats $SINGLEMDS "unlink" 2
14430
14431         # remove working dir and check mdt stats again.
14432         rmdir ${testdir} || error "rmdir failed"
14433         check_stats $SINGLEMDS "rmdir" 1
14434
14435         local testdir1=$DIR/${tdir}/stats_testdir1
14436         mkdir_on_mdt0 -p ${testdir}
14437         mkdir_on_mdt0 -p ${testdir1}
14438         touch ${testdir1}/test1
14439         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14440         check_stats $SINGLEMDS "crossdir_rename" 1
14441
14442         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14443         check_stats $SINGLEMDS "samedir_rename" 1
14444
14445         rm -rf $DIR/${tdir}
14446 }
14447 run_test 133a "Verifying MDT stats ========================================"
14448
14449 test_133b() {
14450         local res
14451
14452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14453         remote_ost_nodsh && skip "remote OST with nodsh"
14454         remote_mds_nodsh && skip "remote MDS with nodsh"
14455
14456         local testdir=$DIR/${tdir}/stats_testdir
14457
14458         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14459         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14460         touch ${testdir}/${tfile} || error "touch failed"
14461         cancel_lru_locks mdc
14462
14463         # clear stats.
14464         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14465         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14466
14467         # extra mdt stats verification.
14468         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14469         check_stats $SINGLEMDS "setattr" 1
14470         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14471         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14472         then            # LU-1740
14473                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14474                 check_stats $SINGLEMDS "getattr" 1
14475         fi
14476         rm -rf $DIR/${tdir}
14477
14478         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14479         # so the check below is not reliable
14480         [ $MDSCOUNT -eq 1 ] || return 0
14481
14482         # Sleep to avoid a cached response.
14483         #define OBD_STATFS_CACHE_SECONDS 1
14484         sleep 2
14485         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14486         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14487         $LFS df || error "lfs failed"
14488         check_stats $SINGLEMDS "statfs" 1
14489
14490         # check aggregated statfs (LU-10018)
14491         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14492                 return 0
14493         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14494                 return 0
14495         sleep 2
14496         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14497         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14498         df $DIR
14499         check_stats $SINGLEMDS "statfs" 1
14500
14501         # We want to check that the client didn't send OST_STATFS to
14502         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14503         # extra care is needed here.
14504         if remote_mds; then
14505                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14506                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14507
14508                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14509                 [ "$res" ] && error "OST got STATFS"
14510         fi
14511
14512         return 0
14513 }
14514 run_test 133b "Verifying extra MDT stats =================================="
14515
14516 test_133c() {
14517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14518         remote_ost_nodsh && skip "remote OST with nodsh"
14519         remote_mds_nodsh && skip "remote MDS with nodsh"
14520
14521         local testdir=$DIR/$tdir/stats_testdir
14522
14523         test_mkdir -p $testdir
14524
14525         # verify obdfilter stats.
14526         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14527         sync
14528         cancel_lru_locks osc
14529         wait_delete_completed
14530
14531         # clear stats.
14532         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14533         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14534
14535         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14536                 error "dd failed"
14537         sync
14538         cancel_lru_locks osc
14539         check_stats ost1 "write" 1
14540
14541         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14542         check_stats ost1 "read" 1
14543
14544         > $testdir/$tfile || error "truncate failed"
14545         check_stats ost1 "punch" 1
14546
14547         rm -f $testdir/$tfile || error "file remove failed"
14548         wait_delete_completed
14549         check_stats ost1 "destroy" 1
14550
14551         rm -rf $DIR/$tdir
14552 }
14553 run_test 133c "Verifying OST stats ========================================"
14554
14555 order_2() {
14556         local value=$1
14557         local orig=$value
14558         local order=1
14559
14560         while [ $value -ge 2 ]; do
14561                 order=$((order*2))
14562                 value=$((value/2))
14563         done
14564
14565         if [ $orig -gt $order ]; then
14566                 order=$((order*2))
14567         fi
14568         echo $order
14569 }
14570
14571 size_in_KMGT() {
14572     local value=$1
14573     local size=('K' 'M' 'G' 'T');
14574     local i=0
14575     local size_string=$value
14576
14577     while [ $value -ge 1024 ]; do
14578         if [ $i -gt 3 ]; then
14579             #T is the biggest unit we get here, if that is bigger,
14580             #just return XXXT
14581             size_string=${value}T
14582             break
14583         fi
14584         value=$((value >> 10))
14585         if [ $value -lt 1024 ]; then
14586             size_string=${value}${size[$i]}
14587             break
14588         fi
14589         i=$((i + 1))
14590     done
14591
14592     echo $size_string
14593 }
14594
14595 get_rename_size() {
14596         local size=$1
14597         local context=${2:-.}
14598         local sample=$(do_facet $SINGLEMDS $LCTL \
14599                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14600                 grep -A1 $context |
14601                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14602         echo $sample
14603 }
14604
14605 test_133d() {
14606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14607         remote_ost_nodsh && skip "remote OST with nodsh"
14608         remote_mds_nodsh && skip "remote MDS with nodsh"
14609         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14610                 skip_env "MDS doesn't support rename stats"
14611
14612         local testdir1=$DIR/${tdir}/stats_testdir1
14613         local testdir2=$DIR/${tdir}/stats_testdir2
14614         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14615
14616         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14617
14618         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14619         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14620
14621         createmany -o $testdir1/test 512 || error "createmany failed"
14622
14623         # check samedir rename size
14624         mv ${testdir1}/test0 ${testdir1}/test_0
14625
14626         local testdir1_size=$(ls -l $DIR/${tdir} |
14627                 awk '/stats_testdir1/ {print $5}')
14628         local testdir2_size=$(ls -l $DIR/${tdir} |
14629                 awk '/stats_testdir2/ {print $5}')
14630
14631         testdir1_size=$(order_2 $testdir1_size)
14632         testdir2_size=$(order_2 $testdir2_size)
14633
14634         testdir1_size=$(size_in_KMGT $testdir1_size)
14635         testdir2_size=$(size_in_KMGT $testdir2_size)
14636
14637         echo "source rename dir size: ${testdir1_size}"
14638         echo "target rename dir size: ${testdir2_size}"
14639
14640         local cmd="do_facet $SINGLEMDS $LCTL "
14641         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14642
14643         eval $cmd || error "$cmd failed"
14644         local samedir=$($cmd | grep 'same_dir')
14645         local same_sample=$(get_rename_size $testdir1_size)
14646         [ -z "$samedir" ] && error "samedir_rename_size count error"
14647         [[ $same_sample -eq 1 ]] ||
14648                 error "samedir_rename_size error $same_sample"
14649         echo "Check same dir rename stats success"
14650
14651         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14652
14653         # check crossdir rename size
14654         mv ${testdir1}/test_0 ${testdir2}/test_0
14655
14656         testdir1_size=$(ls -l $DIR/${tdir} |
14657                 awk '/stats_testdir1/ {print $5}')
14658         testdir2_size=$(ls -l $DIR/${tdir} |
14659                 awk '/stats_testdir2/ {print $5}')
14660
14661         testdir1_size=$(order_2 $testdir1_size)
14662         testdir2_size=$(order_2 $testdir2_size)
14663
14664         testdir1_size=$(size_in_KMGT $testdir1_size)
14665         testdir2_size=$(size_in_KMGT $testdir2_size)
14666
14667         echo "source rename dir size: ${testdir1_size}"
14668         echo "target rename dir size: ${testdir2_size}"
14669
14670         eval $cmd || error "$cmd failed"
14671         local crossdir=$($cmd | grep 'crossdir')
14672         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14673         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14674         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14675         [[ $src_sample -eq 1 ]] ||
14676                 error "crossdir_rename_size error $src_sample"
14677         [[ $tgt_sample -eq 1 ]] ||
14678                 error "crossdir_rename_size error $tgt_sample"
14679         echo "Check cross dir rename stats success"
14680         rm -rf $DIR/${tdir}
14681 }
14682 run_test 133d "Verifying rename_stats ========================================"
14683
14684 test_133e() {
14685         remote_mds_nodsh && skip "remote MDS with nodsh"
14686         remote_ost_nodsh && skip "remote OST with nodsh"
14687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14688
14689         local testdir=$DIR/${tdir}/stats_testdir
14690         local ctr f0 f1 bs=32768 count=42 sum
14691
14692         mkdir -p ${testdir} || error "mkdir failed"
14693
14694         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14695
14696         for ctr in {write,read}_bytes; do
14697                 sync
14698                 cancel_lru_locks osc
14699
14700                 do_facet ost1 $LCTL set_param -n \
14701                         "obdfilter.*.exports.clear=clear"
14702
14703                 if [ $ctr = write_bytes ]; then
14704                         f0=/dev/zero
14705                         f1=${testdir}/${tfile}
14706                 else
14707                         f0=${testdir}/${tfile}
14708                         f1=/dev/null
14709                 fi
14710
14711                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14712                         error "dd failed"
14713                 sync
14714                 cancel_lru_locks osc
14715
14716                 sum=$(do_facet ost1 $LCTL get_param \
14717                         "obdfilter.*.exports.*.stats" |
14718                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14719                                 $1 == ctr { sum += $7 }
14720                                 END { printf("%0.0f", sum) }')
14721
14722                 if ((sum != bs * count)); then
14723                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14724                 fi
14725         done
14726
14727         rm -rf $DIR/${tdir}
14728 }
14729 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14730
14731 test_133f() {
14732         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14733                 skip "too old lustre for get_param -R ($facet_ver)"
14734
14735         # verifying readability.
14736         $LCTL get_param -R '*' &> /dev/null
14737
14738         # Verifing writability with badarea_io.
14739         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14740         local skipped_params='force_lbug|changelog_mask|daemon_file'
14741         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14742                 egrep -v "$skipped_params" |
14743                 xargs -n 1 find $proc_dirs -name |
14744                 xargs -n 1 badarea_io ||
14745                 error "client badarea_io failed"
14746
14747         # remount the FS in case writes/reads /proc break the FS
14748         cleanup || error "failed to unmount"
14749         setup || error "failed to setup"
14750 }
14751 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14752
14753 test_133g() {
14754         remote_mds_nodsh && skip "remote MDS with nodsh"
14755         remote_ost_nodsh && skip "remote OST with nodsh"
14756
14757         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14758         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14759         local facet
14760         for facet in mds1 ost1; do
14761                 local facet_ver=$(lustre_version_code $facet)
14762                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14763                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14764                 else
14765                         log "$facet: too old lustre for get_param -R"
14766                 fi
14767                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14768                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14769                                 tr -d = | egrep -v $skipped_params |
14770                                 xargs -n 1 find $proc_dirs -name |
14771                                 xargs -n 1 badarea_io" ||
14772                                         error "$facet badarea_io failed"
14773                 else
14774                         skip_noexit "$facet: too old lustre for get_param -R"
14775                 fi
14776         done
14777
14778         # remount the FS in case writes/reads /proc break the FS
14779         cleanup || error "failed to unmount"
14780         setup || error "failed to setup"
14781 }
14782 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14783
14784 test_133h() {
14785         remote_mds_nodsh && skip "remote MDS with nodsh"
14786         remote_ost_nodsh && skip "remote OST with nodsh"
14787         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14788                 skip "Need MDS version at least 2.9.54"
14789
14790         local facet
14791         for facet in client mds1 ost1; do
14792                 # Get the list of files that are missing the terminating newline
14793                 local plist=$(do_facet $facet
14794                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14795                 local ent
14796                 for ent in $plist; do
14797                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14798                                 awk -v FS='\v' -v RS='\v\v' \
14799                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14800                                         print FILENAME}'" 2>/dev/null)
14801                         [ -z $missing ] || {
14802                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14803                                 error "file does not end with newline: $facet-$ent"
14804                         }
14805                 done
14806         done
14807 }
14808 run_test 133h "Proc files should end with newlines"
14809
14810 test_134a() {
14811         remote_mds_nodsh && skip "remote MDS with nodsh"
14812         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14813                 skip "Need MDS version at least 2.7.54"
14814
14815         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14816         cancel_lru_locks mdc
14817
14818         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14819         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14820         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14821
14822         local nr=1000
14823         createmany -o $DIR/$tdir/f $nr ||
14824                 error "failed to create $nr files in $DIR/$tdir"
14825         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14826
14827         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14828         do_facet mds1 $LCTL set_param fail_loc=0x327
14829         do_facet mds1 $LCTL set_param fail_val=500
14830         touch $DIR/$tdir/m
14831
14832         echo "sleep 10 seconds ..."
14833         sleep 10
14834         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14835
14836         do_facet mds1 $LCTL set_param fail_loc=0
14837         do_facet mds1 $LCTL set_param fail_val=0
14838         [ $lck_cnt -lt $unused ] ||
14839                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14840
14841         rm $DIR/$tdir/m
14842         unlinkmany $DIR/$tdir/f $nr
14843 }
14844 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14845
14846 test_134b() {
14847         remote_mds_nodsh && skip "remote MDS with nodsh"
14848         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14849                 skip "Need MDS version at least 2.7.54"
14850
14851         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14852         cancel_lru_locks mdc
14853
14854         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14855                         ldlm.lock_reclaim_threshold_mb)
14856         # disable reclaim temporarily
14857         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14858
14859         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14860         do_facet mds1 $LCTL set_param fail_loc=0x328
14861         do_facet mds1 $LCTL set_param fail_val=500
14862
14863         $LCTL set_param debug=+trace
14864
14865         local nr=600
14866         createmany -o $DIR/$tdir/f $nr &
14867         local create_pid=$!
14868
14869         echo "Sleep $TIMEOUT seconds ..."
14870         sleep $TIMEOUT
14871         if ! ps -p $create_pid  > /dev/null 2>&1; then
14872                 do_facet mds1 $LCTL set_param fail_loc=0
14873                 do_facet mds1 $LCTL set_param fail_val=0
14874                 do_facet mds1 $LCTL set_param \
14875                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14876                 error "createmany finished incorrectly!"
14877         fi
14878         do_facet mds1 $LCTL set_param fail_loc=0
14879         do_facet mds1 $LCTL set_param fail_val=0
14880         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14881         wait $create_pid || return 1
14882
14883         unlinkmany $DIR/$tdir/f $nr
14884 }
14885 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14886
14887 test_135() {
14888         remote_mds_nodsh && skip "remote MDS with nodsh"
14889         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14890                 skip "Need MDS version at least 2.13.50"
14891         local fname
14892
14893         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14894
14895 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14896         #set only one record at plain llog
14897         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14898
14899         #fill already existed plain llog each 64767
14900         #wrapping whole catalog
14901         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14902
14903         createmany -o $DIR/$tdir/$tfile_ 64700
14904         for (( i = 0; i < 64700; i = i + 2 ))
14905         do
14906                 rm $DIR/$tdir/$tfile_$i &
14907                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14908                 local pid=$!
14909                 wait $pid
14910         done
14911
14912         #waiting osp synchronization
14913         wait_delete_completed
14914 }
14915 run_test 135 "Race catalog processing"
14916
14917 test_136() {
14918         remote_mds_nodsh && skip "remote MDS with nodsh"
14919         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14920                 skip "Need MDS version at least 2.13.50"
14921         local fname
14922
14923         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14924         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14925         #set only one record at plain llog
14926 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14928
14929         #fill already existed 2 plain llogs each 64767
14930         #wrapping whole catalog
14931         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14932         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14933         wait_delete_completed
14934
14935         createmany -o $DIR/$tdir/$tfile_ 10
14936         sleep 25
14937
14938         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14939         for (( i = 0; i < 10; i = i + 3 ))
14940         do
14941                 rm $DIR/$tdir/$tfile_$i &
14942                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14943                 local pid=$!
14944                 wait $pid
14945                 sleep 7
14946                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14947         done
14948
14949         #waiting osp synchronization
14950         wait_delete_completed
14951 }
14952 run_test 136 "Race catalog processing 2"
14953
14954 test_140() { #bug-17379
14955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14956
14957         test_mkdir $DIR/$tdir
14958         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14959         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14960
14961         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14962         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14963         local i=0
14964         while i=$((i + 1)); do
14965                 test_mkdir $i
14966                 cd $i || error "Changing to $i"
14967                 ln -s ../stat stat || error "Creating stat symlink"
14968                 # Read the symlink until ELOOP present,
14969                 # not LBUGing the system is considered success,
14970                 # we didn't overrun the stack.
14971                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14972                 if [ $ret -ne 0 ]; then
14973                         if [ $ret -eq 40 ]; then
14974                                 break  # -ELOOP
14975                         else
14976                                 error "Open stat symlink"
14977                                         return
14978                         fi
14979                 fi
14980         done
14981         i=$((i - 1))
14982         echo "The symlink depth = $i"
14983         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14984                 error "Invalid symlink depth"
14985
14986         # Test recursive symlink
14987         ln -s symlink_self symlink_self
14988         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14989         echo "open symlink_self returns $ret"
14990         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14991 }
14992 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14993
14994 test_150a() {
14995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14996
14997         local TF="$TMP/$tfile"
14998
14999         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15000         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15001         cp $TF $DIR/$tfile
15002         cancel_lru_locks $OSC
15003         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15004         remount_client $MOUNT
15005         df -P $MOUNT
15006         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15007
15008         $TRUNCATE $TF 6000
15009         $TRUNCATE $DIR/$tfile 6000
15010         cancel_lru_locks $OSC
15011         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15012
15013         echo "12345" >>$TF
15014         echo "12345" >>$DIR/$tfile
15015         cancel_lru_locks $OSC
15016         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15017
15018         echo "12345" >>$TF
15019         echo "12345" >>$DIR/$tfile
15020         cancel_lru_locks $OSC
15021         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15022 }
15023 run_test 150a "truncate/append tests"
15024
15025 test_150b() {
15026         check_set_fallocate_or_skip
15027         local out
15028
15029         touch $DIR/$tfile
15030         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15031         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15032                 skip_eopnotsupp "$out|check_fallocate failed"
15033 }
15034 run_test 150b "Verify fallocate (prealloc) functionality"
15035
15036 test_150bb() {
15037         check_set_fallocate_or_skip
15038
15039         touch $DIR/$tfile
15040         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15041         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15042         > $DIR/$tfile
15043         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15044         # precomputed md5sum for 20MB of zeroes
15045         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15046         local sum=($(md5sum $DIR/$tfile))
15047
15048         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15049
15050         check_set_fallocate 1
15051
15052         > $DIR/$tfile
15053         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15054         sum=($(md5sum $DIR/$tfile))
15055
15056         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15057 }
15058 run_test 150bb "Verify fallocate modes both zero space"
15059
15060 test_150c() {
15061         check_set_fallocate_or_skip
15062         local striping="-c2"
15063
15064         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15065         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15066         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15067         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15068         local want=$((OSTCOUNT * 1048576))
15069
15070         # Must allocate all requested space, not more than 5% extra
15071         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15072                 error "bytes $bytes is not $want"
15073
15074         rm -f $DIR/$tfile
15075
15076         echo "verify fallocate on PFL file"
15077
15078         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15079
15080         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15081                 error "Create $DIR/$tfile failed"
15082         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15083         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15084         want=$((512 * 1048576))
15085
15086         # Must allocate all requested space, not more than 5% extra
15087         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15088                 error "bytes $bytes is not $want"
15089 }
15090 run_test 150c "Verify fallocate Size and Blocks"
15091
15092 test_150d() {
15093         check_set_fallocate_or_skip
15094         local striping="-c2"
15095
15096         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15097
15098         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15099         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15100                 error "setstripe failed"
15101         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15102         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15103         local want=$((OSTCOUNT * 1048576))
15104
15105         # Must allocate all requested space, not more than 5% extra
15106         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15107                 error "bytes $bytes is not $want"
15108 }
15109 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15110
15111 test_150e() {
15112         check_set_fallocate_or_skip
15113
15114         echo "df before:"
15115         $LFS df
15116         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15117         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15118                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15119
15120         # Find OST with Minimum Size
15121         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15122                        sort -un | head -1)
15123
15124         # Get 100MB per OST of the available space to reduce run time
15125         # else 60% of the available space if we are running SLOW tests
15126         if [ $SLOW == "no" ]; then
15127                 local space=$((1024 * 100 * OSTCOUNT))
15128         else
15129                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15130         fi
15131
15132         fallocate -l${space}k $DIR/$tfile ||
15133                 error "fallocate ${space}k $DIR/$tfile failed"
15134         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15135
15136         # get size immediately after fallocate. This should be correctly
15137         # updated
15138         local size=$(stat -c '%s' $DIR/$tfile)
15139         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15140
15141         # Sleep for a while for statfs to get updated. And not pull from cache.
15142         sleep 2
15143
15144         echo "df after fallocate:"
15145         $LFS df
15146
15147         (( size / 1024 == space )) || error "size $size != requested $space"
15148         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15149                 error "used $used < space $space"
15150
15151         rm $DIR/$tfile || error "rm failed"
15152         sync
15153         wait_delete_completed
15154
15155         echo "df after unlink:"
15156         $LFS df
15157 }
15158 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15159
15160 test_150f() {
15161         local size
15162         local blocks
15163         local want_size_before=20480 # in bytes
15164         local want_blocks_before=40 # 512 sized blocks
15165         local want_blocks_after=24  # 512 sized blocks
15166         local length=$(((want_blocks_before - want_blocks_after) * 512))
15167
15168         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15169                 skip "need at least 2.14.0 for fallocate punch"
15170
15171         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15172                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15173         fi
15174
15175         check_set_fallocate_or_skip
15176         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15177
15178         [[ "x$DOM" == "xyes" ]] &&
15179                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15180
15181         echo "Verify fallocate punch: Range within the file range"
15182         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15183                 error "dd failed for bs 4096 and count 5"
15184
15185         # Call fallocate with punch range which is within the file range
15186         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15187                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15188         # client must see changes immediately after fallocate
15189         size=$(stat -c '%s' $DIR/$tfile)
15190         blocks=$(stat -c '%b' $DIR/$tfile)
15191
15192         # Verify punch worked.
15193         (( blocks == want_blocks_after )) ||
15194                 error "punch failed: blocks $blocks != $want_blocks_after"
15195
15196         (( size == want_size_before )) ||
15197                 error "punch failed: size $size != $want_size_before"
15198
15199         # Verify there is hole in file
15200         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15201         # precomputed md5sum
15202         local expect="4a9a834a2db02452929c0a348273b4aa"
15203
15204         cksum=($(md5sum $DIR/$tfile))
15205         [[ "${cksum[0]}" == "$expect" ]] ||
15206                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15207
15208         # Start second sub-case for fallocate punch.
15209         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15210         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15211                 error "dd failed for bs 4096 and count 5"
15212
15213         # Punch range less than block size will have no change in block count
15214         want_blocks_after=40  # 512 sized blocks
15215
15216         # Punch overlaps two blocks and less than blocksize
15217         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15218                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15219         size=$(stat -c '%s' $DIR/$tfile)
15220         blocks=$(stat -c '%b' $DIR/$tfile)
15221
15222         # Verify punch worked.
15223         (( blocks == want_blocks_after )) ||
15224                 error "punch failed: blocks $blocks != $want_blocks_after"
15225
15226         (( size == want_size_before )) ||
15227                 error "punch failed: size $size != $want_size_before"
15228
15229         # Verify if range is really zero'ed out. We expect Zeros.
15230         # precomputed md5sum
15231         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15232         cksum=($(md5sum $DIR/$tfile))
15233         [[ "${cksum[0]}" == "$expect" ]] ||
15234                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15235 }
15236 run_test 150f "Verify fallocate punch functionality"
15237
15238 test_150g() {
15239         local space
15240         local size
15241         local blocks
15242         local blocks_after
15243         local size_after
15244         local BS=4096 # Block size in bytes
15245
15246         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15247                 skip "need at least 2.14.0 for fallocate punch"
15248
15249         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15250                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15251         fi
15252
15253         check_set_fallocate_or_skip
15254         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15255
15256         if [[ "x$DOM" == "xyes" ]]; then
15257                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15258                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15259         else
15260                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15261                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15262         fi
15263
15264         # Get 100MB per OST of the available space to reduce run time
15265         # else 60% of the available space if we are running SLOW tests
15266         if [ $SLOW == "no" ]; then
15267                 space=$((1024 * 100 * OSTCOUNT))
15268         else
15269                 # Find OST with Minimum Size
15270                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15271                         sort -un | head -1)
15272                 echo "min size OST: $space"
15273                 space=$(((space * 60)/100 * OSTCOUNT))
15274         fi
15275         # space in 1k units, round to 4k blocks
15276         local blkcount=$((space * 1024 / $BS))
15277
15278         echo "Verify fallocate punch: Very large Range"
15279         fallocate -l${space}k $DIR/$tfile ||
15280                 error "fallocate ${space}k $DIR/$tfile failed"
15281         # write 1M at the end, start and in the middle
15282         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15283                 error "dd failed: bs $BS count 256"
15284         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15285                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15286         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15287                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15288
15289         # Gather stats.
15290         size=$(stat -c '%s' $DIR/$tfile)
15291
15292         # gather punch length.
15293         local punch_size=$((size - (BS * 2)))
15294
15295         echo "punch_size = $punch_size"
15296         echo "size - punch_size: $((size - punch_size))"
15297         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15298
15299         # Call fallocate to punch all except 2 blocks. We leave the
15300         # first and the last block
15301         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15302         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15303                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15304
15305         size_after=$(stat -c '%s' $DIR/$tfile)
15306         blocks_after=$(stat -c '%b' $DIR/$tfile)
15307
15308         # Verify punch worked.
15309         # Size should be kept
15310         (( size == size_after )) ||
15311                 error "punch failed: size $size != $size_after"
15312
15313         # two 4k data blocks to remain plus possible 1 extra extent block
15314         (( blocks_after <= ((BS / 512) * 3) )) ||
15315                 error "too many blocks remains: $blocks_after"
15316
15317         # Verify that file has hole between the first and the last blocks
15318         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15319         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15320
15321         echo "Hole at [$hole_start, $hole_end)"
15322         (( hole_start == BS )) ||
15323                 error "no hole at offset $BS after punch"
15324
15325         (( hole_end == BS + punch_size )) ||
15326                 error "data at offset $hole_end < $((BS + punch_size))"
15327 }
15328 run_test 150g "Verify fallocate punch on large range"
15329
15330 test_150h() {
15331         local file=$DIR/$tfile
15332         local size
15333
15334         check_set_fallocate_or_skip
15335         statx_supported || skip_env "Test must be statx() syscall supported"
15336
15337         # fallocate() does not update the size information on the MDT
15338         fallocate -l 16K $file || error "failed to fallocate $file"
15339         cancel_lru_locks $OSC
15340         # STATX with cached-always mode will not send glimpse RPCs to OST,
15341         # it uses the caching attrs on the client side as much as possible.
15342         size=$($STATX --cached=always -c %s $file)
15343         [ $size == 16384 ] ||
15344                 error "size after fallocate() is $size, expected 16384"
15345 }
15346 run_test 150h "Verify extend fallocate updates the file size"
15347
15348 #LU-2902 roc_hit was not able to read all values from lproc
15349 function roc_hit_init() {
15350         local list=$(comma_list $(osts_nodes))
15351         local dir=$DIR/$tdir-check
15352         local file=$dir/$tfile
15353         local BEFORE
15354         local AFTER
15355         local idx
15356
15357         test_mkdir $dir
15358         #use setstripe to do a write to every ost
15359         for i in $(seq 0 $((OSTCOUNT-1))); do
15360                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15361                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15362                 idx=$(printf %04x $i)
15363                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15364                         awk '$1 == "cache_access" {sum += $7}
15365                                 END { printf("%0.0f", sum) }')
15366
15367                 cancel_lru_locks osc
15368                 cat $file >/dev/null
15369
15370                 AFTER=$(get_osd_param $list *OST*$idx stats |
15371                         awk '$1 == "cache_access" {sum += $7}
15372                                 END { printf("%0.0f", sum) }')
15373
15374                 echo BEFORE:$BEFORE AFTER:$AFTER
15375                 if ! let "AFTER - BEFORE == 4"; then
15376                         rm -rf $dir
15377                         error "roc_hit is not safe to use"
15378                 fi
15379                 rm $file
15380         done
15381
15382         rm -rf $dir
15383 }
15384
15385 function roc_hit() {
15386         local list=$(comma_list $(osts_nodes))
15387         echo $(get_osd_param $list '' stats |
15388                 awk '$1 == "cache_hit" {sum += $7}
15389                         END { printf("%0.0f", sum) }')
15390 }
15391
15392 function set_cache() {
15393         local on=1
15394
15395         if [ "$2" == "off" ]; then
15396                 on=0;
15397         fi
15398         local list=$(comma_list $(osts_nodes))
15399         set_osd_param $list '' $1_cache_enable $on
15400
15401         cancel_lru_locks osc
15402 }
15403
15404 test_151() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         remote_ost_nodsh && skip "remote OST with nodsh"
15407
15408         local CPAGES=3
15409         local list=$(comma_list $(osts_nodes))
15410
15411         # check whether obdfilter is cache capable at all
15412         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15413                 skip "not cache-capable obdfilter"
15414         fi
15415
15416         # check cache is enabled on all obdfilters
15417         if get_osd_param $list '' read_cache_enable | grep 0; then
15418                 skip "oss cache is disabled"
15419         fi
15420
15421         set_osd_param $list '' writethrough_cache_enable 1
15422
15423         # check write cache is enabled on all obdfilters
15424         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15425                 skip "oss write cache is NOT enabled"
15426         fi
15427
15428         roc_hit_init
15429
15430         #define OBD_FAIL_OBD_NO_LRU  0x609
15431         do_nodes $list $LCTL set_param fail_loc=0x609
15432
15433         # pages should be in the case right after write
15434         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15435                 error "dd failed"
15436
15437         local BEFORE=$(roc_hit)
15438         cancel_lru_locks osc
15439         cat $DIR/$tfile >/dev/null
15440         local AFTER=$(roc_hit)
15441
15442         do_nodes $list $LCTL set_param fail_loc=0
15443
15444         if ! let "AFTER - BEFORE == CPAGES"; then
15445                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15446         fi
15447
15448         cancel_lru_locks osc
15449         # invalidates OST cache
15450         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15451         set_osd_param $list '' read_cache_enable 0
15452         cat $DIR/$tfile >/dev/null
15453
15454         # now data shouldn't be found in the cache
15455         BEFORE=$(roc_hit)
15456         cancel_lru_locks osc
15457         cat $DIR/$tfile >/dev/null
15458         AFTER=$(roc_hit)
15459         if let "AFTER - BEFORE != 0"; then
15460                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15461         fi
15462
15463         set_osd_param $list '' read_cache_enable 1
15464         rm -f $DIR/$tfile
15465 }
15466 run_test 151 "test cache on oss and controls ==============================="
15467
15468 test_152() {
15469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15470
15471         local TF="$TMP/$tfile"
15472
15473         # simulate ENOMEM during write
15474 #define OBD_FAIL_OST_NOMEM      0x226
15475         lctl set_param fail_loc=0x80000226
15476         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15477         cp $TF $DIR/$tfile
15478         sync || error "sync failed"
15479         lctl set_param fail_loc=0
15480
15481         # discard client's cache
15482         cancel_lru_locks osc
15483
15484         # simulate ENOMEM during read
15485         lctl set_param fail_loc=0x80000226
15486         cmp $TF $DIR/$tfile || error "cmp failed"
15487         lctl set_param fail_loc=0
15488
15489         rm -f $TF
15490 }
15491 run_test 152 "test read/write with enomem ============================"
15492
15493 test_153() {
15494         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15495 }
15496 run_test 153 "test if fdatasync does not crash ======================="
15497
15498 dot_lustre_fid_permission_check() {
15499         local fid=$1
15500         local ffid=$MOUNT/.lustre/fid/$fid
15501         local test_dir=$2
15502
15503         echo "stat fid $fid"
15504         stat $ffid || error "stat $ffid failed."
15505         echo "touch fid $fid"
15506         touch $ffid || error "touch $ffid failed."
15507         echo "write to fid $fid"
15508         cat /etc/hosts > $ffid || error "write $ffid failed."
15509         echo "read fid $fid"
15510         diff /etc/hosts $ffid || error "read $ffid failed."
15511         echo "append write to fid $fid"
15512         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15513         echo "rename fid $fid"
15514         mv $ffid $test_dir/$tfile.1 &&
15515                 error "rename $ffid to $tfile.1 should fail."
15516         touch $test_dir/$tfile.1
15517         mv $test_dir/$tfile.1 $ffid &&
15518                 error "rename $tfile.1 to $ffid should fail."
15519         rm -f $test_dir/$tfile.1
15520         echo "truncate fid $fid"
15521         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15522         echo "link fid $fid"
15523         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15524         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15525                 echo "setfacl fid $fid"
15526                 setfacl -R -m u:$USER0:rwx $ffid ||
15527                         error "setfacl $ffid failed"
15528                 echo "getfacl fid $fid"
15529                 getfacl $ffid || error "getfacl $ffid failed."
15530         fi
15531         echo "unlink fid $fid"
15532         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15533         echo "mknod fid $fid"
15534         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15535
15536         fid=[0xf00000400:0x1:0x0]
15537         ffid=$MOUNT/.lustre/fid/$fid
15538
15539         echo "stat non-exist fid $fid"
15540         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15541         echo "write to non-exist fid $fid"
15542         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15543         echo "link new fid $fid"
15544         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15545
15546         mkdir -p $test_dir/$tdir
15547         touch $test_dir/$tdir/$tfile
15548         fid=$($LFS path2fid $test_dir/$tdir)
15549         rc=$?
15550         [ $rc -ne 0 ] &&
15551                 error "error: could not get fid for $test_dir/$dir/$tfile."
15552
15553         ffid=$MOUNT/.lustre/fid/$fid
15554
15555         echo "ls $fid"
15556         ls $ffid || error "ls $ffid failed."
15557         echo "touch $fid/$tfile.1"
15558         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15559
15560         echo "touch $MOUNT/.lustre/fid/$tfile"
15561         touch $MOUNT/.lustre/fid/$tfile && \
15562                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15563
15564         echo "setxattr to $MOUNT/.lustre/fid"
15565         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15566
15567         echo "listxattr for $MOUNT/.lustre/fid"
15568         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15569
15570         echo "delxattr from $MOUNT/.lustre/fid"
15571         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15572
15573         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15574         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15575                 error "touch invalid fid should fail."
15576
15577         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15578         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15579                 error "touch non-normal fid should fail."
15580
15581         echo "rename $tdir to $MOUNT/.lustre/fid"
15582         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15583                 error "rename to $MOUNT/.lustre/fid should fail."
15584
15585         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15586         then            # LU-3547
15587                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15588                 local new_obf_mode=777
15589
15590                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15591                 chmod $new_obf_mode $DIR/.lustre/fid ||
15592                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15593
15594                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15595                 [ $obf_mode -eq $new_obf_mode ] ||
15596                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15597
15598                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15599                 chmod $old_obf_mode $DIR/.lustre/fid ||
15600                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15601         fi
15602
15603         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15604         fid=$($LFS path2fid $test_dir/$tfile-2)
15605
15606         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15607         then # LU-5424
15608                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15609                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15610                         error "create lov data thru .lustre failed"
15611         fi
15612         echo "cp /etc/passwd $test_dir/$tfile-2"
15613         cp /etc/passwd $test_dir/$tfile-2 ||
15614                 error "copy to $test_dir/$tfile-2 failed."
15615         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15616         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15617                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15618
15619         rm -rf $test_dir/tfile.lnk
15620         rm -rf $test_dir/$tfile-2
15621 }
15622
15623 test_154A() {
15624         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15625                 skip "Need MDS version at least 2.4.1"
15626
15627         local tf=$DIR/$tfile
15628         touch $tf
15629
15630         local fid=$($LFS path2fid $tf)
15631         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15632
15633         # check that we get the same pathname back
15634         local rootpath
15635         local found
15636         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15637                 echo "$rootpath $fid"
15638                 found=$($LFS fid2path $rootpath "$fid")
15639                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15640                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15641         done
15642
15643         # check wrong root path format
15644         rootpath=$MOUNT"_wrong"
15645         found=$($LFS fid2path $rootpath "$fid")
15646         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15647 }
15648 run_test 154A "lfs path2fid and fid2path basic checks"
15649
15650 test_154B() {
15651         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15652                 skip "Need MDS version at least 2.4.1"
15653
15654         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15655         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15656         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15657         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15658
15659         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15660         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15661
15662         # check that we get the same pathname
15663         echo "PFID: $PFID, name: $name"
15664         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15665         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15666         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15667                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15668
15669         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15670 }
15671 run_test 154B "verify the ll_decode_linkea tool"
15672
15673 test_154a() {
15674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15675         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15676         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15677                 skip "Need MDS version at least 2.2.51"
15678         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15679
15680         cp /etc/hosts $DIR/$tfile
15681
15682         fid=$($LFS path2fid $DIR/$tfile)
15683         rc=$?
15684         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15685
15686         dot_lustre_fid_permission_check "$fid" $DIR ||
15687                 error "dot lustre permission check $fid failed"
15688
15689         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15690
15691         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15692
15693         touch $MOUNT/.lustre/file &&
15694                 error "creation is not allowed under .lustre"
15695
15696         mkdir $MOUNT/.lustre/dir &&
15697                 error "mkdir is not allowed under .lustre"
15698
15699         rm -rf $DIR/$tfile
15700 }
15701 run_test 154a "Open-by-FID"
15702
15703 test_154b() {
15704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15705         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15707         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15708                 skip "Need MDS version at least 2.2.51"
15709
15710         local remote_dir=$DIR/$tdir/remote_dir
15711         local MDTIDX=1
15712         local rc=0
15713
15714         mkdir -p $DIR/$tdir
15715         $LFS mkdir -i $MDTIDX $remote_dir ||
15716                 error "create remote directory failed"
15717
15718         cp /etc/hosts $remote_dir/$tfile
15719
15720         fid=$($LFS path2fid $remote_dir/$tfile)
15721         rc=$?
15722         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15723
15724         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15725                 error "dot lustre permission check $fid failed"
15726         rm -rf $DIR/$tdir
15727 }
15728 run_test 154b "Open-by-FID for remote directory"
15729
15730 test_154c() {
15731         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15732                 skip "Need MDS version at least 2.4.1"
15733
15734         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15735         local FID1=$($LFS path2fid $DIR/$tfile.1)
15736         local FID2=$($LFS path2fid $DIR/$tfile.2)
15737         local FID3=$($LFS path2fid $DIR/$tfile.3)
15738
15739         local N=1
15740         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15741                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15742                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15743                 local want=FID$N
15744                 [ "$FID" = "${!want}" ] ||
15745                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15746                 N=$((N + 1))
15747         done
15748
15749         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15750         do
15751                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15752                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15753                 N=$((N + 1))
15754         done
15755 }
15756 run_test 154c "lfs path2fid and fid2path multiple arguments"
15757
15758 test_154d() {
15759         remote_mds_nodsh && skip "remote MDS with nodsh"
15760         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15761                 skip "Need MDS version at least 2.5.53"
15762
15763         if remote_mds; then
15764                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15765         else
15766                 nid="0@lo"
15767         fi
15768         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15769         local fd
15770         local cmd
15771
15772         rm -f $DIR/$tfile
15773         touch $DIR/$tfile
15774
15775         local fid=$($LFS path2fid $DIR/$tfile)
15776         # Open the file
15777         fd=$(free_fd)
15778         cmd="exec $fd<$DIR/$tfile"
15779         eval $cmd
15780         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15781         echo "$fid_list" | grep "$fid"
15782         rc=$?
15783
15784         cmd="exec $fd>/dev/null"
15785         eval $cmd
15786         if [ $rc -ne 0 ]; then
15787                 error "FID $fid not found in open files list $fid_list"
15788         fi
15789 }
15790 run_test 154d "Verify open file fid"
15791
15792 test_154e()
15793 {
15794         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15795                 skip "Need MDS version at least 2.6.50"
15796
15797         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15798                 error ".lustre returned by readdir"
15799         fi
15800 }
15801 run_test 154e ".lustre is not returned by readdir"
15802
15803 test_154f() {
15804         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15805
15806         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15807         mkdir_on_mdt0 $DIR/$tdir
15808         # test dirs inherit from its stripe
15809         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15810         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15811         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15812         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15813         touch $DIR/f
15814
15815         # get fid of parents
15816         local FID0=$($LFS path2fid $DIR/$tdir)
15817         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15818         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15819         local FID3=$($LFS path2fid $DIR)
15820
15821         # check that path2fid --parents returns expected <parent_fid>/name
15822         # 1) test for a directory (single parent)
15823         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15824         [ "$parent" == "$FID0/foo1" ] ||
15825                 error "expected parent: $FID0/foo1, got: $parent"
15826
15827         # 2) test for a file with nlink > 1 (multiple parents)
15828         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15829         echo "$parent" | grep -F "$FID1/$tfile" ||
15830                 error "$FID1/$tfile not returned in parent list"
15831         echo "$parent" | grep -F "$FID2/link" ||
15832                 error "$FID2/link not returned in parent list"
15833
15834         # 3) get parent by fid
15835         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15836         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15837         echo "$parent" | grep -F "$FID1/$tfile" ||
15838                 error "$FID1/$tfile not returned in parent list (by fid)"
15839         echo "$parent" | grep -F "$FID2/link" ||
15840                 error "$FID2/link not returned in parent list (by fid)"
15841
15842         # 4) test for entry in root directory
15843         parent=$($LFS path2fid --parents $DIR/f)
15844         echo "$parent" | grep -F "$FID3/f" ||
15845                 error "$FID3/f not returned in parent list"
15846
15847         # 5) test it on root directory
15848         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15849                 error "$MOUNT should not have parents"
15850
15851         # enable xattr caching and check that linkea is correctly updated
15852         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15853         save_lustre_params client "llite.*.xattr_cache" > $save
15854         lctl set_param llite.*.xattr_cache 1
15855
15856         # 6.1) linkea update on rename
15857         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15858
15859         # get parents by fid
15860         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15861         # foo1 should no longer be returned in parent list
15862         echo "$parent" | grep -F "$FID1" &&
15863                 error "$FID1 should no longer be in parent list"
15864         # the new path should appear
15865         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15866                 error "$FID2/$tfile.moved is not in parent list"
15867
15868         # 6.2) linkea update on unlink
15869         rm -f $DIR/$tdir/foo2/link
15870         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15871         # foo2/link should no longer be returned in parent list
15872         echo "$parent" | grep -F "$FID2/link" &&
15873                 error "$FID2/link should no longer be in parent list"
15874         true
15875
15876         rm -f $DIR/f
15877         restore_lustre_params < $save
15878         rm -f $save
15879 }
15880 run_test 154f "get parent fids by reading link ea"
15881
15882 test_154g()
15883 {
15884         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15885            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15886                 skip "Need MDS version at least 2.6.92"
15887
15888         mkdir_on_mdt0 $DIR/$tdir
15889         llapi_fid_test -d $DIR/$tdir
15890 }
15891 run_test 154g "various llapi FID tests"
15892
15893 test_155_small_load() {
15894     local temp=$TMP/$tfile
15895     local file=$DIR/$tfile
15896
15897     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15898         error "dd of=$temp bs=6096 count=1 failed"
15899     cp $temp $file
15900     cancel_lru_locks $OSC
15901     cmp $temp $file || error "$temp $file differ"
15902
15903     $TRUNCATE $temp 6000
15904     $TRUNCATE $file 6000
15905     cmp $temp $file || error "$temp $file differ (truncate1)"
15906
15907     echo "12345" >>$temp
15908     echo "12345" >>$file
15909     cmp $temp $file || error "$temp $file differ (append1)"
15910
15911     echo "12345" >>$temp
15912     echo "12345" >>$file
15913     cmp $temp $file || error "$temp $file differ (append2)"
15914
15915     rm -f $temp $file
15916     true
15917 }
15918
15919 test_155_big_load() {
15920         remote_ost_nodsh && skip "remote OST with nodsh"
15921
15922         local temp=$TMP/$tfile
15923         local file=$DIR/$tfile
15924
15925         free_min_max
15926         local cache_size=$(do_facet ost$((MAXI+1)) \
15927                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15928
15929         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
15930         # pre-set value
15931         if [ -z "$cache_size" ]; then
15932                 cache_size=256
15933         fi
15934         local large_file_size=$((cache_size * 2))
15935
15936         echo "OSS cache size: $cache_size KB"
15937         echo "Large file size: $large_file_size KB"
15938
15939         [ $MAXV -le $large_file_size ] &&
15940                 skip_env "max available OST size needs > $large_file_size KB"
15941
15942         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15943
15944         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15945                 error "dd of=$temp bs=$large_file_size count=1k failed"
15946         cp $temp $file
15947         ls -lh $temp $file
15948         cancel_lru_locks osc
15949         cmp $temp $file || error "$temp $file differ"
15950
15951         rm -f $temp $file
15952         true
15953 }
15954
15955 save_writethrough() {
15956         local facets=$(get_facets OST)
15957
15958         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15959 }
15960
15961 test_155a() {
15962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15963
15964         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15965
15966         save_writethrough $p
15967
15968         set_cache read on
15969         set_cache writethrough on
15970         test_155_small_load
15971         restore_lustre_params < $p
15972         rm -f $p
15973 }
15974 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15975
15976 test_155b() {
15977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15978
15979         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15980
15981         save_writethrough $p
15982
15983         set_cache read on
15984         set_cache writethrough off
15985         test_155_small_load
15986         restore_lustre_params < $p
15987         rm -f $p
15988 }
15989 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15990
15991 test_155c() {
15992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15993
15994         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15995
15996         save_writethrough $p
15997
15998         set_cache read off
15999         set_cache writethrough on
16000         test_155_small_load
16001         restore_lustre_params < $p
16002         rm -f $p
16003 }
16004 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16005
16006 test_155d() {
16007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16008
16009         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16010
16011         save_writethrough $p
16012
16013         set_cache read off
16014         set_cache writethrough off
16015         test_155_small_load
16016         restore_lustre_params < $p
16017         rm -f $p
16018 }
16019 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16020
16021 test_155e() {
16022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16023
16024         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16025
16026         save_writethrough $p
16027
16028         set_cache read on
16029         set_cache writethrough on
16030         test_155_big_load
16031         restore_lustre_params < $p
16032         rm -f $p
16033 }
16034 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16035
16036 test_155f() {
16037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16038
16039         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16040
16041         save_writethrough $p
16042
16043         set_cache read on
16044         set_cache writethrough off
16045         test_155_big_load
16046         restore_lustre_params < $p
16047         rm -f $p
16048 }
16049 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16050
16051 test_155g() {
16052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16053
16054         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16055
16056         save_writethrough $p
16057
16058         set_cache read off
16059         set_cache writethrough on
16060         test_155_big_load
16061         restore_lustre_params < $p
16062         rm -f $p
16063 }
16064 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16065
16066 test_155h() {
16067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16068
16069         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16070
16071         save_writethrough $p
16072
16073         set_cache read off
16074         set_cache writethrough off
16075         test_155_big_load
16076         restore_lustre_params < $p
16077         rm -f $p
16078 }
16079 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16080
16081 test_156() {
16082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16083         remote_ost_nodsh && skip "remote OST with nodsh"
16084         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16085                 skip "stats not implemented on old servers"
16086         [ "$ost1_FSTYPE" = "zfs" ] &&
16087                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16088
16089         local CPAGES=3
16090         local BEFORE
16091         local AFTER
16092         local file="$DIR/$tfile"
16093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16094
16095         save_writethrough $p
16096         roc_hit_init
16097
16098         log "Turn on read and write cache"
16099         set_cache read on
16100         set_cache writethrough on
16101
16102         log "Write data and read it back."
16103         log "Read should be satisfied from the cache."
16104         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16105         BEFORE=$(roc_hit)
16106         cancel_lru_locks osc
16107         cat $file >/dev/null
16108         AFTER=$(roc_hit)
16109         if ! let "AFTER - BEFORE == CPAGES"; then
16110                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16111         else
16112                 log "cache hits: before: $BEFORE, after: $AFTER"
16113         fi
16114
16115         log "Read again; it should be satisfied from the cache."
16116         BEFORE=$AFTER
16117         cancel_lru_locks osc
16118         cat $file >/dev/null
16119         AFTER=$(roc_hit)
16120         if ! let "AFTER - BEFORE == CPAGES"; then
16121                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16122         else
16123                 log "cache hits:: before: $BEFORE, after: $AFTER"
16124         fi
16125
16126         log "Turn off the read cache and turn on the write cache"
16127         set_cache read off
16128         set_cache writethrough on
16129
16130         log "Read again; it should be satisfied from the cache."
16131         BEFORE=$(roc_hit)
16132         cancel_lru_locks osc
16133         cat $file >/dev/null
16134         AFTER=$(roc_hit)
16135         if ! let "AFTER - BEFORE == CPAGES"; then
16136                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16137         else
16138                 log "cache hits:: before: $BEFORE, after: $AFTER"
16139         fi
16140
16141         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16142                 # > 2.12.56 uses pagecache if cached
16143                 log "Read again; it should not be satisfied from the cache."
16144                 BEFORE=$AFTER
16145                 cancel_lru_locks osc
16146                 cat $file >/dev/null
16147                 AFTER=$(roc_hit)
16148                 if ! let "AFTER - BEFORE == 0"; then
16149                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16150                 else
16151                         log "cache hits:: before: $BEFORE, after: $AFTER"
16152                 fi
16153         fi
16154
16155         log "Write data and read it back."
16156         log "Read should be satisfied from the cache."
16157         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16158         BEFORE=$(roc_hit)
16159         cancel_lru_locks osc
16160         cat $file >/dev/null
16161         AFTER=$(roc_hit)
16162         if ! let "AFTER - BEFORE == CPAGES"; then
16163                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16164         else
16165                 log "cache hits:: before: $BEFORE, after: $AFTER"
16166         fi
16167
16168         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16169                 # > 2.12.56 uses pagecache if cached
16170                 log "Read again; it should not be satisfied from the cache."
16171                 BEFORE=$AFTER
16172                 cancel_lru_locks osc
16173                 cat $file >/dev/null
16174                 AFTER=$(roc_hit)
16175                 if ! let "AFTER - BEFORE == 0"; then
16176                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16177                 else
16178                         log "cache hits:: before: $BEFORE, after: $AFTER"
16179                 fi
16180         fi
16181
16182         log "Turn off read and write cache"
16183         set_cache read off
16184         set_cache writethrough off
16185
16186         log "Write data and read it back"
16187         log "It should not be satisfied from the cache."
16188         rm -f $file
16189         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16190         cancel_lru_locks osc
16191         BEFORE=$(roc_hit)
16192         cat $file >/dev/null
16193         AFTER=$(roc_hit)
16194         if ! let "AFTER - BEFORE == 0"; then
16195                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16196         else
16197                 log "cache hits:: before: $BEFORE, after: $AFTER"
16198         fi
16199
16200         log "Turn on the read cache and turn off the write cache"
16201         set_cache read on
16202         set_cache writethrough off
16203
16204         log "Write data and read it back"
16205         log "It should not be satisfied from the cache."
16206         rm -f $file
16207         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16208         BEFORE=$(roc_hit)
16209         cancel_lru_locks osc
16210         cat $file >/dev/null
16211         AFTER=$(roc_hit)
16212         if ! let "AFTER - BEFORE == 0"; then
16213                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16214         else
16215                 log "cache hits:: before: $BEFORE, after: $AFTER"
16216         fi
16217
16218         log "Read again; it should be satisfied from the cache."
16219         BEFORE=$(roc_hit)
16220         cancel_lru_locks osc
16221         cat $file >/dev/null
16222         AFTER=$(roc_hit)
16223         if ! let "AFTER - BEFORE == CPAGES"; then
16224                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16225         else
16226                 log "cache hits:: before: $BEFORE, after: $AFTER"
16227         fi
16228
16229         restore_lustre_params < $p
16230         rm -f $p $file
16231 }
16232 run_test 156 "Verification of tunables"
16233
16234 test_160a() {
16235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16236         remote_mds_nodsh && skip "remote MDS with nodsh"
16237         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16238                 skip "Need MDS version at least 2.2.0"
16239
16240         changelog_register || error "changelog_register failed"
16241         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16242         changelog_users $SINGLEMDS | grep -q $cl_user ||
16243                 error "User $cl_user not found in changelog_users"
16244
16245         mkdir_on_mdt0 $DIR/$tdir
16246
16247         # change something
16248         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16249         changelog_clear 0 || error "changelog_clear failed"
16250         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16251         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16252         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16253         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16254         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16255         rm $DIR/$tdir/pics/desktop.jpg
16256
16257         echo "verifying changelog mask"
16258         changelog_chmask "-MKDIR"
16259         changelog_chmask "-CLOSE"
16260
16261         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16262         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16263
16264         changelog_chmask "+MKDIR"
16265         changelog_chmask "+CLOSE"
16266
16267         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16268         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16269
16270         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16271         CLOSES=$(changelog_dump | grep -c "CLOSE")
16272         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16273         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16274
16275         # verify contents
16276         echo "verifying target fid"
16277         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16278         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16279         [ "$fidc" == "$fidf" ] ||
16280                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16281         echo "verifying parent fid"
16282         # The FID returned from the Changelog may be the directory shard on
16283         # a different MDT, and not the FID returned by path2fid on the parent.
16284         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16285         # since this is what will matter when recreating this file in the tree.
16286         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16287         local pathp=$($LFS fid2path $MOUNT "$fidp")
16288         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16289                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16290
16291         echo "getting records for $cl_user"
16292         changelog_users $SINGLEMDS
16293         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16294         local nclr=3
16295         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16296                 error "changelog_clear failed"
16297         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16298         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16299         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16300                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16301
16302         local min0_rec=$(changelog_users $SINGLEMDS |
16303                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16304         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16305                           awk '{ print $1; exit; }')
16306
16307         changelog_dump | tail -n 5
16308         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16309         [ $first_rec == $((min0_rec + 1)) ] ||
16310                 error "first index should be $min0_rec + 1 not $first_rec"
16311
16312         # LU-3446 changelog index reset on MDT restart
16313         local cur_rec1=$(changelog_users $SINGLEMDS |
16314                          awk '/^current.index:/ { print $NF }')
16315         changelog_clear 0 ||
16316                 error "clear all changelog records for $cl_user failed"
16317         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16318         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16319                 error "Fail to start $SINGLEMDS"
16320         local cur_rec2=$(changelog_users $SINGLEMDS |
16321                          awk '/^current.index:/ { print $NF }')
16322         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16323         [ $cur_rec1 == $cur_rec2 ] ||
16324                 error "current index should be $cur_rec1 not $cur_rec2"
16325
16326         echo "verifying users from this test are deregistered"
16327         changelog_deregister || error "changelog_deregister failed"
16328         changelog_users $SINGLEMDS | grep -q $cl_user &&
16329                 error "User '$cl_user' still in changelog_users"
16330
16331         # lctl get_param -n mdd.*.changelog_users
16332         # current_index: 144
16333         # ID    index (idle seconds)
16334         # cl3   144   (2) mask=<list>
16335         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16336                 # this is the normal case where all users were deregistered
16337                 # make sure no new records are added when no users are present
16338                 local last_rec1=$(changelog_users $SINGLEMDS |
16339                                   awk '/^current.index:/ { print $NF }')
16340                 touch $DIR/$tdir/chloe
16341                 local last_rec2=$(changelog_users $SINGLEMDS |
16342                                   awk '/^current.index:/ { print $NF }')
16343                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16344                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16345         else
16346                 # any changelog users must be leftovers from a previous test
16347                 changelog_users $SINGLEMDS
16348                 echo "other changelog users; can't verify off"
16349         fi
16350 }
16351 run_test 160a "changelog sanity"
16352
16353 test_160b() { # LU-3587
16354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16355         remote_mds_nodsh && skip "remote MDS with nodsh"
16356         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16357                 skip "Need MDS version at least 2.2.0"
16358
16359         changelog_register || error "changelog_register failed"
16360         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16361         changelog_users $SINGLEMDS | grep -q $cl_user ||
16362                 error "User '$cl_user' not found in changelog_users"
16363
16364         local longname1=$(str_repeat a 255)
16365         local longname2=$(str_repeat b 255)
16366
16367         cd $DIR
16368         echo "creating very long named file"
16369         touch $longname1 || error "create of '$longname1' failed"
16370         echo "renaming very long named file"
16371         mv $longname1 $longname2
16372
16373         changelog_dump | grep RENME | tail -n 5
16374         rm -f $longname2
16375 }
16376 run_test 160b "Verify that very long rename doesn't crash in changelog"
16377
16378 test_160c() {
16379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16380         remote_mds_nodsh && skip "remote MDS with nodsh"
16381
16382         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16383                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16384                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16385                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16386
16387         local rc=0
16388
16389         # Registration step
16390         changelog_register || error "changelog_register failed"
16391
16392         rm -rf $DIR/$tdir
16393         mkdir -p $DIR/$tdir
16394         $MCREATE $DIR/$tdir/foo_160c
16395         changelog_chmask "-TRUNC"
16396         $TRUNCATE $DIR/$tdir/foo_160c 200
16397         changelog_chmask "+TRUNC"
16398         $TRUNCATE $DIR/$tdir/foo_160c 199
16399         changelog_dump | tail -n 5
16400         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16401         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16402 }
16403 run_test 160c "verify that changelog log catch the truncate event"
16404
16405 test_160d() {
16406         remote_mds_nodsh && skip "remote MDS with nodsh"
16407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16409         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16410                 skip "Need MDS version at least 2.7.60"
16411
16412         # Registration step
16413         changelog_register || error "changelog_register failed"
16414
16415         mkdir -p $DIR/$tdir/migrate_dir
16416         changelog_clear 0 || error "changelog_clear failed"
16417
16418         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16419         changelog_dump | tail -n 5
16420         local migrates=$(changelog_dump | grep -c "MIGRT")
16421         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16422 }
16423 run_test 160d "verify that changelog log catch the migrate event"
16424
16425 test_160e() {
16426         remote_mds_nodsh && skip "remote MDS with nodsh"
16427
16428         # Create a user
16429         changelog_register || error "changelog_register failed"
16430
16431         local MDT0=$(facet_svc $SINGLEMDS)
16432         local rc
16433
16434         # No user (expect fail)
16435         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16436         rc=$?
16437         if [ $rc -eq 0 ]; then
16438                 error "Should fail without user"
16439         elif [ $rc -ne 4 ]; then
16440                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16441         fi
16442
16443         # Delete a future user (expect fail)
16444         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16445         rc=$?
16446         if [ $rc -eq 0 ]; then
16447                 error "Deleted non-existant user cl77"
16448         elif [ $rc -ne 2 ]; then
16449                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16450         fi
16451
16452         # Clear to a bad index (1 billion should be safe)
16453         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16454         rc=$?
16455
16456         if [ $rc -eq 0 ]; then
16457                 error "Successfully cleared to invalid CL index"
16458         elif [ $rc -ne 22 ]; then
16459                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16460         fi
16461 }
16462 run_test 160e "changelog negative testing (should return errors)"
16463
16464 test_160f() {
16465         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16466         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16467                 skip "Need MDS version at least 2.10.56"
16468
16469         local mdts=$(comma_list $(mdts_nodes))
16470
16471         # Create a user
16472         changelog_register || error "first changelog_register failed"
16473         changelog_register || error "second changelog_register failed"
16474         local cl_users
16475         declare -A cl_user1
16476         declare -A cl_user2
16477         local user_rec1
16478         local user_rec2
16479         local i
16480
16481         # generate some changelog records to accumulate on each MDT
16482         # use all_char because created files should be evenly distributed
16483         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16484                 error "test_mkdir $tdir failed"
16485         log "$(date +%s): creating first files"
16486         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16487                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16488                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16489         done
16490
16491         # check changelogs have been generated
16492         local start=$SECONDS
16493         local idle_time=$((MDSCOUNT * 5 + 5))
16494         local nbcl=$(changelog_dump | wc -l)
16495         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16496
16497         for param in "changelog_max_idle_time=$idle_time" \
16498                      "changelog_gc=1" \
16499                      "changelog_min_gc_interval=2" \
16500                      "changelog_min_free_cat_entries=3"; do
16501                 local MDT0=$(facet_svc $SINGLEMDS)
16502                 local var="${param%=*}"
16503                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16504
16505                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16506                 do_nodes $mdts $LCTL set_param mdd.*.$param
16507         done
16508
16509         # force cl_user2 to be idle (1st part), but also cancel the
16510         # cl_user1 records so that it is not evicted later in the test.
16511         local sleep1=$((idle_time / 2))
16512         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16513         sleep $sleep1
16514
16515         # simulate changelog catalog almost full
16516         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16517         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16518
16519         for i in $(seq $MDSCOUNT); do
16520                 cl_users=(${CL_USERS[mds$i]})
16521                 cl_user1[mds$i]="${cl_users[0]}"
16522                 cl_user2[mds$i]="${cl_users[1]}"
16523
16524                 [ -n "${cl_user1[mds$i]}" ] ||
16525                         error "mds$i: no user registered"
16526                 [ -n "${cl_user2[mds$i]}" ] ||
16527                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16528
16529                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16530                 [ -n "$user_rec1" ] ||
16531                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16532                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16533                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16534                 [ -n "$user_rec2" ] ||
16535                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16536                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16537                      "$user_rec1 + 2 == $user_rec2"
16538                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16539                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16540                               "$user_rec1 + 2, but is $user_rec2"
16541                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16542                 [ -n "$user_rec2" ] ||
16543                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16544                 [ $user_rec1 == $user_rec2 ] ||
16545                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16546                               "$user_rec1, but is $user_rec2"
16547         done
16548
16549         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16550         local sleep2=$((idle_time - (SECONDS - start) + 1))
16551         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16552         sleep $sleep2
16553
16554         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16555         # cl_user1 should be OK because it recently processed records.
16556         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16557         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16558                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16559                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16560         done
16561
16562         # ensure gc thread is done
16563         for i in $(mdts_nodes); do
16564                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16565                         error "$i: GC-thread not done"
16566         done
16567
16568         local first_rec
16569         for (( i = 1; i <= MDSCOUNT; i++ )); do
16570                 # check cl_user1 still registered
16571                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16572                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16573                 # check cl_user2 unregistered
16574                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16575                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16576
16577                 # check changelogs are present and starting at $user_rec1 + 1
16578                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16579                 [ -n "$user_rec1" ] ||
16580                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16581                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16582                             awk '{ print $1; exit; }')
16583
16584                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16585                 [ $((user_rec1 + 1)) == $first_rec ] ||
16586                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16587         done
16588 }
16589 run_test 160f "changelog garbage collect (timestamped users)"
16590
16591 test_160g() {
16592         remote_mds_nodsh && skip "remote MDS with nodsh"
16593         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16594                 skip "Need MDS version at least 2.14.55"
16595
16596         local mdts=$(comma_list $(mdts_nodes))
16597
16598         # Create a user
16599         changelog_register || error "first changelog_register failed"
16600         changelog_register || error "second changelog_register failed"
16601         local cl_users
16602         declare -A cl_user1
16603         declare -A cl_user2
16604         local user_rec1
16605         local user_rec2
16606         local i
16607
16608         # generate some changelog records to accumulate on each MDT
16609         # use all_char because created files should be evenly distributed
16610         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16611                 error "test_mkdir $tdir failed"
16612         for ((i = 0; i < MDSCOUNT; i++)); do
16613                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16614                         error "create $DIR/$tdir/d$i.1 failed"
16615         done
16616
16617         # check changelogs have been generated
16618         local nbcl=$(changelog_dump | wc -l)
16619         (( $nbcl > 0 )) || error "no changelogs found"
16620
16621         # reduce the max_idle_indexes value to make sure we exceed it
16622         for param in "changelog_max_idle_indexes=2" \
16623                      "changelog_gc=1" \
16624                      "changelog_min_gc_interval=2"; do
16625                 local MDT0=$(facet_svc $SINGLEMDS)
16626                 local var="${param%=*}"
16627                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16628
16629                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16630                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16631                         error "unable to set mdd.*.$param"
16632         done
16633
16634         local start=$SECONDS
16635         for i in $(seq $MDSCOUNT); do
16636                 cl_users=(${CL_USERS[mds$i]})
16637                 cl_user1[mds$i]="${cl_users[0]}"
16638                 cl_user2[mds$i]="${cl_users[1]}"
16639
16640                 [ -n "${cl_user1[mds$i]}" ] ||
16641                         error "mds$i: user1 is not registered"
16642                 [ -n "${cl_user2[mds$i]}" ] ||
16643                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16644
16645                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16646                 [ -n "$user_rec1" ] ||
16647                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16648                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16649                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16650                 [ -n "$user_rec2" ] ||
16651                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16652                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16653                      "$user_rec1 + 2 == $user_rec2"
16654                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16655                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16656                               "expected $user_rec1 + 2, but is $user_rec2"
16657                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16658                 [ -n "$user_rec2" ] ||
16659                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16660                 [ $user_rec1 == $user_rec2 ] ||
16661                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16662                               "expected $user_rec1, but is $user_rec2"
16663         done
16664
16665         # ensure we are past the previous changelog_min_gc_interval set above
16666         local sleep2=$((start + 2 - SECONDS))
16667         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16668         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16669         # cl_user1 should be OK because it recently processed records.
16670         for ((i = 0; i < MDSCOUNT; i++)); do
16671                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16672                         error "create $DIR/$tdir/d$i.3 failed"
16673         done
16674
16675         # ensure gc thread is done
16676         for i in $(mdts_nodes); do
16677                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16678                         error "$i: GC-thread not done"
16679         done
16680
16681         local first_rec
16682         for (( i = 1; i <= MDSCOUNT; i++ )); do
16683                 # check cl_user1 still registered
16684                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16685                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16686                 # check cl_user2 unregistered
16687                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16688                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16689
16690                 # check changelogs are present and starting at $user_rec1 + 1
16691                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16692                 [ -n "$user_rec1" ] ||
16693                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16694                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16695                             awk '{ print $1; exit; }')
16696
16697                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16698                 [ $((user_rec1 + 1)) == $first_rec ] ||
16699                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16700         done
16701 }
16702 run_test 160g "changelog garbage collect on idle records"
16703
16704 test_160h() {
16705         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16706         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16707                 skip "Need MDS version at least 2.10.56"
16708
16709         local mdts=$(comma_list $(mdts_nodes))
16710
16711         # Create a user
16712         changelog_register || error "first changelog_register failed"
16713         changelog_register || error "second changelog_register failed"
16714         local cl_users
16715         declare -A cl_user1
16716         declare -A cl_user2
16717         local user_rec1
16718         local user_rec2
16719         local i
16720
16721         # generate some changelog records to accumulate on each MDT
16722         # use all_char because created files should be evenly distributed
16723         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16724                 error "test_mkdir $tdir failed"
16725         for ((i = 0; i < MDSCOUNT; i++)); do
16726                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16727                         error "create $DIR/$tdir/d$i.1 failed"
16728         done
16729
16730         # check changelogs have been generated
16731         local nbcl=$(changelog_dump | wc -l)
16732         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16733
16734         for param in "changelog_max_idle_time=10" \
16735                      "changelog_gc=1" \
16736                      "changelog_min_gc_interval=2"; do
16737                 local MDT0=$(facet_svc $SINGLEMDS)
16738                 local var="${param%=*}"
16739                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16740
16741                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16742                 do_nodes $mdts $LCTL set_param mdd.*.$param
16743         done
16744
16745         # force cl_user2 to be idle (1st part)
16746         sleep 9
16747
16748         for i in $(seq $MDSCOUNT); do
16749                 cl_users=(${CL_USERS[mds$i]})
16750                 cl_user1[mds$i]="${cl_users[0]}"
16751                 cl_user2[mds$i]="${cl_users[1]}"
16752
16753                 [ -n "${cl_user1[mds$i]}" ] ||
16754                         error "mds$i: no user registered"
16755                 [ -n "${cl_user2[mds$i]}" ] ||
16756                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16757
16758                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16759                 [ -n "$user_rec1" ] ||
16760                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16761                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16762                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16763                 [ -n "$user_rec2" ] ||
16764                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16765                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16766                      "$user_rec1 + 2 == $user_rec2"
16767                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16768                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16769                               "$user_rec1 + 2, but is $user_rec2"
16770                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16771                 [ -n "$user_rec2" ] ||
16772                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16773                 [ $user_rec1 == $user_rec2 ] ||
16774                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16775                               "$user_rec1, but is $user_rec2"
16776         done
16777
16778         # force cl_user2 to be idle (2nd part) and to reach
16779         # changelog_max_idle_time
16780         sleep 2
16781
16782         # force each GC-thread start and block then
16783         # one per MDT/MDD, set fail_val accordingly
16784         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16785         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16786
16787         # generate more changelogs to trigger fail_loc
16788         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16789                 error "create $DIR/$tdir/${tfile}bis failed"
16790
16791         # stop MDT to stop GC-thread, should be done in back-ground as it will
16792         # block waiting for the thread to be released and exit
16793         declare -A stop_pids
16794         for i in $(seq $MDSCOUNT); do
16795                 stop mds$i &
16796                 stop_pids[mds$i]=$!
16797         done
16798
16799         for i in $(mdts_nodes); do
16800                 local facet
16801                 local nb=0
16802                 local facets=$(facets_up_on_host $i)
16803
16804                 for facet in ${facets//,/ }; do
16805                         if [[ $facet == mds* ]]; then
16806                                 nb=$((nb + 1))
16807                         fi
16808                 done
16809                 # ensure each MDS's gc threads are still present and all in "R"
16810                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16811                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16812                         error "$i: expected $nb GC-thread"
16813                 wait_update $i \
16814                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16815                         "R" 20 ||
16816                         error "$i: GC-thread not found in R-state"
16817                 # check umounts of each MDT on MDS have reached kthread_stop()
16818                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16819                         error "$i: expected $nb umount"
16820                 wait_update $i \
16821                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16822                         error "$i: umount not found in D-state"
16823         done
16824
16825         # release all GC-threads
16826         do_nodes $mdts $LCTL set_param fail_loc=0
16827
16828         # wait for MDT stop to complete
16829         for i in $(seq $MDSCOUNT); do
16830                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16831         done
16832
16833         # XXX
16834         # may try to check if any orphan changelog records are present
16835         # via ldiskfs/zfs and llog_reader...
16836
16837         # re-start/mount MDTs
16838         for i in $(seq $MDSCOUNT); do
16839                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16840                         error "Fail to start mds$i"
16841         done
16842
16843         local first_rec
16844         for i in $(seq $MDSCOUNT); do
16845                 # check cl_user1 still registered
16846                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16847                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16848                 # check cl_user2 unregistered
16849                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16850                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16851
16852                 # check changelogs are present and starting at $user_rec1 + 1
16853                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16854                 [ -n "$user_rec1" ] ||
16855                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16856                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16857                             awk '{ print $1; exit; }')
16858
16859                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16860                 [ $((user_rec1 + 1)) == $first_rec ] ||
16861                         error "mds$i: first index should be $user_rec1 + 1, " \
16862                               "but is $first_rec"
16863         done
16864 }
16865 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16866               "during mount"
16867
16868 test_160i() {
16869
16870         local mdts=$(comma_list $(mdts_nodes))
16871
16872         changelog_register || error "first changelog_register failed"
16873
16874         # generate some changelog records to accumulate on each MDT
16875         # use all_char because created files should be evenly distributed
16876         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16877                 error "test_mkdir $tdir failed"
16878         for ((i = 0; i < MDSCOUNT; i++)); do
16879                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16880                         error "create $DIR/$tdir/d$i.1 failed"
16881         done
16882
16883         # check changelogs have been generated
16884         local nbcl=$(changelog_dump | wc -l)
16885         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16886
16887         # simulate race between register and unregister
16888         # XXX as fail_loc is set per-MDS, with DNE configs the race
16889         # simulation will only occur for one MDT per MDS and for the
16890         # others the normal race scenario will take place
16891         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16892         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16893         do_nodes $mdts $LCTL set_param fail_val=1
16894
16895         # unregister 1st user
16896         changelog_deregister &
16897         local pid1=$!
16898         # wait some time for deregister work to reach race rdv
16899         sleep 2
16900         # register 2nd user
16901         changelog_register || error "2nd user register failed"
16902
16903         wait $pid1 || error "1st user deregister failed"
16904
16905         local i
16906         local last_rec
16907         declare -A LAST_REC
16908         for i in $(seq $MDSCOUNT); do
16909                 if changelog_users mds$i | grep "^cl"; then
16910                         # make sure new records are added with one user present
16911                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16912                                           awk '/^current.index:/ { print $NF }')
16913                 else
16914                         error "mds$i has no user registered"
16915                 fi
16916         done
16917
16918         # generate more changelog records to accumulate on each MDT
16919         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16920                 error "create $DIR/$tdir/${tfile}bis failed"
16921
16922         for i in $(seq $MDSCOUNT); do
16923                 last_rec=$(changelog_users $SINGLEMDS |
16924                            awk '/^current.index:/ { print $NF }')
16925                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16926                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16927                         error "changelogs are off on mds$i"
16928         done
16929 }
16930 run_test 160i "changelog user register/unregister race"
16931
16932 test_160j() {
16933         remote_mds_nodsh && skip "remote MDS with nodsh"
16934         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16935                 skip "Need MDS version at least 2.12.56"
16936
16937         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16938         stack_trap "umount $MOUNT2" EXIT
16939
16940         changelog_register || error "first changelog_register failed"
16941         stack_trap "changelog_deregister" EXIT
16942
16943         # generate some changelog
16944         # use all_char because created files should be evenly distributed
16945         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16946                 error "mkdir $tdir failed"
16947         for ((i = 0; i < MDSCOUNT; i++)); do
16948                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16949                         error "create $DIR/$tdir/d$i.1 failed"
16950         done
16951
16952         # open the changelog device
16953         exec 3>/dev/changelog-$FSNAME-MDT0000
16954         stack_trap "exec 3>&-" EXIT
16955         exec 4</dev/changelog-$FSNAME-MDT0000
16956         stack_trap "exec 4<&-" EXIT
16957
16958         # umount the first lustre mount
16959         umount $MOUNT
16960         stack_trap "mount_client $MOUNT" EXIT
16961
16962         # read changelog, which may or may not fail, but should not crash
16963         cat <&4 >/dev/null
16964
16965         # clear changelog
16966         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16967         changelog_users $SINGLEMDS | grep -q $cl_user ||
16968                 error "User $cl_user not found in changelog_users"
16969
16970         printf 'clear:'$cl_user':0' >&3
16971 }
16972 run_test 160j "client can be umounted while its chanangelog is being used"
16973
16974 test_160k() {
16975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16976         remote_mds_nodsh && skip "remote MDS with nodsh"
16977
16978         mkdir -p $DIR/$tdir/1/1
16979
16980         changelog_register || error "changelog_register failed"
16981         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16982
16983         changelog_users $SINGLEMDS | grep -q $cl_user ||
16984                 error "User '$cl_user' not found in changelog_users"
16985 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16986         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16987         rmdir $DIR/$tdir/1/1 & sleep 1
16988         mkdir $DIR/$tdir/2
16989         touch $DIR/$tdir/2/2
16990         rm -rf $DIR/$tdir/2
16991
16992         wait
16993         sleep 4
16994
16995         changelog_dump | grep rmdir || error "rmdir not recorded"
16996 }
16997 run_test 160k "Verify that changelog records are not lost"
16998
16999 # Verifies that a file passed as a parameter has recently had an operation
17000 # performed on it that has generated an MTIME changelog which contains the
17001 # correct parent FID. As files might reside on a different MDT from the
17002 # parent directory in DNE configurations, the FIDs are translated to paths
17003 # before being compared, which should be identical
17004 compare_mtime_changelog() {
17005         local file="${1}"
17006         local mdtidx
17007         local mtime
17008         local cl_fid
17009         local pdir
17010         local dir
17011
17012         mdtidx=$($LFS getstripe --mdt-index $file)
17013         mdtidx=$(printf "%04x" $mdtidx)
17014
17015         # Obtain the parent FID from the MTIME changelog
17016         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17017         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17018
17019         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17020         [ -z "$cl_fid" ] && error "parent FID not present"
17021
17022         # Verify that the path for the parent FID is the same as the path for
17023         # the test directory
17024         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17025
17026         dir=$(dirname $1)
17027
17028         [[ "${pdir%/}" == "$dir" ]] ||
17029                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17030 }
17031
17032 test_160l() {
17033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17034
17035         remote_mds_nodsh && skip "remote MDS with nodsh"
17036         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17037                 skip "Need MDS version at least 2.13.55"
17038
17039         local cl_user
17040
17041         changelog_register || error "changelog_register failed"
17042         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17043
17044         changelog_users $SINGLEMDS | grep -q $cl_user ||
17045                 error "User '$cl_user' not found in changelog_users"
17046
17047         # Clear some types so that MTIME changelogs are generated
17048         changelog_chmask "-CREAT"
17049         changelog_chmask "-CLOSE"
17050
17051         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17052
17053         # Test CL_MTIME during setattr
17054         touch $DIR/$tdir/$tfile
17055         compare_mtime_changelog $DIR/$tdir/$tfile
17056
17057         # Test CL_MTIME during close
17058         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17059         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17060 }
17061 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17062
17063 test_160m() {
17064         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17065         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17066                 skip "Need MDS version at least 2.14.51"
17067         local cl_users
17068         local cl_user1
17069         local cl_user2
17070         local pid1
17071
17072         # Create a user
17073         changelog_register || error "first changelog_register failed"
17074         changelog_register || error "second changelog_register failed"
17075
17076         cl_users=(${CL_USERS[mds1]})
17077         cl_user1="${cl_users[0]}"
17078         cl_user2="${cl_users[1]}"
17079         # generate some changelog records to accumulate on MDT0
17080         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17081         createmany -m $DIR/$tdir/$tfile 50 ||
17082                 error "create $DIR/$tdir/$tfile failed"
17083         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17084         rm -f $DIR/$tdir
17085
17086         # check changelogs have been generated
17087         local nbcl=$(changelog_dump | wc -l)
17088         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17089
17090 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17091         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17092
17093         __changelog_clear mds1 $cl_user1 +10
17094         __changelog_clear mds1 $cl_user2 0 &
17095         pid1=$!
17096         sleep 2
17097         __changelog_clear mds1 $cl_user1 0 ||
17098                 error "fail to cancel record for $cl_user1"
17099         wait $pid1
17100         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17101 }
17102 run_test 160m "Changelog clear race"
17103
17104 test_160n() {
17105         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17106         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17107                 skip "Need MDS version at least 2.14.51"
17108         local cl_users
17109         local cl_user1
17110         local cl_user2
17111         local pid1
17112         local first_rec
17113         local last_rec=0
17114
17115         # Create a user
17116         changelog_register || error "first changelog_register failed"
17117
17118         cl_users=(${CL_USERS[mds1]})
17119         cl_user1="${cl_users[0]}"
17120
17121         # generate some changelog records to accumulate on MDT0
17122         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17123         first_rec=$(changelog_users $SINGLEMDS |
17124                         awk '/^current.index:/ { print $NF }')
17125         while (( last_rec < (( first_rec + 65000)) )); do
17126                 createmany -m $DIR/$tdir/$tfile 10000 ||
17127                         error "create $DIR/$tdir/$tfile failed"
17128
17129                 for i in $(seq 0 10000); do
17130                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17131                                 > /dev/null
17132                 done
17133
17134                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17135                         error "unlinkmany failed unlink"
17136                 last_rec=$(changelog_users $SINGLEMDS |
17137                         awk '/^current.index:/ { print $NF }')
17138                 echo last record $last_rec
17139                 (( last_rec == 0 )) && error "no changelog found"
17140         done
17141
17142 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17143         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17144
17145         __changelog_clear mds1 $cl_user1 0 &
17146         pid1=$!
17147         sleep 2
17148         __changelog_clear mds1 $cl_user1 0 ||
17149                 error "fail to cancel record for $cl_user1"
17150         wait $pid1
17151         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17152 }
17153 run_test 160n "Changelog destroy race"
17154
17155 test_160o() {
17156         local mdt="$(facet_svc $SINGLEMDS)"
17157
17158         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17159         remote_mds_nodsh && skip "remote MDS with nodsh"
17160         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17161                 skip "Need MDS version at least 2.14.52"
17162
17163         changelog_register --user test_160o -m unlnk+close+open ||
17164                 error "changelog_register failed"
17165
17166         do_facet $SINGLEMDS $LCTL --device $mdt \
17167                                 changelog_register -u "Tt3_-#" &&
17168                 error "bad symbols in name should fail"
17169
17170         do_facet $SINGLEMDS $LCTL --device $mdt \
17171                                 changelog_register -u test_160o &&
17172                 error "the same name registration should fail"
17173
17174         do_facet $SINGLEMDS $LCTL --device $mdt \
17175                         changelog_register -u test_160toolongname &&
17176                 error "too long name registration should fail"
17177
17178         changelog_chmask "MARK+HSM"
17179         lctl get_param mdd.*.changelog*mask
17180         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17181         changelog_users $SINGLEMDS | grep -q $cl_user ||
17182                 error "User $cl_user not found in changelog_users"
17183         #verify username
17184         echo $cl_user | grep -q test_160o ||
17185                 error "User $cl_user has no specific name 'test160o'"
17186
17187         # change something
17188         changelog_clear 0 || error "changelog_clear failed"
17189         # generate some changelog records to accumulate on MDT0
17190         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17191         touch $DIR/$tdir/$tfile                 # open 1
17192
17193         OPENS=$(changelog_dump | grep -c "OPEN")
17194         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17195
17196         # must be no MKDIR it wasn't set as user mask
17197         MKDIR=$(changelog_dump | grep -c "MKDIR")
17198         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17199
17200         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17201                                 mdd.$mdt.changelog_current_mask -n)
17202         # register maskless user
17203         changelog_register || error "changelog_register failed"
17204         # effective mask should be not changed because it is not minimal
17205         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17206                                 mdd.$mdt.changelog_current_mask -n)
17207         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17208         # set server mask to minimal value
17209         changelog_chmask "MARK"
17210         # check effective mask again, should be treated as DEFMASK now
17211         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17212                                 mdd.$mdt.changelog_current_mask -n)
17213         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17214
17215         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17216                 # set server mask back to some value
17217                 changelog_chmask "CLOSE,UNLNK"
17218                 # check effective mask again, should not remain as DEFMASK
17219                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17220                                 mdd.$mdt.changelog_current_mask -n)
17221                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17222         fi
17223
17224         do_facet $SINGLEMDS $LCTL --device $mdt \
17225                                 changelog_deregister -u test_160o ||
17226                 error "cannot deregister by name"
17227 }
17228 run_test 160o "changelog user name and mask"
17229
17230 test_160p() {
17231         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17232         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17233                 skip "Need MDS version at least 2.14.51"
17234         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17235         local cl_users
17236         local cl_user1
17237         local entry_count
17238
17239         # Create a user
17240         changelog_register || error "first changelog_register failed"
17241
17242         cl_users=(${CL_USERS[mds1]})
17243         cl_user1="${cl_users[0]}"
17244
17245         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17246         createmany -m $DIR/$tdir/$tfile 50 ||
17247                 error "create $DIR/$tdir/$tfile failed"
17248         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17249         rm -rf $DIR/$tdir
17250
17251         # check changelogs have been generated
17252         entry_count=$(changelog_dump | wc -l)
17253         ((entry_count != 0)) || error "no changelog entries found"
17254
17255         # remove changelog_users and check that orphan entries are removed
17256         stop mds1
17257         local dev=$(mdsdevname 1)
17258         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17259         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17260         entry_count=$(changelog_dump | wc -l)
17261         ((entry_count == 0)) ||
17262                 error "found $entry_count changelog entries, expected none"
17263 }
17264 run_test 160p "Changelog orphan cleanup with no users"
17265
17266 test_160q() {
17267         local mdt="$(facet_svc $SINGLEMDS)"
17268         local clu
17269
17270         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17271         remote_mds_nodsh && skip "remote MDS with nodsh"
17272         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17273                 skip "Need MDS version at least 2.14.54"
17274
17275         # set server mask to minimal value like server init does
17276         changelog_chmask "MARK"
17277         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17278                 error "changelog_register failed"
17279         # check effective mask again, should be treated as DEFMASK now
17280         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17281                                 mdd.$mdt.changelog_current_mask -n)
17282         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17283                 error "changelog_deregister failed"
17284         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17285 }
17286 run_test 160q "changelog effective mask is DEFMASK if not set"
17287
17288 test_160s() {
17289         remote_mds_nodsh && skip "remote MDS with nodsh"
17290         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17291                 skip "Need MDS version at least 2.14.55"
17292
17293         local mdts=$(comma_list $(mdts_nodes))
17294
17295         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17296         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17297                                        fail_val=$((24 * 3600 * 10))
17298
17299         # Create a user which is 10 days old
17300         changelog_register || error "first changelog_register failed"
17301         local cl_users
17302         declare -A cl_user1
17303         local i
17304
17305         # generate some changelog records to accumulate on each MDT
17306         # use all_char because created files should be evenly distributed
17307         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17308                 error "test_mkdir $tdir failed"
17309         for ((i = 0; i < MDSCOUNT; i++)); do
17310                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17311                         error "create $DIR/$tdir/d$i.1 failed"
17312         done
17313
17314         # check changelogs have been generated
17315         local nbcl=$(changelog_dump | wc -l)
17316         (( nbcl > 0 )) || error "no changelogs found"
17317
17318         # reduce the max_idle_indexes value to make sure we exceed it
17319         for param in "changelog_max_idle_indexes=2097446912" \
17320                      "changelog_max_idle_time=2592000" \
17321                      "changelog_gc=1" \
17322                      "changelog_min_gc_interval=2"; do
17323                 local MDT0=$(facet_svc $SINGLEMDS)
17324                 local var="${param%=*}"
17325                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17326
17327                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17328                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17329                         error "unable to set mdd.*.$param"
17330         done
17331
17332         local start=$SECONDS
17333         for i in $(seq $MDSCOUNT); do
17334                 cl_users=(${CL_USERS[mds$i]})
17335                 cl_user1[mds$i]="${cl_users[0]}"
17336
17337                 [[ -n "${cl_user1[mds$i]}" ]] ||
17338                         error "mds$i: no user registered"
17339         done
17340
17341         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17342         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17343
17344         # ensure we are past the previous changelog_min_gc_interval set above
17345         local sleep2=$((start + 2 - SECONDS))
17346         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17347
17348         # Generate one more changelog to trigger GC
17349         for ((i = 0; i < MDSCOUNT; i++)); do
17350                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17351                         error "create $DIR/$tdir/d$i.3 failed"
17352         done
17353
17354         # ensure gc thread is done
17355         for node in $(mdts_nodes); do
17356                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17357                         error "$node: GC-thread not done"
17358         done
17359
17360         do_nodes $mdts $LCTL set_param fail_loc=0
17361
17362         for (( i = 1; i <= MDSCOUNT; i++ )); do
17363                 # check cl_user1 is purged
17364                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17365                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17366         done
17367         return 0
17368 }
17369 run_test 160s "changelog garbage collect on idle records * time"
17370
17371 test_160t() {
17372         remote_mds_nodsh && skip "remote MDS with nodsh"
17373         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17374                 skip "Need MDS version at least 2.15.50"
17375
17376         local MDT0=$(facet_svc $SINGLEMDS)
17377         local cl_users
17378         local cl_user1
17379         local cl_user2
17380         local start
17381
17382         changelog_register --user user1 -m all ||
17383                 error "user1 failed to register"
17384
17385         mkdir_on_mdt0 $DIR/$tdir
17386         # create default overstripe to maximize changelog size
17387         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17388         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17389         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17390
17391         # user2 consumes less records so less space
17392         changelog_register --user user2 || error "user2 failed to register"
17393         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17394         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17395
17396         # check changelogs have been generated
17397         local nbcl=$(changelog_dump | wc -l)
17398         (( nbcl > 0 )) || error "no changelogs found"
17399
17400         # reduce the changelog_min_gc_interval to force check
17401         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17402                 local var="${param%=*}"
17403                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17404
17405                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17406                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17407                         error "unable to set mdd.*.$param"
17408         done
17409
17410         start=$SECONDS
17411         cl_users=(${CL_USERS[mds1]})
17412         cl_user1="${cl_users[0]}"
17413         cl_user2="${cl_users[1]}"
17414
17415         [[ -n $cl_user1 ]] ||
17416                 error "mds1: user #1 isn't registered"
17417         [[ -n $cl_user2 ]] ||
17418                 error "mds1: user #2 isn't registered"
17419
17420         # ensure we are past the previous changelog_min_gc_interval set above
17421         local sleep2=$((start + 2 - SECONDS))
17422         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17423
17424         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17425         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17426                         fail_val=$(((llog_size1 + llog_size2) / 2))
17427
17428         # Generate more changelog to trigger GC
17429         createmany -o $DIR/$tdir/u3_ 4 ||
17430                 error "create failed for more files"
17431
17432         # ensure gc thread is done
17433         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17434                 error "mds1: GC-thread not done"
17435
17436         do_facet mds1 $LCTL set_param fail_loc=0
17437
17438         # check cl_user1 is purged
17439         changelog_users mds1 | grep -q "$cl_user1" &&
17440                 error "User $cl_user1 is registered"
17441         # check cl_user2 is not purged
17442         changelog_users mds1 | grep -q "$cl_user2" ||
17443                 error "User $cl_user2 is not registered"
17444 }
17445 run_test 160t "changelog garbage collect on lack of space"
17446
17447 test_161a() {
17448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17449
17450         test_mkdir -c1 $DIR/$tdir
17451         cp /etc/hosts $DIR/$tdir/$tfile
17452         test_mkdir -c1 $DIR/$tdir/foo1
17453         test_mkdir -c1 $DIR/$tdir/foo2
17454         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17455         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17456         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17457         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17458         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17459         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17460                 $LFS fid2path $DIR $FID
17461                 error "bad link ea"
17462         fi
17463         # middle
17464         rm $DIR/$tdir/foo2/zachary
17465         # last
17466         rm $DIR/$tdir/foo2/thor
17467         # first
17468         rm $DIR/$tdir/$tfile
17469         # rename
17470         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17471         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17472                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17473         rm $DIR/$tdir/foo2/maggie
17474
17475         # overflow the EA
17476         local longname=$tfile.avg_len_is_thirty_two_
17477         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17478                 error_noexit 'failed to unlink many hardlinks'" EXIT
17479         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17480                 error "failed to hardlink many files"
17481         links=$($LFS fid2path $DIR $FID | wc -l)
17482         echo -n "${links}/1000 links in link EA"
17483         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17484 }
17485 run_test 161a "link ea sanity"
17486
17487 test_161b() {
17488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17489         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17490
17491         local MDTIDX=1
17492         local remote_dir=$DIR/$tdir/remote_dir
17493
17494         mkdir -p $DIR/$tdir
17495         $LFS mkdir -i $MDTIDX $remote_dir ||
17496                 error "create remote directory failed"
17497
17498         cp /etc/hosts $remote_dir/$tfile
17499         mkdir -p $remote_dir/foo1
17500         mkdir -p $remote_dir/foo2
17501         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17502         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17503         ln $remote_dir/$tfile $remote_dir/foo1/luna
17504         ln $remote_dir/$tfile $remote_dir/foo2/thor
17505
17506         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17507                      tr -d ']')
17508         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17509                 $LFS fid2path $DIR $FID
17510                 error "bad link ea"
17511         fi
17512         # middle
17513         rm $remote_dir/foo2/zachary
17514         # last
17515         rm $remote_dir/foo2/thor
17516         # first
17517         rm $remote_dir/$tfile
17518         # rename
17519         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17520         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17521         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17522                 $LFS fid2path $DIR $FID
17523                 error "bad link rename"
17524         fi
17525         rm $remote_dir/foo2/maggie
17526
17527         # overflow the EA
17528         local longname=filename_avg_len_is_thirty_two_
17529         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17530                 error "failed to hardlink many files"
17531         links=$($LFS fid2path $DIR $FID | wc -l)
17532         echo -n "${links}/1000 links in link EA"
17533         [[ ${links} -gt 60 ]] ||
17534                 error "expected at least 60 links in link EA"
17535         unlinkmany $remote_dir/foo2/$longname 1000 ||
17536         error "failed to unlink many hardlinks"
17537 }
17538 run_test 161b "link ea sanity under remote directory"
17539
17540 test_161c() {
17541         remote_mds_nodsh && skip "remote MDS with nodsh"
17542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17543         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17544                 skip "Need MDS version at least 2.1.5"
17545
17546         # define CLF_RENAME_LAST 0x0001
17547         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17548         changelog_register || error "changelog_register failed"
17549
17550         rm -rf $DIR/$tdir
17551         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17552         touch $DIR/$tdir/foo_161c
17553         touch $DIR/$tdir/bar_161c
17554         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17555         changelog_dump | grep RENME | tail -n 5
17556         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17557         changelog_clear 0 || error "changelog_clear failed"
17558         if [ x$flags != "x0x1" ]; then
17559                 error "flag $flags is not 0x1"
17560         fi
17561
17562         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17563         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17564         touch $DIR/$tdir/foo_161c
17565         touch $DIR/$tdir/bar_161c
17566         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17567         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17568         changelog_dump | grep RENME | tail -n 5
17569         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17570         changelog_clear 0 || error "changelog_clear failed"
17571         if [ x$flags != "x0x0" ]; then
17572                 error "flag $flags is not 0x0"
17573         fi
17574         echo "rename overwrite a target having nlink > 1," \
17575                 "changelog record has flags of $flags"
17576
17577         # rename doesn't overwrite a target (changelog flag 0x0)
17578         touch $DIR/$tdir/foo_161c
17579         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17580         changelog_dump | grep RENME | tail -n 5
17581         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17582         changelog_clear 0 || error "changelog_clear failed"
17583         if [ x$flags != "x0x0" ]; then
17584                 error "flag $flags is not 0x0"
17585         fi
17586         echo "rename doesn't overwrite a target," \
17587                 "changelog record has flags of $flags"
17588
17589         # define CLF_UNLINK_LAST 0x0001
17590         # unlink a file having nlink = 1 (changelog flag 0x1)
17591         rm -f $DIR/$tdir/foo2_161c
17592         changelog_dump | grep UNLNK | tail -n 5
17593         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17594         changelog_clear 0 || error "changelog_clear failed"
17595         if [ x$flags != "x0x1" ]; then
17596                 error "flag $flags is not 0x1"
17597         fi
17598         echo "unlink a file having nlink = 1," \
17599                 "changelog record has flags of $flags"
17600
17601         # unlink a file having nlink > 1 (changelog flag 0x0)
17602         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17603         rm -f $DIR/$tdir/foobar_161c
17604         changelog_dump | grep UNLNK | tail -n 5
17605         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17606         changelog_clear 0 || error "changelog_clear failed"
17607         if [ x$flags != "x0x0" ]; then
17608                 error "flag $flags is not 0x0"
17609         fi
17610         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17611 }
17612 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17613
17614 test_161d() {
17615         remote_mds_nodsh && skip "remote MDS with nodsh"
17616         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17617
17618         local pid
17619         local fid
17620
17621         changelog_register || error "changelog_register failed"
17622
17623         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17624         # interfer with $MOUNT/.lustre/fid/ access
17625         mkdir $DIR/$tdir
17626         [[ $? -eq 0 ]] || error "mkdir failed"
17627
17628         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17629         $LCTL set_param fail_loc=0x8000140c
17630         # 5s pause
17631         $LCTL set_param fail_val=5
17632
17633         # create file
17634         echo foofoo > $DIR/$tdir/$tfile &
17635         pid=$!
17636
17637         # wait for create to be delayed
17638         sleep 2
17639
17640         ps -p $pid
17641         [[ $? -eq 0 ]] || error "create should be blocked"
17642
17643         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17644         stack_trap "rm -f $tempfile"
17645         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17646         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17647         # some delay may occur during ChangeLog publishing and file read just
17648         # above, that could allow file write to happen finally
17649         [[ -s $tempfile ]] && echo "file should be empty"
17650
17651         $LCTL set_param fail_loc=0
17652
17653         wait $pid
17654         [[ $? -eq 0 ]] || error "create failed"
17655 }
17656 run_test 161d "create with concurrent .lustre/fid access"
17657
17658 check_path() {
17659         local expected="$1"
17660         shift
17661         local fid="$2"
17662
17663         local path
17664         path=$($LFS fid2path "$@")
17665         local rc=$?
17666
17667         if [ $rc -ne 0 ]; then
17668                 error "path looked up of '$expected' failed: rc=$rc"
17669         elif [ "$path" != "$expected" ]; then
17670                 error "path looked up '$path' instead of '$expected'"
17671         else
17672                 echo "FID '$fid' resolves to path '$path' as expected"
17673         fi
17674 }
17675
17676 test_162a() { # was test_162
17677         test_mkdir -p -c1 $DIR/$tdir/d2
17678         touch $DIR/$tdir/d2/$tfile
17679         touch $DIR/$tdir/d2/x1
17680         touch $DIR/$tdir/d2/x2
17681         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17682         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17683         # regular file
17684         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17685         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17686
17687         # softlink
17688         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17689         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17690         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17691
17692         # softlink to wrong file
17693         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17694         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17695         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17696
17697         # hardlink
17698         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17699         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17700         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17701         # fid2path dir/fsname should both work
17702         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17703         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17704
17705         # hardlink count: check that there are 2 links
17706         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17707         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17708
17709         # hardlink indexing: remove the first link
17710         rm $DIR/$tdir/d2/p/q/r/hlink
17711         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17712 }
17713 run_test 162a "path lookup sanity"
17714
17715 test_162b() {
17716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17718
17719         mkdir $DIR/$tdir
17720         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17721                                 error "create striped dir failed"
17722
17723         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17724                                         tail -n 1 | awk '{print $2}')
17725         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17726
17727         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17728         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17729
17730         # regular file
17731         for ((i=0;i<5;i++)); do
17732                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17733                         error "get fid for f$i failed"
17734                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17735
17736                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17737                         error "get fid for d$i failed"
17738                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17739         done
17740
17741         return 0
17742 }
17743 run_test 162b "striped directory path lookup sanity"
17744
17745 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17746 test_162c() {
17747         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17748                 skip "Need MDS version at least 2.7.51"
17749
17750         local lpath=$tdir.local
17751         local rpath=$tdir.remote
17752
17753         test_mkdir $DIR/$lpath
17754         test_mkdir $DIR/$rpath
17755
17756         for ((i = 0; i <= 101; i++)); do
17757                 lpath="$lpath/$i"
17758                 mkdir $DIR/$lpath
17759                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17760                         error "get fid for local directory $DIR/$lpath failed"
17761                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17762
17763                 rpath="$rpath/$i"
17764                 test_mkdir $DIR/$rpath
17765                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17766                         error "get fid for remote directory $DIR/$rpath failed"
17767                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17768         done
17769
17770         return 0
17771 }
17772 run_test 162c "fid2path works with paths 100 or more directories deep"
17773
17774 oalr_event_count() {
17775         local event="${1}"
17776         local trace="${2}"
17777
17778         awk -v name="${FSNAME}-OST0000" \
17779             -v event="${event}" \
17780             '$1 == "TRACE" && $2 == event && $3 == name' \
17781             "${trace}" |
17782         wc -l
17783 }
17784
17785 oalr_expect_event_count() {
17786         local event="${1}"
17787         local trace="${2}"
17788         local expect="${3}"
17789         local count
17790
17791         count=$(oalr_event_count "${event}" "${trace}")
17792         if ((count == expect)); then
17793                 return 0
17794         fi
17795
17796         error_noexit "${event} event count was '${count}', expected ${expect}"
17797         cat "${trace}" >&2
17798         exit 1
17799 }
17800
17801 cleanup_165() {
17802         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17803         stop ost1
17804         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17805 }
17806
17807 setup_165() {
17808         sync # Flush previous IOs so we can count log entries.
17809         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17810         stack_trap cleanup_165 EXIT
17811 }
17812
17813 test_165a() {
17814         local trace="/tmp/${tfile}.trace"
17815         local rc
17816         local count
17817
17818         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17819                 skip "OFD access log unsupported"
17820
17821         setup_165
17822         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17823         sleep 5
17824
17825         do_facet ost1 ofd_access_log_reader --list
17826         stop ost1
17827
17828         do_facet ost1 killall -TERM ofd_access_log_reader
17829         wait
17830         rc=$?
17831
17832         if ((rc != 0)); then
17833                 error "ofd_access_log_reader exited with rc = '${rc}'"
17834         fi
17835
17836         # Parse trace file for discovery events:
17837         oalr_expect_event_count alr_log_add "${trace}" 1
17838         oalr_expect_event_count alr_log_eof "${trace}" 1
17839         oalr_expect_event_count alr_log_free "${trace}" 1
17840 }
17841 run_test 165a "ofd access log discovery"
17842
17843 test_165b() {
17844         local trace="/tmp/${tfile}.trace"
17845         local file="${DIR}/${tfile}"
17846         local pfid1
17847         local pfid2
17848         local -a entry
17849         local rc
17850         local count
17851         local size
17852         local flags
17853
17854         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17855                 skip "OFD access log unsupported"
17856
17857         setup_165
17858         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17859         sleep 5
17860
17861         do_facet ost1 ofd_access_log_reader --list
17862
17863         lfs setstripe -c 1 -i 0 "${file}"
17864         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17865                 error "cannot create '${file}'"
17866
17867         sleep 5
17868         do_facet ost1 killall -TERM ofd_access_log_reader
17869         wait
17870         rc=$?
17871
17872         if ((rc != 0)); then
17873                 error "ofd_access_log_reader exited with rc = '${rc}'"
17874         fi
17875
17876         oalr_expect_event_count alr_log_entry "${trace}" 1
17877
17878         pfid1=$($LFS path2fid "${file}")
17879
17880         # 1     2             3   4    5     6   7    8    9     10
17881         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17882         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17883
17884         echo "entry = '${entry[*]}'" >&2
17885
17886         pfid2=${entry[4]}
17887         if [[ "${pfid1}" != "${pfid2}" ]]; then
17888                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17889         fi
17890
17891         size=${entry[8]}
17892         if ((size != 1048576)); then
17893                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17894         fi
17895
17896         flags=${entry[10]}
17897         if [[ "${flags}" != "w" ]]; then
17898                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17899         fi
17900
17901         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17902         sleep 5
17903
17904         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17905                 error "cannot read '${file}'"
17906         sleep 5
17907
17908         do_facet ost1 killall -TERM ofd_access_log_reader
17909         wait
17910         rc=$?
17911
17912         if ((rc != 0)); then
17913                 error "ofd_access_log_reader exited with rc = '${rc}'"
17914         fi
17915
17916         oalr_expect_event_count alr_log_entry "${trace}" 1
17917
17918         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17919         echo "entry = '${entry[*]}'" >&2
17920
17921         pfid2=${entry[4]}
17922         if [[ "${pfid1}" != "${pfid2}" ]]; then
17923                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17924         fi
17925
17926         size=${entry[8]}
17927         if ((size != 524288)); then
17928                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17929         fi
17930
17931         flags=${entry[10]}
17932         if [[ "${flags}" != "r" ]]; then
17933                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17934         fi
17935 }
17936 run_test 165b "ofd access log entries are produced and consumed"
17937
17938 test_165c() {
17939         local trace="/tmp/${tfile}.trace"
17940         local file="${DIR}/${tdir}/${tfile}"
17941
17942         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17943                 skip "OFD access log unsupported"
17944
17945         test_mkdir "${DIR}/${tdir}"
17946
17947         setup_165
17948         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17949         sleep 5
17950
17951         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17952
17953         # 4096 / 64 = 64. Create twice as many entries.
17954         for ((i = 0; i < 128; i++)); do
17955                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17956                         error "cannot create file"
17957         done
17958
17959         sync
17960
17961         do_facet ost1 killall -TERM ofd_access_log_reader
17962         wait
17963         rc=$?
17964         if ((rc != 0)); then
17965                 error "ofd_access_log_reader exited with rc = '${rc}'"
17966         fi
17967
17968         unlinkmany  "${file}-%d" 128
17969 }
17970 run_test 165c "full ofd access logs do not block IOs"
17971
17972 oal_get_read_count() {
17973         local stats="$1"
17974
17975         # STATS lustre-OST0001 alr_read_count 1
17976
17977         do_facet ost1 cat "${stats}" |
17978         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17979              END { print count; }'
17980 }
17981
17982 oal_expect_read_count() {
17983         local stats="$1"
17984         local count
17985         local expect="$2"
17986
17987         # Ask ofd_access_log_reader to write stats.
17988         do_facet ost1 killall -USR1 ofd_access_log_reader
17989
17990         # Allow some time for things to happen.
17991         sleep 1
17992
17993         count=$(oal_get_read_count "${stats}")
17994         if ((count == expect)); then
17995                 return 0
17996         fi
17997
17998         error_noexit "bad read count, got ${count}, expected ${expect}"
17999         do_facet ost1 cat "${stats}" >&2
18000         exit 1
18001 }
18002
18003 test_165d() {
18004         local stats="/tmp/${tfile}.stats"
18005         local file="${DIR}/${tdir}/${tfile}"
18006         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18007
18008         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18009                 skip "OFD access log unsupported"
18010
18011         test_mkdir "${DIR}/${tdir}"
18012
18013         setup_165
18014         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18015         sleep 5
18016
18017         lfs setstripe -c 1 -i 0 "${file}"
18018
18019         do_facet ost1 lctl set_param "${param}=rw"
18020         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18021                 error "cannot create '${file}'"
18022         oal_expect_read_count "${stats}" 1
18023
18024         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18025                 error "cannot read '${file}'"
18026         oal_expect_read_count "${stats}" 2
18027
18028         do_facet ost1 lctl set_param "${param}=r"
18029         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18030                 error "cannot create '${file}'"
18031         oal_expect_read_count "${stats}" 2
18032
18033         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18034                 error "cannot read '${file}'"
18035         oal_expect_read_count "${stats}" 3
18036
18037         do_facet ost1 lctl set_param "${param}=w"
18038         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18039                 error "cannot create '${file}'"
18040         oal_expect_read_count "${stats}" 4
18041
18042         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18043                 error "cannot read '${file}'"
18044         oal_expect_read_count "${stats}" 4
18045
18046         do_facet ost1 lctl set_param "${param}=0"
18047         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18048                 error "cannot create '${file}'"
18049         oal_expect_read_count "${stats}" 4
18050
18051         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18052                 error "cannot read '${file}'"
18053         oal_expect_read_count "${stats}" 4
18054
18055         do_facet ost1 killall -TERM ofd_access_log_reader
18056         wait
18057         rc=$?
18058         if ((rc != 0)); then
18059                 error "ofd_access_log_reader exited with rc = '${rc}'"
18060         fi
18061 }
18062 run_test 165d "ofd_access_log mask works"
18063
18064 test_165e() {
18065         local stats="/tmp/${tfile}.stats"
18066         local file0="${DIR}/${tdir}-0/${tfile}"
18067         local file1="${DIR}/${tdir}-1/${tfile}"
18068
18069         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18070                 skip "OFD access log unsupported"
18071
18072         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18073
18074         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18075         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18076
18077         lfs setstripe -c 1 -i 0 "${file0}"
18078         lfs setstripe -c 1 -i 0 "${file1}"
18079
18080         setup_165
18081         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18082         sleep 5
18083
18084         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18085                 error "cannot create '${file0}'"
18086         sync
18087         oal_expect_read_count "${stats}" 0
18088
18089         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18090                 error "cannot create '${file1}'"
18091         sync
18092         oal_expect_read_count "${stats}" 1
18093
18094         do_facet ost1 killall -TERM ofd_access_log_reader
18095         wait
18096         rc=$?
18097         if ((rc != 0)); then
18098                 error "ofd_access_log_reader exited with rc = '${rc}'"
18099         fi
18100 }
18101 run_test 165e "ofd_access_log MDT index filter works"
18102
18103 test_165f() {
18104         local trace="/tmp/${tfile}.trace"
18105         local rc
18106         local count
18107
18108         setup_165
18109         do_facet ost1 timeout 60 ofd_access_log_reader \
18110                 --exit-on-close --debug=- --trace=- > "${trace}" &
18111         sleep 5
18112         stop ost1
18113
18114         wait
18115         rc=$?
18116
18117         if ((rc != 0)); then
18118                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18119                 cat "${trace}"
18120                 exit 1
18121         fi
18122 }
18123 run_test 165f "ofd_access_log_reader --exit-on-close works"
18124
18125 test_169() {
18126         # do directio so as not to populate the page cache
18127         log "creating a 10 Mb file"
18128         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18129                 error "multiop failed while creating a file"
18130         log "starting reads"
18131         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18132         log "truncating the file"
18133         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18134                 error "multiop failed while truncating the file"
18135         log "killing dd"
18136         kill %+ || true # reads might have finished
18137         echo "wait until dd is finished"
18138         wait
18139         log "removing the temporary file"
18140         rm -rf $DIR/$tfile || error "tmp file removal failed"
18141 }
18142 run_test 169 "parallel read and truncate should not deadlock"
18143
18144 test_170() {
18145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18146
18147         $LCTL clear     # bug 18514
18148         $LCTL debug_daemon start $TMP/${tfile}_log_good
18149         touch $DIR/$tfile
18150         $LCTL debug_daemon stop
18151         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18152                 error "sed failed to read log_good"
18153
18154         $LCTL debug_daemon start $TMP/${tfile}_log_good
18155         rm -rf $DIR/$tfile
18156         $LCTL debug_daemon stop
18157
18158         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18159                error "lctl df log_bad failed"
18160
18161         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18162         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18163
18164         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18165         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18166
18167         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18168                 error "bad_line good_line1 good_line2 are empty"
18169
18170         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18171         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18172         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18173
18174         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18175         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18176         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18177
18178         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18179                 error "bad_line_new good_line_new are empty"
18180
18181         local expected_good=$((good_line1 + good_line2*2))
18182
18183         rm -f $TMP/${tfile}*
18184         # LU-231, short malformed line may not be counted into bad lines
18185         if [ $bad_line -ne $bad_line_new ] &&
18186                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18187                 error "expected $bad_line bad lines, but got $bad_line_new"
18188                 return 1
18189         fi
18190
18191         if [ $expected_good -ne $good_line_new ]; then
18192                 error "expected $expected_good good lines, but got $good_line_new"
18193                 return 2
18194         fi
18195         true
18196 }
18197 run_test 170 "test lctl df to handle corrupted log ====================="
18198
18199 test_171() { # bug20592
18200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18201
18202         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18203         $LCTL set_param fail_loc=0x50e
18204         $LCTL set_param fail_val=3000
18205         multiop_bg_pause $DIR/$tfile O_s || true
18206         local MULTIPID=$!
18207         kill -USR1 $MULTIPID
18208         # cause log dump
18209         sleep 3
18210         wait $MULTIPID
18211         if dmesg | grep "recursive fault"; then
18212                 error "caught a recursive fault"
18213         fi
18214         $LCTL set_param fail_loc=0
18215         true
18216 }
18217 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18218
18219 test_172() {
18220
18221         #define OBD_FAIL_OBD_CLEANUP  0x60e
18222         $LCTL set_param fail_loc=0x60e
18223         umount $MOUNT || error "umount $MOUNT failed"
18224         stack_trap "mount_client $MOUNT"
18225
18226         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18227                 error "no client OBDs are remained"
18228
18229         $LCTL dl | while read devno state type name foo; do
18230                 case $type in
18231                 lov|osc|lmv|mdc)
18232                         $LCTL --device $name cleanup
18233                         $LCTL --device $name detach
18234                         ;;
18235                 *)
18236                         # skip server devices
18237                         ;;
18238                 esac
18239         done
18240
18241         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18242                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18243                 error "some client OBDs are still remained"
18244         fi
18245
18246 }
18247 run_test 172 "manual device removal with lctl cleanup/detach ======"
18248
18249 # it would be good to share it with obdfilter-survey/iokit-libecho code
18250 setup_obdecho_osc () {
18251         local rc=0
18252         local ost_nid=$1
18253         local obdfilter_name=$2
18254         echo "Creating new osc for $obdfilter_name on $ost_nid"
18255         # make sure we can find loopback nid
18256         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18257
18258         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18259                            ${obdfilter_name}_osc_UUID || rc=2; }
18260         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18261                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18262         return $rc
18263 }
18264
18265 cleanup_obdecho_osc () {
18266         local obdfilter_name=$1
18267         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18268         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18269         return 0
18270 }
18271
18272 obdecho_test() {
18273         local OBD=$1
18274         local node=$2
18275         local pages=${3:-64}
18276         local rc=0
18277         local id
18278
18279         local count=10
18280         local obd_size=$(get_obd_size $node $OBD)
18281         local page_size=$(get_page_size $node)
18282         if [[ -n "$obd_size" ]]; then
18283                 local new_count=$((obd_size / (pages * page_size / 1024)))
18284                 [[ $new_count -ge $count ]] || count=$new_count
18285         fi
18286
18287         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18288         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18289                            rc=2; }
18290         if [ $rc -eq 0 ]; then
18291             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18292             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18293         fi
18294         echo "New object id is $id"
18295         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18296                            rc=4; }
18297         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18298                            "test_brw $count w v $pages $id" || rc=4; }
18299         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18300                            rc=4; }
18301         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18302                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18303         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18304                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18305         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18306         return $rc
18307 }
18308
18309 test_180a() {
18310         skip "obdecho on osc is no longer supported"
18311 }
18312 run_test 180a "test obdecho on osc"
18313
18314 test_180b() {
18315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18316         remote_ost_nodsh && skip "remote OST with nodsh"
18317
18318         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18319                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18320                 error "failed to load module obdecho"
18321
18322         local target=$(do_facet ost1 $LCTL dl |
18323                        awk '/obdfilter/ { print $4; exit; }')
18324
18325         if [ -n "$target" ]; then
18326                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18327         else
18328                 do_facet ost1 $LCTL dl
18329                 error "there is no obdfilter target on ost1"
18330         fi
18331 }
18332 run_test 180b "test obdecho directly on obdfilter"
18333
18334 test_180c() { # LU-2598
18335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18336         remote_ost_nodsh && skip "remote OST with nodsh"
18337         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18338                 skip "Need MDS version at least 2.4.0"
18339
18340         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18341                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18342                 error "failed to load module obdecho"
18343
18344         local target=$(do_facet ost1 $LCTL dl |
18345                        awk '/obdfilter/ { print $4; exit; }')
18346
18347         if [ -n "$target" ]; then
18348                 local pages=16384 # 64MB bulk I/O RPC size
18349
18350                 obdecho_test "$target" ost1 "$pages" ||
18351                         error "obdecho_test with pages=$pages failed with $?"
18352         else
18353                 do_facet ost1 $LCTL dl
18354                 error "there is no obdfilter target on ost1"
18355         fi
18356 }
18357 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18358
18359 test_181() { # bug 22177
18360         test_mkdir $DIR/$tdir
18361         # create enough files to index the directory
18362         createmany -o $DIR/$tdir/foobar 4000
18363         # print attributes for debug purpose
18364         lsattr -d .
18365         # open dir
18366         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18367         MULTIPID=$!
18368         # remove the files & current working dir
18369         unlinkmany $DIR/$tdir/foobar 4000
18370         rmdir $DIR/$tdir
18371         kill -USR1 $MULTIPID
18372         wait $MULTIPID
18373         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18374         return 0
18375 }
18376 run_test 181 "Test open-unlinked dir ========================"
18377
18378 test_182a() {
18379         local fcount=1000
18380         local tcount=10
18381
18382         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18383
18384         $LCTL set_param mdc.*.rpc_stats=clear
18385
18386         for (( i = 0; i < $tcount; i++ )) ; do
18387                 mkdir $DIR/$tdir/$i
18388         done
18389
18390         for (( i = 0; i < $tcount; i++ )) ; do
18391                 createmany -o $DIR/$tdir/$i/f- $fcount &
18392         done
18393         wait
18394
18395         for (( i = 0; i < $tcount; i++ )) ; do
18396                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18397         done
18398         wait
18399
18400         $LCTL get_param mdc.*.rpc_stats
18401
18402         rm -rf $DIR/$tdir
18403 }
18404 run_test 182a "Test parallel modify metadata operations from mdc"
18405
18406 test_182b() {
18407         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18408         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18409         local dcount=1000
18410         local tcount=10
18411         local stime
18412         local etime
18413         local delta
18414
18415         do_facet mds1 $LCTL list_param \
18416                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18417                 skip "MDS lacks parallel RPC handling"
18418
18419         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18420
18421         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18422                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18423
18424         stime=$(date +%s)
18425         createmany -i 0 -d $DIR/$tdir/t- $tcount
18426
18427         for (( i = 0; i < $tcount; i++ )) ; do
18428                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18429         done
18430         wait
18431         etime=$(date +%s)
18432         delta=$((etime - stime))
18433         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18434
18435         stime=$(date +%s)
18436         for (( i = 0; i < $tcount; i++ )) ; do
18437                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18438         done
18439         wait
18440         etime=$(date +%s)
18441         delta=$((etime - stime))
18442         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18443
18444         rm -rf $DIR/$tdir
18445
18446         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18447
18448         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18449
18450         stime=$(date +%s)
18451         createmany -i 0 -d $DIR/$tdir/t- $tcount
18452
18453         for (( i = 0; i < $tcount; i++ )) ; do
18454                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18455         done
18456         wait
18457         etime=$(date +%s)
18458         delta=$((etime - stime))
18459         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18460
18461         stime=$(date +%s)
18462         for (( i = 0; i < $tcount; i++ )) ; do
18463                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18464         done
18465         wait
18466         etime=$(date +%s)
18467         delta=$((etime - stime))
18468         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18469
18470         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18471 }
18472 run_test 182b "Test parallel modify metadata operations from osp"
18473
18474 test_183() { # LU-2275
18475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18476         remote_mds_nodsh && skip "remote MDS with nodsh"
18477         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18478                 skip "Need MDS version at least 2.3.56"
18479
18480         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18481         echo aaa > $DIR/$tdir/$tfile
18482
18483 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18484         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18485
18486         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18487         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18488
18489         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18490
18491         # Flush negative dentry cache
18492         touch $DIR/$tdir/$tfile
18493
18494         # We are not checking for any leaked references here, they'll
18495         # become evident next time we do cleanup with module unload.
18496         rm -rf $DIR/$tdir
18497 }
18498 run_test 183 "No crash or request leak in case of strange dispositions ========"
18499
18500 # test suite 184 is for LU-2016, LU-2017
18501 test_184a() {
18502         check_swap_layouts_support
18503
18504         dir0=$DIR/$tdir/$testnum
18505         test_mkdir -p -c1 $dir0
18506         ref1=/etc/passwd
18507         ref2=/etc/group
18508         file1=$dir0/f1
18509         file2=$dir0/f2
18510         $LFS setstripe -c1 $file1
18511         cp $ref1 $file1
18512         $LFS setstripe -c2 $file2
18513         cp $ref2 $file2
18514         gen1=$($LFS getstripe -g $file1)
18515         gen2=$($LFS getstripe -g $file2)
18516
18517         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18518         gen=$($LFS getstripe -g $file1)
18519         [[ $gen1 != $gen ]] ||
18520                 error "Layout generation on $file1 does not change"
18521         gen=$($LFS getstripe -g $file2)
18522         [[ $gen2 != $gen ]] ||
18523                 error "Layout generation on $file2 does not change"
18524
18525         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18526         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18527
18528         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18529 }
18530 run_test 184a "Basic layout swap"
18531
18532 test_184b() {
18533         check_swap_layouts_support
18534
18535         dir0=$DIR/$tdir/$testnum
18536         mkdir -p $dir0 || error "creating dir $dir0"
18537         file1=$dir0/f1
18538         file2=$dir0/f2
18539         file3=$dir0/f3
18540         dir1=$dir0/d1
18541         dir2=$dir0/d2
18542         mkdir $dir1 $dir2
18543         $LFS setstripe -c1 $file1
18544         $LFS setstripe -c2 $file2
18545         $LFS setstripe -c1 $file3
18546         chown $RUNAS_ID $file3
18547         gen1=$($LFS getstripe -g $file1)
18548         gen2=$($LFS getstripe -g $file2)
18549
18550         $LFS swap_layouts $dir1 $dir2 &&
18551                 error "swap of directories layouts should fail"
18552         $LFS swap_layouts $dir1 $file1 &&
18553                 error "swap of directory and file layouts should fail"
18554         $RUNAS $LFS swap_layouts $file1 $file2 &&
18555                 error "swap of file we cannot write should fail"
18556         $LFS swap_layouts $file1 $file3 &&
18557                 error "swap of file with different owner should fail"
18558         /bin/true # to clear error code
18559 }
18560 run_test 184b "Forbidden layout swap (will generate errors)"
18561
18562 test_184c() {
18563         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18564         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18565         check_swap_layouts_support
18566         check_swap_layout_no_dom $DIR
18567
18568         local dir0=$DIR/$tdir/$testnum
18569         mkdir -p $dir0 || error "creating dir $dir0"
18570
18571         local ref1=$dir0/ref1
18572         local ref2=$dir0/ref2
18573         local file1=$dir0/file1
18574         local file2=$dir0/file2
18575         # create a file large enough for the concurrent test
18576         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18577         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18578         echo "ref file size: ref1($(stat -c %s $ref1))," \
18579              "ref2($(stat -c %s $ref2))"
18580
18581         cp $ref2 $file2
18582         dd if=$ref1 of=$file1 bs=16k &
18583         local DD_PID=$!
18584
18585         # Make sure dd starts to copy file, but wait at most 5 seconds
18586         local loops=0
18587         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18588
18589         $LFS swap_layouts $file1 $file2
18590         local rc=$?
18591         wait $DD_PID
18592         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18593         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18594
18595         # how many bytes copied before swapping layout
18596         local copied=$(stat -c %s $file2)
18597         local remaining=$(stat -c %s $ref1)
18598         remaining=$((remaining - copied))
18599         echo "Copied $copied bytes before swapping layout..."
18600
18601         cmp -n $copied $file1 $ref2 | grep differ &&
18602                 error "Content mismatch [0, $copied) of ref2 and file1"
18603         cmp -n $copied $file2 $ref1 ||
18604                 error "Content mismatch [0, $copied) of ref1 and file2"
18605         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18606                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18607
18608         # clean up
18609         rm -f $ref1 $ref2 $file1 $file2
18610 }
18611 run_test 184c "Concurrent write and layout swap"
18612
18613 test_184d() {
18614         check_swap_layouts_support
18615         check_swap_layout_no_dom $DIR
18616         [ -z "$(which getfattr 2>/dev/null)" ] &&
18617                 skip_env "no getfattr command"
18618
18619         local file1=$DIR/$tdir/$tfile-1
18620         local file2=$DIR/$tdir/$tfile-2
18621         local file3=$DIR/$tdir/$tfile-3
18622         local lovea1
18623         local lovea2
18624
18625         mkdir -p $DIR/$tdir
18626         touch $file1 || error "create $file1 failed"
18627         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18628                 error "create $file2 failed"
18629         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18630                 error "create $file3 failed"
18631         lovea1=$(get_layout_param $file1)
18632
18633         $LFS swap_layouts $file2 $file3 ||
18634                 error "swap $file2 $file3 layouts failed"
18635         $LFS swap_layouts $file1 $file2 ||
18636                 error "swap $file1 $file2 layouts failed"
18637
18638         lovea2=$(get_layout_param $file2)
18639         echo "$lovea1"
18640         echo "$lovea2"
18641         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18642
18643         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18644         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18645 }
18646 run_test 184d "allow stripeless layouts swap"
18647
18648 test_184e() {
18649         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18650                 skip "Need MDS version at least 2.6.94"
18651         check_swap_layouts_support
18652         check_swap_layout_no_dom $DIR
18653         [ -z "$(which getfattr 2>/dev/null)" ] &&
18654                 skip_env "no getfattr command"
18655
18656         local file1=$DIR/$tdir/$tfile-1
18657         local file2=$DIR/$tdir/$tfile-2
18658         local file3=$DIR/$tdir/$tfile-3
18659         local lovea
18660
18661         mkdir -p $DIR/$tdir
18662         touch $file1 || error "create $file1 failed"
18663         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18664                 error "create $file2 failed"
18665         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18666                 error "create $file3 failed"
18667
18668         $LFS swap_layouts $file1 $file2 ||
18669                 error "swap $file1 $file2 layouts failed"
18670
18671         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18672         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18673
18674         echo 123 > $file1 || error "Should be able to write into $file1"
18675
18676         $LFS swap_layouts $file1 $file3 ||
18677                 error "swap $file1 $file3 layouts failed"
18678
18679         echo 123 > $file1 || error "Should be able to write into $file1"
18680
18681         rm -rf $file1 $file2 $file3
18682 }
18683 run_test 184e "Recreate layout after stripeless layout swaps"
18684
18685 test_184f() {
18686         # Create a file with name longer than sizeof(struct stat) ==
18687         # 144 to see if we can get chars from the file name to appear
18688         # in the returned striping. Note that 'f' == 0x66.
18689         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18690
18691         mkdir -p $DIR/$tdir
18692         mcreate $DIR/$tdir/$file
18693         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18694                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18695         fi
18696 }
18697 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18698
18699 test_185() { # LU-2441
18700         # LU-3553 - no volatile file support in old servers
18701         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18702                 skip "Need MDS version at least 2.3.60"
18703
18704         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18705         touch $DIR/$tdir/spoo
18706         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18707         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18708                 error "cannot create/write a volatile file"
18709         [ "$FILESET" == "" ] &&
18710         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18711                 error "FID is still valid after close"
18712
18713         multiop_bg_pause $DIR/$tdir vVw4096_c
18714         local multi_pid=$!
18715
18716         local OLD_IFS=$IFS
18717         IFS=":"
18718         local fidv=($fid)
18719         IFS=$OLD_IFS
18720         # assume that the next FID for this client is sequential, since stdout
18721         # is unfortunately eaten by multiop_bg_pause
18722         local n=$((${fidv[1]} + 1))
18723         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18724         if [ "$FILESET" == "" ]; then
18725                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18726                         error "FID is missing before close"
18727         fi
18728         kill -USR1 $multi_pid
18729         # 1 second delay, so if mtime change we will see it
18730         sleep 1
18731         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18732         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18733 }
18734 run_test 185 "Volatile file support"
18735
18736 function create_check_volatile() {
18737         local idx=$1
18738         local tgt
18739
18740         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18741         local PID=$!
18742         sleep 1
18743         local FID=$(cat /tmp/${tfile}.fid)
18744         [ "$FID" == "" ] && error "can't get FID for volatile"
18745         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18746         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18747         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18748         kill -USR1 $PID
18749         wait
18750         sleep 1
18751         cancel_lru_locks mdc # flush opencache
18752         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18753         return 0
18754 }
18755
18756 test_185a(){
18757         # LU-12516 - volatile creation via .lustre
18758         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18759                 skip "Need MDS version at least 2.3.55"
18760
18761         create_check_volatile 0
18762         [ $MDSCOUNT -lt 2 ] && return 0
18763
18764         # DNE case
18765         create_check_volatile 1
18766
18767         return 0
18768 }
18769 run_test 185a "Volatile file creation in .lustre/fid/"
18770
18771 test_187a() {
18772         remote_mds_nodsh && skip "remote MDS with nodsh"
18773         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18774                 skip "Need MDS version at least 2.3.0"
18775
18776         local dir0=$DIR/$tdir/$testnum
18777         mkdir -p $dir0 || error "creating dir $dir0"
18778
18779         local file=$dir0/file1
18780         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18781         local dv1=$($LFS data_version $file)
18782         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18783         local dv2=$($LFS data_version $file)
18784         [[ $dv1 != $dv2 ]] ||
18785                 error "data version did not change on write $dv1 == $dv2"
18786
18787         # clean up
18788         rm -f $file1
18789 }
18790 run_test 187a "Test data version change"
18791
18792 test_187b() {
18793         remote_mds_nodsh && skip "remote MDS with nodsh"
18794         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18795                 skip "Need MDS version at least 2.3.0"
18796
18797         local dir0=$DIR/$tdir/$testnum
18798         mkdir -p $dir0 || error "creating dir $dir0"
18799
18800         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18801         [[ ${DV[0]} != ${DV[1]} ]] ||
18802                 error "data version did not change on write"\
18803                       " ${DV[0]} == ${DV[1]}"
18804
18805         # clean up
18806         rm -f $file1
18807 }
18808 run_test 187b "Test data version change on volatile file"
18809
18810 test_200() {
18811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18812         remote_mgs_nodsh && skip "remote MGS with nodsh"
18813         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18814
18815         local POOL=${POOL:-cea1}
18816         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18817         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18818         # Pool OST targets
18819         local first_ost=0
18820         local last_ost=$(($OSTCOUNT - 1))
18821         local ost_step=2
18822         local ost_list=$(seq $first_ost $ost_step $last_ost)
18823         local ost_range="$first_ost $last_ost $ost_step"
18824         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18825         local file_dir=$POOL_ROOT/file_tst
18826         local subdir=$test_path/subdir
18827         local rc=0
18828
18829         while : ; do
18830                 # former test_200a test_200b
18831                 pool_add $POOL                          || { rc=$? ; break; }
18832                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18833                 # former test_200c test_200d
18834                 mkdir -p $test_path
18835                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18836                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18837                 mkdir -p $subdir
18838                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18839                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18840                                                         || { rc=$? ; break; }
18841                 # former test_200e test_200f
18842                 local files=$((OSTCOUNT*3))
18843                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18844                                                         || { rc=$? ; break; }
18845                 pool_create_files $POOL $file_dir $files "$ost_list" \
18846                                                         || { rc=$? ; break; }
18847                 # former test_200g test_200h
18848                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18849                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18850
18851                 # former test_201a test_201b test_201c
18852                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18853
18854                 local f=$test_path/$tfile
18855                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18856                 pool_remove $POOL $f                    || { rc=$? ; break; }
18857                 break
18858         done
18859
18860         destroy_test_pools
18861
18862         return $rc
18863 }
18864 run_test 200 "OST pools"
18865
18866 # usage: default_attr <count | size | offset>
18867 default_attr() {
18868         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18869 }
18870
18871 # usage: check_default_stripe_attr
18872 check_default_stripe_attr() {
18873         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18874         case $1 in
18875         --stripe-count|-c)
18876                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18877         --stripe-size|-S)
18878                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18879         --stripe-index|-i)
18880                 EXPECTED=-1;;
18881         *)
18882                 error "unknown getstripe attr '$1'"
18883         esac
18884
18885         [ $ACTUAL == $EXPECTED ] ||
18886                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18887 }
18888
18889 test_204a() {
18890         test_mkdir $DIR/$tdir
18891         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18892
18893         check_default_stripe_attr --stripe-count
18894         check_default_stripe_attr --stripe-size
18895         check_default_stripe_attr --stripe-index
18896 }
18897 run_test 204a "Print default stripe attributes"
18898
18899 test_204b() {
18900         test_mkdir $DIR/$tdir
18901         $LFS setstripe --stripe-count 1 $DIR/$tdir
18902
18903         check_default_stripe_attr --stripe-size
18904         check_default_stripe_attr --stripe-index
18905 }
18906 run_test 204b "Print default stripe size and offset"
18907
18908 test_204c() {
18909         test_mkdir $DIR/$tdir
18910         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18911
18912         check_default_stripe_attr --stripe-count
18913         check_default_stripe_attr --stripe-index
18914 }
18915 run_test 204c "Print default stripe count and offset"
18916
18917 test_204d() {
18918         test_mkdir $DIR/$tdir
18919         $LFS setstripe --stripe-index 0 $DIR/$tdir
18920
18921         check_default_stripe_attr --stripe-count
18922         check_default_stripe_attr --stripe-size
18923 }
18924 run_test 204d "Print default stripe count and size"
18925
18926 test_204e() {
18927         test_mkdir $DIR/$tdir
18928         $LFS setstripe -d $DIR/$tdir
18929
18930         check_default_stripe_attr --stripe-count --raw
18931         check_default_stripe_attr --stripe-size --raw
18932         check_default_stripe_attr --stripe-index --raw
18933 }
18934 run_test 204e "Print raw stripe attributes"
18935
18936 test_204f() {
18937         test_mkdir $DIR/$tdir
18938         $LFS setstripe --stripe-count 1 $DIR/$tdir
18939
18940         check_default_stripe_attr --stripe-size --raw
18941         check_default_stripe_attr --stripe-index --raw
18942 }
18943 run_test 204f "Print raw stripe size and offset"
18944
18945 test_204g() {
18946         test_mkdir $DIR/$tdir
18947         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18948
18949         check_default_stripe_attr --stripe-count --raw
18950         check_default_stripe_attr --stripe-index --raw
18951 }
18952 run_test 204g "Print raw stripe count and offset"
18953
18954 test_204h() {
18955         test_mkdir $DIR/$tdir
18956         $LFS setstripe --stripe-index 0 $DIR/$tdir
18957
18958         check_default_stripe_attr --stripe-count --raw
18959         check_default_stripe_attr --stripe-size --raw
18960 }
18961 run_test 204h "Print raw stripe count and size"
18962
18963 # Figure out which job scheduler is being used, if any,
18964 # or use a fake one
18965 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18966         JOBENV=SLURM_JOB_ID
18967 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18968         JOBENV=LSB_JOBID
18969 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18970         JOBENV=PBS_JOBID
18971 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18972         JOBENV=LOADL_STEP_ID
18973 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18974         JOBENV=JOB_ID
18975 else
18976         $LCTL list_param jobid_name > /dev/null 2>&1
18977         if [ $? -eq 0 ]; then
18978                 JOBENV=nodelocal
18979         else
18980                 JOBENV=FAKE_JOBID
18981         fi
18982 fi
18983 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18984
18985 verify_jobstats() {
18986         local cmd=($1)
18987         shift
18988         local facets="$@"
18989
18990 # we don't really need to clear the stats for this test to work, since each
18991 # command has a unique jobid, but it makes debugging easier if needed.
18992 #       for facet in $facets; do
18993 #               local dev=$(convert_facet2label $facet)
18994 #               # clear old jobstats
18995 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18996 #       done
18997
18998         # use a new JobID for each test, or we might see an old one
18999         [ "$JOBENV" = "FAKE_JOBID" ] &&
19000                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19001
19002         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19003
19004         [ "$JOBENV" = "nodelocal" ] && {
19005                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19006                 $LCTL set_param jobid_name=$FAKE_JOBID
19007                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19008         }
19009
19010         log "Test: ${cmd[*]}"
19011         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19012
19013         if [ $JOBENV = "FAKE_JOBID" ]; then
19014                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19015         else
19016                 ${cmd[*]}
19017         fi
19018
19019         # all files are created on OST0000
19020         for facet in $facets; do
19021                 local stats="*.$(convert_facet2label $facet).job_stats"
19022
19023                 # strip out libtool wrappers for in-tree executables
19024                 if (( $(do_facet $facet lctl get_param $stats |
19025                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19026                         do_facet $facet lctl get_param $stats
19027                         error "No jobstats for $JOBVAL found on $facet::$stats"
19028                 fi
19029         done
19030 }
19031
19032 jobstats_set() {
19033         local new_jobenv=$1
19034
19035         set_persistent_param_and_check client "jobid_var" \
19036                 "$FSNAME.sys.jobid_var" $new_jobenv
19037 }
19038
19039 test_205a() { # Job stats
19040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19041         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19042                 skip "Need MDS version with at least 2.7.1"
19043         remote_mgs_nodsh && skip "remote MGS with nodsh"
19044         remote_mds_nodsh && skip "remote MDS with nodsh"
19045         remote_ost_nodsh && skip "remote OST with nodsh"
19046         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19047                 skip "Server doesn't support jobstats"
19048         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19049
19050         local old_jobenv=$($LCTL get_param -n jobid_var)
19051         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19052
19053         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19054                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19055         else
19056                 stack_trap "do_facet mgs $PERM_CMD \
19057                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19058         fi
19059         changelog_register
19060
19061         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19062                                 mdt.*.job_cleanup_interval | head -n 1)
19063         local new_interval=5
19064         do_facet $SINGLEMDS \
19065                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19066         stack_trap "do_facet $SINGLEMDS \
19067                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19068         local start=$SECONDS
19069
19070         local cmd
19071         # mkdir
19072         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19073         verify_jobstats "$cmd" "$SINGLEMDS"
19074         # rmdir
19075         cmd="rmdir $DIR/$tdir"
19076         verify_jobstats "$cmd" "$SINGLEMDS"
19077         # mkdir on secondary MDT
19078         if [ $MDSCOUNT -gt 1 ]; then
19079                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19080                 verify_jobstats "$cmd" "mds2"
19081         fi
19082         # mknod
19083         cmd="mknod $DIR/$tfile c 1 3"
19084         verify_jobstats "$cmd" "$SINGLEMDS"
19085         # unlink
19086         cmd="rm -f $DIR/$tfile"
19087         verify_jobstats "$cmd" "$SINGLEMDS"
19088         # create all files on OST0000 so verify_jobstats can find OST stats
19089         # open & close
19090         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19091         verify_jobstats "$cmd" "$SINGLEMDS"
19092         # setattr
19093         cmd="touch $DIR/$tfile"
19094         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19095         # write
19096         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19097         verify_jobstats "$cmd" "ost1"
19098         # read
19099         cancel_lru_locks osc
19100         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19101         verify_jobstats "$cmd" "ost1"
19102         # truncate
19103         cmd="$TRUNCATE $DIR/$tfile 0"
19104         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19105         # rename
19106         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19107         verify_jobstats "$cmd" "$SINGLEMDS"
19108         # jobstats expiry - sleep until old stats should be expired
19109         local left=$((new_interval + 5 - (SECONDS - start)))
19110         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19111                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19112                         "0" $left
19113         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19114         verify_jobstats "$cmd" "$SINGLEMDS"
19115         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19116             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19117
19118         # Ensure that jobid are present in changelog (if supported by MDS)
19119         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19120                 changelog_dump | tail -10
19121                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19122                 [ $jobids -eq 9 ] ||
19123                         error "Wrong changelog jobid count $jobids != 9"
19124
19125                 # LU-5862
19126                 JOBENV="disable"
19127                 jobstats_set $JOBENV
19128                 touch $DIR/$tfile
19129                 changelog_dump | grep $tfile
19130                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19131                 [ $jobids -eq 0 ] ||
19132                         error "Unexpected jobids when jobid_var=$JOBENV"
19133         fi
19134
19135         # test '%j' access to environment variable - if supported
19136         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19137                 JOBENV="JOBCOMPLEX"
19138                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19139
19140                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19141         fi
19142
19143         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19144                 JOBENV="JOBCOMPLEX"
19145                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19146
19147                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19148         fi
19149
19150         # test '%j' access to per-session jobid - if supported
19151         if lctl list_param jobid_this_session > /dev/null 2>&1
19152         then
19153                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19154                 lctl set_param jobid_this_session=$USER
19155
19156                 JOBENV="JOBCOMPLEX"
19157                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19158
19159                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19160         fi
19161 }
19162 run_test 205a "Verify job stats"
19163
19164 # LU-13117, LU-13597
19165 test_205b() {
19166         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19167                 skip "Need MDS version at least 2.13.54.91"
19168
19169         local job_stats="mdt.*.job_stats"
19170         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19171
19172         do_facet mds1 $LCTL set_param $job_stats=clear
19173
19174         # Setting jobid_var to USER might not be supported
19175         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19176         $LCTL set_param jobid_var=USER || true
19177         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19178         $LCTL set_param jobid_name="%j.%e.%u"
19179
19180         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19181         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19182                 { do_facet mds1 $LCTL get_param $job_stats;
19183                   error "Unexpected jobid found"; }
19184         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19185                 { do_facet mds1 $LCTL get_param $job_stats;
19186                   error "wrong job_stats format found"; }
19187
19188         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19189                 echo "MDS does not yet escape jobid" && return 0
19190         $LCTL set_param jobid_var=TEST205b
19191         env -i TEST205b="has sp" touch $DIR/$tfile.2
19192         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19193                 { do_facet mds1 $LCTL get_param $job_stats;
19194                   error "jobid not escaped"; }
19195 }
19196 run_test 205b "Verify job stats jobid and output format"
19197
19198 # LU-13733
19199 test_205c() {
19200         $LCTL set_param llite.*.stats=0
19201         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19202         $LCTL get_param llite.*.stats
19203         $LCTL get_param llite.*.stats | grep \
19204                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19205                         error "wrong client stats format found"
19206 }
19207 run_test 205c "Verify client stats format"
19208
19209 test_205d() {
19210         local file=$DIR/$tdir/$tfile
19211
19212         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
19213                 skip "need lustre >= 2.15.51"
19214         (( $OST1_VERSION >= $(version_code 2.15.52) )) ||
19215                 skip "need lustre >= 2.15.51"
19216         verify_yaml_available || skip_env "YAML verification not installed"
19217
19218         test_mkdir -i 0 $DIR/$tdir
19219         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19220
19221         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19222                 error "failed to write data to $file"
19223         mv $file $file.2
19224
19225         echo -n 'verify rename_stats...'
19226         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19227                 verify_yaml || error "rename_stats is not valid YAML"
19228         echo " OK"
19229
19230         echo -n 'verify mdt job_stats...'
19231         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19232                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19233         echo " OK"
19234
19235         echo -n 'verify ost job_stats...'
19236         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19237                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19238         echo " OK"
19239 }
19240 run_test 205d "verify the format of some stats files"
19241
19242 # LU-1480, LU-1773 and LU-1657
19243 test_206() {
19244         mkdir -p $DIR/$tdir
19245         $LFS setstripe -c -1 $DIR/$tdir
19246 #define OBD_FAIL_LOV_INIT 0x1403
19247         $LCTL set_param fail_loc=0xa0001403
19248         $LCTL set_param fail_val=1
19249         touch $DIR/$tdir/$tfile || true
19250 }
19251 run_test 206 "fail lov_init_raid0() doesn't lbug"
19252
19253 test_207a() {
19254         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19255         local fsz=`stat -c %s $DIR/$tfile`
19256         cancel_lru_locks mdc
19257
19258         # do not return layout in getattr intent
19259 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19260         $LCTL set_param fail_loc=0x170
19261         local sz=`stat -c %s $DIR/$tfile`
19262
19263         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19264
19265         rm -rf $DIR/$tfile
19266 }
19267 run_test 207a "can refresh layout at glimpse"
19268
19269 test_207b() {
19270         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19271         local cksum=`md5sum $DIR/$tfile`
19272         local fsz=`stat -c %s $DIR/$tfile`
19273         cancel_lru_locks mdc
19274         cancel_lru_locks osc
19275
19276         # do not return layout in getattr intent
19277 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19278         $LCTL set_param fail_loc=0x171
19279
19280         # it will refresh layout after the file is opened but before read issues
19281         echo checksum is "$cksum"
19282         echo "$cksum" |md5sum -c --quiet || error "file differs"
19283
19284         rm -rf $DIR/$tfile
19285 }
19286 run_test 207b "can refresh layout at open"
19287
19288 test_208() {
19289         # FIXME: in this test suite, only RD lease is used. This is okay
19290         # for now as only exclusive open is supported. After generic lease
19291         # is done, this test suite should be revised. - Jinshan
19292
19293         remote_mds_nodsh && skip "remote MDS with nodsh"
19294         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19295                 skip "Need MDS version at least 2.4.52"
19296
19297         echo "==== test 1: verify get lease work"
19298         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19299
19300         echo "==== test 2: verify lease can be broken by upcoming open"
19301         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19302         local PID=$!
19303         sleep 2
19304
19305         $MULTIOP $DIR/$tfile oO_RDWR:c
19306         kill -USR1 $PID && wait $PID || error "break lease error"
19307
19308         echo "==== test 3: verify lease can't be granted if an open already exists"
19309         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19310         local PID=$!
19311         sleep 2
19312
19313         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19314         kill -USR1 $PID && wait $PID || error "open file error"
19315
19316         echo "==== test 4: lease can sustain over recovery"
19317         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19318         PID=$!
19319         sleep 2
19320
19321         fail mds1
19322
19323         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19324
19325         echo "==== test 5: lease broken can't be regained by replay"
19326         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19327         PID=$!
19328         sleep 2
19329
19330         # open file to break lease and then recovery
19331         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19332         fail mds1
19333
19334         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19335
19336         rm -f $DIR/$tfile
19337 }
19338 run_test 208 "Exclusive open"
19339
19340 test_209() {
19341         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19342                 skip_env "must have disp_stripe"
19343
19344         touch $DIR/$tfile
19345         sync; sleep 5; sync;
19346
19347         echo 3 > /proc/sys/vm/drop_caches
19348         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19349                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19350         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19351
19352         # open/close 500 times
19353         for i in $(seq 500); do
19354                 cat $DIR/$tfile
19355         done
19356
19357         echo 3 > /proc/sys/vm/drop_caches
19358         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19359                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19360         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19361
19362         echo "before: $req_before, after: $req_after"
19363         [ $((req_after - req_before)) -ge 300 ] &&
19364                 error "open/close requests are not freed"
19365         return 0
19366 }
19367 run_test 209 "read-only open/close requests should be freed promptly"
19368
19369 test_210() {
19370         local pid
19371
19372         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19373         pid=$!
19374         sleep 1
19375
19376         $LFS getstripe $DIR/$tfile
19377         kill -USR1 $pid
19378         wait $pid || error "multiop failed"
19379
19380         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19381         pid=$!
19382         sleep 1
19383
19384         $LFS getstripe $DIR/$tfile
19385         kill -USR1 $pid
19386         wait $pid || error "multiop failed"
19387 }
19388 run_test 210 "lfs getstripe does not break leases"
19389
19390 test_212() {
19391         size=`date +%s`
19392         size=$((size % 8192 + 1))
19393         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19394         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19395         rm -f $DIR/f212 $DIR/f212.xyz
19396 }
19397 run_test 212 "Sendfile test ============================================"
19398
19399 test_213() {
19400         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19401         cancel_lru_locks osc
19402         lctl set_param fail_loc=0x8000040f
19403         # generate a read lock
19404         cat $DIR/$tfile > /dev/null
19405         # write to the file, it will try to cancel the above read lock.
19406         cat /etc/hosts >> $DIR/$tfile
19407 }
19408 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19409
19410 test_214() { # for bug 20133
19411         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19412         for (( i=0; i < 340; i++ )) ; do
19413                 touch $DIR/$tdir/d214c/a$i
19414         done
19415
19416         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19417         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19418         ls $DIR/d214c || error "ls $DIR/d214c failed"
19419         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19420         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19421 }
19422 run_test 214 "hash-indexed directory test - bug 20133"
19423
19424 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19425 create_lnet_proc_files() {
19426         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19427 }
19428
19429 # counterpart of create_lnet_proc_files
19430 remove_lnet_proc_files() {
19431         rm -f $TMP/lnet_$1.sys
19432 }
19433
19434 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19435 # 3rd arg as regexp for body
19436 check_lnet_proc_stats() {
19437         local l=$(cat "$TMP/lnet_$1" |wc -l)
19438         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19439
19440         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19441 }
19442
19443 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19444 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19445 # optional and can be regexp for 2nd line (lnet.routes case)
19446 check_lnet_proc_entry() {
19447         local blp=2          # blp stands for 'position of 1st line of body'
19448         [ -z "$5" ] || blp=3 # lnet.routes case
19449
19450         local l=$(cat "$TMP/lnet_$1" |wc -l)
19451         # subtracting one from $blp because the body can be empty
19452         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19453
19454         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19455                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19456
19457         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19458                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19459
19460         # bail out if any unexpected line happened
19461         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19462         [ "$?" != 0 ] || error "$2 misformatted"
19463 }
19464
19465 test_215() { # for bugs 18102, 21079, 21517
19466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19467
19468         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19469         local P='[1-9][0-9]*'           # positive numeric
19470         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19471         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19472         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19473         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19474
19475         local L1 # regexp for 1st line
19476         local L2 # regexp for 2nd line (optional)
19477         local BR # regexp for the rest (body)
19478
19479         # lnet.stats should look as 11 space-separated non-negative numerics
19480         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19481         create_lnet_proc_files "stats"
19482         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19483         remove_lnet_proc_files "stats"
19484
19485         # lnet.routes should look like this:
19486         # Routing disabled/enabled
19487         # net hops priority state router
19488         # where net is a string like tcp0, hops > 0, priority >= 0,
19489         # state is up/down,
19490         # router is a string like 192.168.1.1@tcp2
19491         L1="^Routing (disabled|enabled)$"
19492         L2="^net +hops +priority +state +router$"
19493         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19494         create_lnet_proc_files "routes"
19495         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19496         remove_lnet_proc_files "routes"
19497
19498         # lnet.routers should look like this:
19499         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19500         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19501         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19502         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19503         L1="^ref +rtr_ref +alive +router$"
19504         BR="^$P +$P +(up|down) +$NID$"
19505         create_lnet_proc_files "routers"
19506         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19507         remove_lnet_proc_files "routers"
19508
19509         # lnet.peers should look like this:
19510         # nid refs state last max rtr min tx min queue
19511         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19512         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19513         # numeric (0 or >0 or <0), queue >= 0.
19514         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19515         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19516         create_lnet_proc_files "peers"
19517         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19518         remove_lnet_proc_files "peers"
19519
19520         # lnet.buffers  should look like this:
19521         # pages count credits min
19522         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19523         L1="^pages +count +credits +min$"
19524         BR="^ +$N +$N +$I +$I$"
19525         create_lnet_proc_files "buffers"
19526         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19527         remove_lnet_proc_files "buffers"
19528
19529         # lnet.nis should look like this:
19530         # nid status alive refs peer rtr max tx min
19531         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19532         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19533         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19534         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19535         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19536         create_lnet_proc_files "nis"
19537         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19538         remove_lnet_proc_files "nis"
19539
19540         # can we successfully write to lnet.stats?
19541         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19542 }
19543 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19544
19545 test_216() { # bug 20317
19546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19547         remote_ost_nodsh && skip "remote OST with nodsh"
19548
19549         local node
19550         local facets=$(get_facets OST)
19551         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19552
19553         save_lustre_params client "osc.*.contention_seconds" > $p
19554         save_lustre_params $facets \
19555                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19556         save_lustre_params $facets \
19557                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19558         save_lustre_params $facets \
19559                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19560         clear_stats osc.*.osc_stats
19561
19562         # agressive lockless i/o settings
19563         do_nodes $(comma_list $(osts_nodes)) \
19564                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19565                         ldlm.namespaces.filter-*.contended_locks=0 \
19566                         ldlm.namespaces.filter-*.contention_seconds=60"
19567         lctl set_param -n osc.*.contention_seconds=60
19568
19569         $DIRECTIO write $DIR/$tfile 0 10 4096
19570         $CHECKSTAT -s 40960 $DIR/$tfile
19571
19572         # disable lockless i/o
19573         do_nodes $(comma_list $(osts_nodes)) \
19574                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19575                         ldlm.namespaces.filter-*.contended_locks=32 \
19576                         ldlm.namespaces.filter-*.contention_seconds=0"
19577         lctl set_param -n osc.*.contention_seconds=0
19578         clear_stats osc.*.osc_stats
19579
19580         dd if=/dev/zero of=$DIR/$tfile count=0
19581         $CHECKSTAT -s 0 $DIR/$tfile
19582
19583         restore_lustre_params <$p
19584         rm -f $p
19585         rm $DIR/$tfile
19586 }
19587 run_test 216 "check lockless direct write updates file size and kms correctly"
19588
19589 test_217() { # bug 22430
19590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19591
19592         local node
19593         local nid
19594
19595         for node in $(nodes_list); do
19596                 nid=$(host_nids_address $node $NETTYPE)
19597                 if [[ $nid = *-* ]] ; then
19598                         echo "lctl ping $(h2nettype $nid)"
19599                         lctl ping $(h2nettype $nid)
19600                 else
19601                         echo "skipping $node (no hyphen detected)"
19602                 fi
19603         done
19604 }
19605 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19606
19607 test_218() {
19608        # do directio so as not to populate the page cache
19609        log "creating a 10 Mb file"
19610        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19611        log "starting reads"
19612        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19613        log "truncating the file"
19614        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19615        log "killing dd"
19616        kill %+ || true # reads might have finished
19617        echo "wait until dd is finished"
19618        wait
19619        log "removing the temporary file"
19620        rm -rf $DIR/$tfile || error "tmp file removal failed"
19621 }
19622 run_test 218 "parallel read and truncate should not deadlock"
19623
19624 test_219() {
19625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19626
19627         # write one partial page
19628         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19629         # set no grant so vvp_io_commit_write will do sync write
19630         $LCTL set_param fail_loc=0x411
19631         # write a full page at the end of file
19632         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19633
19634         $LCTL set_param fail_loc=0
19635         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19636         $LCTL set_param fail_loc=0x411
19637         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19638
19639         # LU-4201
19640         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19641         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19642 }
19643 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19644
19645 test_220() { #LU-325
19646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19647         remote_ost_nodsh && skip "remote OST with nodsh"
19648         remote_mds_nodsh && skip "remote MDS with nodsh"
19649         remote_mgs_nodsh && skip "remote MGS with nodsh"
19650
19651         local OSTIDX=0
19652
19653         # create on MDT0000 so the last_id and next_id are correct
19654         mkdir_on_mdt0 $DIR/$tdir
19655         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19656         OST=${OST%_UUID}
19657
19658         # on the mdt's osc
19659         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19660         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19661                         osp.$mdtosc_proc1.prealloc_last_id)
19662         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19663                         osp.$mdtosc_proc1.prealloc_next_id)
19664
19665         $LFS df -i
19666
19667         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19668         #define OBD_FAIL_OST_ENOINO              0x229
19669         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19670         create_pool $FSNAME.$TESTNAME || return 1
19671         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19672
19673         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19674
19675         MDSOBJS=$((last_id - next_id))
19676         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19677
19678         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19679         echo "OST still has $count kbytes free"
19680
19681         echo "create $MDSOBJS files @next_id..."
19682         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19683
19684         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19685                         osp.$mdtosc_proc1.prealloc_last_id)
19686         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19687                         osp.$mdtosc_proc1.prealloc_next_id)
19688
19689         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19690         $LFS df -i
19691
19692         echo "cleanup..."
19693
19694         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19695         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19696
19697         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19698                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19699         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19700                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19701         echo "unlink $MDSOBJS files @$next_id..."
19702         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19703 }
19704 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19705
19706 test_221() {
19707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19708
19709         dd if=`which date` of=$MOUNT/date oflag=sync
19710         chmod +x $MOUNT/date
19711
19712         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19713         $LCTL set_param fail_loc=0x80001401
19714
19715         $MOUNT/date > /dev/null
19716         rm -f $MOUNT/date
19717 }
19718 run_test 221 "make sure fault and truncate race to not cause OOM"
19719
19720 test_222a () {
19721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19722
19723         rm -rf $DIR/$tdir
19724         test_mkdir $DIR/$tdir
19725         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19726         createmany -o $DIR/$tdir/$tfile 10
19727         cancel_lru_locks mdc
19728         cancel_lru_locks osc
19729         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19730         $LCTL set_param fail_loc=0x31a
19731         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19732         $LCTL set_param fail_loc=0
19733         rm -r $DIR/$tdir
19734 }
19735 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19736
19737 test_222b () {
19738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19739
19740         rm -rf $DIR/$tdir
19741         test_mkdir $DIR/$tdir
19742         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19743         createmany -o $DIR/$tdir/$tfile 10
19744         cancel_lru_locks mdc
19745         cancel_lru_locks osc
19746         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19747         $LCTL set_param fail_loc=0x31a
19748         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19749         $LCTL set_param fail_loc=0
19750 }
19751 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19752
19753 test_223 () {
19754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19755
19756         rm -rf $DIR/$tdir
19757         test_mkdir $DIR/$tdir
19758         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19759         createmany -o $DIR/$tdir/$tfile 10
19760         cancel_lru_locks mdc
19761         cancel_lru_locks osc
19762         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19763         $LCTL set_param fail_loc=0x31b
19764         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19765         $LCTL set_param fail_loc=0
19766         rm -r $DIR/$tdir
19767 }
19768 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19769
19770 test_224a() { # LU-1039, MRP-303
19771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19772         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19773         $LCTL set_param fail_loc=0x508
19774         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19775         $LCTL set_param fail_loc=0
19776         df $DIR
19777 }
19778 run_test 224a "Don't panic on bulk IO failure"
19779
19780 test_224bd_sub() { # LU-1039, MRP-303
19781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19782         local timeout=$1
19783
19784         shift
19785         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19786
19787         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19788
19789         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19790         cancel_lru_locks osc
19791         set_checksums 0
19792         stack_trap "set_checksums $ORIG_CSUM" EXIT
19793         local at_max_saved=0
19794
19795         # adaptive timeouts may prevent seeing the issue
19796         if at_is_enabled; then
19797                 at_max_saved=$(at_max_get mds)
19798                 at_max_set 0 mds client
19799                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19800         fi
19801
19802         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19803         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19804         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19805
19806         do_facet ost1 $LCTL set_param fail_loc=0
19807         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19808         df $DIR
19809 }
19810
19811 test_224b() {
19812         test_224bd_sub 3 error "dd failed"
19813 }
19814 run_test 224b "Don't panic on bulk IO failure"
19815
19816 test_224c() { # LU-6441
19817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19818         remote_mds_nodsh && skip "remote MDS with nodsh"
19819
19820         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19821         save_writethrough $p
19822         set_cache writethrough on
19823
19824         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19825         local at_max=$($LCTL get_param -n at_max)
19826         local timeout=$($LCTL get_param -n timeout)
19827         local test_at="at_max"
19828         local param_at="$FSNAME.sys.at_max"
19829         local test_timeout="timeout"
19830         local param_timeout="$FSNAME.sys.timeout"
19831
19832         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19833
19834         set_persistent_param_and_check client "$test_at" "$param_at" 0
19835         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19836
19837         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19838         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19839         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19840         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19841         sync
19842         do_facet ost1 "$LCTL set_param fail_loc=0"
19843
19844         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19845         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19846                 $timeout
19847
19848         $LCTL set_param -n $pages_per_rpc
19849         restore_lustre_params < $p
19850         rm -f $p
19851 }
19852 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19853
19854 test_224d() { # LU-11169
19855         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19856 }
19857 run_test 224d "Don't corrupt data on bulk IO timeout"
19858
19859 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19860 test_225a () {
19861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19862         if [ -z ${MDSSURVEY} ]; then
19863                 skip_env "mds-survey not found"
19864         fi
19865         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19866                 skip "Need MDS version at least 2.2.51"
19867
19868         local mds=$(facet_host $SINGLEMDS)
19869         local target=$(do_nodes $mds 'lctl dl' |
19870                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19871
19872         local cmd1="file_count=1000 thrhi=4"
19873         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19874         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19875         local cmd="$cmd1 $cmd2 $cmd3"
19876
19877         rm -f ${TMP}/mds_survey*
19878         echo + $cmd
19879         eval $cmd || error "mds-survey with zero-stripe failed"
19880         cat ${TMP}/mds_survey*
19881         rm -f ${TMP}/mds_survey*
19882 }
19883 run_test 225a "Metadata survey sanity with zero-stripe"
19884
19885 test_225b () {
19886         if [ -z ${MDSSURVEY} ]; then
19887                 skip_env "mds-survey not found"
19888         fi
19889         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19890                 skip "Need MDS version at least 2.2.51"
19891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19892         remote_mds_nodsh && skip "remote MDS with nodsh"
19893         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19894                 skip_env "Need to mount OST to test"
19895         fi
19896
19897         local mds=$(facet_host $SINGLEMDS)
19898         local target=$(do_nodes $mds 'lctl dl' |
19899                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19900
19901         local cmd1="file_count=1000 thrhi=4"
19902         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19903         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19904         local cmd="$cmd1 $cmd2 $cmd3"
19905
19906         rm -f ${TMP}/mds_survey*
19907         echo + $cmd
19908         eval $cmd || error "mds-survey with stripe_count failed"
19909         cat ${TMP}/mds_survey*
19910         rm -f ${TMP}/mds_survey*
19911 }
19912 run_test 225b "Metadata survey sanity with stripe_count = 1"
19913
19914 mcreate_path2fid () {
19915         local mode=$1
19916         local major=$2
19917         local minor=$3
19918         local name=$4
19919         local desc=$5
19920         local path=$DIR/$tdir/$name
19921         local fid
19922         local rc
19923         local fid_path
19924
19925         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19926                 error "cannot create $desc"
19927
19928         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19929         rc=$?
19930         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19931
19932         fid_path=$($LFS fid2path $MOUNT $fid)
19933         rc=$?
19934         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19935
19936         [ "$path" == "$fid_path" ] ||
19937                 error "fid2path returned $fid_path, expected $path"
19938
19939         echo "pass with $path and $fid"
19940 }
19941
19942 test_226a () {
19943         rm -rf $DIR/$tdir
19944         mkdir -p $DIR/$tdir
19945
19946         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19947         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19948         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19949         mcreate_path2fid 0040666 0 0 dir "directory"
19950         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19951         mcreate_path2fid 0100666 0 0 file "regular file"
19952         mcreate_path2fid 0120666 0 0 link "symbolic link"
19953         mcreate_path2fid 0140666 0 0 sock "socket"
19954 }
19955 run_test 226a "call path2fid and fid2path on files of all type"
19956
19957 test_226b () {
19958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19959
19960         local MDTIDX=1
19961
19962         rm -rf $DIR/$tdir
19963         mkdir -p $DIR/$tdir
19964         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19965                 error "create remote directory failed"
19966         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19967         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19968                                 "character special file (null)"
19969         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19970                                 "character special file (no device)"
19971         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19972         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19973                                 "block special file (loop)"
19974         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19975         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19976         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19977 }
19978 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19979
19980 test_226c () {
19981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19982         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19983                 skip "Need MDS version at least 2.13.55"
19984
19985         local submnt=/mnt/submnt
19986         local srcfile=/etc/passwd
19987         local dstfile=$submnt/passwd
19988         local path
19989         local fid
19990
19991         rm -rf $DIR/$tdir
19992         rm -rf $submnt
19993         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19994                 error "create remote directory failed"
19995         mkdir -p $submnt || error "create $submnt failed"
19996         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19997                 error "mount $submnt failed"
19998         stack_trap "umount $submnt" EXIT
19999
20000         cp $srcfile $dstfile
20001         fid=$($LFS path2fid $dstfile)
20002         path=$($LFS fid2path $submnt "$fid")
20003         [ "$path" = "$dstfile" ] ||
20004                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20005 }
20006 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20007
20008 # LU-1299 Executing or running ldd on a truncated executable does not
20009 # cause an out-of-memory condition.
20010 test_227() {
20011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20012         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20013
20014         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20015         chmod +x $MOUNT/date
20016
20017         $MOUNT/date > /dev/null
20018         ldd $MOUNT/date > /dev/null
20019         rm -f $MOUNT/date
20020 }
20021 run_test 227 "running truncated executable does not cause OOM"
20022
20023 # LU-1512 try to reuse idle OI blocks
20024 test_228a() {
20025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20026         remote_mds_nodsh && skip "remote MDS with nodsh"
20027         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20028
20029         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20030         local myDIR=$DIR/$tdir
20031
20032         mkdir -p $myDIR
20033         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20034         $LCTL set_param fail_loc=0x80001002
20035         createmany -o $myDIR/t- 10000
20036         $LCTL set_param fail_loc=0
20037         # The guard is current the largest FID holder
20038         touch $myDIR/guard
20039         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20040                     tr -d '[')
20041         local IDX=$(($SEQ % 64))
20042
20043         do_facet $SINGLEMDS sync
20044         # Make sure journal flushed.
20045         sleep 6
20046         local blk1=$(do_facet $SINGLEMDS \
20047                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20048                      grep Blockcount | awk '{print $4}')
20049
20050         # Remove old files, some OI blocks will become idle.
20051         unlinkmany $myDIR/t- 10000
20052         # Create new files, idle OI blocks should be reused.
20053         createmany -o $myDIR/t- 2000
20054         do_facet $SINGLEMDS sync
20055         # Make sure journal flushed.
20056         sleep 6
20057         local blk2=$(do_facet $SINGLEMDS \
20058                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20059                      grep Blockcount | awk '{print $4}')
20060
20061         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20062 }
20063 run_test 228a "try to reuse idle OI blocks"
20064
20065 test_228b() {
20066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20067         remote_mds_nodsh && skip "remote MDS with nodsh"
20068         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20069
20070         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20071         local myDIR=$DIR/$tdir
20072
20073         mkdir -p $myDIR
20074         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20075         $LCTL set_param fail_loc=0x80001002
20076         createmany -o $myDIR/t- 10000
20077         $LCTL set_param fail_loc=0
20078         # The guard is current the largest FID holder
20079         touch $myDIR/guard
20080         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20081                     tr -d '[')
20082         local IDX=$(($SEQ % 64))
20083
20084         do_facet $SINGLEMDS sync
20085         # Make sure journal flushed.
20086         sleep 6
20087         local blk1=$(do_facet $SINGLEMDS \
20088                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20089                      grep Blockcount | awk '{print $4}')
20090
20091         # Remove old files, some OI blocks will become idle.
20092         unlinkmany $myDIR/t- 10000
20093
20094         # stop the MDT
20095         stop $SINGLEMDS || error "Fail to stop MDT."
20096         # remount the MDT
20097         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20098                 error "Fail to start MDT."
20099
20100         client_up || error "Fail to df."
20101         # Create new files, idle OI blocks should be reused.
20102         createmany -o $myDIR/t- 2000
20103         do_facet $SINGLEMDS sync
20104         # Make sure journal flushed.
20105         sleep 6
20106         local blk2=$(do_facet $SINGLEMDS \
20107                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20108                      grep Blockcount | awk '{print $4}')
20109
20110         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20111 }
20112 run_test 228b "idle OI blocks can be reused after MDT restart"
20113
20114 #LU-1881
20115 test_228c() {
20116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20117         remote_mds_nodsh && skip "remote MDS with nodsh"
20118         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20119
20120         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20121         local myDIR=$DIR/$tdir
20122
20123         mkdir -p $myDIR
20124         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20125         $LCTL set_param fail_loc=0x80001002
20126         # 20000 files can guarantee there are index nodes in the OI file
20127         createmany -o $myDIR/t- 20000
20128         $LCTL set_param fail_loc=0
20129         # The guard is current the largest FID holder
20130         touch $myDIR/guard
20131         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20132                     tr -d '[')
20133         local IDX=$(($SEQ % 64))
20134
20135         do_facet $SINGLEMDS sync
20136         # Make sure journal flushed.
20137         sleep 6
20138         local blk1=$(do_facet $SINGLEMDS \
20139                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20140                      grep Blockcount | awk '{print $4}')
20141
20142         # Remove old files, some OI blocks will become idle.
20143         unlinkmany $myDIR/t- 20000
20144         rm -f $myDIR/guard
20145         # The OI file should become empty now
20146
20147         # Create new files, idle OI blocks should be reused.
20148         createmany -o $myDIR/t- 2000
20149         do_facet $SINGLEMDS sync
20150         # Make sure journal flushed.
20151         sleep 6
20152         local blk2=$(do_facet $SINGLEMDS \
20153                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20154                      grep Blockcount | awk '{print $4}')
20155
20156         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20157 }
20158 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20159
20160 test_229() { # LU-2482, LU-3448
20161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20162         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20163         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20164                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20165
20166         rm -f $DIR/$tfile
20167
20168         # Create a file with a released layout and stripe count 2.
20169         $MULTIOP $DIR/$tfile H2c ||
20170                 error "failed to create file with released layout"
20171
20172         $LFS getstripe -v $DIR/$tfile
20173
20174         local pattern=$($LFS getstripe -L $DIR/$tfile)
20175         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20176
20177         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20178                 error "getstripe"
20179         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20180         stat $DIR/$tfile || error "failed to stat released file"
20181
20182         chown $RUNAS_ID $DIR/$tfile ||
20183                 error "chown $RUNAS_ID $DIR/$tfile failed"
20184
20185         chgrp $RUNAS_ID $DIR/$tfile ||
20186                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20187
20188         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20189         rm $DIR/$tfile || error "failed to remove released file"
20190 }
20191 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20192
20193 test_230a() {
20194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20196         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20197                 skip "Need MDS version at least 2.11.52"
20198
20199         local MDTIDX=1
20200
20201         test_mkdir $DIR/$tdir
20202         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20203         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20204         [ $mdt_idx -ne 0 ] &&
20205                 error "create local directory on wrong MDT $mdt_idx"
20206
20207         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20208                         error "create remote directory failed"
20209         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20210         [ $mdt_idx -ne $MDTIDX ] &&
20211                 error "create remote directory on wrong MDT $mdt_idx"
20212
20213         createmany -o $DIR/$tdir/test_230/t- 10 ||
20214                 error "create files on remote directory failed"
20215         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20216         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20217         rm -r $DIR/$tdir || error "unlink remote directory failed"
20218 }
20219 run_test 230a "Create remote directory and files under the remote directory"
20220
20221 test_230b() {
20222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20224         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20225                 skip "Need MDS version at least 2.11.52"
20226
20227         local MDTIDX=1
20228         local mdt_index
20229         local i
20230         local file
20231         local pid
20232         local stripe_count
20233         local migrate_dir=$DIR/$tdir/migrate_dir
20234         local other_dir=$DIR/$tdir/other_dir
20235
20236         test_mkdir $DIR/$tdir
20237         test_mkdir -i0 -c1 $migrate_dir
20238         test_mkdir -i0 -c1 $other_dir
20239         for ((i=0; i<10; i++)); do
20240                 mkdir -p $migrate_dir/dir_${i}
20241                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20242                         error "create files under remote dir failed $i"
20243         done
20244
20245         cp /etc/passwd $migrate_dir/$tfile
20246         cp /etc/passwd $other_dir/$tfile
20247         chattr +SAD $migrate_dir
20248         chattr +SAD $migrate_dir/$tfile
20249
20250         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20251         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20252         local old_dir_mode=$(stat -c%f $migrate_dir)
20253         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20254
20255         mkdir -p $migrate_dir/dir_default_stripe2
20256         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20257         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20258
20259         mkdir -p $other_dir
20260         ln $migrate_dir/$tfile $other_dir/luna
20261         ln $migrate_dir/$tfile $migrate_dir/sofia
20262         ln $other_dir/$tfile $migrate_dir/david
20263         ln -s $migrate_dir/$tfile $other_dir/zachary
20264         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20265         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20266
20267         local len
20268         local lnktgt
20269
20270         # inline symlink
20271         for len in 58 59 60; do
20272                 lnktgt=$(str_repeat 'l' $len)
20273                 touch $migrate_dir/$lnktgt
20274                 ln -s $lnktgt $migrate_dir/${len}char_ln
20275         done
20276
20277         # PATH_MAX
20278         for len in 4094 4095; do
20279                 lnktgt=$(str_repeat 'l' $len)
20280                 ln -s $lnktgt $migrate_dir/${len}char_ln
20281         done
20282
20283         # NAME_MAX
20284         for len in 254 255; do
20285                 touch $migrate_dir/$(str_repeat 'l' $len)
20286         done
20287
20288         $LFS migrate -m $MDTIDX $migrate_dir ||
20289                 error "fails on migrating remote dir to MDT1"
20290
20291         echo "migratate to MDT1, then checking.."
20292         for ((i = 0; i < 10; i++)); do
20293                 for file in $(find $migrate_dir/dir_${i}); do
20294                         mdt_index=$($LFS getstripe -m $file)
20295                         # broken symlink getstripe will fail
20296                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20297                                 error "$file is not on MDT${MDTIDX}"
20298                 done
20299         done
20300
20301         # the multiple link file should still in MDT0
20302         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20303         [ $mdt_index == 0 ] ||
20304                 error "$file is not on MDT${MDTIDX}"
20305
20306         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20307         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20308                 error " expect $old_dir_flag get $new_dir_flag"
20309
20310         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20311         [ "$old_file_flag" = "$new_file_flag" ] ||
20312                 error " expect $old_file_flag get $new_file_flag"
20313
20314         local new_dir_mode=$(stat -c%f $migrate_dir)
20315         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20316                 error "expect mode $old_dir_mode get $new_dir_mode"
20317
20318         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20319         [ "$old_file_mode" = "$new_file_mode" ] ||
20320                 error "expect mode $old_file_mode get $new_file_mode"
20321
20322         diff /etc/passwd $migrate_dir/$tfile ||
20323                 error "$tfile different after migration"
20324
20325         diff /etc/passwd $other_dir/luna ||
20326                 error "luna different after migration"
20327
20328         diff /etc/passwd $migrate_dir/sofia ||
20329                 error "sofia different after migration"
20330
20331         diff /etc/passwd $migrate_dir/david ||
20332                 error "david different after migration"
20333
20334         diff /etc/passwd $other_dir/zachary ||
20335                 error "zachary different after migration"
20336
20337         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20338                 error "${tfile}_ln different after migration"
20339
20340         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20341                 error "${tfile}_ln_other different after migration"
20342
20343         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20344         [ $stripe_count = 2 ] ||
20345                 error "dir strpe_count $d != 2 after migration."
20346
20347         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20348         [ $stripe_count = 2 ] ||
20349                 error "file strpe_count $d != 2 after migration."
20350
20351         #migrate back to MDT0
20352         MDTIDX=0
20353
20354         $LFS migrate -m $MDTIDX $migrate_dir ||
20355                 error "fails on migrating remote dir to MDT0"
20356
20357         echo "migrate back to MDT0, checking.."
20358         for file in $(find $migrate_dir); do
20359                 mdt_index=$($LFS getstripe -m $file)
20360                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20361                         error "$file is not on MDT${MDTIDX}"
20362         done
20363
20364         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20365         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20366                 error " expect $old_dir_flag get $new_dir_flag"
20367
20368         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20369         [ "$old_file_flag" = "$new_file_flag" ] ||
20370                 error " expect $old_file_flag get $new_file_flag"
20371
20372         local new_dir_mode=$(stat -c%f $migrate_dir)
20373         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20374                 error "expect mode $old_dir_mode get $new_dir_mode"
20375
20376         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20377         [ "$old_file_mode" = "$new_file_mode" ] ||
20378                 error "expect mode $old_file_mode get $new_file_mode"
20379
20380         diff /etc/passwd ${migrate_dir}/$tfile ||
20381                 error "$tfile different after migration"
20382
20383         diff /etc/passwd ${other_dir}/luna ||
20384                 error "luna different after migration"
20385
20386         diff /etc/passwd ${migrate_dir}/sofia ||
20387                 error "sofia different after migration"
20388
20389         diff /etc/passwd ${other_dir}/zachary ||
20390                 error "zachary different after migration"
20391
20392         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20393                 error "${tfile}_ln different after migration"
20394
20395         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20396                 error "${tfile}_ln_other different after migration"
20397
20398         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20399         [ $stripe_count = 2 ] ||
20400                 error "dir strpe_count $d != 2 after migration."
20401
20402         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20403         [ $stripe_count = 2 ] ||
20404                 error "file strpe_count $d != 2 after migration."
20405
20406         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20407 }
20408 run_test 230b "migrate directory"
20409
20410 test_230c() {
20411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20413         remote_mds_nodsh && skip "remote MDS with nodsh"
20414         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20415                 skip "Need MDS version at least 2.11.52"
20416
20417         local MDTIDX=1
20418         local total=3
20419         local mdt_index
20420         local file
20421         local migrate_dir=$DIR/$tdir/migrate_dir
20422
20423         #If migrating directory fails in the middle, all entries of
20424         #the directory is still accessiable.
20425         test_mkdir $DIR/$tdir
20426         test_mkdir -i0 -c1 $migrate_dir
20427         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20428         stat $migrate_dir
20429         createmany -o $migrate_dir/f $total ||
20430                 error "create files under ${migrate_dir} failed"
20431
20432         # fail after migrating top dir, and this will fail only once, so the
20433         # first sub file migration will fail (currently f3), others succeed.
20434         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20435         do_facet mds1 lctl set_param fail_loc=0x1801
20436         local t=$(ls $migrate_dir | wc -l)
20437         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20438                 error "migrate should fail"
20439         local u=$(ls $migrate_dir | wc -l)
20440         [ "$u" == "$t" ] || error "$u != $t during migration"
20441
20442         # add new dir/file should succeed
20443         mkdir $migrate_dir/dir ||
20444                 error "mkdir failed under migrating directory"
20445         touch $migrate_dir/file ||
20446                 error "create file failed under migrating directory"
20447
20448         # add file with existing name should fail
20449         for file in $migrate_dir/f*; do
20450                 stat $file > /dev/null || error "stat $file failed"
20451                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20452                         error "open(O_CREAT|O_EXCL) $file should fail"
20453                 $MULTIOP $file m && error "create $file should fail"
20454                 touch $DIR/$tdir/remote_dir/$tfile ||
20455                         error "touch $tfile failed"
20456                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20457                         error "link $file should fail"
20458                 mdt_index=$($LFS getstripe -m $file)
20459                 if [ $mdt_index == 0 ]; then
20460                         # file failed to migrate is not allowed to rename to
20461                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20462                                 error "rename to $file should fail"
20463                 else
20464                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20465                                 error "rename to $file failed"
20466                 fi
20467                 echo hello >> $file || error "write $file failed"
20468         done
20469
20470         # resume migration with different options should fail
20471         $LFS migrate -m 0 $migrate_dir &&
20472                 error "migrate -m 0 $migrate_dir should fail"
20473
20474         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20475                 error "migrate -c 2 $migrate_dir should fail"
20476
20477         # resume migration should succeed
20478         $LFS migrate -m $MDTIDX $migrate_dir ||
20479                 error "migrate $migrate_dir failed"
20480
20481         echo "Finish migration, then checking.."
20482         for file in $(find $migrate_dir); do
20483                 mdt_index=$($LFS getstripe -m $file)
20484                 [ $mdt_index == $MDTIDX ] ||
20485                         error "$file is not on MDT${MDTIDX}"
20486         done
20487
20488         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20489 }
20490 run_test 230c "check directory accessiblity if migration failed"
20491
20492 test_230d() {
20493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20495         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20496                 skip "Need MDS version at least 2.11.52"
20497         # LU-11235
20498         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20499
20500         local migrate_dir=$DIR/$tdir/migrate_dir
20501         local old_index
20502         local new_index
20503         local old_count
20504         local new_count
20505         local new_hash
20506         local mdt_index
20507         local i
20508         local j
20509
20510         old_index=$((RANDOM % MDSCOUNT))
20511         old_count=$((MDSCOUNT - old_index))
20512         new_index=$((RANDOM % MDSCOUNT))
20513         new_count=$((MDSCOUNT - new_index))
20514         new_hash=1 # for all_char
20515
20516         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20517         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20518
20519         test_mkdir $DIR/$tdir
20520         test_mkdir -i $old_index -c $old_count $migrate_dir
20521
20522         for ((i=0; i<100; i++)); do
20523                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20524                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20525                         error "create files under remote dir failed $i"
20526         done
20527
20528         echo -n "Migrate from MDT$old_index "
20529         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20530         echo -n "to MDT$new_index"
20531         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20532         echo
20533
20534         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20535         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20536                 error "migrate remote dir error"
20537
20538         echo "Finish migration, then checking.."
20539         for file in $(find $migrate_dir -maxdepth 1); do
20540                 mdt_index=$($LFS getstripe -m $file)
20541                 if [ $mdt_index -lt $new_index ] ||
20542                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20543                         error "$file is on MDT$mdt_index"
20544                 fi
20545         done
20546
20547         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20548 }
20549 run_test 230d "check migrate big directory"
20550
20551 test_230e() {
20552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20555                 skip "Need MDS version at least 2.11.52"
20556
20557         local i
20558         local j
20559         local a_fid
20560         local b_fid
20561
20562         mkdir_on_mdt0 $DIR/$tdir
20563         mkdir $DIR/$tdir/migrate_dir
20564         mkdir $DIR/$tdir/other_dir
20565         touch $DIR/$tdir/migrate_dir/a
20566         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20567         ls $DIR/$tdir/other_dir
20568
20569         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20570                 error "migrate dir fails"
20571
20572         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20573         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20574
20575         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20576         [ $mdt_index == 0 ] || error "a is not on MDT0"
20577
20578         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20579                 error "migrate dir fails"
20580
20581         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20582         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20583
20584         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20585         [ $mdt_index == 1 ] || error "a is not on MDT1"
20586
20587         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20588         [ $mdt_index == 1 ] || error "b is not on MDT1"
20589
20590         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20591         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20592
20593         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20594
20595         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20596 }
20597 run_test 230e "migrate mulitple local link files"
20598
20599 test_230f() {
20600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20602         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20603                 skip "Need MDS version at least 2.11.52"
20604
20605         local a_fid
20606         local ln_fid
20607
20608         mkdir -p $DIR/$tdir
20609         mkdir $DIR/$tdir/migrate_dir
20610         $LFS mkdir -i1 $DIR/$tdir/other_dir
20611         touch $DIR/$tdir/migrate_dir/a
20612         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20613         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20614         ls $DIR/$tdir/other_dir
20615
20616         # a should be migrated to MDT1, since no other links on MDT0
20617         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20618                 error "#1 migrate dir fails"
20619         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20620         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20621         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20622         [ $mdt_index == 1 ] || error "a is not on MDT1"
20623
20624         # a should stay on MDT1, because it is a mulitple link file
20625         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20626                 error "#2 migrate dir fails"
20627         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20628         [ $mdt_index == 1 ] || error "a is not on MDT1"
20629
20630         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20631                 error "#3 migrate dir fails"
20632
20633         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20634         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20635         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20636
20637         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20638         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20639
20640         # a should be migrated to MDT0, since no other links on MDT1
20641         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20642                 error "#4 migrate dir fails"
20643         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20644         [ $mdt_index == 0 ] || error "a is not on MDT0"
20645
20646         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20647 }
20648 run_test 230f "migrate mulitple remote link files"
20649
20650 test_230g() {
20651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20653         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20654                 skip "Need MDS version at least 2.11.52"
20655
20656         mkdir -p $DIR/$tdir/migrate_dir
20657
20658         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20659                 error "migrating dir to non-exist MDT succeeds"
20660         true
20661 }
20662 run_test 230g "migrate dir to non-exist MDT"
20663
20664 test_230h() {
20665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20667         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20668                 skip "Need MDS version at least 2.11.52"
20669
20670         local mdt_index
20671
20672         mkdir -p $DIR/$tdir/migrate_dir
20673
20674         $LFS migrate -m1 $DIR &&
20675                 error "migrating mountpoint1 should fail"
20676
20677         $LFS migrate -m1 $DIR/$tdir/.. &&
20678                 error "migrating mountpoint2 should fail"
20679
20680         # same as mv
20681         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20682                 error "migrating $tdir/migrate_dir/.. should fail"
20683
20684         true
20685 }
20686 run_test 230h "migrate .. and root"
20687
20688 test_230i() {
20689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20690         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20691         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20692                 skip "Need MDS version at least 2.11.52"
20693
20694         mkdir -p $DIR/$tdir/migrate_dir
20695
20696         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20697                 error "migration fails with a tailing slash"
20698
20699         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20700                 error "migration fails with two tailing slashes"
20701 }
20702 run_test 230i "lfs migrate -m tolerates trailing slashes"
20703
20704 test_230j() {
20705         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20706         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20707                 skip "Need MDS version at least 2.11.52"
20708
20709         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20710         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20711                 error "create $tfile failed"
20712         cat /etc/passwd > $DIR/$tdir/$tfile
20713
20714         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20715
20716         cmp /etc/passwd $DIR/$tdir/$tfile ||
20717                 error "DoM file mismatch after migration"
20718 }
20719 run_test 230j "DoM file data not changed after dir migration"
20720
20721 test_230k() {
20722         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20723         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20724                 skip "Need MDS version at least 2.11.56"
20725
20726         local total=20
20727         local files_on_starting_mdt=0
20728
20729         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20730         $LFS getdirstripe $DIR/$tdir
20731         for i in $(seq $total); do
20732                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20733                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20734                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20735         done
20736
20737         echo "$files_on_starting_mdt files on MDT0"
20738
20739         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20740         $LFS getdirstripe $DIR/$tdir
20741
20742         files_on_starting_mdt=0
20743         for i in $(seq $total); do
20744                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20745                         error "file $tfile.$i mismatch after migration"
20746                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20747                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20748         done
20749
20750         echo "$files_on_starting_mdt files on MDT1 after migration"
20751         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20752
20753         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20754         $LFS getdirstripe $DIR/$tdir
20755
20756         files_on_starting_mdt=0
20757         for i in $(seq $total); do
20758                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20759                         error "file $tfile.$i mismatch after 2nd migration"
20760                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20761                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20762         done
20763
20764         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20765         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20766
20767         true
20768 }
20769 run_test 230k "file data not changed after dir migration"
20770
20771 test_230l() {
20772         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20773         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20774                 skip "Need MDS version at least 2.11.56"
20775
20776         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20777         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20778                 error "create files under remote dir failed $i"
20779         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20780 }
20781 run_test 230l "readdir between MDTs won't crash"
20782
20783 test_230m() {
20784         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20785         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20786                 skip "Need MDS version at least 2.11.56"
20787
20788         local MDTIDX=1
20789         local mig_dir=$DIR/$tdir/migrate_dir
20790         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20791         local shortstr="b"
20792         local val
20793
20794         echo "Creating files and dirs with xattrs"
20795         test_mkdir $DIR/$tdir
20796         test_mkdir -i0 -c1 $mig_dir
20797         mkdir $mig_dir/dir
20798         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20799                 error "cannot set xattr attr1 on dir"
20800         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20801                 error "cannot set xattr attr2 on dir"
20802         touch $mig_dir/dir/f0
20803         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20804                 error "cannot set xattr attr1 on file"
20805         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20806                 error "cannot set xattr attr2 on file"
20807         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20808         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20809         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20810         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20811         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20812         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20813         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20814         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20815         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20816
20817         echo "Migrating to MDT1"
20818         $LFS migrate -m $MDTIDX $mig_dir ||
20819                 error "fails on migrating dir to MDT1"
20820
20821         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20822         echo "Checking xattrs"
20823         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20824         [ "$val" = $longstr ] ||
20825                 error "expecting xattr1 $longstr on dir, found $val"
20826         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20827         [ "$val" = $shortstr ] ||
20828                 error "expecting xattr2 $shortstr on dir, found $val"
20829         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20830         [ "$val" = $longstr ] ||
20831                 error "expecting xattr1 $longstr on file, found $val"
20832         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20833         [ "$val" = $shortstr ] ||
20834                 error "expecting xattr2 $shortstr on file, found $val"
20835 }
20836 run_test 230m "xattrs not changed after dir migration"
20837
20838 test_230n() {
20839         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20840         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20841                 skip "Need MDS version at least 2.13.53"
20842
20843         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20844         cat /etc/hosts > $DIR/$tdir/$tfile
20845         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20846         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20847
20848         cmp /etc/hosts $DIR/$tdir/$tfile ||
20849                 error "File data mismatch after migration"
20850 }
20851 run_test 230n "Dir migration with mirrored file"
20852
20853 test_230o() {
20854         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20855         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20856                 skip "Need MDS version at least 2.13.52"
20857
20858         local mdts=$(comma_list $(mdts_nodes))
20859         local timeout=100
20860         local restripe_status
20861         local delta
20862         local i
20863
20864         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20865
20866         # in case "crush" hash type is not set
20867         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20868
20869         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20870                            mdt.*MDT0000.enable_dir_restripe)
20871         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20872         stack_trap "do_nodes $mdts $LCTL set_param \
20873                     mdt.*.enable_dir_restripe=$restripe_status"
20874
20875         mkdir $DIR/$tdir
20876         createmany -m $DIR/$tdir/f 100 ||
20877                 error "create files under remote dir failed $i"
20878         createmany -d $DIR/$tdir/d 100 ||
20879                 error "create dirs under remote dir failed $i"
20880
20881         for i in $(seq 2 $MDSCOUNT); do
20882                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20883                 $LFS setdirstripe -c $i $DIR/$tdir ||
20884                         error "split -c $i $tdir failed"
20885                 wait_update $HOSTNAME \
20886                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20887                         error "dir split not finished"
20888                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20889                         awk '/migrate/ {sum += $2} END { print sum }')
20890                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20891                 # delta is around total_files/stripe_count
20892                 (( $delta < 200 / (i - 1) + 4 )) ||
20893                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20894         done
20895 }
20896 run_test 230o "dir split"
20897
20898 test_230p() {
20899         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20900         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20901                 skip "Need MDS version at least 2.13.52"
20902
20903         local mdts=$(comma_list $(mdts_nodes))
20904         local timeout=100
20905         local restripe_status
20906         local delta
20907         local c
20908
20909         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20910
20911         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20912
20913         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20914                            mdt.*MDT0000.enable_dir_restripe)
20915         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20916         stack_trap "do_nodes $mdts $LCTL set_param \
20917                     mdt.*.enable_dir_restripe=$restripe_status"
20918
20919         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20920         createmany -m $DIR/$tdir/f 100 ||
20921                 error "create files under remote dir failed"
20922         createmany -d $DIR/$tdir/d 100 ||
20923                 error "create dirs under remote dir failed"
20924
20925         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20926                 local mdt_hash="crush"
20927
20928                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20929                 $LFS setdirstripe -c $c $DIR/$tdir ||
20930                         error "split -c $c $tdir failed"
20931                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20932                         mdt_hash="$mdt_hash,fixed"
20933                 elif [ $c -eq 1 ]; then
20934                         mdt_hash="none"
20935                 fi
20936                 wait_update $HOSTNAME \
20937                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20938                         error "dir merge not finished"
20939                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20940                         awk '/migrate/ {sum += $2} END { print sum }')
20941                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20942                 # delta is around total_files/stripe_count
20943                 (( delta < 200 / c + 4 )) ||
20944                         error "$delta files migrated >= $((200 / c + 4))"
20945         done
20946 }
20947 run_test 230p "dir merge"
20948
20949 test_230q() {
20950         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20951         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20952                 skip "Need MDS version at least 2.13.52"
20953
20954         local mdts=$(comma_list $(mdts_nodes))
20955         local saved_threshold=$(do_facet mds1 \
20956                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20957         local saved_delta=$(do_facet mds1 \
20958                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20959         local threshold=100
20960         local delta=2
20961         local total=0
20962         local stripe_count=0
20963         local stripe_index
20964         local nr_files
20965         local create
20966
20967         # test with fewer files on ZFS
20968         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20969
20970         stack_trap "do_nodes $mdts $LCTL set_param \
20971                     mdt.*.dir_split_count=$saved_threshold"
20972         stack_trap "do_nodes $mdts $LCTL set_param \
20973                     mdt.*.dir_split_delta=$saved_delta"
20974         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20975         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20976         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20977         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20978         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20979         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20980
20981         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20982         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20983
20984         create=$((threshold * 3 / 2))
20985         while [ $stripe_count -lt $MDSCOUNT ]; do
20986                 createmany -m $DIR/$tdir/f $total $create ||
20987                         error "create sub files failed"
20988                 stat $DIR/$tdir > /dev/null
20989                 total=$((total + create))
20990                 stripe_count=$((stripe_count + delta))
20991                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20992
20993                 wait_update $HOSTNAME \
20994                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20995                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20996
20997                 wait_update $HOSTNAME \
20998                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20999                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21000
21001                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21002                 echo "$nr_files/$total files on MDT$stripe_index after split"
21003                 # allow 10% margin of imbalance with crush hash
21004                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21005                         error "$nr_files files on MDT$stripe_index after split"
21006
21007                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21008                 [ $nr_files -eq $total ] ||
21009                         error "total sub files $nr_files != $total"
21010         done
21011
21012         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21013
21014         echo "fixed layout directory won't auto split"
21015         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21016         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21017                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21018         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21019                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21020 }
21021 run_test 230q "dir auto split"
21022
21023 test_230r() {
21024         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21025         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21026         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21027                 skip "Need MDS version at least 2.13.54"
21028
21029         # maximum amount of local locks:
21030         # parent striped dir - 2 locks
21031         # new stripe in parent to migrate to - 1 lock
21032         # source and target - 2 locks
21033         # Total 5 locks for regular file
21034         mkdir -p $DIR/$tdir
21035         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21036         touch $DIR/$tdir/dir1/eee
21037
21038         # create 4 hardlink for 4 more locks
21039         # Total: 9 locks > RS_MAX_LOCKS (8)
21040         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21041         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21042         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21043         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21044         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21045         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21046         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21047         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21048
21049         cancel_lru_locks mdc
21050
21051         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21052                 error "migrate dir fails"
21053
21054         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21055 }
21056 run_test 230r "migrate with too many local locks"
21057
21058 test_230s() {
21059         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21060                 skip "Need MDS version at least 2.14.52"
21061
21062         local mdts=$(comma_list $(mdts_nodes))
21063         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21064                                 mdt.*MDT0000.enable_dir_restripe)
21065
21066         stack_trap "do_nodes $mdts $LCTL set_param \
21067                     mdt.*.enable_dir_restripe=$restripe_status"
21068
21069         local st
21070         for st in 0 1; do
21071                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21072                 test_mkdir $DIR/$tdir
21073                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21074                         error "$LFS mkdir should return EEXIST if target exists"
21075                 rmdir $DIR/$tdir
21076         done
21077 }
21078 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21079
21080 test_230t()
21081 {
21082         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21083         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21084                 skip "Need MDS version at least 2.14.50"
21085
21086         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21087         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21088         $LFS project -p 1 -s $DIR/$tdir ||
21089                 error "set $tdir project id failed"
21090         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21091                 error "set subdir project id failed"
21092         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21093 }
21094 run_test 230t "migrate directory with project ID set"
21095
21096 test_230u()
21097 {
21098         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21099         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21100                 skip "Need MDS version at least 2.14.53"
21101
21102         local count
21103
21104         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21105         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21106         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21107         for i in $(seq 0 $((MDSCOUNT - 1))); do
21108                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21109                 echo "$count dirs migrated to MDT$i"
21110         done
21111         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21112         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21113 }
21114 run_test 230u "migrate directory by QOS"
21115
21116 test_230v()
21117 {
21118         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21119         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21120                 skip "Need MDS version at least 2.14.53"
21121
21122         local count
21123
21124         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21125         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21126         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21127         for i in $(seq 0 $((MDSCOUNT - 1))); do
21128                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21129                 echo "$count subdirs migrated to MDT$i"
21130                 (( i == 3 )) && (( count > 0 )) &&
21131                         error "subdir shouldn't be migrated to MDT3"
21132         done
21133         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21134         (( count == 3 )) || error "dirs migrated to $count MDTs"
21135 }
21136 run_test 230v "subdir migrated to the MDT where its parent is located"
21137
21138 test_230w() {
21139         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21140         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21141                 skip "Need MDS version at least 2.15.0"
21142
21143         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21144         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21145         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21146
21147         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21148                 error "migrate failed"
21149
21150         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21151                 error "$tdir stripe count mismatch"
21152
21153         for i in $(seq 0 9); do
21154                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21155                         error "d$i is striped"
21156         done
21157 }
21158 run_test 230w "non-recursive mode dir migration"
21159
21160 test_230x() {
21161         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21162         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21163                 skip "Need MDS version at least 2.15.0"
21164
21165         mkdir -p $DIR/$tdir || error "mkdir failed"
21166         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21167
21168         local mdt_name=$(mdtname_from_index 0)
21169         local low=$(do_facet mds2 $LCTL get_param -n \
21170                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21171         local high=$(do_facet mds2 $LCTL get_param -n \
21172                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21173         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21174         local maxage=$(do_facet mds2 $LCTL get_param -n \
21175                 osp.*$mdt_name-osp-MDT0001.maxage)
21176
21177         stack_trap "do_facet mds2 $LCTL set_param -n \
21178                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21179                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21180         stack_trap "do_facet mds2 $LCTL set_param -n \
21181                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21182
21183         do_facet mds2 $LCTL set_param -n \
21184                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21185         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21186         sleep 4
21187         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21188                 error "migrate $tdir should fail"
21189
21190         do_facet mds2 $LCTL set_param -n \
21191                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21192         do_facet mds2 $LCTL set_param -n \
21193                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21194         sleep 4
21195         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21196                 error "migrate failed"
21197         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21198                 error "$tdir stripe count mismatch"
21199 }
21200 run_test 230x "dir migration check space"
21201
21202 test_231a()
21203 {
21204         # For simplicity this test assumes that max_pages_per_rpc
21205         # is the same across all OSCs
21206         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21207         local bulk_size=$((max_pages * PAGE_SIZE))
21208         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21209                                        head -n 1)
21210
21211         mkdir -p $DIR/$tdir
21212         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21213                 error "failed to set stripe with -S ${brw_size}M option"
21214
21215         # clear the OSC stats
21216         $LCTL set_param osc.*.stats=0 &>/dev/null
21217         stop_writeback
21218
21219         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21220         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21221                 oflag=direct &>/dev/null || error "dd failed"
21222
21223         sync; sleep 1; sync # just to be safe
21224         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21225         if [ x$nrpcs != "x1" ]; then
21226                 $LCTL get_param osc.*.stats
21227                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21228         fi
21229
21230         start_writeback
21231         # Drop the OSC cache, otherwise we will read from it
21232         cancel_lru_locks osc
21233
21234         # clear the OSC stats
21235         $LCTL set_param osc.*.stats=0 &>/dev/null
21236
21237         # Client reads $bulk_size.
21238         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21239                 iflag=direct &>/dev/null || error "dd failed"
21240
21241         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21242         if [ x$nrpcs != "x1" ]; then
21243                 $LCTL get_param osc.*.stats
21244                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21245         fi
21246 }
21247 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21248
21249 test_231b() {
21250         mkdir -p $DIR/$tdir
21251         local i
21252         for i in {0..1023}; do
21253                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21254                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21255                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21256         done
21257         sync
21258 }
21259 run_test 231b "must not assert on fully utilized OST request buffer"
21260
21261 test_232a() {
21262         mkdir -p $DIR/$tdir
21263         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21264
21265         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21266         do_facet ost1 $LCTL set_param fail_loc=0x31c
21267
21268         # ignore dd failure
21269         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21270
21271         do_facet ost1 $LCTL set_param fail_loc=0
21272         umount_client $MOUNT || error "umount failed"
21273         mount_client $MOUNT || error "mount failed"
21274         stop ost1 || error "cannot stop ost1"
21275         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21276 }
21277 run_test 232a "failed lock should not block umount"
21278
21279 test_232b() {
21280         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21281                 skip "Need MDS version at least 2.10.58"
21282
21283         mkdir -p $DIR/$tdir
21284         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21285         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21286         sync
21287         cancel_lru_locks osc
21288
21289         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21290         do_facet ost1 $LCTL set_param fail_loc=0x31c
21291
21292         # ignore failure
21293         $LFS data_version $DIR/$tdir/$tfile || true
21294
21295         do_facet ost1 $LCTL set_param fail_loc=0
21296         umount_client $MOUNT || error "umount failed"
21297         mount_client $MOUNT || error "mount failed"
21298         stop ost1 || error "cannot stop ost1"
21299         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21300 }
21301 run_test 232b "failed data version lock should not block umount"
21302
21303 test_233a() {
21304         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21305                 skip "Need MDS version at least 2.3.64"
21306         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21307
21308         local fid=$($LFS path2fid $MOUNT)
21309
21310         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21311                 error "cannot access $MOUNT using its FID '$fid'"
21312 }
21313 run_test 233a "checking that OBF of the FS root succeeds"
21314
21315 test_233b() {
21316         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21317                 skip "Need MDS version at least 2.5.90"
21318         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21319
21320         local fid=$($LFS path2fid $MOUNT/.lustre)
21321
21322         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21323                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21324
21325         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21326         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21327                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21328 }
21329 run_test 233b "checking that OBF of the FS .lustre succeeds"
21330
21331 test_234() {
21332         local p="$TMP/sanityN-$TESTNAME.parameters"
21333         save_lustre_params client "llite.*.xattr_cache" > $p
21334         lctl set_param llite.*.xattr_cache 1 ||
21335                 skip_env "xattr cache is not supported"
21336
21337         mkdir -p $DIR/$tdir || error "mkdir failed"
21338         touch $DIR/$tdir/$tfile || error "touch failed"
21339         # OBD_FAIL_LLITE_XATTR_ENOMEM
21340         $LCTL set_param fail_loc=0x1405
21341         getfattr -n user.attr $DIR/$tdir/$tfile &&
21342                 error "getfattr should have failed with ENOMEM"
21343         $LCTL set_param fail_loc=0x0
21344         rm -rf $DIR/$tdir
21345
21346         restore_lustre_params < $p
21347         rm -f $p
21348 }
21349 run_test 234 "xattr cache should not crash on ENOMEM"
21350
21351 test_235() {
21352         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21353                 skip "Need MDS version at least 2.4.52"
21354
21355         flock_deadlock $DIR/$tfile
21356         local RC=$?
21357         case $RC in
21358                 0)
21359                 ;;
21360                 124) error "process hangs on a deadlock"
21361                 ;;
21362                 *) error "error executing flock_deadlock $DIR/$tfile"
21363                 ;;
21364         esac
21365 }
21366 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21367
21368 #LU-2935
21369 test_236() {
21370         check_swap_layouts_support
21371
21372         local ref1=/etc/passwd
21373         local ref2=/etc/group
21374         local file1=$DIR/$tdir/f1
21375         local file2=$DIR/$tdir/f2
21376
21377         test_mkdir -c1 $DIR/$tdir
21378         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21379         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21380         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21381         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21382         local fd=$(free_fd)
21383         local cmd="exec $fd<>$file2"
21384         eval $cmd
21385         rm $file2
21386         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21387                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21388         cmd="exec $fd>&-"
21389         eval $cmd
21390         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21391
21392         #cleanup
21393         rm -rf $DIR/$tdir
21394 }
21395 run_test 236 "Layout swap on open unlinked file"
21396
21397 # LU-4659 linkea consistency
21398 test_238() {
21399         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21400                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21401                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21402                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21403
21404         touch $DIR/$tfile
21405         ln $DIR/$tfile $DIR/$tfile.lnk
21406         touch $DIR/$tfile.new
21407         mv $DIR/$tfile.new $DIR/$tfile
21408         local fid1=$($LFS path2fid $DIR/$tfile)
21409         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21410         local path1=$($LFS fid2path $FSNAME "$fid1")
21411         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21412         local path2=$($LFS fid2path $FSNAME "$fid2")
21413         [ $tfile.lnk == $path2 ] ||
21414                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21415         rm -f $DIR/$tfile*
21416 }
21417 run_test 238 "Verify linkea consistency"
21418
21419 test_239A() { # was test_239
21420         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21421                 skip "Need MDS version at least 2.5.60"
21422
21423         local list=$(comma_list $(mdts_nodes))
21424
21425         mkdir -p $DIR/$tdir
21426         createmany -o $DIR/$tdir/f- 5000
21427         unlinkmany $DIR/$tdir/f- 5000
21428         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21429                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21430         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21431                         osp.*MDT*.sync_in_flight" | calc_sum)
21432         [ "$changes" -eq 0 ] || error "$changes not synced"
21433 }
21434 run_test 239A "osp_sync test"
21435
21436 test_239a() { #LU-5297
21437         remote_mds_nodsh && skip "remote MDS with nodsh"
21438
21439         touch $DIR/$tfile
21440         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21441         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21442         chgrp $RUNAS_GID $DIR/$tfile
21443         wait_delete_completed
21444 }
21445 run_test 239a "process invalid osp sync record correctly"
21446
21447 test_239b() { #LU-5297
21448         remote_mds_nodsh && skip "remote MDS with nodsh"
21449
21450         touch $DIR/$tfile1
21451         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21452         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21453         chgrp $RUNAS_GID $DIR/$tfile1
21454         wait_delete_completed
21455         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21456         touch $DIR/$tfile2
21457         chgrp $RUNAS_GID $DIR/$tfile2
21458         wait_delete_completed
21459 }
21460 run_test 239b "process osp sync record with ENOMEM error correctly"
21461
21462 test_240() {
21463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21464         remote_mds_nodsh && skip "remote MDS with nodsh"
21465
21466         mkdir -p $DIR/$tdir
21467
21468         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21469                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21470         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21471                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21472
21473         umount_client $MOUNT || error "umount failed"
21474         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21475         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21476         mount_client $MOUNT || error "failed to mount client"
21477
21478         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21479         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21480 }
21481 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21482
21483 test_241_bio() {
21484         local count=$1
21485         local bsize=$2
21486
21487         for LOOP in $(seq $count); do
21488                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21489                 cancel_lru_locks $OSC || true
21490         done
21491 }
21492
21493 test_241_dio() {
21494         local count=$1
21495         local bsize=$2
21496
21497         for LOOP in $(seq $1); do
21498                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21499                         2>/dev/null
21500         done
21501 }
21502
21503 test_241a() { # was test_241
21504         local bsize=$PAGE_SIZE
21505
21506         (( bsize < 40960 )) && bsize=40960
21507         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21508         ls -la $DIR/$tfile
21509         cancel_lru_locks $OSC
21510         test_241_bio 1000 $bsize &
21511         PID=$!
21512         test_241_dio 1000 $bsize
21513         wait $PID
21514 }
21515 run_test 241a "bio vs dio"
21516
21517 test_241b() {
21518         local bsize=$PAGE_SIZE
21519
21520         (( bsize < 40960 )) && bsize=40960
21521         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21522         ls -la $DIR/$tfile
21523         test_241_dio 1000 $bsize &
21524         PID=$!
21525         test_241_dio 1000 $bsize
21526         wait $PID
21527 }
21528 run_test 241b "dio vs dio"
21529
21530 test_242() {
21531         remote_mds_nodsh && skip "remote MDS with nodsh"
21532
21533         mkdir_on_mdt0 $DIR/$tdir
21534         touch $DIR/$tdir/$tfile
21535
21536         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21537         do_facet mds1 lctl set_param fail_loc=0x105
21538         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21539
21540         do_facet mds1 lctl set_param fail_loc=0
21541         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21542 }
21543 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21544
21545 test_243()
21546 {
21547         test_mkdir $DIR/$tdir
21548         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21549 }
21550 run_test 243 "various group lock tests"
21551
21552 test_244a()
21553 {
21554         test_mkdir $DIR/$tdir
21555         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21556         sendfile_grouplock $DIR/$tdir/$tfile || \
21557                 error "sendfile+grouplock failed"
21558         rm -rf $DIR/$tdir
21559 }
21560 run_test 244a "sendfile with group lock tests"
21561
21562 test_244b()
21563 {
21564         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21565
21566         local threads=50
21567         local size=$((1024*1024))
21568
21569         test_mkdir $DIR/$tdir
21570         for i in $(seq 1 $threads); do
21571                 local file=$DIR/$tdir/file_$((i / 10))
21572                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21573                 local pids[$i]=$!
21574         done
21575         for i in $(seq 1 $threads); do
21576                 wait ${pids[$i]}
21577         done
21578 }
21579 run_test 244b "multi-threaded write with group lock"
21580
21581 test_245a() {
21582         local flagname="multi_mod_rpcs"
21583         local connect_data_name="max_mod_rpcs"
21584         local out
21585
21586         # check if multiple modify RPCs flag is set
21587         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21588                 grep "connect_flags:")
21589         echo "$out"
21590
21591         echo "$out" | grep -qw $flagname
21592         if [ $? -ne 0 ]; then
21593                 echo "connect flag $flagname is not set"
21594                 return
21595         fi
21596
21597         # check if multiple modify RPCs data is set
21598         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21599         echo "$out"
21600
21601         echo "$out" | grep -qw $connect_data_name ||
21602                 error "import should have connect data $connect_data_name"
21603 }
21604 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21605
21606 test_245b() {
21607         local flagname="multi_mod_rpcs"
21608         local connect_data_name="max_mod_rpcs"
21609         local out
21610
21611         remote_mds_nodsh && skip "remote MDS with nodsh"
21612         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21613
21614         # check if multiple modify RPCs flag is set
21615         out=$(do_facet mds1 \
21616               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21617               grep "connect_flags:")
21618         echo "$out"
21619
21620         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21621
21622         # check if multiple modify RPCs data is set
21623         out=$(do_facet mds1 \
21624               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21625
21626         [[ "$out" =~ $connect_data_name ]] ||
21627                 {
21628                         echo "$out"
21629                         error "missing connect data $connect_data_name"
21630                 }
21631 }
21632 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21633
21634 cleanup_247() {
21635         local submount=$1
21636
21637         trap 0
21638         umount_client $submount
21639         rmdir $submount
21640 }
21641
21642 test_247a() {
21643         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21644                 grep -q subtree ||
21645                 skip_env "Fileset feature is not supported"
21646
21647         local submount=${MOUNT}_$tdir
21648
21649         mkdir $MOUNT/$tdir
21650         mkdir -p $submount || error "mkdir $submount failed"
21651         FILESET="$FILESET/$tdir" mount_client $submount ||
21652                 error "mount $submount failed"
21653         trap "cleanup_247 $submount" EXIT
21654         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21655         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21656                 error "read $MOUNT/$tdir/$tfile failed"
21657         cleanup_247 $submount
21658 }
21659 run_test 247a "mount subdir as fileset"
21660
21661 test_247b() {
21662         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21663                 skip_env "Fileset feature is not supported"
21664
21665         local submount=${MOUNT}_$tdir
21666
21667         rm -rf $MOUNT/$tdir
21668         mkdir -p $submount || error "mkdir $submount failed"
21669         SKIP_FILESET=1
21670         FILESET="$FILESET/$tdir" mount_client $submount &&
21671                 error "mount $submount should fail"
21672         rmdir $submount
21673 }
21674 run_test 247b "mount subdir that dose not exist"
21675
21676 test_247c() {
21677         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21678                 skip_env "Fileset feature is not supported"
21679
21680         local submount=${MOUNT}_$tdir
21681
21682         mkdir -p $MOUNT/$tdir/dir1
21683         mkdir -p $submount || error "mkdir $submount failed"
21684         trap "cleanup_247 $submount" EXIT
21685         FILESET="$FILESET/$tdir" mount_client $submount ||
21686                 error "mount $submount failed"
21687         local fid=$($LFS path2fid $MOUNT/)
21688         $LFS fid2path $submount $fid && error "fid2path should fail"
21689         cleanup_247 $submount
21690 }
21691 run_test 247c "running fid2path outside subdirectory root"
21692
21693 test_247d() {
21694         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21695                 skip "Fileset feature is not supported"
21696
21697         local submount=${MOUNT}_$tdir
21698
21699         mkdir -p $MOUNT/$tdir/dir1
21700         mkdir -p $submount || error "mkdir $submount failed"
21701         FILESET="$FILESET/$tdir" mount_client $submount ||
21702                 error "mount $submount failed"
21703         trap "cleanup_247 $submount" EXIT
21704
21705         local td=$submount/dir1
21706         local fid=$($LFS path2fid $td)
21707         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21708
21709         # check that we get the same pathname back
21710         local rootpath
21711         local found
21712         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21713                 echo "$rootpath $fid"
21714                 found=$($LFS fid2path $rootpath "$fid")
21715                 [ -n "$found" ] || error "fid2path should succeed"
21716                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21717         done
21718         # check wrong root path format
21719         rootpath=$submount"_wrong"
21720         found=$($LFS fid2path $rootpath "$fid")
21721         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21722
21723         cleanup_247 $submount
21724 }
21725 run_test 247d "running fid2path inside subdirectory root"
21726
21727 # LU-8037
21728 test_247e() {
21729         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21730                 grep -q subtree ||
21731                 skip "Fileset feature is not supported"
21732
21733         local submount=${MOUNT}_$tdir
21734
21735         mkdir $MOUNT/$tdir
21736         mkdir -p $submount || error "mkdir $submount failed"
21737         FILESET="$FILESET/.." mount_client $submount &&
21738                 error "mount $submount should fail"
21739         rmdir $submount
21740 }
21741 run_test 247e "mount .. as fileset"
21742
21743 test_247f() {
21744         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21745         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21746                 skip "Need at least version 2.14.50.162"
21747         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21748                 skip "Fileset feature is not supported"
21749
21750         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21751         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21752                 error "mkdir remote failed"
21753         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21754                 error "mkdir remote/subdir failed"
21755         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21756                 error "mkdir striped failed"
21757         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21758
21759         local submount=${MOUNT}_$tdir
21760
21761         mkdir -p $submount || error "mkdir $submount failed"
21762         stack_trap "rmdir $submount"
21763
21764         local dir
21765         local fileset=$FILESET
21766         local mdts=$(comma_list $(mdts_nodes))
21767
21768         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21769         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
21770                 $tdir/striped/subdir $tdir/striped/.; do
21771                 FILESET="$fileset/$dir" mount_client $submount ||
21772                         error "mount $dir failed"
21773                 umount_client $submount
21774         done
21775 }
21776 run_test 247f "mount striped or remote directory as fileset"
21777
21778 test_subdir_mount_lock()
21779 {
21780         local testdir=$1
21781         local submount=${MOUNT}_$(basename $testdir)
21782
21783         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
21784
21785         mkdir -p $submount || error "mkdir $submount failed"
21786         stack_trap "rmdir $submount"
21787
21788         FILESET="$fileset/$testdir" mount_client $submount ||
21789                 error "mount $FILESET failed"
21790         stack_trap "umount $submount"
21791
21792         local mdts=$(comma_list $(mdts_nodes))
21793
21794         local nrpcs
21795
21796         stat $submount > /dev/null || error "stat $submount failed"
21797         cancel_lru_locks $MDC
21798         stat $submount > /dev/null || error "stat $submount failed"
21799         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21800         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21801         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21802         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21803                 awk '/getattr/ {sum += $2} END {print sum}')
21804
21805         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21806 }
21807
21808 test_247g() {
21809         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21810
21811         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21812                 error "mkdir $tdir failed"
21813         test_subdir_mount_lock $tdir
21814 }
21815 run_test 247g "striped directory submount revalidate ROOT from cache"
21816
21817 test_247h() {
21818         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21819         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
21820                 skip "Need MDS version at least 2.15.51"
21821
21822         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21823         test_subdir_mount_lock $tdir
21824         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
21825         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
21826                 error "mkdir $tdir.1 failed"
21827         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
21828 }
21829 run_test 247h "remote directory submount revalidate ROOT from cache"
21830
21831 test_248a() {
21832         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21833         [ -z "$fast_read_sav" ] && skip "no fast read support"
21834
21835         # create a large file for fast read verification
21836         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21837
21838         # make sure the file is created correctly
21839         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21840                 { rm -f $DIR/$tfile; skip "file creation error"; }
21841
21842         echo "Test 1: verify that fast read is 4 times faster on cache read"
21843
21844         # small read with fast read enabled
21845         $LCTL set_param -n llite.*.fast_read=1
21846         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21847                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21848                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21849         # small read with fast read disabled
21850         $LCTL set_param -n llite.*.fast_read=0
21851         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21852                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21853                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21854
21855         # verify that fast read is 4 times faster for cache read
21856         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21857                 error_not_in_vm "fast read was not 4 times faster: " \
21858                            "$t_fast vs $t_slow"
21859
21860         echo "Test 2: verify the performance between big and small read"
21861         $LCTL set_param -n llite.*.fast_read=1
21862
21863         # 1k non-cache read
21864         cancel_lru_locks osc
21865         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21866                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21867                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21868
21869         # 1M non-cache read
21870         cancel_lru_locks osc
21871         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21872                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21873                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21874
21875         # verify that big IO is not 4 times faster than small IO
21876         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21877                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21878
21879         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21880         rm -f $DIR/$tfile
21881 }
21882 run_test 248a "fast read verification"
21883
21884 test_248b() {
21885         # Default short_io_bytes=16384, try both smaller and larger sizes.
21886         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21887         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21888         echo "bs=53248 count=113 normal buffered write"
21889         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21890                 error "dd of initial data file failed"
21891         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21892
21893         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21894         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21895                 error "dd with sync normal writes failed"
21896         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21897
21898         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21899         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21900                 error "dd with sync small writes failed"
21901         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21902
21903         cancel_lru_locks osc
21904
21905         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21906         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21907         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21908         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21909                 iflag=direct || error "dd with O_DIRECT small read failed"
21910         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21911         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21912                 error "compare $TMP/$tfile.1 failed"
21913
21914         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21915         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21916
21917         # just to see what the maximum tunable value is, and test parsing
21918         echo "test invalid parameter 2MB"
21919         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21920                 error "too-large short_io_bytes allowed"
21921         echo "test maximum parameter 512KB"
21922         # if we can set a larger short_io_bytes, run test regardless of version
21923         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21924                 # older clients may not allow setting it this large, that's OK
21925                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21926                         skip "Need at least client version 2.13.50"
21927                 error "medium short_io_bytes failed"
21928         fi
21929         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21930         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21931
21932         echo "test large parameter 64KB"
21933         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21934         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21935
21936         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21937         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21938                 error "dd with sync large writes failed"
21939         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21940
21941         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21942         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21943         num=$((113 * 4096 / PAGE_SIZE))
21944         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21945         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21946                 error "dd with O_DIRECT large writes failed"
21947         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21948                 error "compare $DIR/$tfile.3 failed"
21949
21950         cancel_lru_locks osc
21951
21952         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21953         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21954                 error "dd with O_DIRECT large read failed"
21955         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21956                 error "compare $TMP/$tfile.2 failed"
21957
21958         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21959         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21960                 error "dd with O_DIRECT large read failed"
21961         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21962                 error "compare $TMP/$tfile.3 failed"
21963 }
21964 run_test 248b "test short_io read and write for both small and large sizes"
21965
21966 test_249() { # LU-7890
21967         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21968                 skip "Need at least version 2.8.54"
21969
21970         rm -f $DIR/$tfile
21971         $LFS setstripe -c 1 $DIR/$tfile
21972         # Offset 2T == 4k * 512M
21973         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21974                 error "dd to 2T offset failed"
21975 }
21976 run_test 249 "Write above 2T file size"
21977
21978 test_250() {
21979         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21980          && skip "no 16TB file size limit on ZFS"
21981
21982         $LFS setstripe -c 1 $DIR/$tfile
21983         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21984         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21985         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21986         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21987                 conv=notrunc,fsync && error "append succeeded"
21988         return 0
21989 }
21990 run_test 250 "Write above 16T limit"
21991
21992 test_251() {
21993         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21994
21995         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21996         #Skip once - writing the first stripe will succeed
21997         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21998         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21999                 error "short write happened"
22000
22001         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22002         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22003                 error "short read happened"
22004
22005         rm -f $DIR/$tfile
22006 }
22007 run_test 251 "Handling short read and write correctly"
22008
22009 test_252() {
22010         remote_mds_nodsh && skip "remote MDS with nodsh"
22011         remote_ost_nodsh && skip "remote OST with nodsh"
22012         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22013                 skip_env "ldiskfs only test"
22014         fi
22015
22016         local tgt
22017         local dev
22018         local out
22019         local uuid
22020         local num
22021         local gen
22022
22023         # check lr_reader on OST0000
22024         tgt=ost1
22025         dev=$(facet_device $tgt)
22026         out=$(do_facet $tgt $LR_READER $dev)
22027         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22028         echo "$out"
22029         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22030         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22031                 error "Invalid uuid returned by $LR_READER on target $tgt"
22032         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22033
22034         # check lr_reader -c on MDT0000
22035         tgt=mds1
22036         dev=$(facet_device $tgt)
22037         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22038                 skip "$LR_READER does not support additional options"
22039         fi
22040         out=$(do_facet $tgt $LR_READER -c $dev)
22041         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22042         echo "$out"
22043         num=$(echo "$out" | grep -c "mdtlov")
22044         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22045                 error "Invalid number of mdtlov clients returned by $LR_READER"
22046         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22047
22048         # check lr_reader -cr on MDT0000
22049         out=$(do_facet $tgt $LR_READER -cr $dev)
22050         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22051         echo "$out"
22052         echo "$out" | grep -q "^reply_data:$" ||
22053                 error "$LR_READER should have returned 'reply_data' section"
22054         num=$(echo "$out" | grep -c "client_generation")
22055         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22056 }
22057 run_test 252 "check lr_reader tool"
22058
22059 test_253() {
22060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22061         remote_mds_nodsh && skip "remote MDS with nodsh"
22062         remote_mgs_nodsh && skip "remote MGS with nodsh"
22063
22064         local ostidx=0
22065         local rc=0
22066         local ost_name=$(ostname_from_index $ostidx)
22067
22068         # on the mdt's osc
22069         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22070         do_facet $SINGLEMDS $LCTL get_param -n \
22071                 osp.$mdtosc_proc1.reserved_mb_high ||
22072                 skip  "remote MDS does not support reserved_mb_high"
22073
22074         rm -rf $DIR/$tdir
22075         wait_mds_ost_sync
22076         wait_delete_completed
22077         mkdir $DIR/$tdir
22078
22079         pool_add $TESTNAME || error "Pool creation failed"
22080         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22081
22082         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22083                 error "Setstripe failed"
22084
22085         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22086
22087         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22088                     grep "watermarks")
22089         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22090
22091         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22092                         osp.$mdtosc_proc1.prealloc_status)
22093         echo "prealloc_status $oa_status"
22094
22095         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22096                 error "File creation should fail"
22097
22098         #object allocation was stopped, but we still able to append files
22099         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22100                 oflag=append || error "Append failed"
22101
22102         rm -f $DIR/$tdir/$tfile.0
22103
22104         # For this test, we want to delete the files we created to go out of
22105         # space but leave the watermark, so we remain nearly out of space
22106         ost_watermarks_enospc_delete_files $tfile $ostidx
22107
22108         wait_delete_completed
22109
22110         sleep_maxage
22111
22112         for i in $(seq 10 12); do
22113                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22114                         2>/dev/null || error "File creation failed after rm"
22115         done
22116
22117         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22118                         osp.$mdtosc_proc1.prealloc_status)
22119         echo "prealloc_status $oa_status"
22120
22121         if (( oa_status != 0 )); then
22122                 error "Object allocation still disable after rm"
22123         fi
22124 }
22125 run_test 253 "Check object allocation limit"
22126
22127 test_254() {
22128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22129         remote_mds_nodsh && skip "remote MDS with nodsh"
22130
22131         local mdt=$(facet_svc $SINGLEMDS)
22132
22133         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22134                 skip "MDS does not support changelog_size"
22135
22136         local cl_user
22137
22138         changelog_register || error "changelog_register failed"
22139
22140         changelog_clear 0 || error "changelog_clear failed"
22141
22142         local size1=$(do_facet $SINGLEMDS \
22143                       $LCTL get_param -n mdd.$mdt.changelog_size)
22144         echo "Changelog size $size1"
22145
22146         rm -rf $DIR/$tdir
22147         $LFS mkdir -i 0 $DIR/$tdir
22148         # change something
22149         mkdir -p $DIR/$tdir/pics/2008/zachy
22150         touch $DIR/$tdir/pics/2008/zachy/timestamp
22151         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22152         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22153         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22154         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22155         rm $DIR/$tdir/pics/desktop.jpg
22156
22157         local size2=$(do_facet $SINGLEMDS \
22158                       $LCTL get_param -n mdd.$mdt.changelog_size)
22159         echo "Changelog size after work $size2"
22160
22161         (( $size2 > $size1 )) ||
22162                 error "new Changelog size=$size2 less than old size=$size1"
22163 }
22164 run_test 254 "Check changelog size"
22165
22166 ladvise_no_type()
22167 {
22168         local type=$1
22169         local file=$2
22170
22171         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22172                 awk -F: '{print $2}' | grep $type > /dev/null
22173         if [ $? -ne 0 ]; then
22174                 return 0
22175         fi
22176         return 1
22177 }
22178
22179 ladvise_no_ioctl()
22180 {
22181         local file=$1
22182
22183         lfs ladvise -a willread $file > /dev/null 2>&1
22184         if [ $? -eq 0 ]; then
22185                 return 1
22186         fi
22187
22188         lfs ladvise -a willread $file 2>&1 |
22189                 grep "Inappropriate ioctl for device" > /dev/null
22190         if [ $? -eq 0 ]; then
22191                 return 0
22192         fi
22193         return 1
22194 }
22195
22196 percent() {
22197         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22198 }
22199
22200 # run a random read IO workload
22201 # usage: random_read_iops <filename> <filesize> <iosize>
22202 random_read_iops() {
22203         local file=$1
22204         local fsize=$2
22205         local iosize=${3:-4096}
22206
22207         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22208                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22209 }
22210
22211 drop_file_oss_cache() {
22212         local file="$1"
22213         local nodes="$2"
22214
22215         $LFS ladvise -a dontneed $file 2>/dev/null ||
22216                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22217 }
22218
22219 ladvise_willread_performance()
22220 {
22221         local repeat=10
22222         local average_origin=0
22223         local average_cache=0
22224         local average_ladvise=0
22225
22226         for ((i = 1; i <= $repeat; i++)); do
22227                 echo "Iter $i/$repeat: reading without willread hint"
22228                 cancel_lru_locks osc
22229                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22230                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22231                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22232                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22233
22234                 cancel_lru_locks osc
22235                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22236                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22237                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22238
22239                 cancel_lru_locks osc
22240                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22241                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22242                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22243                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22244                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22245         done
22246         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22247         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22248         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22249
22250         speedup_cache=$(percent $average_cache $average_origin)
22251         speedup_ladvise=$(percent $average_ladvise $average_origin)
22252
22253         echo "Average uncached read: $average_origin"
22254         echo "Average speedup with OSS cached read: " \
22255                 "$average_cache = +$speedup_cache%"
22256         echo "Average speedup with ladvise willread: " \
22257                 "$average_ladvise = +$speedup_ladvise%"
22258
22259         local lowest_speedup=20
22260         if (( ${average_cache%.*} < $lowest_speedup )); then
22261                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22262                      " got $average_cache%. Skipping ladvise willread check."
22263                 return 0
22264         fi
22265
22266         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22267         # it is still good to run until then to exercise 'ladvise willread'
22268         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22269                 [ "$ost1_FSTYPE" = "zfs" ] &&
22270                 echo "osd-zfs does not support dontneed or drop_caches" &&
22271                 return 0
22272
22273         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22274         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22275                 error_not_in_vm "Speedup with willread is less than " \
22276                         "$lowest_speedup%, got $average_ladvise%"
22277 }
22278
22279 test_255a() {
22280         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22281                 skip "lustre < 2.8.54 does not support ladvise "
22282         remote_ost_nodsh && skip "remote OST with nodsh"
22283
22284         stack_trap "rm -f $DIR/$tfile"
22285         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22286
22287         ladvise_no_type willread $DIR/$tfile &&
22288                 skip "willread ladvise is not supported"
22289
22290         ladvise_no_ioctl $DIR/$tfile &&
22291                 skip "ladvise ioctl is not supported"
22292
22293         local size_mb=100
22294         local size=$((size_mb * 1048576))
22295         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22296                 error "dd to $DIR/$tfile failed"
22297
22298         lfs ladvise -a willread $DIR/$tfile ||
22299                 error "Ladvise failed with no range argument"
22300
22301         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22302                 error "Ladvise failed with no -l or -e argument"
22303
22304         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22305                 error "Ladvise failed with only -e argument"
22306
22307         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22308                 error "Ladvise failed with only -l argument"
22309
22310         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22311                 error "End offset should not be smaller than start offset"
22312
22313         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22314                 error "End offset should not be equal to start offset"
22315
22316         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22317                 error "Ladvise failed with overflowing -s argument"
22318
22319         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22320                 error "Ladvise failed with overflowing -e argument"
22321
22322         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22323                 error "Ladvise failed with overflowing -l argument"
22324
22325         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22326                 error "Ladvise succeeded with conflicting -l and -e arguments"
22327
22328         echo "Synchronous ladvise should wait"
22329         local delay=4
22330 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22331         do_nodes $(comma_list $(osts_nodes)) \
22332                 $LCTL set_param fail_val=$delay fail_loc=0x237
22333
22334         local start_ts=$SECONDS
22335         lfs ladvise -a willread $DIR/$tfile ||
22336                 error "Ladvise failed with no range argument"
22337         local end_ts=$SECONDS
22338         local inteval_ts=$((end_ts - start_ts))
22339
22340         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22341                 error "Synchronous advice didn't wait reply"
22342         fi
22343
22344         echo "Asynchronous ladvise shouldn't wait"
22345         local start_ts=$SECONDS
22346         lfs ladvise -a willread -b $DIR/$tfile ||
22347                 error "Ladvise failed with no range argument"
22348         local end_ts=$SECONDS
22349         local inteval_ts=$((end_ts - start_ts))
22350
22351         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22352                 error "Asynchronous advice blocked"
22353         fi
22354
22355         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22356         ladvise_willread_performance
22357 }
22358 run_test 255a "check 'lfs ladvise -a willread'"
22359
22360 facet_meminfo() {
22361         local facet=$1
22362         local info=$2
22363
22364         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22365 }
22366
22367 test_255b() {
22368         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22369                 skip "lustre < 2.8.54 does not support ladvise "
22370         remote_ost_nodsh && skip "remote OST with nodsh"
22371
22372         stack_trap "rm -f $DIR/$tfile"
22373         lfs setstripe -c 1 -i 0 $DIR/$tfile
22374
22375         ladvise_no_type dontneed $DIR/$tfile &&
22376                 skip "dontneed ladvise is not supported"
22377
22378         ladvise_no_ioctl $DIR/$tfile &&
22379                 skip "ladvise ioctl is not supported"
22380
22381         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22382                 [ "$ost1_FSTYPE" = "zfs" ] &&
22383                 skip "zfs-osd does not support 'ladvise dontneed'"
22384
22385         local size_mb=100
22386         local size=$((size_mb * 1048576))
22387         # In order to prevent disturbance of other processes, only check 3/4
22388         # of the memory usage
22389         local kibibytes=$((size_mb * 1024 * 3 / 4))
22390
22391         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22392                 error "dd to $DIR/$tfile failed"
22393
22394         #force write to complete before dropping OST cache & checking memory
22395         sync
22396
22397         local total=$(facet_meminfo ost1 MemTotal)
22398         echo "Total memory: $total KiB"
22399
22400         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22401         local before_read=$(facet_meminfo ost1 Cached)
22402         echo "Cache used before read: $before_read KiB"
22403
22404         lfs ladvise -a willread $DIR/$tfile ||
22405                 error "Ladvise willread failed"
22406         local after_read=$(facet_meminfo ost1 Cached)
22407         echo "Cache used after read: $after_read KiB"
22408
22409         lfs ladvise -a dontneed $DIR/$tfile ||
22410                 error "Ladvise dontneed again failed"
22411         local no_read=$(facet_meminfo ost1 Cached)
22412         echo "Cache used after dontneed ladvise: $no_read KiB"
22413
22414         if [ $total -lt $((before_read + kibibytes)) ]; then
22415                 echo "Memory is too small, abort checking"
22416                 return 0
22417         fi
22418
22419         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22420                 error "Ladvise willread should use more memory" \
22421                         "than $kibibytes KiB"
22422         fi
22423
22424         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22425                 error "Ladvise dontneed should release more memory" \
22426                         "than $kibibytes KiB"
22427         fi
22428 }
22429 run_test 255b "check 'lfs ladvise -a dontneed'"
22430
22431 test_255c() {
22432         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22433                 skip "lustre < 2.10.50 does not support lockahead"
22434
22435         local ost1_imp=$(get_osc_import_name client ost1)
22436         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22437                          cut -d'.' -f2)
22438         local count
22439         local new_count
22440         local difference
22441         local i
22442         local rc
22443
22444         test_mkdir -p $DIR/$tdir
22445         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22446
22447         #test 10 returns only success/failure
22448         i=10
22449         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22450         rc=$?
22451         if [ $rc -eq 255 ]; then
22452                 error "Ladvise test${i} failed, ${rc}"
22453         fi
22454
22455         #test 11 counts lock enqueue requests, all others count new locks
22456         i=11
22457         count=$(do_facet ost1 \
22458                 $LCTL get_param -n ost.OSS.ost.stats)
22459         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22460
22461         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22462         rc=$?
22463         if [ $rc -eq 255 ]; then
22464                 error "Ladvise test${i} failed, ${rc}"
22465         fi
22466
22467         new_count=$(do_facet ost1 \
22468                 $LCTL get_param -n ost.OSS.ost.stats)
22469         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22470                    awk '{ print $2 }')
22471
22472         difference="$((new_count - count))"
22473         if [ $difference -ne $rc ]; then
22474                 error "Ladvise test${i}, bad enqueue count, returned " \
22475                       "${rc}, actual ${difference}"
22476         fi
22477
22478         for i in $(seq 12 21); do
22479                 # If we do not do this, we run the risk of having too many
22480                 # locks and starting lock cancellation while we are checking
22481                 # lock counts.
22482                 cancel_lru_locks osc
22483
22484                 count=$($LCTL get_param -n \
22485                        ldlm.namespaces.$imp_name.lock_unused_count)
22486
22487                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22488                 rc=$?
22489                 if [ $rc -eq 255 ]; then
22490                         error "Ladvise test ${i} failed, ${rc}"
22491                 fi
22492
22493                 new_count=$($LCTL get_param -n \
22494                        ldlm.namespaces.$imp_name.lock_unused_count)
22495                 difference="$((new_count - count))"
22496
22497                 # Test 15 output is divided by 100 to map down to valid return
22498                 if [ $i -eq 15 ]; then
22499                         rc="$((rc * 100))"
22500                 fi
22501
22502                 if [ $difference -ne $rc ]; then
22503                         error "Ladvise test ${i}, bad lock count, returned " \
22504                               "${rc}, actual ${difference}"
22505                 fi
22506         done
22507
22508         #test 22 returns only success/failure
22509         i=22
22510         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22511         rc=$?
22512         if [ $rc -eq 255 ]; then
22513                 error "Ladvise test${i} failed, ${rc}"
22514         fi
22515 }
22516 run_test 255c "suite of ladvise lockahead tests"
22517
22518 test_256() {
22519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22520         remote_mds_nodsh && skip "remote MDS with nodsh"
22521         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22522         changelog_users $SINGLEMDS | grep "^cl" &&
22523                 skip "active changelog user"
22524
22525         local cl_user
22526         local cat_sl
22527         local mdt_dev
22528
22529         mdt_dev=$(facet_device $SINGLEMDS)
22530         echo $mdt_dev
22531
22532         changelog_register || error "changelog_register failed"
22533
22534         rm -rf $DIR/$tdir
22535         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22536
22537         changelog_clear 0 || error "changelog_clear failed"
22538
22539         # change something
22540         touch $DIR/$tdir/{1..10}
22541
22542         # stop the MDT
22543         stop $SINGLEMDS || error "Fail to stop MDT"
22544
22545         # remount the MDT
22546         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22547                 error "Fail to start MDT"
22548
22549         #after mount new plainllog is used
22550         touch $DIR/$tdir/{11..19}
22551         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22552         stack_trap "rm -f $tmpfile"
22553         cat_sl=$(do_facet $SINGLEMDS "sync; \
22554                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22555                  llog_reader $tmpfile | grep -c type=1064553b")
22556         do_facet $SINGLEMDS llog_reader $tmpfile
22557
22558         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22559
22560         changelog_clear 0 || error "changelog_clear failed"
22561
22562         cat_sl=$(do_facet $SINGLEMDS "sync; \
22563                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22564                  llog_reader $tmpfile | grep -c type=1064553b")
22565
22566         if (( cat_sl == 2 )); then
22567                 error "Empty plain llog was not deleted from changelog catalog"
22568         elif (( cat_sl != 1 )); then
22569                 error "Active plain llog shouldn't be deleted from catalog"
22570         fi
22571 }
22572 run_test 256 "Check llog delete for empty and not full state"
22573
22574 test_257() {
22575         remote_mds_nodsh && skip "remote MDS with nodsh"
22576         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22577                 skip "Need MDS version at least 2.8.55"
22578
22579         test_mkdir $DIR/$tdir
22580
22581         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22582                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22583         stat $DIR/$tdir
22584
22585 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22586         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22587         local facet=mds$((mdtidx + 1))
22588         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22589         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22590
22591         stop $facet || error "stop MDS failed"
22592         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22593                 error "start MDS fail"
22594         wait_recovery_complete $facet
22595 }
22596 run_test 257 "xattr locks are not lost"
22597
22598 # Verify we take the i_mutex when security requires it
22599 test_258a() {
22600 #define OBD_FAIL_IMUTEX_SEC 0x141c
22601         $LCTL set_param fail_loc=0x141c
22602         touch $DIR/$tfile
22603         chmod u+s $DIR/$tfile
22604         chmod a+rwx $DIR/$tfile
22605         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22606         RC=$?
22607         if [ $RC -ne 0 ]; then
22608                 error "error, failed to take i_mutex, rc=$?"
22609         fi
22610         rm -f $DIR/$tfile
22611 }
22612 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22613
22614 # Verify we do NOT take the i_mutex in the normal case
22615 test_258b() {
22616 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22617         $LCTL set_param fail_loc=0x141d
22618         touch $DIR/$tfile
22619         chmod a+rwx $DIR
22620         chmod a+rw $DIR/$tfile
22621         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22622         RC=$?
22623         if [ $RC -ne 0 ]; then
22624                 error "error, took i_mutex unnecessarily, rc=$?"
22625         fi
22626         rm -f $DIR/$tfile
22627
22628 }
22629 run_test 258b "verify i_mutex security behavior"
22630
22631 test_259() {
22632         local file=$DIR/$tfile
22633         local before
22634         local after
22635
22636         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22637
22638         stack_trap "rm -f $file" EXIT
22639
22640         wait_delete_completed
22641         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22642         echo "before: $before"
22643
22644         $LFS setstripe -i 0 -c 1 $file
22645         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22646         sync_all_data
22647         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22648         echo "after write: $after"
22649
22650 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22651         do_facet ost1 $LCTL set_param fail_loc=0x2301
22652         $TRUNCATE $file 0
22653         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22654         echo "after truncate: $after"
22655
22656         stop ost1
22657         do_facet ost1 $LCTL set_param fail_loc=0
22658         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22659         sleep 2
22660         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22661         echo "after restart: $after"
22662         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22663                 error "missing truncate?"
22664
22665         return 0
22666 }
22667 run_test 259 "crash at delayed truncate"
22668
22669 test_260() {
22670 #define OBD_FAIL_MDC_CLOSE               0x806
22671         $LCTL set_param fail_loc=0x80000806
22672         touch $DIR/$tfile
22673
22674 }
22675 run_test 260 "Check mdc_close fail"
22676
22677 ### Data-on-MDT sanity tests ###
22678 test_270a() {
22679         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22680                 skip "Need MDS version at least 2.10.55 for DoM"
22681
22682         # create DoM file
22683         local dom=$DIR/$tdir/dom_file
22684         local tmp=$DIR/$tdir/tmp_file
22685
22686         mkdir_on_mdt0 $DIR/$tdir
22687
22688         # basic checks for DoM component creation
22689         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22690                 error "Can set MDT layout to non-first entry"
22691
22692         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22693                 error "Can define multiple entries as MDT layout"
22694
22695         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22696
22697         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22698         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22699         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22700
22701         local mdtidx=$($LFS getstripe -m $dom)
22702         local mdtname=MDT$(printf %04x $mdtidx)
22703         local facet=mds$((mdtidx + 1))
22704         local space_check=1
22705
22706         # Skip free space checks with ZFS
22707         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22708
22709         # write
22710         sync
22711         local size_tmp=$((65536 * 3))
22712         local mdtfree1=$(do_facet $facet \
22713                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22714
22715         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22716         # check also direct IO along write
22717         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22718         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22719         sync
22720         cmp $tmp $dom || error "file data is different"
22721         [ $(stat -c%s $dom) == $size_tmp ] ||
22722                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22723         if [ $space_check == 1 ]; then
22724                 local mdtfree2=$(do_facet $facet \
22725                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22726
22727                 # increase in usage from by $size_tmp
22728                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22729                         error "MDT free space wrong after write: " \
22730                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22731         fi
22732
22733         # truncate
22734         local size_dom=10000
22735
22736         $TRUNCATE $dom $size_dom
22737         [ $(stat -c%s $dom) == $size_dom ] ||
22738                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22739         if [ $space_check == 1 ]; then
22740                 mdtfree1=$(do_facet $facet \
22741                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22742                 # decrease in usage from $size_tmp to new $size_dom
22743                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22744                   $(((size_tmp - size_dom) / 1024)) ] ||
22745                         error "MDT free space is wrong after truncate: " \
22746                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22747         fi
22748
22749         # append
22750         cat $tmp >> $dom
22751         sync
22752         size_dom=$((size_dom + size_tmp))
22753         [ $(stat -c%s $dom) == $size_dom ] ||
22754                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22755         if [ $space_check == 1 ]; then
22756                 mdtfree2=$(do_facet $facet \
22757                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22758                 # increase in usage by $size_tmp from previous
22759                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22760                         error "MDT free space is wrong after append: " \
22761                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22762         fi
22763
22764         # delete
22765         rm $dom
22766         if [ $space_check == 1 ]; then
22767                 mdtfree1=$(do_facet $facet \
22768                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22769                 # decrease in usage by $size_dom from previous
22770                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22771                         error "MDT free space is wrong after removal: " \
22772                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22773         fi
22774
22775         # combined striping
22776         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22777                 error "Can't create DoM + OST striping"
22778
22779         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22780         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22781         # check also direct IO along write
22782         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22783         sync
22784         cmp $tmp $dom || error "file data is different"
22785         [ $(stat -c%s $dom) == $size_tmp ] ||
22786                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22787         rm $dom $tmp
22788
22789         return 0
22790 }
22791 run_test 270a "DoM: basic functionality tests"
22792
22793 test_270b() {
22794         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22795                 skip "Need MDS version at least 2.10.55"
22796
22797         local dom=$DIR/$tdir/dom_file
22798         local max_size=1048576
22799
22800         mkdir -p $DIR/$tdir
22801         $LFS setstripe -E $max_size -L mdt $dom
22802
22803         # truncate over the limit
22804         $TRUNCATE $dom $(($max_size + 1)) &&
22805                 error "successful truncate over the maximum size"
22806         # write over the limit
22807         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22808                 error "successful write over the maximum size"
22809         # append over the limit
22810         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22811         echo "12345" >> $dom && error "successful append over the maximum size"
22812         rm $dom
22813
22814         return 0
22815 }
22816 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22817
22818 test_270c() {
22819         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22820                 skip "Need MDS version at least 2.10.55"
22821
22822         mkdir -p $DIR/$tdir
22823         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22824
22825         # check files inherit DoM EA
22826         touch $DIR/$tdir/first
22827         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22828                 error "bad pattern"
22829         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22830                 error "bad stripe count"
22831         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22832                 error "bad stripe size"
22833
22834         # check directory inherits DoM EA and uses it as default
22835         mkdir $DIR/$tdir/subdir
22836         touch $DIR/$tdir/subdir/second
22837         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22838                 error "bad pattern in sub-directory"
22839         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22840                 error "bad stripe count in sub-directory"
22841         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22842                 error "bad stripe size in sub-directory"
22843         return 0
22844 }
22845 run_test 270c "DoM: DoM EA inheritance tests"
22846
22847 test_270d() {
22848         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22849                 skip "Need MDS version at least 2.10.55"
22850
22851         mkdir -p $DIR/$tdir
22852         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22853
22854         # inherit default DoM striping
22855         mkdir $DIR/$tdir/subdir
22856         touch $DIR/$tdir/subdir/f1
22857
22858         # change default directory striping
22859         $LFS setstripe -c 1 $DIR/$tdir/subdir
22860         touch $DIR/$tdir/subdir/f2
22861         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22862                 error "wrong default striping in file 2"
22863         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22864                 error "bad pattern in file 2"
22865         return 0
22866 }
22867 run_test 270d "DoM: change striping from DoM to RAID0"
22868
22869 test_270e() {
22870         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22871                 skip "Need MDS version at least 2.10.55"
22872
22873         mkdir -p $DIR/$tdir/dom
22874         mkdir -p $DIR/$tdir/norm
22875         DOMFILES=20
22876         NORMFILES=10
22877         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22878         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22879
22880         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22881         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22882
22883         # find DoM files by layout
22884         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22885         [ $NUM -eq  $DOMFILES ] ||
22886                 error "lfs find -L: found $NUM, expected $DOMFILES"
22887         echo "Test 1: lfs find 20 DOM files by layout: OK"
22888
22889         # there should be 1 dir with default DOM striping
22890         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22891         [ $NUM -eq  1 ] ||
22892                 error "lfs find -L: found $NUM, expected 1 dir"
22893         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22894
22895         # find DoM files by stripe size
22896         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22897         [ $NUM -eq  $DOMFILES ] ||
22898                 error "lfs find -S: found $NUM, expected $DOMFILES"
22899         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22900
22901         # find files by stripe offset except DoM files
22902         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22903         [ $NUM -eq  $NORMFILES ] ||
22904                 error "lfs find -i: found $NUM, expected $NORMFILES"
22905         echo "Test 5: lfs find no DOM files by stripe index: OK"
22906         return 0
22907 }
22908 run_test 270e "DoM: lfs find with DoM files test"
22909
22910 test_270f() {
22911         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22912                 skip "Need MDS version at least 2.10.55"
22913
22914         local mdtname=${FSNAME}-MDT0000-mdtlov
22915         local dom=$DIR/$tdir/dom_file
22916         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22917                                                 lod.$mdtname.dom_stripesize)
22918         local dom_limit=131072
22919
22920         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22921         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22922                                                 lod.$mdtname.dom_stripesize)
22923         [ ${dom_limit} -eq ${dom_current} ] ||
22924                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22925
22926         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22927         $LFS setstripe -d $DIR/$tdir
22928         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22929                 error "Can't set directory default striping"
22930
22931         # exceed maximum stripe size
22932         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22933                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22934         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22935                 error "Able to create DoM component size more than LOD limit"
22936
22937         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22938         dom_current=$(do_facet mds1 $LCTL get_param -n \
22939                                                 lod.$mdtname.dom_stripesize)
22940         [ 0 -eq ${dom_current} ] ||
22941                 error "Can't set zero DoM stripe limit"
22942         rm $dom
22943
22944         # attempt to create DoM file on server with disabled DoM should
22945         # remove DoM entry from layout and be succeed
22946         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22947                 error "Can't create DoM file (DoM is disabled)"
22948         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22949                 error "File has DoM component while DoM is disabled"
22950         rm $dom
22951
22952         # attempt to create DoM file with only DoM stripe should return error
22953         $LFS setstripe -E $dom_limit -L mdt $dom &&
22954                 error "Able to create DoM-only file while DoM is disabled"
22955
22956         # too low values to be aligned with smallest stripe size 64K
22957         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22958         dom_current=$(do_facet mds1 $LCTL get_param -n \
22959                                                 lod.$mdtname.dom_stripesize)
22960         [ 30000 -eq ${dom_current} ] &&
22961                 error "Can set too small DoM stripe limit"
22962
22963         # 64K is a minimal stripe size in Lustre, expect limit of that size
22964         [ 65536 -eq ${dom_current} ] ||
22965                 error "Limit is not set to 64K but ${dom_current}"
22966
22967         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22968         dom_current=$(do_facet mds1 $LCTL get_param -n \
22969                                                 lod.$mdtname.dom_stripesize)
22970         echo $dom_current
22971         [ 2147483648 -eq ${dom_current} ] &&
22972                 error "Can set too large DoM stripe limit"
22973
22974         do_facet mds1 $LCTL set_param -n \
22975                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22976         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22977                 error "Can't create DoM component size after limit change"
22978         do_facet mds1 $LCTL set_param -n \
22979                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22980         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22981                 error "Can't create DoM file after limit decrease"
22982         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22983                 error "Can create big DoM component after limit decrease"
22984         touch ${dom}_def ||
22985                 error "Can't create file with old default layout"
22986
22987         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22988         return 0
22989 }
22990 run_test 270f "DoM: maximum DoM stripe size checks"
22991
22992 test_270g() {
22993         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22994                 skip "Need MDS version at least 2.13.52"
22995         local dom=$DIR/$tdir/$tfile
22996
22997         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22998         local lodname=${FSNAME}-MDT0000-mdtlov
22999
23000         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23001         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23002         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23003         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23004
23005         local dom_limit=1024
23006         local dom_threshold="50%"
23007
23008         $LFS setstripe -d $DIR/$tdir
23009         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23010                 error "Can't set directory default striping"
23011
23012         do_facet mds1 $LCTL set_param -n \
23013                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23014         # set 0 threshold and create DOM file to change tunable stripesize
23015         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23016         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23017                 error "Failed to create $dom file"
23018         # now tunable dom_cur_stripesize should reach maximum
23019         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23020                                         lod.${lodname}.dom_stripesize_cur_kb)
23021         [[ $dom_current == $dom_limit ]] ||
23022                 error "Current DOM stripesize is not maximum"
23023         rm $dom
23024
23025         # set threshold for further tests
23026         do_facet mds1 $LCTL set_param -n \
23027                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23028         echo "DOM threshold is $dom_threshold free space"
23029         local dom_def
23030         local dom_set
23031         # Spoof bfree to exceed threshold
23032         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23033         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23034         for spfree in 40 20 0 15 30 55; do
23035                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23036                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23037                         error "Failed to create $dom file"
23038                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23039                                         lod.${lodname}.dom_stripesize_cur_kb)
23040                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23041                 [[ $dom_def != $dom_current ]] ||
23042                         error "Default stripe size was not changed"
23043                 if (( spfree > 0 )) ; then
23044                         dom_set=$($LFS getstripe -S $dom)
23045                         (( dom_set == dom_def * 1024 )) ||
23046                                 error "DOM component size is still old"
23047                 else
23048                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23049                                 error "DoM component is set with no free space"
23050                 fi
23051                 rm $dom
23052                 dom_current=$dom_def
23053         done
23054 }
23055 run_test 270g "DoM: default DoM stripe size depends on free space"
23056
23057 test_270h() {
23058         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23059                 skip "Need MDS version at least 2.13.53"
23060
23061         local mdtname=${FSNAME}-MDT0000-mdtlov
23062         local dom=$DIR/$tdir/$tfile
23063         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23064
23065         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23066         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23067
23068         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23069         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23070                 error "can't create OST file"
23071         # mirrored file with DOM entry in the second mirror
23072         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23073                 error "can't create mirror with DoM component"
23074
23075         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23076
23077         # DOM component in the middle and has other enries in the same mirror,
23078         # should succeed but lost DoM component
23079         $LFS setstripe --copy=${dom}_1 $dom ||
23080                 error "Can't create file from OST|DOM mirror layout"
23081         # check new file has no DoM layout after all
23082         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23083                 error "File has DoM component while DoM is disabled"
23084 }
23085 run_test 270h "DoM: DoM stripe removal when disabled on server"
23086
23087 test_270i() {
23088         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23089                 skip "Need MDS version at least 2.14.54"
23090
23091         mkdir $DIR/$tdir
23092         # DoM with plain layout
23093         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23094                 error "default plain layout with DoM must fail"
23095         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23096                 error "setstripe plain file layout with DoM must fail"
23097         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23098                 error "default DoM layout with bad striping must fail"
23099         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23100                 error "setstripe to DoM layout with bad striping must fail"
23101         return 0
23102 }
23103 run_test 270i "DoM: setting invalid DoM striping should fail"
23104
23105 test_271a() {
23106         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23107                 skip "Need MDS version at least 2.10.55"
23108
23109         local dom=$DIR/$tdir/dom
23110
23111         mkdir -p $DIR/$tdir
23112
23113         $LFS setstripe -E 1024K -L mdt $dom
23114
23115         lctl set_param -n mdc.*.stats=clear
23116         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23117         cat $dom > /dev/null
23118         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23119         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23120         ls $dom
23121         rm -f $dom
23122 }
23123 run_test 271a "DoM: data is cached for read after write"
23124
23125 test_271b() {
23126         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23127                 skip "Need MDS version at least 2.10.55"
23128
23129         local dom=$DIR/$tdir/dom
23130
23131         mkdir -p $DIR/$tdir
23132
23133         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23134
23135         lctl set_param -n mdc.*.stats=clear
23136         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23137         cancel_lru_locks mdc
23138         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23139         # second stat to check size is cached on client
23140         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23141         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23142         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23143         rm -f $dom
23144 }
23145 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23146
23147 test_271ba() {
23148         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23149                 skip "Need MDS version at least 2.10.55"
23150
23151         local dom=$DIR/$tdir/dom
23152
23153         mkdir -p $DIR/$tdir
23154
23155         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23156
23157         lctl set_param -n mdc.*.stats=clear
23158         lctl set_param -n osc.*.stats=clear
23159         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23160         cancel_lru_locks mdc
23161         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23162         # second stat to check size is cached on client
23163         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23164         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23165         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23166         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23167         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23168         rm -f $dom
23169 }
23170 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23171
23172
23173 get_mdc_stats() {
23174         local mdtidx=$1
23175         local param=$2
23176         local mdt=MDT$(printf %04x $mdtidx)
23177
23178         if [ -z $param ]; then
23179                 lctl get_param -n mdc.*$mdt*.stats
23180         else
23181                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23182         fi
23183 }
23184
23185 test_271c() {
23186         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23187                 skip "Need MDS version at least 2.10.55"
23188
23189         local dom=$DIR/$tdir/dom
23190
23191         mkdir -p $DIR/$tdir
23192
23193         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23194
23195         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23196         local facet=mds$((mdtidx + 1))
23197
23198         cancel_lru_locks mdc
23199         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23200         createmany -o $dom 1000
23201         lctl set_param -n mdc.*.stats=clear
23202         smalliomany -w $dom 1000 200
23203         get_mdc_stats $mdtidx
23204         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23205         # Each file has 1 open, 1 IO enqueues, total 2000
23206         # but now we have also +1 getxattr for security.capability, total 3000
23207         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23208         unlinkmany $dom 1000
23209
23210         cancel_lru_locks mdc
23211         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23212         createmany -o $dom 1000
23213         lctl set_param -n mdc.*.stats=clear
23214         smalliomany -w $dom 1000 200
23215         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23216         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23217         # for OPEN and IO lock.
23218         [ $((enq - enq_2)) -ge 1000 ] ||
23219                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23220         unlinkmany $dom 1000
23221         return 0
23222 }
23223 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23224
23225 cleanup_271def_tests() {
23226         trap 0
23227         rm -f $1
23228 }
23229
23230 test_271d() {
23231         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23232                 skip "Need MDS version at least 2.10.57"
23233
23234         local dom=$DIR/$tdir/dom
23235         local tmp=$TMP/$tfile
23236         trap "cleanup_271def_tests $tmp" EXIT
23237
23238         mkdir -p $DIR/$tdir
23239
23240         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23241
23242         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23243
23244         cancel_lru_locks mdc
23245         dd if=/dev/urandom of=$tmp bs=1000 count=1
23246         dd if=$tmp of=$dom bs=1000 count=1
23247         cancel_lru_locks mdc
23248
23249         cat /etc/hosts >> $tmp
23250         lctl set_param -n mdc.*.stats=clear
23251
23252         # append data to the same file it should update local page
23253         echo "Append to the same page"
23254         cat /etc/hosts >> $dom
23255         local num=$(get_mdc_stats $mdtidx ost_read)
23256         local ra=$(get_mdc_stats $mdtidx req_active)
23257         local rw=$(get_mdc_stats $mdtidx req_waittime)
23258
23259         [ -z $num ] || error "$num READ RPC occured"
23260         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23261         echo "... DONE"
23262
23263         # compare content
23264         cmp $tmp $dom || error "file miscompare"
23265
23266         cancel_lru_locks mdc
23267         lctl set_param -n mdc.*.stats=clear
23268
23269         echo "Open and read file"
23270         cat $dom > /dev/null
23271         local num=$(get_mdc_stats $mdtidx ost_read)
23272         local ra=$(get_mdc_stats $mdtidx req_active)
23273         local rw=$(get_mdc_stats $mdtidx req_waittime)
23274
23275         [ -z $num ] || error "$num READ RPC occured"
23276         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23277         echo "... DONE"
23278
23279         # compare content
23280         cmp $tmp $dom || error "file miscompare"
23281
23282         return 0
23283 }
23284 run_test 271d "DoM: read on open (1K file in reply buffer)"
23285
23286 test_271f() {
23287         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23288                 skip "Need MDS version at least 2.10.57"
23289
23290         local dom=$DIR/$tdir/dom
23291         local tmp=$TMP/$tfile
23292         trap "cleanup_271def_tests $tmp" EXIT
23293
23294         mkdir -p $DIR/$tdir
23295
23296         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23297
23298         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23299
23300         cancel_lru_locks mdc
23301         dd if=/dev/urandom of=$tmp bs=265000 count=1
23302         dd if=$tmp of=$dom bs=265000 count=1
23303         cancel_lru_locks mdc
23304         cat /etc/hosts >> $tmp
23305         lctl set_param -n mdc.*.stats=clear
23306
23307         echo "Append to the same page"
23308         cat /etc/hosts >> $dom
23309         local num=$(get_mdc_stats $mdtidx ost_read)
23310         local ra=$(get_mdc_stats $mdtidx req_active)
23311         local rw=$(get_mdc_stats $mdtidx req_waittime)
23312
23313         [ -z $num ] || error "$num READ RPC occured"
23314         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23315         echo "... DONE"
23316
23317         # compare content
23318         cmp $tmp $dom || error "file miscompare"
23319
23320         cancel_lru_locks mdc
23321         lctl set_param -n mdc.*.stats=clear
23322
23323         echo "Open and read file"
23324         cat $dom > /dev/null
23325         local num=$(get_mdc_stats $mdtidx ost_read)
23326         local ra=$(get_mdc_stats $mdtidx req_active)
23327         local rw=$(get_mdc_stats $mdtidx req_waittime)
23328
23329         [ -z $num ] && num=0
23330         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23331         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23332         echo "... DONE"
23333
23334         # compare content
23335         cmp $tmp $dom || error "file miscompare"
23336
23337         return 0
23338 }
23339 run_test 271f "DoM: read on open (200K file and read tail)"
23340
23341 test_271g() {
23342         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23343                 skip "Skipping due to old client or server version"
23344
23345         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23346         # to get layout
23347         $CHECKSTAT -t file $DIR1/$tfile
23348
23349         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23350         MULTIOP_PID=$!
23351         sleep 1
23352         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23353         $LCTL set_param fail_loc=0x80000314
23354         rm $DIR1/$tfile || error "Unlink fails"
23355         RC=$?
23356         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23357         [ $RC -eq 0 ] || error "Failed write to stale object"
23358 }
23359 run_test 271g "Discard DoM data vs client flush race"
23360
23361 test_272a() {
23362         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23363                 skip "Need MDS version at least 2.11.50"
23364
23365         local dom=$DIR/$tdir/dom
23366         mkdir -p $DIR/$tdir
23367
23368         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23369         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23370                 error "failed to write data into $dom"
23371         local old_md5=$(md5sum $dom)
23372
23373         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23374                 error "failed to migrate to the same DoM component"
23375
23376         local new_md5=$(md5sum $dom)
23377
23378         [ "$old_md5" == "$new_md5" ] ||
23379                 error "md5sum differ: $old_md5, $new_md5"
23380
23381         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23382                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23383 }
23384 run_test 272a "DoM migration: new layout with the same DOM component"
23385
23386 test_272b() {
23387         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23388                 skip "Need MDS version at least 2.11.50"
23389
23390         local dom=$DIR/$tdir/dom
23391         mkdir -p $DIR/$tdir
23392         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23393
23394         local mdtidx=$($LFS getstripe -m $dom)
23395         local mdtname=MDT$(printf %04x $mdtidx)
23396         local facet=mds$((mdtidx + 1))
23397
23398         local mdtfree1=$(do_facet $facet \
23399                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23400         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23401                 error "failed to write data into $dom"
23402         local old_md5=$(md5sum $dom)
23403         cancel_lru_locks mdc
23404         local mdtfree1=$(do_facet $facet \
23405                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23406
23407         $LFS migrate -c2 $dom ||
23408                 error "failed to migrate to the new composite layout"
23409         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23410                 error "MDT stripe was not removed"
23411
23412         cancel_lru_locks mdc
23413         local new_md5=$(md5sum $dom)
23414         [ "$old_md5" == "$new_md5" ] ||
23415                 error "$old_md5 != $new_md5"
23416
23417         # Skip free space checks with ZFS
23418         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23419                 local mdtfree2=$(do_facet $facet \
23420                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23421                 [ $mdtfree2 -gt $mdtfree1 ] ||
23422                         error "MDT space is not freed after migration"
23423         fi
23424         return 0
23425 }
23426 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23427
23428 test_272c() {
23429         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23430                 skip "Need MDS version at least 2.11.50"
23431
23432         local dom=$DIR/$tdir/$tfile
23433         mkdir -p $DIR/$tdir
23434         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23435
23436         local mdtidx=$($LFS getstripe -m $dom)
23437         local mdtname=MDT$(printf %04x $mdtidx)
23438         local facet=mds$((mdtidx + 1))
23439
23440         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23441                 error "failed to write data into $dom"
23442         local old_md5=$(md5sum $dom)
23443         cancel_lru_locks mdc
23444         local mdtfree1=$(do_facet $facet \
23445                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23446
23447         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23448                 error "failed to migrate to the new composite layout"
23449         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23450                 error "MDT stripe was not removed"
23451
23452         cancel_lru_locks mdc
23453         local new_md5=$(md5sum $dom)
23454         [ "$old_md5" == "$new_md5" ] ||
23455                 error "$old_md5 != $new_md5"
23456
23457         # Skip free space checks with ZFS
23458         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23459                 local mdtfree2=$(do_facet $facet \
23460                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23461                 [ $mdtfree2 -gt $mdtfree1 ] ||
23462                         error "MDS space is not freed after migration"
23463         fi
23464         return 0
23465 }
23466 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23467
23468 test_272d() {
23469         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23470                 skip "Need MDS version at least 2.12.55"
23471
23472         local dom=$DIR/$tdir/$tfile
23473         mkdir -p $DIR/$tdir
23474         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23475
23476         local mdtidx=$($LFS getstripe -m $dom)
23477         local mdtname=MDT$(printf %04x $mdtidx)
23478         local facet=mds$((mdtidx + 1))
23479
23480         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23481                 error "failed to write data into $dom"
23482         local old_md5=$(md5sum $dom)
23483         cancel_lru_locks mdc
23484         local mdtfree1=$(do_facet $facet \
23485                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23486
23487         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23488                 error "failed mirroring to the new composite layout"
23489         $LFS mirror resync $dom ||
23490                 error "failed mirror resync"
23491         $LFS mirror split --mirror-id 1 -d $dom ||
23492                 error "failed mirror split"
23493
23494         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23495                 error "MDT stripe was not removed"
23496
23497         cancel_lru_locks mdc
23498         local new_md5=$(md5sum $dom)
23499         [ "$old_md5" == "$new_md5" ] ||
23500                 error "$old_md5 != $new_md5"
23501
23502         # Skip free space checks with ZFS
23503         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23504                 local mdtfree2=$(do_facet $facet \
23505                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23506                 [ $mdtfree2 -gt $mdtfree1 ] ||
23507                         error "MDS space is not freed after DOM mirror deletion"
23508         fi
23509         return 0
23510 }
23511 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23512
23513 test_272e() {
23514         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23515                 skip "Need MDS version at least 2.12.55"
23516
23517         local dom=$DIR/$tdir/$tfile
23518         mkdir -p $DIR/$tdir
23519         $LFS setstripe -c 2 $dom
23520
23521         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23522                 error "failed to write data into $dom"
23523         local old_md5=$(md5sum $dom)
23524         cancel_lru_locks
23525
23526         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23527                 error "failed mirroring to the DOM layout"
23528         $LFS mirror resync $dom ||
23529                 error "failed mirror resync"
23530         $LFS mirror split --mirror-id 1 -d $dom ||
23531                 error "failed mirror split"
23532
23533         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23534                 error "MDT stripe wasn't set"
23535
23536         cancel_lru_locks
23537         local new_md5=$(md5sum $dom)
23538         [ "$old_md5" == "$new_md5" ] ||
23539                 error "$old_md5 != $new_md5"
23540
23541         return 0
23542 }
23543 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23544
23545 test_272f() {
23546         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23547                 skip "Need MDS version at least 2.12.55"
23548
23549         local dom=$DIR/$tdir/$tfile
23550         mkdir -p $DIR/$tdir
23551         $LFS setstripe -c 2 $dom
23552
23553         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23554                 error "failed to write data into $dom"
23555         local old_md5=$(md5sum $dom)
23556         cancel_lru_locks
23557
23558         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23559                 error "failed migrating to the DOM file"
23560
23561         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23562                 error "MDT stripe wasn't set"
23563
23564         cancel_lru_locks
23565         local new_md5=$(md5sum $dom)
23566         [ "$old_md5" != "$new_md5" ] &&
23567                 error "$old_md5 != $new_md5"
23568
23569         return 0
23570 }
23571 run_test 272f "DoM migration: OST-striped file to DOM file"
23572
23573 test_273a() {
23574         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23575                 skip "Need MDS version at least 2.11.50"
23576
23577         # Layout swap cannot be done if either file has DOM component,
23578         # this will never be supported, migration should be used instead
23579
23580         local dom=$DIR/$tdir/$tfile
23581         mkdir -p $DIR/$tdir
23582
23583         $LFS setstripe -c2 ${dom}_plain
23584         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23585         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23586                 error "can swap layout with DoM component"
23587         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23588                 error "can swap layout with DoM component"
23589
23590         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23591         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23592                 error "can swap layout with DoM component"
23593         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23594                 error "can swap layout with DoM component"
23595         return 0
23596 }
23597 run_test 273a "DoM: layout swapping should fail with DOM"
23598
23599 test_273b() {
23600         mkdir -p $DIR/$tdir
23601         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23602
23603 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23604         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23605
23606         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23607 }
23608 run_test 273b "DoM: race writeback and object destroy"
23609
23610 test_275() {
23611         remote_ost_nodsh && skip "remote OST with nodsh"
23612         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23613                 skip "Need OST version >= 2.10.57"
23614
23615         local file=$DIR/$tfile
23616         local oss
23617
23618         oss=$(comma_list $(osts_nodes))
23619
23620         dd if=/dev/urandom of=$file bs=1M count=2 ||
23621                 error "failed to create a file"
23622         cancel_lru_locks osc
23623
23624         #lock 1
23625         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23626                 error "failed to read a file"
23627
23628 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23629         $LCTL set_param fail_loc=0x8000031f
23630
23631         cancel_lru_locks osc &
23632         sleep 1
23633
23634 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23635         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23636         #IO takes another lock, but matches the PENDING one
23637         #and places it to the IO RPC
23638         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23639                 error "failed to read a file with PENDING lock"
23640 }
23641 run_test 275 "Read on a canceled duplicate lock"
23642
23643 test_276() {
23644         remote_ost_nodsh && skip "remote OST with nodsh"
23645         local pid
23646
23647         do_facet ost1 "(while true; do \
23648                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23649                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23650         pid=$!
23651
23652         for LOOP in $(seq 20); do
23653                 stop ost1
23654                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23655         done
23656         kill -9 $pid
23657         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23658                 rm $TMP/sanity_276_pid"
23659 }
23660 run_test 276 "Race between mount and obd_statfs"
23661
23662 test_277() {
23663         $LCTL set_param ldlm.namespaces.*.lru_size=0
23664         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23665         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23666                         grep ^used_mb | awk '{print $2}')
23667         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23668         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23669                 oflag=direct conv=notrunc
23670         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23671                         grep ^used_mb | awk '{print $2}')
23672         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23673 }
23674 run_test 277 "Direct IO shall drop page cache"
23675
23676 test_278() {
23677         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23678         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23679         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23680                 skip "needs the same host for mdt1 mdt2" && return
23681
23682         local pid1
23683         local pid2
23684
23685 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23686         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23687         stop mds2 &
23688         pid2=$!
23689
23690         stop mds1
23691
23692         echo "Starting MDTs"
23693         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23694         wait $pid2
23695 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23696 #will return NULL
23697         do_facet mds2 $LCTL set_param fail_loc=0
23698
23699         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23700         wait_recovery_complete mds2
23701 }
23702 run_test 278 "Race starting MDS between MDTs stop/start"
23703
23704 test_280() {
23705         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23706                 skip "Need MGS version at least 2.13.52"
23707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23708         combined_mgs_mds || skip "needs combined MGS/MDT"
23709
23710         umount_client $MOUNT
23711 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23712         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23713
23714         mount_client $MOUNT &
23715         sleep 1
23716         stop mgs || error "stop mgs failed"
23717         #for a race mgs would crash
23718         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23719         # make sure we unmount client before remounting
23720         wait
23721         umount_client $MOUNT
23722         mount_client $MOUNT || error "mount client failed"
23723 }
23724 run_test 280 "Race between MGS umount and client llog processing"
23725
23726 cleanup_test_300() {
23727         trap 0
23728         umask $SAVE_UMASK
23729 }
23730 test_striped_dir() {
23731         local mdt_index=$1
23732         local stripe_count
23733         local stripe_index
23734
23735         mkdir -p $DIR/$tdir
23736
23737         SAVE_UMASK=$(umask)
23738         trap cleanup_test_300 RETURN EXIT
23739
23740         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23741                                                 $DIR/$tdir/striped_dir ||
23742                 error "set striped dir error"
23743
23744         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23745         [ "$mode" = "755" ] || error "expect 755 got $mode"
23746
23747         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23748                 error "getdirstripe failed"
23749         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23750         if [ "$stripe_count" != "2" ]; then
23751                 error "1:stripe_count is $stripe_count, expect 2"
23752         fi
23753         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23754         if [ "$stripe_count" != "2" ]; then
23755                 error "2:stripe_count is $stripe_count, expect 2"
23756         fi
23757
23758         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23759         if [ "$stripe_index" != "$mdt_index" ]; then
23760                 error "stripe_index is $stripe_index, expect $mdt_index"
23761         fi
23762
23763         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23764                 error "nlink error after create striped dir"
23765
23766         mkdir $DIR/$tdir/striped_dir/a
23767         mkdir $DIR/$tdir/striped_dir/b
23768
23769         stat $DIR/$tdir/striped_dir/a ||
23770                 error "create dir under striped dir failed"
23771         stat $DIR/$tdir/striped_dir/b ||
23772                 error "create dir under striped dir failed"
23773
23774         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23775                 error "nlink error after mkdir"
23776
23777         rmdir $DIR/$tdir/striped_dir/a
23778         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23779                 error "nlink error after rmdir"
23780
23781         rmdir $DIR/$tdir/striped_dir/b
23782         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23783                 error "nlink error after rmdir"
23784
23785         chattr +i $DIR/$tdir/striped_dir
23786         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23787                 error "immutable flags not working under striped dir!"
23788         chattr -i $DIR/$tdir/striped_dir
23789
23790         rmdir $DIR/$tdir/striped_dir ||
23791                 error "rmdir striped dir error"
23792
23793         cleanup_test_300
23794
23795         true
23796 }
23797
23798 test_300a() {
23799         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23800                 skip "skipped for lustre < 2.7.0"
23801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23803
23804         test_striped_dir 0 || error "failed on striped dir on MDT0"
23805         test_striped_dir 1 || error "failed on striped dir on MDT0"
23806 }
23807 run_test 300a "basic striped dir sanity test"
23808
23809 test_300b() {
23810         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23811                 skip "skipped for lustre < 2.7.0"
23812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23814
23815         local i
23816         local mtime1
23817         local mtime2
23818         local mtime3
23819
23820         test_mkdir $DIR/$tdir || error "mkdir fail"
23821         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23822                 error "set striped dir error"
23823         for i in {0..9}; do
23824                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23825                 sleep 1
23826                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23827                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23828                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23829                 sleep 1
23830                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23831                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23832                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23833         done
23834         true
23835 }
23836 run_test 300b "check ctime/mtime for striped dir"
23837
23838 test_300c() {
23839         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23840                 skip "skipped for lustre < 2.7.0"
23841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23843
23844         local file_count
23845
23846         mkdir_on_mdt0 $DIR/$tdir
23847         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23848                 error "set striped dir error"
23849
23850         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23851                 error "chown striped dir failed"
23852
23853         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23854                 error "create 5k files failed"
23855
23856         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23857
23858         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23859
23860         rm -rf $DIR/$tdir
23861 }
23862 run_test 300c "chown && check ls under striped directory"
23863
23864 test_300d() {
23865         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23866                 skip "skipped for lustre < 2.7.0"
23867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23868         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23869
23870         local stripe_count
23871         local file
23872
23873         mkdir -p $DIR/$tdir
23874         $LFS setstripe -c 2 $DIR/$tdir
23875
23876         #local striped directory
23877         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23878                 error "set striped dir error"
23879         #look at the directories for debug purposes
23880         ls -l $DIR/$tdir
23881         $LFS getdirstripe $DIR/$tdir
23882         ls -l $DIR/$tdir/striped_dir
23883         $LFS getdirstripe $DIR/$tdir/striped_dir
23884         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23885                 error "create 10 files failed"
23886
23887         #remote striped directory
23888         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23889                 error "set striped dir error"
23890         #look at the directories for debug purposes
23891         ls -l $DIR/$tdir
23892         $LFS getdirstripe $DIR/$tdir
23893         ls -l $DIR/$tdir/remote_striped_dir
23894         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23895         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23896                 error "create 10 files failed"
23897
23898         for file in $(find $DIR/$tdir); do
23899                 stripe_count=$($LFS getstripe -c $file)
23900                 [ $stripe_count -eq 2 ] ||
23901                         error "wrong stripe $stripe_count for $file"
23902         done
23903
23904         rm -rf $DIR/$tdir
23905 }
23906 run_test 300d "check default stripe under striped directory"
23907
23908 test_300e() {
23909         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23910                 skip "Need MDS version at least 2.7.55"
23911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23913
23914         local stripe_count
23915         local file
23916
23917         mkdir -p $DIR/$tdir
23918
23919         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23920                 error "set striped dir error"
23921
23922         touch $DIR/$tdir/striped_dir/a
23923         touch $DIR/$tdir/striped_dir/b
23924         touch $DIR/$tdir/striped_dir/c
23925
23926         mkdir $DIR/$tdir/striped_dir/dir_a
23927         mkdir $DIR/$tdir/striped_dir/dir_b
23928         mkdir $DIR/$tdir/striped_dir/dir_c
23929
23930         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23931                 error "set striped adir under striped dir error"
23932
23933         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23934                 error "set striped bdir under striped dir error"
23935
23936         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23937                 error "set striped cdir under striped dir error"
23938
23939         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23940                 error "rename dir under striped dir fails"
23941
23942         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23943                 error "rename dir under different stripes fails"
23944
23945         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23946                 error "rename file under striped dir should succeed"
23947
23948         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23949                 error "rename dir under striped dir should succeed"
23950
23951         rm -rf $DIR/$tdir
23952 }
23953 run_test 300e "check rename under striped directory"
23954
23955 test_300f() {
23956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23958         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23959                 skip "Need MDS version at least 2.7.55"
23960
23961         local stripe_count
23962         local file
23963
23964         rm -rf $DIR/$tdir
23965         mkdir -p $DIR/$tdir
23966
23967         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23968                 error "set striped dir error"
23969
23970         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23971                 error "set striped dir error"
23972
23973         touch $DIR/$tdir/striped_dir/a
23974         mkdir $DIR/$tdir/striped_dir/dir_a
23975         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23976                 error "create striped dir under striped dir fails"
23977
23978         touch $DIR/$tdir/striped_dir1/b
23979         mkdir $DIR/$tdir/striped_dir1/dir_b
23980         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23981                 error "create striped dir under striped dir fails"
23982
23983         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23984                 error "rename dir under different striped dir should fail"
23985
23986         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23987                 error "rename striped dir under diff striped dir should fail"
23988
23989         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23990                 error "rename file under diff striped dirs fails"
23991
23992         rm -rf $DIR/$tdir
23993 }
23994 run_test 300f "check rename cross striped directory"
23995
23996 test_300_check_default_striped_dir()
23997 {
23998         local dirname=$1
23999         local default_count=$2
24000         local default_index=$3
24001         local stripe_count
24002         local stripe_index
24003         local dir_stripe_index
24004         local dir
24005
24006         echo "checking $dirname $default_count $default_index"
24007         $LFS setdirstripe -D -c $default_count -i $default_index \
24008                                 -H all_char $DIR/$tdir/$dirname ||
24009                 error "set default stripe on striped dir error"
24010         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24011         [ $stripe_count -eq $default_count ] ||
24012                 error "expect $default_count get $stripe_count for $dirname"
24013
24014         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24015         [ $stripe_index -eq $default_index ] ||
24016                 error "expect $default_index get $stripe_index for $dirname"
24017
24018         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24019                                                 error "create dirs failed"
24020
24021         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24022         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24023         for dir in $(find $DIR/$tdir/$dirname/*); do
24024                 stripe_count=$($LFS getdirstripe -c $dir)
24025                 (( $stripe_count == $default_count )) ||
24026                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24027                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24028                 error "stripe count $default_count != $stripe_count for $dir"
24029
24030                 stripe_index=$($LFS getdirstripe -i $dir)
24031                 [ $default_index -eq -1 ] ||
24032                         [ $stripe_index -eq $default_index ] ||
24033                         error "$stripe_index != $default_index for $dir"
24034
24035                 #check default stripe
24036                 stripe_count=$($LFS getdirstripe -D -c $dir)
24037                 [ $stripe_count -eq $default_count ] ||
24038                 error "default count $default_count != $stripe_count for $dir"
24039
24040                 stripe_index=$($LFS getdirstripe -D -i $dir)
24041                 [ $stripe_index -eq $default_index ] ||
24042                 error "default index $default_index != $stripe_index for $dir"
24043         done
24044         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24045 }
24046
24047 test_300g() {
24048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24049         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24050                 skip "Need MDS version at least 2.7.55"
24051
24052         local dir
24053         local stripe_count
24054         local stripe_index
24055
24056         mkdir_on_mdt0 $DIR/$tdir
24057         mkdir $DIR/$tdir/normal_dir
24058
24059         #Checking when client cache stripe index
24060         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24061         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24062                 error "create striped_dir failed"
24063
24064         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24065                 error "create dir0 fails"
24066         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24067         [ $stripe_index -eq 0 ] ||
24068                 error "dir0 expect index 0 got $stripe_index"
24069
24070         mkdir $DIR/$tdir/striped_dir/dir1 ||
24071                 error "create dir1 fails"
24072         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24073         [ $stripe_index -eq 1 ] ||
24074                 error "dir1 expect index 1 got $stripe_index"
24075
24076         #check default stripe count/stripe index
24077         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24078         test_300_check_default_striped_dir normal_dir 1 0
24079         test_300_check_default_striped_dir normal_dir -1 1
24080         test_300_check_default_striped_dir normal_dir 2 -1
24081
24082         #delete default stripe information
24083         echo "delete default stripeEA"
24084         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24085                 error "set default stripe on striped dir error"
24086
24087         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24088         for dir in $(find $DIR/$tdir/normal_dir/*); do
24089                 stripe_count=$($LFS getdirstripe -c $dir)
24090                 [ $stripe_count -eq 0 ] ||
24091                         error "expect 1 get $stripe_count for $dir"
24092         done
24093 }
24094 run_test 300g "check default striped directory for normal directory"
24095
24096 test_300h() {
24097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24098         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24099                 skip "Need MDS version at least 2.7.55"
24100
24101         local dir
24102         local stripe_count
24103
24104         mkdir $DIR/$tdir
24105         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24106                 error "set striped dir error"
24107
24108         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24109         test_300_check_default_striped_dir striped_dir 1 0
24110         test_300_check_default_striped_dir striped_dir -1 1
24111         test_300_check_default_striped_dir striped_dir 2 -1
24112
24113         #delete default stripe information
24114         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24115                 error "set default stripe on striped dir error"
24116
24117         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24118         for dir in $(find $DIR/$tdir/striped_dir/*); do
24119                 stripe_count=$($LFS getdirstripe -c $dir)
24120                 [ $stripe_count -eq 0 ] ||
24121                         error "expect 1 get $stripe_count for $dir"
24122         done
24123 }
24124 run_test 300h "check default striped directory for striped directory"
24125
24126 test_300i() {
24127         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24128         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24129         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24130                 skip "Need MDS version at least 2.7.55"
24131
24132         local stripe_count
24133         local file
24134
24135         mkdir $DIR/$tdir
24136
24137         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24138                 error "set striped dir error"
24139
24140         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24141                 error "create files under striped dir failed"
24142
24143         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24144                 error "set striped hashdir error"
24145
24146         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24147                 error "create dir0 under hash dir failed"
24148         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24149                 error "create dir1 under hash dir failed"
24150         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24151                 error "create dir2 under hash dir failed"
24152
24153         # unfortunately, we need to umount to clear dir layout cache for now
24154         # once we fully implement dir layout, we can drop this
24155         umount_client $MOUNT || error "umount failed"
24156         mount_client $MOUNT || error "mount failed"
24157
24158         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24159         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24160         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24161
24162         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24163                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24164                         error "create crush2 dir $tdir/hashdir/d3 failed"
24165                 $LFS find -H crush2 $DIR/$tdir/hashdir
24166                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24167                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24168
24169                 # mkdir with an invalid hash type (hash=fail_val) from client
24170                 # should be replaced on MDS with a valid (default) hash type
24171                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24172                 $LCTL set_param fail_loc=0x1901 fail_val=99
24173                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24174
24175                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24176                 local expect=$(do_facet mds1 \
24177                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24178                 [[ $hash == $expect ]] ||
24179                         error "d99 hash '$hash' != expected hash '$expect'"
24180         fi
24181
24182         #set the stripe to be unknown hash type on read
24183         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24184         $LCTL set_param fail_loc=0x1901 fail_val=99
24185         for ((i = 0; i < 10; i++)); do
24186                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24187                         error "stat f-$i failed"
24188                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24189         done
24190
24191         touch $DIR/$tdir/striped_dir/f0 &&
24192                 error "create under striped dir with unknown hash should fail"
24193
24194         $LCTL set_param fail_loc=0
24195
24196         umount_client $MOUNT || error "umount failed"
24197         mount_client $MOUNT || error "mount failed"
24198
24199         return 0
24200 }
24201 run_test 300i "client handle unknown hash type striped directory"
24202
24203 test_300j() {
24204         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24206         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24207                 skip "Need MDS version at least 2.7.55"
24208
24209         local stripe_count
24210         local file
24211
24212         mkdir $DIR/$tdir
24213
24214         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24215         $LCTL set_param fail_loc=0x1702
24216         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24217                 error "set striped dir error"
24218
24219         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24220                 error "create files under striped dir failed"
24221
24222         $LCTL set_param fail_loc=0
24223
24224         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24225
24226         return 0
24227 }
24228 run_test 300j "test large update record"
24229
24230 test_300k() {
24231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24232         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24233         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24234                 skip "Need MDS version at least 2.7.55"
24235
24236         # this test needs a huge transaction
24237         local kb
24238         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24239              osd*.$FSNAME-MDT0000.kbytestotal")
24240         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24241
24242         local stripe_count
24243         local file
24244
24245         mkdir $DIR/$tdir
24246
24247         #define OBD_FAIL_LARGE_STRIPE   0x1703
24248         $LCTL set_param fail_loc=0x1703
24249         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24250                 error "set striped dir error"
24251         $LCTL set_param fail_loc=0
24252
24253         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24254                 error "getstripeddir fails"
24255         rm -rf $DIR/$tdir/striped_dir ||
24256                 error "unlink striped dir fails"
24257
24258         return 0
24259 }
24260 run_test 300k "test large striped directory"
24261
24262 test_300l() {
24263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24265         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24266                 skip "Need MDS version at least 2.7.55"
24267
24268         local stripe_index
24269
24270         test_mkdir -p $DIR/$tdir/striped_dir
24271         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24272                         error "chown $RUNAS_ID failed"
24273         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24274                 error "set default striped dir failed"
24275
24276         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24277         $LCTL set_param fail_loc=0x80000158
24278         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24279
24280         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24281         [ $stripe_index -eq 1 ] ||
24282                 error "expect 1 get $stripe_index for $dir"
24283 }
24284 run_test 300l "non-root user to create dir under striped dir with stale layout"
24285
24286 test_300m() {
24287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24288         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24289         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24290                 skip "Need MDS version at least 2.7.55"
24291
24292         mkdir -p $DIR/$tdir/striped_dir
24293         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24294                 error "set default stripes dir error"
24295
24296         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24297
24298         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24299         [ $stripe_count -eq 0 ] ||
24300                         error "expect 0 get $stripe_count for a"
24301
24302         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24303                 error "set default stripes dir error"
24304
24305         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24306
24307         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24308         [ $stripe_count -eq 0 ] ||
24309                         error "expect 0 get $stripe_count for b"
24310
24311         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24312                 error "set default stripes dir error"
24313
24314         mkdir $DIR/$tdir/striped_dir/c &&
24315                 error "default stripe_index is invalid, mkdir c should fails"
24316
24317         rm -rf $DIR/$tdir || error "rmdir fails"
24318 }
24319 run_test 300m "setstriped directory on single MDT FS"
24320
24321 cleanup_300n() {
24322         local list=$(comma_list $(mdts_nodes))
24323
24324         trap 0
24325         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24326 }
24327
24328 test_300n() {
24329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24331         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24332                 skip "Need MDS version at least 2.7.55"
24333         remote_mds_nodsh && skip "remote MDS with nodsh"
24334
24335         local stripe_index
24336         local list=$(comma_list $(mdts_nodes))
24337
24338         trap cleanup_300n RETURN EXIT
24339         mkdir -p $DIR/$tdir
24340         chmod 777 $DIR/$tdir
24341         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24342                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24343                 error "create striped dir succeeds with gid=0"
24344
24345         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24346         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24347                 error "create striped dir fails with gid=-1"
24348
24349         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24350         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24351                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24352                 error "set default striped dir succeeds with gid=0"
24353
24354
24355         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24356         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24357                 error "set default striped dir fails with gid=-1"
24358
24359
24360         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24361         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24362                                         error "create test_dir fails"
24363         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24364                                         error "create test_dir1 fails"
24365         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24366                                         error "create test_dir2 fails"
24367         cleanup_300n
24368 }
24369 run_test 300n "non-root user to create dir under striped dir with default EA"
24370
24371 test_300o() {
24372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24374         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24375                 skip "Need MDS version at least 2.7.55"
24376
24377         local numfree1
24378         local numfree2
24379
24380         mkdir -p $DIR/$tdir
24381
24382         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24383         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24384         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24385                 skip "not enough free inodes $numfree1 $numfree2"
24386         fi
24387
24388         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24389         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24390         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24391                 skip "not enough free space $numfree1 $numfree2"
24392         fi
24393
24394         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24395                 error "setdirstripe fails"
24396
24397         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24398                 error "create dirs fails"
24399
24400         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24401         ls $DIR/$tdir/striped_dir > /dev/null ||
24402                 error "ls striped dir fails"
24403         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24404                 error "unlink big striped dir fails"
24405 }
24406 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24407
24408 test_300p() {
24409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24411         remote_mds_nodsh && skip "remote MDS with nodsh"
24412
24413         mkdir_on_mdt0 $DIR/$tdir
24414
24415         #define OBD_FAIL_OUT_ENOSPC     0x1704
24416         do_facet mds2 lctl set_param fail_loc=0x80001704
24417         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24418                  && error "create striped directory should fail"
24419
24420         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24421
24422         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24423         true
24424 }
24425 run_test 300p "create striped directory without space"
24426
24427 test_300q() {
24428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24430
24431         local fd=$(free_fd)
24432         local cmd="exec $fd<$tdir"
24433         cd $DIR
24434         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24435         eval $cmd
24436         cmd="exec $fd<&-"
24437         trap "eval $cmd" EXIT
24438         cd $tdir || error "cd $tdir fails"
24439         rmdir  ../$tdir || error "rmdir $tdir fails"
24440         mkdir local_dir && error "create dir succeeds"
24441         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24442         eval $cmd
24443         return 0
24444 }
24445 run_test 300q "create remote directory under orphan directory"
24446
24447 test_300r() {
24448         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24449                 skip "Need MDS version at least 2.7.55" && return
24450         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24451
24452         mkdir $DIR/$tdir
24453
24454         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24455                 error "set striped dir error"
24456
24457         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24458                 error "getstripeddir fails"
24459
24460         local stripe_count
24461         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24462                       awk '/lmv_stripe_count:/ { print $2 }')
24463
24464         [ $MDSCOUNT -ne $stripe_count ] &&
24465                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24466
24467         rm -rf $DIR/$tdir/striped_dir ||
24468                 error "unlink striped dir fails"
24469 }
24470 run_test 300r "test -1 striped directory"
24471
24472 test_300s_helper() {
24473         local count=$1
24474
24475         local stripe_dir=$DIR/$tdir/striped_dir.$count
24476
24477         $LFS mkdir -c $count $stripe_dir ||
24478                 error "lfs mkdir -c error"
24479
24480         $LFS getdirstripe $stripe_dir ||
24481                 error "lfs getdirstripe fails"
24482
24483         local stripe_count
24484         stripe_count=$($LFS getdirstripe $stripe_dir |
24485                       awk '/lmv_stripe_count:/ { print $2 }')
24486
24487         [ $count -ne $stripe_count ] &&
24488                 error_noexit "bad stripe count $stripe_count expected $count"
24489
24490         local dupe_stripes
24491         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24492                 awk '/0x/ {count[$1] += 1}; END {
24493                         for (idx in count) {
24494                                 if (count[idx]>1) {
24495                                         print "index " idx " count " count[idx]
24496                                 }
24497                         }
24498                 }')
24499
24500         if [[ -n "$dupe_stripes" ]] ; then
24501                 lfs getdirstripe $stripe_dir
24502                 error_noexit "Dupe MDT above: $dupe_stripes "
24503         fi
24504
24505         rm -rf $stripe_dir ||
24506                 error_noexit "unlink $stripe_dir fails"
24507 }
24508
24509 test_300s() {
24510         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24511                 skip "Need MDS version at least 2.7.55" && return
24512         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24513
24514         mkdir $DIR/$tdir
24515         for count in $(seq 2 $MDSCOUNT); do
24516                 test_300s_helper $count
24517         done
24518 }
24519 run_test 300s "test lfs mkdir -c without -i"
24520
24521 test_300t() {
24522         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24523                 skip "need MDS 2.14.55 or later"
24524         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24525
24526         local testdir="$DIR/$tdir/striped_dir"
24527         local dir1=$testdir/dir1
24528         local dir2=$testdir/dir2
24529
24530         mkdir -p $testdir
24531
24532         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24533                 error "failed to set default stripe count for $testdir"
24534
24535         mkdir $dir1
24536         local stripe_count=$($LFS getdirstripe -c $dir1)
24537
24538         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24539
24540         local max_count=$((MDSCOUNT - 1))
24541         local mdts=$(comma_list $(mdts_nodes))
24542
24543         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24544         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24545
24546         mkdir $dir2
24547         stripe_count=$($LFS getdirstripe -c $dir2)
24548
24549         (( $stripe_count == $max_count )) || error "wrong stripe count"
24550 }
24551 run_test 300t "test max_mdt_stripecount"
24552
24553 prepare_remote_file() {
24554         mkdir $DIR/$tdir/src_dir ||
24555                 error "create remote source failed"
24556
24557         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24558                  error "cp to remote source failed"
24559         touch $DIR/$tdir/src_dir/a
24560
24561         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24562                 error "create remote target dir failed"
24563
24564         touch $DIR/$tdir/tgt_dir/b
24565
24566         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24567                 error "rename dir cross MDT failed!"
24568
24569         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24570                 error "src_child still exists after rename"
24571
24572         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24573                 error "missing file(a) after rename"
24574
24575         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24576                 error "diff after rename"
24577 }
24578
24579 test_310a() {
24580         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24582
24583         local remote_file=$DIR/$tdir/tgt_dir/b
24584
24585         mkdir -p $DIR/$tdir
24586
24587         prepare_remote_file || error "prepare remote file failed"
24588
24589         #open-unlink file
24590         $OPENUNLINK $remote_file $remote_file ||
24591                 error "openunlink $remote_file failed"
24592         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24593 }
24594 run_test 310a "open unlink remote file"
24595
24596 test_310b() {
24597         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24599
24600         local remote_file=$DIR/$tdir/tgt_dir/b
24601
24602         mkdir -p $DIR/$tdir
24603
24604         prepare_remote_file || error "prepare remote file failed"
24605
24606         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24607         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24608         $CHECKSTAT -t file $remote_file || error "check file failed"
24609 }
24610 run_test 310b "unlink remote file with multiple links while open"
24611
24612 test_310c() {
24613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24614         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24615
24616         local remote_file=$DIR/$tdir/tgt_dir/b
24617
24618         mkdir -p $DIR/$tdir
24619
24620         prepare_remote_file || error "prepare remote file failed"
24621
24622         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24623         multiop_bg_pause $remote_file O_uc ||
24624                         error "mulitop failed for remote file"
24625         MULTIPID=$!
24626         $MULTIOP $DIR/$tfile Ouc
24627         kill -USR1 $MULTIPID
24628         wait $MULTIPID
24629 }
24630 run_test 310c "open-unlink remote file with multiple links"
24631
24632 #LU-4825
24633 test_311() {
24634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24635         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24636         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24637                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24638         remote_mds_nodsh && skip "remote MDS with nodsh"
24639
24640         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24641         local mdts=$(comma_list $(mdts_nodes))
24642
24643         mkdir -p $DIR/$tdir
24644         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24645         createmany -o $DIR/$tdir/$tfile. 1000
24646
24647         # statfs data is not real time, let's just calculate it
24648         old_iused=$((old_iused + 1000))
24649
24650         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24651                         osp.*OST0000*MDT0000.create_count")
24652         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24653                                 osp.*OST0000*MDT0000.max_create_count")
24654         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24655
24656         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24657         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24658         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24659
24660         unlinkmany $DIR/$tdir/$tfile. 1000
24661
24662         do_nodes $mdts "$LCTL set_param -n \
24663                         osp.*OST0000*.max_create_count=$max_count"
24664         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24665                 do_nodes $mdts "$LCTL set_param -n \
24666                                 osp.*OST0000*.create_count=$count"
24667         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24668                         grep "=0" && error "create_count is zero"
24669
24670         local new_iused
24671         for i in $(seq 120); do
24672                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24673                 # system may be too busy to destroy all objs in time, use
24674                 # a somewhat small value to not fail autotest
24675                 [ $((old_iused - new_iused)) -gt 400 ] && break
24676                 sleep 1
24677         done
24678
24679         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24680         [ $((old_iused - new_iused)) -gt 400 ] ||
24681                 error "objs not destroyed after unlink"
24682 }
24683 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24684
24685 zfs_get_objid()
24686 {
24687         local ost=$1
24688         local tf=$2
24689         local fid=($($LFS getstripe $tf | grep 0x))
24690         local seq=${fid[3]#0x}
24691         local objid=${fid[1]}
24692
24693         local vdevdir=$(dirname $(facet_vdevice $ost))
24694         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24695         local zfs_zapid=$(do_facet $ost $cmd |
24696                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24697                           awk '/Object/{getline; print $1}')
24698         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24699                           awk "/$objid = /"'{printf $3}')
24700
24701         echo $zfs_objid
24702 }
24703
24704 zfs_object_blksz() {
24705         local ost=$1
24706         local objid=$2
24707
24708         local vdevdir=$(dirname $(facet_vdevice $ost))
24709         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24710         local blksz=$(do_facet $ost $cmd $objid |
24711                       awk '/dblk/{getline; printf $4}')
24712
24713         case "${blksz: -1}" in
24714                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24715                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24716                 *) ;;
24717         esac
24718
24719         echo $blksz
24720 }
24721
24722 test_312() { # LU-4856
24723         remote_ost_nodsh && skip "remote OST with nodsh"
24724         [ "$ost1_FSTYPE" = "zfs" ] ||
24725                 skip_env "the test only applies to zfs"
24726
24727         local max_blksz=$(do_facet ost1 \
24728                           $ZFS get -p recordsize $(facet_device ost1) |
24729                           awk '!/VALUE/{print $3}')
24730         local tf=$DIR/$tfile
24731
24732         $LFS setstripe -c1 $tf
24733         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
24734
24735         # Get ZFS object id
24736         local zfs_objid=$(zfs_get_objid $facet $tf)
24737         # block size change by sequential overwrite
24738         local bs
24739
24740         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24741                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24742
24743                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
24744                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
24745         done
24746         rm -f $tf
24747
24748         $LFS setstripe -c1 $tf
24749         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24750
24751         # block size change by sequential append write
24752         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24753         zfs_objid=$(zfs_get_objid $facet $tf)
24754         local count
24755
24756         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24757                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24758                         oflag=sync conv=notrunc
24759
24760                 blksz=$(zfs_object_blksz $facet $zfs_objid)
24761                 (( $blksz == 2 * count * PAGE_SIZE )) ||
24762                         error "blksz error, actual $blksz, " \
24763                                 "expected: 2 * $count * $PAGE_SIZE"
24764         done
24765         rm -f $tf
24766
24767         # random write
24768         $LFS setstripe -c1 $tf
24769         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24770         zfs_objid=$(zfs_get_objid $facet $tf)
24771
24772         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24773         blksz=$(zfs_object_blksz $facet $zfs_objid)
24774         (( blksz == PAGE_SIZE )) ||
24775                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24776
24777         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24778         blksz=$(zfs_object_blksz $facet $zfs_objid)
24779         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
24780
24781         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24782         blksz=$(zfs_object_blksz $facet $zfs_objid)
24783         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
24784 }
24785 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24786
24787 test_313() {
24788         remote_ost_nodsh && skip "remote OST with nodsh"
24789
24790         local file=$DIR/$tfile
24791
24792         rm -f $file
24793         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24794
24795         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24796         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24797         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24798                 error "write should failed"
24799         do_facet ost1 "$LCTL set_param fail_loc=0"
24800         rm -f $file
24801 }
24802 run_test 313 "io should fail after last_rcvd update fail"
24803
24804 test_314() {
24805         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24806
24807         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24808         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24809         rm -f $DIR/$tfile
24810         wait_delete_completed
24811         do_facet ost1 "$LCTL set_param fail_loc=0"
24812 }
24813 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24814
24815 test_315() { # LU-618
24816         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24817
24818         local file=$DIR/$tfile
24819         rm -f $file
24820
24821         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24822                 error "multiop file write failed"
24823         $MULTIOP $file oO_RDONLY:r4063232_c &
24824         PID=$!
24825
24826         sleep 2
24827
24828         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24829         kill -USR1 $PID
24830
24831         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24832         rm -f $file
24833 }
24834 run_test 315 "read should be accounted"
24835
24836 test_316() {
24837         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24838         large_xattr_enabled || skip "ea_inode feature disabled"
24839
24840         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24841         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24842         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24843         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24844
24845         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24846 }
24847 run_test 316 "lfs migrate of file with large_xattr enabled"
24848
24849 test_317() {
24850         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24851                 skip "Need MDS version at least 2.11.53"
24852         if [ "$ost1_FSTYPE" == "zfs" ]; then
24853                 skip "LU-10370: no implementation for ZFS"
24854         fi
24855
24856         local trunc_sz
24857         local grant_blk_size
24858
24859         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24860                         awk '/grant_block_size:/ { print $2; exit; }')
24861         #
24862         # Create File of size 5M. Truncate it to below size's and verify
24863         # blocks count.
24864         #
24865         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24866                 error "Create file $DIR/$tfile failed"
24867         stack_trap "rm -f $DIR/$tfile" EXIT
24868
24869         for trunc_sz in 2097152 4097 4000 509 0; do
24870                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24871                         error "truncate $tfile to $trunc_sz failed"
24872                 local sz=$(stat --format=%s $DIR/$tfile)
24873                 local blk=$(stat --format=%b $DIR/$tfile)
24874                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24875                                      grant_blk_size) * 8))
24876
24877                 if [[ $blk -ne $trunc_blk ]]; then
24878                         $(which stat) $DIR/$tfile
24879                         error "Expected Block $trunc_blk got $blk for $tfile"
24880                 fi
24881
24882                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24883                         error "Expected Size $trunc_sz got $sz for $tfile"
24884         done
24885
24886         #
24887         # sparse file test
24888         # Create file with a hole and write actual 65536 bytes which aligned
24889         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24890         #
24891         local bs=65536
24892         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24893                 error "Create file : $DIR/$tfile"
24894
24895         #
24896         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24897         # blocks. The block count must drop to 8.
24898         #
24899         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
24900                 ((bs - grant_blk_size) + 1)))
24901         $TRUNCATE $DIR/$tfile $trunc_sz ||
24902                 error "truncate $tfile to $trunc_sz failed"
24903
24904         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24905         sz=$(stat --format=%s $DIR/$tfile)
24906         blk=$(stat --format=%b $DIR/$tfile)
24907
24908         if [[ $blk -ne $trunc_bsz ]]; then
24909                 $(which stat) $DIR/$tfile
24910                 error "Expected Block $trunc_bsz got $blk for $tfile"
24911         fi
24912
24913         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24914                 error "Expected Size $trunc_sz got $sz for $tfile"
24915 }
24916 run_test 317 "Verify blocks get correctly update after truncate"
24917
24918 test_318() {
24919         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24920         local old_max_active=$($LCTL get_param -n \
24921                             ${llite_name}.max_read_ahead_async_active \
24922                             2>/dev/null)
24923
24924         $LCTL set_param llite.*.max_read_ahead_async_active=256
24925         local max_active=$($LCTL get_param -n \
24926                            ${llite_name}.max_read_ahead_async_active \
24927                            2>/dev/null)
24928         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24929
24930         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24931                 error "set max_read_ahead_async_active should succeed"
24932
24933         $LCTL set_param llite.*.max_read_ahead_async_active=512
24934         max_active=$($LCTL get_param -n \
24935                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24936         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24937
24938         # restore @max_active
24939         [ $old_max_active -ne 0 ] && $LCTL set_param \
24940                 llite.*.max_read_ahead_async_active=$old_max_active
24941
24942         local old_threshold=$($LCTL get_param -n \
24943                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24944         local max_per_file_mb=$($LCTL get_param -n \
24945                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24946
24947         local invalid=$(($max_per_file_mb + 1))
24948         $LCTL set_param \
24949                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24950                         && error "set $invalid should fail"
24951
24952         local valid=$(($invalid - 1))
24953         $LCTL set_param \
24954                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24955                         error "set $valid should succeed"
24956         local threshold=$($LCTL get_param -n \
24957                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24958         [ $threshold -eq $valid ] || error \
24959                 "expect threshold $valid got $threshold"
24960         $LCTL set_param \
24961                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24962 }
24963 run_test 318 "Verify async readahead tunables"
24964
24965 test_319() {
24966         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24967
24968         local before=$(date +%s)
24969         local evict
24970         local mdir=$DIR/$tdir
24971         local file=$mdir/xxx
24972
24973         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24974         touch $file
24975
24976 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24977         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24978         $LFS migrate -m1 $mdir &
24979
24980         sleep 1
24981         dd if=$file of=/dev/null
24982         wait
24983         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24984           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24985
24986         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24987 }
24988 run_test 319 "lost lease lock on migrate error"
24989
24990 test_398a() { # LU-4198
24991         local ost1_imp=$(get_osc_import_name client ost1)
24992         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24993                          cut -d'.' -f2)
24994
24995         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24996         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24997
24998         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
24999         # request a new lock on client
25000         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25001
25002         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25003         #local lock_count=$($LCTL get_param -n \
25004         #                  ldlm.namespaces.$imp_name.lru_size)
25005         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25006
25007         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25008
25009         # no lock cached, should use lockless DIO and not enqueue new lock
25010         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25011                 conv=notrunc ||
25012                 error "dio write failed"
25013         lock_count=$($LCTL get_param -n \
25014                      ldlm.namespaces.$imp_name.lru_size)
25015         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25016
25017         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25018
25019         # no lock cached, should use locked DIO append
25020         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25021                 conv=notrunc || error "DIO append failed"
25022         lock_count=$($LCTL get_param -n \
25023                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25024         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25025 }
25026 run_test 398a "direct IO should cancel lock otherwise lockless"
25027
25028 test_398b() { # LU-4198
25029         which fio || skip_env "no fio installed"
25030         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25031
25032         local size=48
25033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25034
25035         local njobs=4
25036         # Single page, multiple pages, stripe size, 4*stripe size
25037         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25038                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25039                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25040                         --numjobs=$njobs --fallocate=none \
25041                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25042                         --filename=$DIR/$tfile &
25043                 bg_pid=$!
25044
25045                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25046                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25047                         --numjobs=$njobs --fallocate=none \
25048                         --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25049                         --filename=$DIR/$tfile || true
25050                 wait $bg_pid
25051         done
25052
25053         evict=$(do_facet client $LCTL get_param \
25054                 osc.$FSNAME-OST*-osc-*/state |
25055             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25056
25057         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25058                 (do_facet client $LCTL get_param \
25059                         osc.$FSNAME-OST*-osc-*/state;
25060                     error "eviction happened: $evict before:$before")
25061
25062         rm -f $DIR/$tfile
25063 }
25064 run_test 398b "DIO and buffer IO race"
25065
25066 test_398c() { # LU-4198
25067         local ost1_imp=$(get_osc_import_name client ost1)
25068         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25069                          cut -d'.' -f2)
25070
25071         which fio || skip_env "no fio installed"
25072
25073         saved_debug=$($LCTL get_param -n debug)
25074         $LCTL set_param debug=0
25075
25076         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25077         ((size /= 1024)) # by megabytes
25078         ((size /= 2)) # write half of the OST at most
25079         [ $size -gt 40 ] && size=40 #reduce test time anyway
25080
25081         $LFS setstripe -c 1 $DIR/$tfile
25082
25083         # it seems like ldiskfs reserves more space than necessary if the
25084         # writing blocks are not mapped, so it extends the file firstly
25085         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25086         cancel_lru_locks osc
25087
25088         # clear and verify rpc_stats later
25089         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25090
25091         local njobs=4
25092         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25093         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25094                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25095                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25096                 --filename=$DIR/$tfile
25097         [ $? -eq 0 ] || error "fio write error"
25098
25099         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25100                 error "Locks were requested while doing AIO"
25101
25102         # get the percentage of 1-page I/O
25103         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25104                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25105                 awk '{print $7}')
25106         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25107
25108         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25109         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25110                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25111                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25112                 --filename=$DIR/$tfile
25113         [ $? -eq 0 ] || error "fio mixed read write error"
25114
25115         echo "AIO with large block size ${size}M"
25116         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25117                 --numjobs=1 --fallocate=none --ioengine=libaio \
25118                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25119                 --filename=$DIR/$tfile
25120         [ $? -eq 0 ] || error "fio large block size failed"
25121
25122         rm -f $DIR/$tfile
25123         $LCTL set_param debug="$saved_debug"
25124 }
25125 run_test 398c "run fio to test AIO"
25126
25127 test_398d() { #  LU-13846
25128         which aiocp || skip_env "no aiocp installed"
25129         local aio_file=$DIR/$tfile.aio
25130
25131         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25132
25133         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25134         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25135         stack_trap "rm -f $DIR/$tfile $aio_file"
25136
25137         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25138
25139         # make sure we don't crash and fail properly
25140         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25141                 error "aio not aligned with PAGE SIZE should fail"
25142
25143         rm -f $DIR/$tfile $aio_file
25144 }
25145 run_test 398d "run aiocp to verify block size > stripe size"
25146
25147 test_398e() {
25148         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25149         touch $DIR/$tfile.new
25150         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25151 }
25152 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25153
25154 test_398f() { #  LU-14687
25155         which aiocp || skip_env "no aiocp installed"
25156         local aio_file=$DIR/$tfile.aio
25157
25158         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25159
25160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25161         stack_trap "rm -f $DIR/$tfile $aio_file"
25162
25163         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25164         $LCTL set_param fail_loc=0x1418
25165         # make sure we don't crash and fail properly
25166         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25167                 error "aio with page allocation failure succeeded"
25168         $LCTL set_param fail_loc=0
25169         diff $DIR/$tfile $aio_file
25170         [[ $? != 0 ]] || error "no diff after failed aiocp"
25171 }
25172 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25173
25174 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25175 # stripe and i/o size must be > stripe size
25176 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25177 # single RPC in flight.  This test shows async DIO submission is working by
25178 # showing multiple RPCs in flight.
25179 test_398g() { #  LU-13798
25180         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25181
25182         # We need to do some i/o first to acquire enough grant to put our RPCs
25183         # in flight; otherwise a new connection may not have enough grant
25184         # available
25185         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25186                 error "parallel dio failed"
25187         stack_trap "rm -f $DIR/$tfile"
25188
25189         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25190         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25191         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25192         stack_trap "$LCTL set_param -n $pages_per_rpc"
25193
25194         # Recreate file so it's empty
25195         rm -f $DIR/$tfile
25196         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25197         #Pause rpc completion to guarantee we see multiple rpcs in flight
25198         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25199         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25200         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25201
25202         # Clear rpc stats
25203         $LCTL set_param osc.*.rpc_stats=c
25204
25205         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25206                 error "parallel dio failed"
25207         stack_trap "rm -f $DIR/$tfile"
25208
25209         $LCTL get_param osc.*-OST0000-*.rpc_stats
25210         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25211                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25212                 grep "8:" | awk '{print $8}')
25213         # We look at the "8 rpcs in flight" field, and verify A) it is present
25214         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25215         # as expected for an 8M DIO to a file with 1M stripes.
25216         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25217
25218         # Verify turning off parallel dio works as expected
25219         # Clear rpc stats
25220         $LCTL set_param osc.*.rpc_stats=c
25221         $LCTL set_param llite.*.parallel_dio=0
25222         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25223
25224         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25225                 error "dio with parallel dio disabled failed"
25226
25227         # Ideally, we would see only one RPC in flight here, but there is an
25228         # unavoidable race between i/o completion and RPC in flight counting,
25229         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25230         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25231         # So instead we just verify it's always < 8.
25232         $LCTL get_param osc.*-OST0000-*.rpc_stats
25233         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25234                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25235                 grep '^$' -B1 | grep . | awk '{print $1}')
25236         [ $ret != "8:" ] ||
25237                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25238 }
25239 run_test 398g "verify parallel dio async RPC submission"
25240
25241 test_398h() { #  LU-13798
25242         local dio_file=$DIR/$tfile.dio
25243
25244         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25245
25246         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25247         stack_trap "rm -f $DIR/$tfile $dio_file"
25248
25249         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25250                 error "parallel dio failed"
25251         diff $DIR/$tfile $dio_file
25252         [[ $? == 0 ]] || error "file diff after aiocp"
25253 }
25254 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25255
25256 test_398i() { #  LU-13798
25257         local dio_file=$DIR/$tfile.dio
25258
25259         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25260
25261         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25262         stack_trap "rm -f $DIR/$tfile $dio_file"
25263
25264         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25265         $LCTL set_param fail_loc=0x1418
25266         # make sure we don't crash and fail properly
25267         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25268                 error "parallel dio page allocation failure succeeded"
25269         diff $DIR/$tfile $dio_file
25270         [[ $? != 0 ]] || error "no diff after failed aiocp"
25271 }
25272 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25273
25274 test_398j() { #  LU-13798
25275         # Stripe size > RPC size but less than i/o size tests split across
25276         # stripes and RPCs for individual i/o op
25277         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25278
25279         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25280         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25281         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25282         stack_trap "$LCTL set_param -n $pages_per_rpc"
25283
25284         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25285                 error "parallel dio write failed"
25286         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25287
25288         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25289                 error "parallel dio read failed"
25290         diff $DIR/$tfile $DIR/$tfile.2
25291         [[ $? == 0 ]] || error "file diff after parallel dio read"
25292 }
25293 run_test 398j "test parallel dio where stripe size > rpc_size"
25294
25295 test_398k() { #  LU-13798
25296         wait_delete_completed
25297         wait_mds_ost_sync
25298
25299         # 4 stripe file; we will cause out of space on OST0
25300         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25301
25302         # Fill OST0 (if it's not too large)
25303         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25304                    head -n1)
25305         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25306                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25307         fi
25308         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25309         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25310                 error "dd should fill OST0"
25311         stack_trap "rm -f $DIR/$tfile.1"
25312
25313         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25314         err=$?
25315
25316         ls -la $DIR/$tfile
25317         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25318                 error "file is not 0 bytes in size"
25319
25320         # dd above should not succeed, but don't error until here so we can
25321         # get debug info above
25322         [[ $err != 0 ]] ||
25323                 error "parallel dio write with enospc succeeded"
25324         stack_trap "rm -f $DIR/$tfile"
25325 }
25326 run_test 398k "test enospc on first stripe"
25327
25328 test_398l() { #  LU-13798
25329         wait_delete_completed
25330         wait_mds_ost_sync
25331
25332         # 4 stripe file; we will cause out of space on OST0
25333         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25334         # happens on the second i/o chunk we issue
25335         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25336
25337         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25338         stack_trap "rm -f $DIR/$tfile"
25339
25340         # Fill OST0 (if it's not too large)
25341         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25342                    head -n1)
25343         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25344                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25345         fi
25346         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25347         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25348                 error "dd should fill OST0"
25349         stack_trap "rm -f $DIR/$tfile.1"
25350
25351         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25352         err=$?
25353         stack_trap "rm -f $DIR/$tfile.2"
25354
25355         # Check that short write completed as expected
25356         ls -la $DIR/$tfile.2
25357         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25358                 error "file is not 1M in size"
25359
25360         # dd above should not succeed, but don't error until here so we can
25361         # get debug info above
25362         [[ $err != 0 ]] ||
25363                 error "parallel dio write with enospc succeeded"
25364
25365         # Truncate source file to same length as output file and diff them
25366         $TRUNCATE $DIR/$tfile 1048576
25367         diff $DIR/$tfile $DIR/$tfile.2
25368         [[ $? == 0 ]] || error "data incorrect after short write"
25369 }
25370 run_test 398l "test enospc on intermediate stripe/RPC"
25371
25372 test_398m() { #  LU-13798
25373         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25374
25375         # Set up failure on OST0, the first stripe:
25376         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25377         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25378         # OST0 is on ost1, OST1 is on ost2.
25379         # So this fail_val specifies OST0
25380         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25381         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25382
25383         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25384                 error "parallel dio write with failure on first stripe succeeded"
25385         stack_trap "rm -f $DIR/$tfile"
25386         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25387
25388         # Place data in file for read
25389         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25390                 error "parallel dio write failed"
25391
25392         # Fail read on OST0, first stripe
25393         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25394         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25395         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25396                 error "parallel dio read with error on first stripe succeeded"
25397         rm -f $DIR/$tfile.2
25398         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25399
25400         # Switch to testing on OST1, second stripe
25401         # Clear file contents, maintain striping
25402         echo > $DIR/$tfile
25403         # Set up failure on OST1, second stripe:
25404         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25405         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25406
25407         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25408                 error "parallel dio write with failure on second stripe succeeded"
25409         stack_trap "rm -f $DIR/$tfile"
25410         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25411
25412         # Place data in file for read
25413         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25414                 error "parallel dio write failed"
25415
25416         # Fail read on OST1, second stripe
25417         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25418         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25419         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25420                 error "parallel dio read with error on second stripe succeeded"
25421         rm -f $DIR/$tfile.2
25422         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25423 }
25424 run_test 398m "test RPC failures with parallel dio"
25425
25426 # Parallel submission of DIO should not cause problems for append, but it's
25427 # important to verify.
25428 test_398n() { #  LU-13798
25429         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25430
25431         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25432                 error "dd to create source file failed"
25433         stack_trap "rm -f $DIR/$tfile"
25434
25435         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25436                 error "parallel dio write with failure on second stripe succeeded"
25437         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25438         diff $DIR/$tfile $DIR/$tfile.1
25439         [[ $? == 0 ]] || error "data incorrect after append"
25440
25441 }
25442 run_test 398n "test append with parallel DIO"
25443
25444 test_398o() {
25445         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25446 }
25447 run_test 398o "right kms with DIO"
25448
25449 test_fake_rw() {
25450         local read_write=$1
25451         if [ "$read_write" = "write" ]; then
25452                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25453         elif [ "$read_write" = "read" ]; then
25454                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25455         else
25456                 error "argument error"
25457         fi
25458
25459         # turn off debug for performance testing
25460         local saved_debug=$($LCTL get_param -n debug)
25461         $LCTL set_param debug=0
25462
25463         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25464
25465         # get ost1 size - $FSNAME-OST0000
25466         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25467         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25468         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25469
25470         if [ "$read_write" = "read" ]; then
25471                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25472         fi
25473
25474         local start_time=$(date +%s.%N)
25475         $dd_cmd bs=1M count=$blocks oflag=sync ||
25476                 error "real dd $read_write error"
25477         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25478
25479         if [ "$read_write" = "write" ]; then
25480                 rm -f $DIR/$tfile
25481         fi
25482
25483         # define OBD_FAIL_OST_FAKE_RW           0x238
25484         do_facet ost1 $LCTL set_param fail_loc=0x238
25485
25486         local start_time=$(date +%s.%N)
25487         $dd_cmd bs=1M count=$blocks oflag=sync ||
25488                 error "fake dd $read_write error"
25489         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25490
25491         if [ "$read_write" = "write" ]; then
25492                 # verify file size
25493                 cancel_lru_locks osc
25494                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25495                         error "$tfile size not $blocks MB"
25496         fi
25497         do_facet ost1 $LCTL set_param fail_loc=0
25498
25499         echo "fake $read_write $duration_fake vs. normal $read_write" \
25500                 "$duration in seconds"
25501         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25502                 error_not_in_vm "fake write is slower"
25503
25504         $LCTL set_param -n debug="$saved_debug"
25505         rm -f $DIR/$tfile
25506 }
25507 test_399a() { # LU-7655 for OST fake write
25508         remote_ost_nodsh && skip "remote OST with nodsh"
25509
25510         test_fake_rw write
25511 }
25512 run_test 399a "fake write should not be slower than normal write"
25513
25514 test_399b() { # LU-8726 for OST fake read
25515         remote_ost_nodsh && skip "remote OST with nodsh"
25516         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25517                 skip_env "ldiskfs only test"
25518         fi
25519
25520         test_fake_rw read
25521 }
25522 run_test 399b "fake read should not be slower than normal read"
25523
25524 test_400a() { # LU-1606, was conf-sanity test_74
25525         if ! which $CC > /dev/null 2>&1; then
25526                 skip_env "$CC is not installed"
25527         fi
25528
25529         local extra_flags=''
25530         local out=$TMP/$tfile
25531         local prefix=/usr/include/lustre
25532         local prog
25533
25534         # Oleg removes .c files in his test rig so test if any c files exist
25535         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25536                 skip_env "Needed .c test files are missing"
25537
25538         if ! [[ -d $prefix ]]; then
25539                 # Assume we're running in tree and fixup the include path.
25540                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25541                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25542                 extra_flags+=" -L$LUSTRE/utils/.libs"
25543         fi
25544
25545         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25546                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25547                         error "client api broken"
25548         done
25549         rm -f $out
25550 }
25551 run_test 400a "Lustre client api program can compile and link"
25552
25553 test_400b() { # LU-1606, LU-5011
25554         local header
25555         local out=$TMP/$tfile
25556         local prefix=/usr/include/linux/lustre
25557
25558         # We use a hard coded prefix so that this test will not fail
25559         # when run in tree. There are headers in lustre/include/lustre/
25560         # that are not packaged (like lustre_idl.h) and have more
25561         # complicated include dependencies (like config.h and lnet/types.h).
25562         # Since this test about correct packaging we just skip them when
25563         # they don't exist (see below) rather than try to fixup cppflags.
25564
25565         if ! which $CC > /dev/null 2>&1; then
25566                 skip_env "$CC is not installed"
25567         fi
25568
25569         for header in $prefix/*.h; do
25570                 if ! [[ -f "$header" ]]; then
25571                         continue
25572                 fi
25573
25574                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25575                         continue # lustre_ioctl.h is internal header
25576                 fi
25577
25578                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25579                         error "cannot compile '$header'"
25580         done
25581         rm -f $out
25582 }
25583 run_test 400b "packaged headers can be compiled"
25584
25585 test_401a() { #LU-7437
25586         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25587         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25588
25589         #count the number of parameters by "list_param -R"
25590         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25591         #count the number of parameters by listing proc files
25592         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25593         echo "proc_dirs='$proc_dirs'"
25594         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25595         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25596                       sort -u | wc -l)
25597
25598         [ $params -eq $procs ] ||
25599                 error "found $params parameters vs. $procs proc files"
25600
25601         # test the list_param -D option only returns directories
25602         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25603         #count the number of parameters by listing proc directories
25604         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25605                 sort -u | wc -l)
25606
25607         [ $params -eq $procs ] ||
25608                 error "found $params parameters vs. $procs proc files"
25609 }
25610 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25611
25612 test_401b() {
25613         # jobid_var may not allow arbitrary values, so use jobid_name
25614         # if available
25615         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25616                 local testname=jobid_name tmp='testing%p'
25617         else
25618                 local testname=jobid_var tmp=testing
25619         fi
25620
25621         local save=$($LCTL get_param -n $testname)
25622
25623         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25624                 error "no error returned when setting bad parameters"
25625
25626         local jobid_new=$($LCTL get_param -n foe $testname baz)
25627         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25628
25629         $LCTL set_param -n fog=bam $testname=$save bat=fog
25630         local jobid_old=$($LCTL get_param -n foe $testname bag)
25631         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25632 }
25633 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25634
25635 test_401c() {
25636         # jobid_var may not allow arbitrary values, so use jobid_name
25637         # if available
25638         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25639                 local testname=jobid_name
25640         else
25641                 local testname=jobid_var
25642         fi
25643
25644         local jobid_var_old=$($LCTL get_param -n $testname)
25645         local jobid_var_new
25646
25647         $LCTL set_param $testname= &&
25648                 error "no error returned for 'set_param a='"
25649
25650         jobid_var_new=$($LCTL get_param -n $testname)
25651         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25652                 error "$testname was changed by setting without value"
25653
25654         $LCTL set_param $testname &&
25655                 error "no error returned for 'set_param a'"
25656
25657         jobid_var_new=$($LCTL get_param -n $testname)
25658         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25659                 error "$testname was changed by setting without value"
25660 }
25661 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25662
25663 test_401d() {
25664         # jobid_var may not allow arbitrary values, so use jobid_name
25665         # if available
25666         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25667                 local testname=jobid_name new_value='foo=bar%p'
25668         else
25669                 local testname=jobid_var new_valuie=foo=bar
25670         fi
25671
25672         local jobid_var_old=$($LCTL get_param -n $testname)
25673         local jobid_var_new
25674
25675         $LCTL set_param $testname=$new_value ||
25676                 error "'set_param a=b' did not accept a value containing '='"
25677
25678         jobid_var_new=$($LCTL get_param -n $testname)
25679         [[ "$jobid_var_new" == "$new_value" ]] ||
25680                 error "'set_param a=b' failed on a value containing '='"
25681
25682         # Reset the $testname to test the other format
25683         $LCTL set_param $testname=$jobid_var_old
25684         jobid_var_new=$($LCTL get_param -n $testname)
25685         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25686                 error "failed to reset $testname"
25687
25688         $LCTL set_param $testname $new_value ||
25689                 error "'set_param a b' did not accept a value containing '='"
25690
25691         jobid_var_new=$($LCTL get_param -n $testname)
25692         [[ "$jobid_var_new" == "$new_value" ]] ||
25693                 error "'set_param a b' failed on a value containing '='"
25694
25695         $LCTL set_param $testname $jobid_var_old
25696         jobid_var_new=$($LCTL get_param -n $testname)
25697         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25698                 error "failed to reset $testname"
25699 }
25700 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25701
25702 test_401e() { # LU-14779
25703         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25704                 error "lctl list_param MGC* failed"
25705         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25706         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25707                 error "lctl get_param lru_size failed"
25708 }
25709 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25710
25711 test_402() {
25712         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25713         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25714                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25715         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25716                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25717                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25718         remote_mds_nodsh && skip "remote MDS with nodsh"
25719
25720         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25721 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25722         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25723         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25724                 echo "Touch failed - OK"
25725 }
25726 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25727
25728 test_403() {
25729         local file1=$DIR/$tfile.1
25730         local file2=$DIR/$tfile.2
25731         local tfile=$TMP/$tfile
25732
25733         rm -f $file1 $file2 $tfile
25734
25735         touch $file1
25736         ln $file1 $file2
25737
25738         # 30 sec OBD_TIMEOUT in ll_getattr()
25739         # right before populating st_nlink
25740         $LCTL set_param fail_loc=0x80001409
25741         stat -c %h $file1 > $tfile &
25742
25743         # create an alias, drop all locks and reclaim the dentry
25744         < $file2
25745         cancel_lru_locks mdc
25746         cancel_lru_locks osc
25747         sysctl -w vm.drop_caches=2
25748
25749         wait
25750
25751         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25752
25753         rm -f $tfile $file1 $file2
25754 }
25755 run_test 403 "i_nlink should not drop to zero due to aliasing"
25756
25757 test_404() { # LU-6601
25758         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25759                 skip "Need server version newer than 2.8.52"
25760         remote_mds_nodsh && skip "remote MDS with nodsh"
25761
25762         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25763                 awk '/osp .*-osc-MDT/ { print $4}')
25764
25765         local osp
25766         for osp in $mosps; do
25767                 echo "Deactivate: " $osp
25768                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25769                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25770                         awk -vp=$osp '$4 == p { print $2 }')
25771                 [ $stat = IN ] || {
25772                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25773                         error "deactivate error"
25774                 }
25775                 echo "Activate: " $osp
25776                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25777                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25778                         awk -vp=$osp '$4 == p { print $2 }')
25779                 [ $stat = UP ] || {
25780                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25781                         error "activate error"
25782                 }
25783         done
25784 }
25785 run_test 404 "validate manual {de}activated works properly for OSPs"
25786
25787 test_405() {
25788         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25789         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25790                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25791                         skip "Layout swap lock is not supported"
25792
25793         check_swap_layouts_support
25794         check_swap_layout_no_dom $DIR
25795
25796         test_mkdir $DIR/$tdir
25797         swap_lock_test -d $DIR/$tdir ||
25798                 error "One layout swap locked test failed"
25799 }
25800 run_test 405 "Various layout swap lock tests"
25801
25802 test_406() {
25803         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25804         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25805         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25807         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25808                 skip "Need MDS version at least 2.8.50"
25809
25810         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25811         local test_pool=$TESTNAME
25812
25813         pool_add $test_pool || error "pool_add failed"
25814         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25815                 error "pool_add_targets failed"
25816
25817         save_layout_restore_at_exit $MOUNT
25818
25819         # parent set default stripe count only, child will stripe from both
25820         # parent and fs default
25821         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25822                 error "setstripe $MOUNT failed"
25823         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25824         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25825         for i in $(seq 10); do
25826                 local f=$DIR/$tdir/$tfile.$i
25827                 touch $f || error "touch failed"
25828                 local count=$($LFS getstripe -c $f)
25829                 [ $count -eq $OSTCOUNT ] ||
25830                         error "$f stripe count $count != $OSTCOUNT"
25831                 local offset=$($LFS getstripe -i $f)
25832                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25833                 local size=$($LFS getstripe -S $f)
25834                 [ $size -eq $((def_stripe_size * 2)) ] ||
25835                         error "$f stripe size $size != $((def_stripe_size * 2))"
25836                 local pool=$($LFS getstripe -p $f)
25837                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25838         done
25839
25840         # change fs default striping, delete parent default striping, now child
25841         # will stripe from new fs default striping only
25842         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25843                 error "change $MOUNT default stripe failed"
25844         $LFS setstripe -c 0 $DIR/$tdir ||
25845                 error "delete $tdir default stripe failed"
25846         for i in $(seq 11 20); do
25847                 local f=$DIR/$tdir/$tfile.$i
25848                 touch $f || error "touch $f failed"
25849                 local count=$($LFS getstripe -c $f)
25850                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
25851                 local offset=$($LFS getstripe -i $f)
25852                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
25853                 local size=$($LFS getstripe -S $f)
25854                 [ $size -eq $def_stripe_size ] ||
25855                         error "$f stripe size $size != $def_stripe_size"
25856                 local pool=$($LFS getstripe -p $f)
25857                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
25858         done
25859
25860         unlinkmany $DIR/$tdir/$tfile. 1 20
25861
25862         local f=$DIR/$tdir/$tfile
25863         pool_remove_all_targets $test_pool $f
25864         pool_remove $test_pool $f
25865 }
25866 run_test 406 "DNE support fs default striping"
25867
25868 test_407() {
25869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25870         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25871                 skip "Need MDS version at least 2.8.55"
25872         remote_mds_nodsh && skip "remote MDS with nodsh"
25873
25874         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25875                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25876         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25877                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25878         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25879
25880         #define OBD_FAIL_DT_TXN_STOP    0x2019
25881         for idx in $(seq $MDSCOUNT); do
25882                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25883         done
25884         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25885         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25886                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25887         true
25888 }
25889 run_test 407 "transaction fail should cause operation fail"
25890
25891 test_408() {
25892         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25893
25894         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25895         lctl set_param fail_loc=0x8000040a
25896         # let ll_prepare_partial_page() fail
25897         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25898
25899         rm -f $DIR/$tfile
25900
25901         # create at least 100 unused inodes so that
25902         # shrink_icache_memory(0) should not return 0
25903         touch $DIR/$tfile-{0..100}
25904         rm -f $DIR/$tfile-{0..100}
25905         sync
25906
25907         echo 2 > /proc/sys/vm/drop_caches
25908 }
25909 run_test 408 "drop_caches should not hang due to page leaks"
25910
25911 test_409()
25912 {
25913         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25914
25915         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25916         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25917         touch $DIR/$tdir/guard || error "(2) Fail to create"
25918
25919         local PREFIX=$(str_repeat 'A' 128)
25920         echo "Create 1K hard links start at $(date)"
25921         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25922                 error "(3) Fail to hard link"
25923
25924         echo "Links count should be right although linkEA overflow"
25925         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25926         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25927         [ $linkcount -eq 1001 ] ||
25928                 error "(5) Unexpected hard links count: $linkcount"
25929
25930         echo "List all links start at $(date)"
25931         ls -l $DIR/$tdir/foo > /dev/null ||
25932                 error "(6) Fail to list $DIR/$tdir/foo"
25933
25934         echo "Unlink hard links start at $(date)"
25935         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25936                 error "(7) Fail to unlink"
25937         echo "Unlink hard links finished at $(date)"
25938 }
25939 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25940
25941 test_410()
25942 {
25943         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25944                 skip "Need client version at least 2.9.59"
25945         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25946                 skip "Need MODULES build"
25947
25948         # Create a file, and stat it from the kernel
25949         local testfile=$DIR/$tfile
25950         touch $testfile
25951
25952         local run_id=$RANDOM
25953         local my_ino=$(stat --format "%i" $testfile)
25954
25955         # Try to insert the module. This will always fail as the
25956         # module is designed to not be inserted.
25957         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25958             &> /dev/null
25959
25960         # Anything but success is a test failure
25961         dmesg | grep -q \
25962             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25963             error "no inode match"
25964 }
25965 run_test 410 "Test inode number returned from kernel thread"
25966
25967 cleanup_test411_cgroup() {
25968         trap 0
25969         rmdir "$1"
25970 }
25971
25972 test_411() {
25973         local cg_basedir=/sys/fs/cgroup/memory
25974         # LU-9966
25975         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25976                 skip "no setup for cgroup"
25977
25978         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25979                 error "test file creation failed"
25980         cancel_lru_locks osc
25981
25982         # Create a very small memory cgroup to force a slab allocation error
25983         local cgdir=$cg_basedir/osc_slab_alloc
25984         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25985         trap "cleanup_test411_cgroup $cgdir" EXIT
25986         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25987         echo 1M > $cgdir/memory.limit_in_bytes
25988
25989         # Should not LBUG, just be killed by oom-killer
25990         # dd will return 0 even allocation failure in some environment.
25991         # So don't check return value
25992         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25993         cleanup_test411_cgroup $cgdir
25994
25995         return 0
25996 }
25997 run_test 411 "Slab allocation error with cgroup does not LBUG"
25998
25999 test_412() {
26000         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26001         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26002                 skip "Need server version at least 2.10.55"
26003
26004         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26005                 error "mkdir failed"
26006         $LFS getdirstripe $DIR/$tdir
26007         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26008         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26009                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26010         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26011         [ $stripe_count -eq 2 ] ||
26012                 error "expect 2 get $stripe_count"
26013
26014         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26015
26016         local index
26017         local index2
26018
26019         # subdirs should be on the same MDT as parent
26020         for i in $(seq 0 $((MDSCOUNT - 1))); do
26021                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26022                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26023                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26024                 (( index == i )) || error "mdt$i/sub on MDT$index"
26025         done
26026
26027         # stripe offset -1, ditto
26028         for i in {1..10}; do
26029                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26030                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26031                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26032                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26033                 (( index == index2 )) ||
26034                         error "qos$i on MDT$index, sub on MDT$index2"
26035         done
26036
26037         local testdir=$DIR/$tdir/inherit
26038
26039         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26040         # inherit 2 levels
26041         for i in 1 2; do
26042                 testdir=$testdir/s$i
26043                 mkdir $testdir || error "mkdir $testdir failed"
26044                 index=$($LFS getstripe -m $testdir)
26045                 (( index == 1 )) ||
26046                         error "$testdir on MDT$index"
26047         done
26048
26049         # not inherit any more
26050         testdir=$testdir/s3
26051         mkdir $testdir || error "mkdir $testdir failed"
26052         getfattr -d -m dmv $testdir | grep dmv &&
26053                 error "default LMV set on $testdir" || true
26054 }
26055 run_test 412 "mkdir on specific MDTs"
26056
26057 TEST413_COUNT=${TEST413_COUNT:-200}
26058 generate_uneven_mdts() {
26059         local threshold=$1
26060         local lmv_qos_maxage
26061         local lod_qos_maxage
26062         local ffree
26063         local bavail
26064         local max
26065         local min
26066         local max_index
26067         local min_index
26068         local tmp
26069         local i
26070
26071         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26072         $LCTL set_param lmv.*.qos_maxage=1
26073         stack_trap "$LCTL set_param \
26074                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26075         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26076                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26077         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26078                 lod.*.mdt_qos_maxage=1
26079         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26080                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26081
26082         echo
26083         echo "Check for uneven MDTs: "
26084
26085         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26086         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26087         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26088
26089         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26090         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26091         max_index=0
26092         min_index=0
26093         for ((i = 1; i < ${#ffree[@]}; i++)); do
26094                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26095                 if [ $tmp -gt $max ]; then
26096                         max=$tmp
26097                         max_index=$i
26098                 fi
26099                 if [ $tmp -lt $min ]; then
26100                         min=$tmp
26101                         min_index=$i
26102                 fi
26103         done
26104
26105         (( ${ffree[min_index]} > 0 )) ||
26106                 skip "no free files in MDT$min_index"
26107         (( ${ffree[min_index]} < 10000000 )) ||
26108                 skip "too many free files in MDT$min_index"
26109
26110         # Check if we need to generate uneven MDTs
26111         local diff=$(((max - min) * 100 / min))
26112         local testdir=$DIR/$tdir-fillmdt
26113         local start
26114
26115         i=0
26116         while (( diff < threshold )); do
26117                 mkdir -p $testdir
26118                 # generate uneven MDTs, create till $threshold% diff
26119                 echo -n "weight diff=$diff% must be > $threshold% ..."
26120                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26121                 testdir=$DIR/$tdir-fillmdt/$i
26122                 [ -d $testdir ] && continue
26123                 $LFS mkdir -i $min_index $testdir ||
26124                         error "mkdir $testdir failed"
26125                 $LFS setstripe -E 1M -L mdt $testdir ||
26126                         error "setstripe $testdir failed"
26127                 start=$SECONDS
26128                 for ((F=0; F < TEST413_COUNT; F++)); do
26129                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26130                                 /dev/null 2>&1 || error "dd $F failed"
26131                 done
26132                 sync; sleep 1; sync
26133
26134                 # wait for QOS to update
26135                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26136
26137                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26138                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26139                 max=$(((${ffree[max_index]} >> 8) *
26140                         (${bavail[max_index]} * bsize >> 16)))
26141                 min=$(((${ffree[min_index]} >> 8) *
26142                         (${bavail[min_index]} * bsize >> 16)))
26143                 diff=$(((max - min) * 100 / min))
26144                 i=$((i + 1))
26145         done
26146
26147         echo "MDT filesfree available: ${ffree[*]}"
26148         echo "MDT blocks available: ${bavail[*]}"
26149         echo "weight diff=$diff%"
26150 }
26151
26152 test_qos_mkdir() {
26153         local mkdir_cmd=$1
26154         local stripe_count=$2
26155         local mdts=$(comma_list $(mdts_nodes))
26156
26157         local testdir
26158         local lmv_qos_prio_free
26159         local lmv_qos_threshold_rr
26160         local lmv_qos_maxage
26161         local lod_qos_prio_free
26162         local lod_qos_threshold_rr
26163         local lod_qos_maxage
26164         local count
26165         local i
26166
26167         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26168         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26169         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26170                 head -n1)
26171         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26172         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26173         stack_trap "$LCTL set_param \
26174                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26175         stack_trap "$LCTL set_param \
26176                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26177         stack_trap "$LCTL set_param \
26178                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26179
26180         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26181                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26182         lod_qos_prio_free=${lod_qos_prio_free%%%}
26183         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26184                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26185         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26186         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26187                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26188         stack_trap "do_nodes $mdts $LCTL set_param \
26189                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26190         stack_trap "do_nodes $mdts $LCTL set_param \
26191                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26192         stack_trap "do_nodes $mdts $LCTL set_param \
26193                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26194
26195         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26196         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26197
26198         testdir=$DIR/$tdir-s$stripe_count/rr
26199
26200         local stripe_index=$($LFS getstripe -m $testdir)
26201         local test_mkdir_rr=true
26202
26203         getfattr -d -m dmv -e hex $testdir | grep dmv
26204         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26205                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26206                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26207                         test_mkdir_rr=false
26208         fi
26209
26210         echo
26211         $test_mkdir_rr &&
26212                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26213                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26214
26215         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26216         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26217                 eval $mkdir_cmd $testdir/subdir$i ||
26218                         error "$mkdir_cmd subdir$i failed"
26219         done
26220
26221         for (( i = 0; i < $MDSCOUNT; i++ )); do
26222                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26223                 echo "$count directories created on MDT$i"
26224                 if $test_mkdir_rr; then
26225                         (( $count == 100 )) ||
26226                                 error "subdirs are not evenly distributed"
26227                 elif (( $i == $stripe_index )); then
26228                         (( $count == 100 * MDSCOUNT )) ||
26229                                 error "$count subdirs created on MDT$i"
26230                 else
26231                         (( $count == 0 )) ||
26232                                 error "$count subdirs created on MDT$i"
26233                 fi
26234
26235                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26236                         count=$($LFS getdirstripe $testdir/* |
26237                                 grep -c -P "^\s+$i\t")
26238                         echo "$count stripes created on MDT$i"
26239                         # deviation should < 5% of average
26240                         (( $count >= 95 * stripe_count &&
26241                            $count <= 105 * stripe_count)) ||
26242                                 error "stripes are not evenly distributed"
26243                 fi
26244         done
26245
26246         echo
26247         echo "Check for uneven MDTs: "
26248
26249         local ffree
26250         local bavail
26251         local max
26252         local min
26253         local max_index
26254         local min_index
26255         local tmp
26256
26257         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26258         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26259         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26260
26261         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26262         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26263         max_index=0
26264         min_index=0
26265         for ((i = 1; i < ${#ffree[@]}; i++)); do
26266                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26267                 if [ $tmp -gt $max ]; then
26268                         max=$tmp
26269                         max_index=$i
26270                 fi
26271                 if [ $tmp -lt $min ]; then
26272                         min=$tmp
26273                         min_index=$i
26274                 fi
26275         done
26276
26277         (( ${ffree[min_index]} > 0 )) ||
26278                 skip "no free files in MDT$min_index"
26279         (( ${ffree[min_index]} < 10000000 )) ||
26280                 skip "too many free files in MDT$min_index"
26281
26282         echo "MDT filesfree available: ${ffree[*]}"
26283         echo "MDT blocks available: ${bavail[*]}"
26284         echo "weight diff=$(((max - min) * 100 / min))%"
26285         echo
26286         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26287
26288         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26289         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26290         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26291         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26292         # decrease statfs age, so that it can be updated in time
26293         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26294         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26295
26296         sleep 1
26297
26298         testdir=$DIR/$tdir-s$stripe_count/qos
26299         local num=200
26300
26301         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26302         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26303                 eval $mkdir_cmd $testdir/subdir$i ||
26304                         error "$mkdir_cmd subdir$i failed"
26305         done
26306
26307         max=0
26308         for (( i = 0; i < $MDSCOUNT; i++ )); do
26309                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26310                 (( count > max )) && max=$count
26311                 echo "$count directories created on MDT$i"
26312         done
26313
26314         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26315
26316         # D-value should > 10% of averge
26317         (( max - min > num / 10 )) ||
26318                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26319
26320         # ditto for stripes
26321         if (( stripe_count > 1 )); then
26322                 max=0
26323                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26324                         count=$($LFS getdirstripe $testdir/* |
26325                                 grep -c -P "^\s+$i\t")
26326                         (( count > max )) && max=$count
26327                         echo "$count stripes created on MDT$i"
26328                 done
26329
26330                 min=$($LFS getdirstripe $testdir/* |
26331                         grep -c -P "^\s+$min_index\t")
26332                 (( max - min > num * stripe_count / 10 )) ||
26333                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26334         fi
26335 }
26336
26337 most_full_mdt() {
26338         local ffree
26339         local bavail
26340         local bsize
26341         local min
26342         local min_index
26343         local tmp
26344
26345         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26346         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26347         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26348
26349         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26350         min_index=0
26351         for ((i = 1; i < ${#ffree[@]}; i++)); do
26352                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26353                 (( tmp < min )) && min=$tmp && min_index=$i
26354         done
26355
26356         echo -n $min_index
26357 }
26358
26359 test_413a() {
26360         [ $MDSCOUNT -lt 2 ] &&
26361                 skip "We need at least 2 MDTs for this test"
26362
26363         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26364                 skip "Need server version at least 2.12.52"
26365
26366         local stripe_count
26367
26368         generate_uneven_mdts 100
26369         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26370                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26371                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26372                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26373                         error "mkdir failed"
26374                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26375         done
26376 }
26377 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26378
26379 test_413b() {
26380         [ $MDSCOUNT -lt 2 ] &&
26381                 skip "We need at least 2 MDTs for this test"
26382
26383         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26384                 skip "Need server version at least 2.12.52"
26385
26386         local testdir
26387         local stripe_count
26388
26389         generate_uneven_mdts 100
26390         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26391                 testdir=$DIR/$tdir-s$stripe_count
26392                 mkdir $testdir || error "mkdir $testdir failed"
26393                 mkdir $testdir/rr || error "mkdir rr failed"
26394                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26395                         error "mkdir qos failed"
26396                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26397                         $testdir/rr || error "setdirstripe rr failed"
26398                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26399                         error "setdirstripe failed"
26400                 test_qos_mkdir "mkdir" $stripe_count
26401         done
26402 }
26403 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26404
26405 test_413c() {
26406         (( $MDSCOUNT >= 2 )) ||
26407                 skip "We need at least 2 MDTs for this test"
26408
26409         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26410                 skip "Need server version at least 2.14.51"
26411
26412         local testdir
26413         local inherit
26414         local inherit_rr
26415
26416         testdir=$DIR/${tdir}-s1
26417         mkdir $testdir || error "mkdir $testdir failed"
26418         mkdir $testdir/rr || error "mkdir rr failed"
26419         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26420         # default max_inherit is -1, default max_inherit_rr is 0
26421         $LFS setdirstripe -D -c 1 $testdir/rr ||
26422                 error "setdirstripe rr failed"
26423         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26424                 error "setdirstripe qos failed"
26425         test_qos_mkdir "mkdir" 1
26426
26427         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26428         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26429         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26430         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26431         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26432
26433         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26434         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26435         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26436         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26437         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26438         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26439         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26440                 error "level2 shouldn't have default LMV" || true
26441 }
26442 run_test 413c "mkdir with default LMV max inherit rr"
26443
26444 test_413d() {
26445         (( MDSCOUNT >= 2 )) ||
26446                 skip "We need at least 2 MDTs for this test"
26447
26448         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26449                 skip "Need server version at least 2.14.51"
26450
26451         local lmv_qos_threshold_rr
26452
26453         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26454                 head -n1)
26455         stack_trap "$LCTL set_param \
26456                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26457
26458         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26459         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26460         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26461                 error "$tdir shouldn't have default LMV"
26462         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26463                 error "mkdir sub failed"
26464
26465         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26466
26467         (( count == 100 )) || error "$count subdirs on MDT0"
26468 }
26469 run_test 413d "inherit ROOT default LMV"
26470
26471 test_413e() {
26472         (( MDSCOUNT >= 2 )) ||
26473                 skip "We need at least 2 MDTs for this test"
26474         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26475                 skip "Need server version at least 2.14.55"
26476
26477         local testdir=$DIR/$tdir
26478         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26479         local max_inherit
26480         local sub_max_inherit
26481
26482         mkdir -p $testdir || error "failed to create $testdir"
26483
26484         # set default max-inherit to -1 if stripe count is 0 or 1
26485         $LFS setdirstripe -D -c 1 $testdir ||
26486                 error "failed to set default LMV"
26487         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26488         (( max_inherit == -1 )) ||
26489                 error "wrong max_inherit value $max_inherit"
26490
26491         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26492         $LFS setdirstripe -D -c -1 $testdir ||
26493                 error "failed to set default LMV"
26494         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26495         (( max_inherit > 0 )) ||
26496                 error "wrong max_inherit value $max_inherit"
26497
26498         # and the subdir will decrease the max_inherit by 1
26499         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26500         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26501         (( sub_max_inherit == max_inherit - 1)) ||
26502                 error "wrong max-inherit of subdir $sub_max_inherit"
26503
26504         # check specified --max-inherit and warning message
26505         stack_trap "rm -f $tmpfile"
26506         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26507                 error "failed to set default LMV"
26508         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26509         (( max_inherit == -1 )) ||
26510                 error "wrong max_inherit value $max_inherit"
26511
26512         # check the warning messages
26513         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26514                 error "failed to detect warning string"
26515         fi
26516 }
26517 run_test 413e "check default max-inherit value"
26518
26519 test_fs_dmv_inherit()
26520 {
26521         local testdir=$DIR/$tdir
26522
26523         local count
26524         local inherit
26525         local inherit_rr
26526
26527         for i in 1 2 3; do
26528                 mkdir $testdir || error "mkdir $testdir failed"
26529                 count=$($LFS getdirstripe -D -c $testdir)
26530                 (( count == 1 )) ||
26531                         error "$testdir default LMV count mismatch $count != 1"
26532                 inherit=$($LFS getdirstripe -D -X $testdir)
26533                 (( inherit == 3 - i )) ||
26534                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26535                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26536                 (( inherit_rr == 3 - i )) ||
26537                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26538                 testdir=$testdir/sub
26539         done
26540
26541         mkdir $testdir || error "mkdir $testdir failed"
26542         count=$($LFS getdirstripe -D -c $testdir)
26543         (( count == 0 )) ||
26544                 error "$testdir default LMV count not zero: $count"
26545 }
26546
26547 test_413f() {
26548         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26549
26550         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26551                 skip "Need server version at least 2.14.55"
26552
26553         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26554                 error "dump $DIR default LMV failed"
26555         stack_trap "setfattr --restore=$TMP/dmv.ea"
26556
26557         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26558                 error "set $DIR default LMV failed"
26559
26560         test_fs_dmv_inherit
26561 }
26562 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26563
26564 test_413g() {
26565         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26566
26567         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26568         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26569                 error "dump $DIR default LMV failed"
26570         stack_trap "setfattr --restore=$TMP/dmv.ea"
26571
26572         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26573                 error "set $DIR default LMV failed"
26574
26575         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26576                 error "mount $MOUNT2 failed"
26577         stack_trap "umount_client $MOUNT2"
26578
26579         local saved_DIR=$DIR
26580
26581         export DIR=$MOUNT2
26582
26583         stack_trap "export DIR=$saved_DIR"
26584
26585         # first check filesystem-wide default LMV inheritance
26586         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26587
26588         # then check subdirs are spread to all MDTs
26589         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26590
26591         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26592
26593         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26594 }
26595 run_test 413g "enforce ROOT default LMV on subdir mount"
26596
26597 test_413h() {
26598         (( MDSCOUNT >= 2 )) ||
26599                 skip "We need at least 2 MDTs for this test"
26600
26601         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26602                 skip "Need server version at least 2.15.50.6"
26603
26604         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26605
26606         stack_trap "$LCTL set_param \
26607                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26608         $LCTL set_param lmv.*.qos_maxage=1
26609
26610         local depth=5
26611         local rr_depth=4
26612         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26613         local count=$((MDSCOUNT * 20))
26614
26615         generate_uneven_mdts 50
26616
26617         mkdir -p $dir || error "mkdir $dir failed"
26618         stack_trap "rm -rf $dir"
26619         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26620                 --max-inherit-rr=$rr_depth $dir
26621
26622         for ((d=0; d < depth + 2; d++)); do
26623                 log "dir=$dir:"
26624                 for ((sub=0; sub < count; sub++)); do
26625                         mkdir $dir/d$sub
26626                 done
26627                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26628                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26629                 # subdirs within $rr_depth should be created round-robin
26630                 if (( d < rr_depth )); then
26631                         (( ${num[0]} != count )) ||
26632                                 error "all objects created on MDT ${num[1]}"
26633                 fi
26634
26635                 dir=$dir/d0
26636         done
26637 }
26638 run_test 413h "don't stick to parent for round-robin dirs"
26639
26640 test_413z() {
26641         local pids=""
26642         local subdir
26643         local pid
26644
26645         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26646                 unlinkmany $subdir/f. $TEST413_COUNT &
26647                 pids="$pids $!"
26648         done
26649
26650         for pid in $pids; do
26651                 wait $pid
26652         done
26653 }
26654 run_test 413z "413 test cleanup"
26655
26656 test_414() {
26657 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26658         $LCTL set_param fail_loc=0x80000521
26659         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26660         rm -f $DIR/$tfile
26661 }
26662 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26663
26664 test_415() {
26665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26666         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26667                 skip "Need server version at least 2.11.52"
26668
26669         # LU-11102
26670         local total
26671         local setattr_pid
26672         local start_time
26673         local end_time
26674         local duration
26675
26676         total=500
26677         # this test may be slow on ZFS
26678         [ "$mds1_FSTYPE" == "zfs" ] && total=50
26679
26680         # though this test is designed for striped directory, let's test normal
26681         # directory too since lock is always saved as CoS lock.
26682         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26683         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26684
26685         (
26686                 while true; do
26687                         touch $DIR/$tdir
26688                 done
26689         ) &
26690         setattr_pid=$!
26691
26692         start_time=$(date +%s)
26693         for i in $(seq $total); do
26694                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26695                         > /dev/null
26696         done
26697         end_time=$(date +%s)
26698         duration=$((end_time - start_time))
26699
26700         kill -9 $setattr_pid
26701
26702         echo "rename $total files took $duration sec"
26703         [ $duration -lt 100 ] || error "rename took $duration sec"
26704 }
26705 run_test 415 "lock revoke is not missing"
26706
26707 test_416() {
26708         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26709                 skip "Need server version at least 2.11.55"
26710
26711         # define OBD_FAIL_OSD_TXN_START    0x19a
26712         do_facet mds1 lctl set_param fail_loc=0x19a
26713
26714         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26715
26716         true
26717 }
26718 run_test 416 "transaction start failure won't cause system hung"
26719
26720 cleanup_417() {
26721         trap 0
26722         do_nodes $(comma_list $(mdts_nodes)) \
26723                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26724         do_nodes $(comma_list $(mdts_nodes)) \
26725                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26726         do_nodes $(comma_list $(mdts_nodes)) \
26727                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26728 }
26729
26730 test_417() {
26731         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26732         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26733                 skip "Need MDS version at least 2.11.56"
26734
26735         trap cleanup_417 RETURN EXIT
26736
26737         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26738         do_nodes $(comma_list $(mdts_nodes)) \
26739                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26740         $LFS migrate -m 0 $DIR/$tdir.1 &&
26741                 error "migrate dir $tdir.1 should fail"
26742
26743         do_nodes $(comma_list $(mdts_nodes)) \
26744                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26745         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26746                 error "create remote dir $tdir.2 should fail"
26747
26748         do_nodes $(comma_list $(mdts_nodes)) \
26749                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26750         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26751                 error "create striped dir $tdir.3 should fail"
26752         true
26753 }
26754 run_test 417 "disable remote dir, striped dir and dir migration"
26755
26756 # Checks that the outputs of df [-i] and lfs df [-i] match
26757 #
26758 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26759 check_lfs_df() {
26760         local dir=$2
26761         local inodes
26762         local df_out
26763         local lfs_df_out
26764         local count
26765         local passed=false
26766
26767         # blocks or inodes
26768         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26769
26770         for count in {1..100}; do
26771                 do_nodes "$CLIENTS" \
26772                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26773                 sync; sleep 0.2
26774
26775                 # read the lines of interest
26776                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26777                         error "df $inodes $dir | tail -n +2 failed"
26778                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26779                         error "lfs df $inodes $dir | grep summary: failed"
26780
26781                 # skip first substrings of each output as they are different
26782                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26783                 # compare the two outputs
26784                 passed=true
26785                 #  skip "available" on MDT until LU-13997 is fixed.
26786                 #for i in {1..5}; do
26787                 for i in 1 2 4 5; do
26788                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26789                 done
26790                 $passed && break
26791         done
26792
26793         if ! $passed; then
26794                 df -P $inodes $dir
26795                 echo
26796                 lfs df $inodes $dir
26797                 error "df and lfs df $1 output mismatch: "      \
26798                       "df ${inodes}: ${df_out[*]}, "            \
26799                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26800         fi
26801 }
26802
26803 test_418() {
26804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26805
26806         local dir=$DIR/$tdir
26807         local numfiles=$((RANDOM % 4096 + 2))
26808         local numblocks=$((RANDOM % 256 + 1))
26809
26810         wait_delete_completed
26811         test_mkdir $dir
26812
26813         # check block output
26814         check_lfs_df blocks $dir
26815         # check inode output
26816         check_lfs_df inodes $dir
26817
26818         # create a single file and retest
26819         echo "Creating a single file and testing"
26820         createmany -o $dir/$tfile- 1 &>/dev/null ||
26821                 error "creating 1 file in $dir failed"
26822         check_lfs_df blocks $dir
26823         check_lfs_df inodes $dir
26824
26825         # create a random number of files
26826         echo "Creating $((numfiles - 1)) files and testing"
26827         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26828                 error "creating $((numfiles - 1)) files in $dir failed"
26829
26830         # write a random number of blocks to the first test file
26831         echo "Writing $numblocks 4K blocks and testing"
26832         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26833                 count=$numblocks &>/dev/null ||
26834                 error "dd to $dir/${tfile}-0 failed"
26835
26836         # retest
26837         check_lfs_df blocks $dir
26838         check_lfs_df inodes $dir
26839
26840         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
26841                 error "unlinking $numfiles files in $dir failed"
26842 }
26843 run_test 418 "df and lfs df outputs match"
26844
26845 test_419()
26846 {
26847         local dir=$DIR/$tdir
26848
26849         mkdir -p $dir
26850         touch $dir/file
26851
26852         cancel_lru_locks mdc
26853
26854         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
26855         $LCTL set_param fail_loc=0x1410
26856         cat $dir/file
26857         $LCTL set_param fail_loc=0
26858         rm -rf $dir
26859 }
26860 run_test 419 "Verify open file by name doesn't crash kernel"
26861
26862 test_420()
26863 {
26864         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
26865                 skip "Need MDS version at least 2.12.53"
26866
26867         local SAVE_UMASK=$(umask)
26868         local dir=$DIR/$tdir
26869         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
26870
26871         mkdir -p $dir
26872         umask 0000
26873         mkdir -m03777 $dir/testdir
26874         ls -dn $dir/testdir
26875         # Need to remove trailing '.' when SELinux is enabled
26876         local dirperms=$(ls -dn $dir/testdir |
26877                          awk '{ sub(/\.$/, "", $1); print $1}')
26878         [ $dirperms == "drwxrwsrwt" ] ||
26879                 error "incorrect perms on $dir/testdir"
26880
26881         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
26882                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
26883         ls -n $dir/testdir/testfile
26884         local fileperms=$(ls -n $dir/testdir/testfile |
26885                           awk '{ sub(/\.$/, "", $1); print $1}')
26886         [ $fileperms == "-rwxr-xr-x" ] ||
26887                 error "incorrect perms on $dir/testdir/testfile"
26888
26889         umask $SAVE_UMASK
26890 }
26891 run_test 420 "clear SGID bit on non-directories for non-members"
26892
26893 test_421a() {
26894         local cnt
26895         local fid1
26896         local fid2
26897
26898         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26899                 skip "Need MDS version at least 2.12.54"
26900
26901         test_mkdir $DIR/$tdir
26902         createmany -o $DIR/$tdir/f 3
26903         cnt=$(ls -1 $DIR/$tdir | wc -l)
26904         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26905
26906         fid1=$(lfs path2fid $DIR/$tdir/f1)
26907         fid2=$(lfs path2fid $DIR/$tdir/f2)
26908         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
26909
26910         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
26911         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
26912
26913         cnt=$(ls -1 $DIR/$tdir | wc -l)
26914         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26915
26916         rm -f $DIR/$tdir/f3 || error "can't remove f3"
26917         createmany -o $DIR/$tdir/f 3
26918         cnt=$(ls -1 $DIR/$tdir | wc -l)
26919         [ $cnt != 3 ] && error "unexpected #files: $cnt"
26920
26921         fid1=$(lfs path2fid $DIR/$tdir/f1)
26922         fid2=$(lfs path2fid $DIR/$tdir/f2)
26923         echo "remove using fsname $FSNAME"
26924         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
26925
26926         cnt=$(ls -1 $DIR/$tdir | wc -l)
26927         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
26928 }
26929 run_test 421a "simple rm by fid"
26930
26931 test_421b() {
26932         local cnt
26933         local FID1
26934         local FID2
26935
26936         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26937                 skip "Need MDS version at least 2.12.54"
26938
26939         test_mkdir $DIR/$tdir
26940         createmany -o $DIR/$tdir/f 3
26941         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
26942         MULTIPID=$!
26943
26944         FID1=$(lfs path2fid $DIR/$tdir/f1)
26945         FID2=$(lfs path2fid $DIR/$tdir/f2)
26946         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
26947
26948         kill -USR1 $MULTIPID
26949         wait
26950
26951         cnt=$(ls $DIR/$tdir | wc -l)
26952         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
26953 }
26954 run_test 421b "rm by fid on open file"
26955
26956 test_421c() {
26957         local cnt
26958         local FIDS
26959
26960         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26961                 skip "Need MDS version at least 2.12.54"
26962
26963         test_mkdir $DIR/$tdir
26964         createmany -o $DIR/$tdir/f 3
26965         touch $DIR/$tdir/$tfile
26966         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
26967         cnt=$(ls -1 $DIR/$tdir | wc -l)
26968         [ $cnt != 184 ] && error "unexpected #files: $cnt"
26969
26970         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
26971         $LFS rmfid $DIR $FID1 || error "rmfid failed"
26972
26973         cnt=$(ls $DIR/$tdir | wc -l)
26974         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
26975 }
26976 run_test 421c "rm by fid against hardlinked files"
26977
26978 test_421d() {
26979         local cnt
26980         local FIDS
26981
26982         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26983                 skip "Need MDS version at least 2.12.54"
26984
26985         test_mkdir $DIR/$tdir
26986         createmany -o $DIR/$tdir/f 4097
26987         cnt=$(ls -1 $DIR/$tdir | wc -l)
26988         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
26989
26990         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
26991         $LFS rmfid $DIR $FIDS || error "rmfid failed"
26992
26993         cnt=$(ls $DIR/$tdir | wc -l)
26994         rm -rf $DIR/$tdir
26995         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26996 }
26997 run_test 421d "rmfid en masse"
26998
26999 test_421e() {
27000         local cnt
27001         local FID
27002
27003         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27004         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27005                 skip "Need MDS version at least 2.12.54"
27006
27007         mkdir -p $DIR/$tdir
27008         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27009         createmany -o $DIR/$tdir/striped_dir/f 512
27010         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27011         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27012
27013         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27014                 sed "s/[/][^:]*://g")
27015         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27016
27017         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27018         rm -rf $DIR/$tdir
27019         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27020 }
27021 run_test 421e "rmfid in DNE"
27022
27023 test_421f() {
27024         local cnt
27025         local FID
27026
27027         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27028                 skip "Need MDS version at least 2.12.54"
27029
27030         test_mkdir $DIR/$tdir
27031         touch $DIR/$tdir/f
27032         cnt=$(ls -1 $DIR/$tdir | wc -l)
27033         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27034
27035         FID=$(lfs path2fid $DIR/$tdir/f)
27036         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27037         # rmfid should fail
27038         cnt=$(ls -1 $DIR/$tdir | wc -l)
27039         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27040
27041         chmod a+rw $DIR/$tdir
27042         ls -la $DIR/$tdir
27043         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27044         # rmfid should fail
27045         cnt=$(ls -1 $DIR/$tdir | wc -l)
27046         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27047
27048         rm -f $DIR/$tdir/f
27049         $RUNAS touch $DIR/$tdir/f
27050         FID=$(lfs path2fid $DIR/$tdir/f)
27051         echo "rmfid as root"
27052         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27053         cnt=$(ls -1 $DIR/$tdir | wc -l)
27054         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27055
27056         rm -f $DIR/$tdir/f
27057         $RUNAS touch $DIR/$tdir/f
27058         cnt=$(ls -1 $DIR/$tdir | wc -l)
27059         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27060         FID=$(lfs path2fid $DIR/$tdir/f)
27061         # rmfid w/o user_fid2path mount option should fail
27062         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27063         cnt=$(ls -1 $DIR/$tdir | wc -l)
27064         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27065
27066         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27067         stack_trap "rmdir $tmpdir"
27068         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27069                 error "failed to mount client'"
27070         stack_trap "umount_client $tmpdir"
27071
27072         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27073         # rmfid should succeed
27074         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27075         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27076
27077         # rmfid shouldn't allow to remove files due to dir's permission
27078         chmod a+rwx $tmpdir/$tdir
27079         touch $tmpdir/$tdir/f
27080         ls -la $tmpdir/$tdir
27081         FID=$(lfs path2fid $tmpdir/$tdir/f)
27082         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27083         return 0
27084 }
27085 run_test 421f "rmfid checks permissions"
27086
27087 test_421g() {
27088         local cnt
27089         local FIDS
27090
27091         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27092         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27093                 skip "Need MDS version at least 2.12.54"
27094
27095         mkdir -p $DIR/$tdir
27096         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27097         createmany -o $DIR/$tdir/striped_dir/f 512
27098         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27099         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27100
27101         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27102                 sed "s/[/][^:]*://g")
27103
27104         rm -f $DIR/$tdir/striped_dir/f1*
27105         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27106         removed=$((512 - cnt))
27107
27108         # few files have been just removed, so we expect
27109         # rmfid to fail on their fids
27110         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27111         [ $removed != $errors ] && error "$errors != $removed"
27112
27113         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27114         rm -rf $DIR/$tdir
27115         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27116 }
27117 run_test 421g "rmfid to return errors properly"
27118
27119 test_422() {
27120         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27121         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27122         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27123         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27124         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27125
27126         local amc=$(at_max_get client)
27127         local amo=$(at_max_get mds1)
27128         local timeout=`lctl get_param -n timeout`
27129
27130         at_max_set 0 client
27131         at_max_set 0 mds1
27132
27133 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27134         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27135                         fail_val=$(((2*timeout + 10)*1000))
27136         touch $DIR/$tdir/d3/file &
27137         sleep 2
27138 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27139         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27140                         fail_val=$((2*timeout + 5))
27141         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27142         local pid=$!
27143         sleep 1
27144         kill -9 $pid
27145         sleep $((2 * timeout))
27146         echo kill $pid
27147         kill -9 $pid
27148         lctl mark touch
27149         touch $DIR/$tdir/d2/file3
27150         touch $DIR/$tdir/d2/file4
27151         touch $DIR/$tdir/d2/file5
27152
27153         wait
27154         at_max_set $amc client
27155         at_max_set $amo mds1
27156
27157         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27158         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27159                 error "Watchdog is always throttled"
27160 }
27161 run_test 422 "kill a process with RPC in progress"
27162
27163 stat_test() {
27164     df -h $MOUNT &
27165     df -h $MOUNT &
27166     df -h $MOUNT &
27167     df -h $MOUNT &
27168     df -h $MOUNT &
27169     df -h $MOUNT &
27170 }
27171
27172 test_423() {
27173     local _stats
27174     # ensure statfs cache is expired
27175     sleep 2;
27176
27177     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27178     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27179
27180     return 0
27181 }
27182 run_test 423 "statfs should return a right data"
27183
27184 test_424() {
27185 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27186         $LCTL set_param fail_loc=0x80000522
27187         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27188         rm -f $DIR/$tfile
27189 }
27190 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27191
27192 test_425() {
27193         test_mkdir -c -1 $DIR/$tdir
27194         $LFS setstripe -c -1 $DIR/$tdir
27195
27196         lru_resize_disable "" 100
27197         stack_trap "lru_resize_enable" EXIT
27198
27199         sleep 5
27200
27201         for i in $(seq $((MDSCOUNT * 125))); do
27202                 local t=$DIR/$tdir/$tfile_$i
27203
27204                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27205                         error_noexit "Create file $t"
27206         done
27207         stack_trap "rm -rf $DIR/$tdir" EXIT
27208
27209         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27210                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27211                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27212
27213                 [ $lock_count -le $lru_size ] ||
27214                         error "osc lock count $lock_count > lru size $lru_size"
27215         done
27216
27217         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27218                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27219                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27220
27221                 [ $lock_count -le $lru_size ] ||
27222                         error "mdc lock count $lock_count > lru size $lru_size"
27223         done
27224 }
27225 run_test 425 "lock count should not exceed lru size"
27226
27227 test_426() {
27228         splice-test -r $DIR/$tfile
27229         splice-test -rd $DIR/$tfile
27230         splice-test $DIR/$tfile
27231         splice-test -d $DIR/$tfile
27232 }
27233 run_test 426 "splice test on Lustre"
27234
27235 test_427() {
27236         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27237         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27238                 skip "Need MDS version at least 2.12.4"
27239         local log
27240
27241         mkdir $DIR/$tdir
27242         mkdir $DIR/$tdir/1
27243         mkdir $DIR/$tdir/2
27244         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27245         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27246
27247         $LFS getdirstripe $DIR/$tdir/1/dir
27248
27249         #first setfattr for creating updatelog
27250         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27251
27252 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27253         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27254         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27255         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27256
27257         sleep 2
27258         fail mds2
27259         wait_recovery_complete mds2 $((2*TIMEOUT))
27260
27261         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27262         echo $log | grep "get update log failed" &&
27263                 error "update log corruption is detected" || true
27264 }
27265 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27266
27267 test_428() {
27268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27269         local cache_limit=$CACHE_MAX
27270
27271         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27272         $LCTL set_param -n llite.*.max_cached_mb=64
27273
27274         mkdir $DIR/$tdir
27275         $LFS setstripe -c 1 $DIR/$tdir
27276         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27277         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27278         #test write
27279         for f in $(seq 4); do
27280                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27281         done
27282         wait
27283
27284         cancel_lru_locks osc
27285         # Test read
27286         for f in $(seq 4); do
27287                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27288         done
27289         wait
27290 }
27291 run_test 428 "large block size IO should not hang"
27292
27293 test_429() { # LU-7915 / LU-10948
27294         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27295         local testfile=$DIR/$tfile
27296         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27297         local new_flag=1
27298         local first_rpc
27299         local second_rpc
27300         local third_rpc
27301
27302         $LCTL get_param $ll_opencache_threshold_count ||
27303                 skip "client does not have opencache parameter"
27304
27305         set_opencache $new_flag
27306         stack_trap "restore_opencache"
27307         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27308                 error "enable opencache failed"
27309         touch $testfile
27310         # drop MDC DLM locks
27311         cancel_lru_locks mdc
27312         # clear MDC RPC stats counters
27313         $LCTL set_param $mdc_rpcstats=clear
27314
27315         # According to the current implementation, we need to run 3 times
27316         # open & close file to verify if opencache is enabled correctly.
27317         # 1st, RPCs are sent for lookup/open and open handle is released on
27318         #      close finally.
27319         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27320         #      so open handle won't be released thereafter.
27321         # 3rd, No RPC is sent out.
27322         $MULTIOP $testfile oc || error "multiop failed"
27323         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27324         echo "1st: $first_rpc RPCs in flight"
27325
27326         $MULTIOP $testfile oc || error "multiop failed"
27327         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27328         echo "2nd: $second_rpc RPCs in flight"
27329
27330         $MULTIOP $testfile oc || error "multiop failed"
27331         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27332         echo "3rd: $third_rpc RPCs in flight"
27333
27334         #verify no MDC RPC is sent
27335         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27336 }
27337 run_test 429 "verify if opencache flag on client side does work"
27338
27339 lseek_test_430() {
27340         local offset
27341         local file=$1
27342
27343         # data at [200K, 400K)
27344         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27345                 error "256K->512K dd fails"
27346         # data at [2M, 3M)
27347         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27348                 error "2M->3M dd fails"
27349         # data at [4M, 5M)
27350         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27351                 error "4M->5M dd fails"
27352         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27353         # start at first component hole #1
27354         printf "Seeking hole from 1000 ... "
27355         offset=$(lseek_test -l 1000 $file)
27356         echo $offset
27357         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27358         printf "Seeking data from 1000 ... "
27359         offset=$(lseek_test -d 1000 $file)
27360         echo $offset
27361         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27362
27363         # start at first component data block
27364         printf "Seeking hole from 300000 ... "
27365         offset=$(lseek_test -l 300000 $file)
27366         echo $offset
27367         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27368         printf "Seeking data from 300000 ... "
27369         offset=$(lseek_test -d 300000 $file)
27370         echo $offset
27371         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27372
27373         # start at the first component but beyond end of object size
27374         printf "Seeking hole from 1000000 ... "
27375         offset=$(lseek_test -l 1000000 $file)
27376         echo $offset
27377         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27378         printf "Seeking data from 1000000 ... "
27379         offset=$(lseek_test -d 1000000 $file)
27380         echo $offset
27381         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27382
27383         # start at second component stripe 2 (empty file)
27384         printf "Seeking hole from 1500000 ... "
27385         offset=$(lseek_test -l 1500000 $file)
27386         echo $offset
27387         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27388         printf "Seeking data from 1500000 ... "
27389         offset=$(lseek_test -d 1500000 $file)
27390         echo $offset
27391         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27392
27393         # start at second component stripe 1 (all data)
27394         printf "Seeking hole from 3000000 ... "
27395         offset=$(lseek_test -l 3000000 $file)
27396         echo $offset
27397         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27398         printf "Seeking data from 3000000 ... "
27399         offset=$(lseek_test -d 3000000 $file)
27400         echo $offset
27401         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27402
27403         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27404                 error "2nd dd fails"
27405         echo "Add data block at 640K...1280K"
27406
27407         # start at before new data block, in hole
27408         printf "Seeking hole from 600000 ... "
27409         offset=$(lseek_test -l 600000 $file)
27410         echo $offset
27411         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27412         printf "Seeking data from 600000 ... "
27413         offset=$(lseek_test -d 600000 $file)
27414         echo $offset
27415         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27416
27417         # start at the first component new data block
27418         printf "Seeking hole from 1000000 ... "
27419         offset=$(lseek_test -l 1000000 $file)
27420         echo $offset
27421         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27422         printf "Seeking data from 1000000 ... "
27423         offset=$(lseek_test -d 1000000 $file)
27424         echo $offset
27425         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27426
27427         # start at second component stripe 2, new data
27428         printf "Seeking hole from 1200000 ... "
27429         offset=$(lseek_test -l 1200000 $file)
27430         echo $offset
27431         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27432         printf "Seeking data from 1200000 ... "
27433         offset=$(lseek_test -d 1200000 $file)
27434         echo $offset
27435         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27436
27437         # start beyond file end
27438         printf "Using offset > filesize ... "
27439         lseek_test -l 4000000 $file && error "lseek should fail"
27440         printf "Using offset > filesize ... "
27441         lseek_test -d 4000000 $file && error "lseek should fail"
27442
27443         printf "Done\n\n"
27444 }
27445
27446 test_430a() {
27447         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27448                 skip "MDT does not support SEEK_HOLE"
27449
27450         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27451                 skip "OST does not support SEEK_HOLE"
27452
27453         local file=$DIR/$tdir/$tfile
27454
27455         mkdir -p $DIR/$tdir
27456
27457         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27458         # OST stripe #1 will have continuous data at [1M, 3M)
27459         # OST stripe #2 is empty
27460         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27461         lseek_test_430 $file
27462         rm $file
27463         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27464         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27465         lseek_test_430 $file
27466         rm $file
27467         $LFS setstripe -c2 -S 512K $file
27468         echo "Two stripes, stripe size 512K"
27469         lseek_test_430 $file
27470         rm $file
27471         # FLR with stale mirror
27472         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27473                        -N -c2 -S 1M $file
27474         echo "Mirrored file:"
27475         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27476         echo "Plain 2 stripes 1M"
27477         lseek_test_430 $file
27478         rm $file
27479 }
27480 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27481
27482 test_430b() {
27483         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27484                 skip "OST does not support SEEK_HOLE"
27485
27486         local offset
27487         local file=$DIR/$tdir/$tfile
27488
27489         mkdir -p $DIR/$tdir
27490         # Empty layout lseek should fail
27491         $MCREATE $file
27492         # seek from 0
27493         printf "Seeking hole from 0 ... "
27494         lseek_test -l 0 $file && error "lseek should fail"
27495         printf "Seeking data from 0 ... "
27496         lseek_test -d 0 $file && error "lseek should fail"
27497         rm $file
27498
27499         # 1M-hole file
27500         $LFS setstripe -E 1M -c2 -E eof $file
27501         $TRUNCATE $file 1048576
27502         printf "Seeking hole from 1000000 ... "
27503         offset=$(lseek_test -l 1000000 $file)
27504         echo $offset
27505         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27506         printf "Seeking data from 1000000 ... "
27507         lseek_test -d 1000000 $file && error "lseek should fail"
27508         rm $file
27509
27510         # full component followed by non-inited one
27511         $LFS setstripe -E 1M -c2 -E eof $file
27512         dd if=/dev/urandom of=$file bs=1M count=1
27513         printf "Seeking hole from 1000000 ... "
27514         offset=$(lseek_test -l 1000000 $file)
27515         echo $offset
27516         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27517         printf "Seeking hole from 1048576 ... "
27518         lseek_test -l 1048576 $file && error "lseek should fail"
27519         # init second component and truncate back
27520         echo "123" >> $file
27521         $TRUNCATE $file 1048576
27522         printf "Seeking hole from 1000000 ... "
27523         offset=$(lseek_test -l 1000000 $file)
27524         echo $offset
27525         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27526         printf "Seeking hole from 1048576 ... "
27527         lseek_test -l 1048576 $file && error "lseek should fail"
27528         # boundary checks for big values
27529         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27530         offset=$(lseek_test -d 0 $file.10g)
27531         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27532         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27533         offset=$(lseek_test -d 0 $file.100g)
27534         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27535         return 0
27536 }
27537 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27538
27539 test_430c() {
27540         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27541                 skip "OST does not support SEEK_HOLE"
27542
27543         local file=$DIR/$tdir/$tfile
27544         local start
27545
27546         mkdir -p $DIR/$tdir
27547         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27548
27549         # cp version 8.33+ prefers lseek over fiemap
27550         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27551                 start=$SECONDS
27552                 time cp $file /dev/null
27553                 (( SECONDS - start < 5 )) ||
27554                         error "cp: too long runtime $((SECONDS - start))"
27555
27556         fi
27557         # tar version 1.29+ supports SEEK_HOLE/DATA
27558         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27559                 start=$SECONDS
27560                 time tar cS $file - | cat > /dev/null
27561                 (( SECONDS - start < 5 )) ||
27562                         error "tar: too long runtime $((SECONDS - start))"
27563         fi
27564 }
27565 run_test 430c "lseek: external tools check"
27566
27567 test_431() { # LU-14187
27568         local file=$DIR/$tdir/$tfile
27569
27570         mkdir -p $DIR/$tdir
27571         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27572         dd if=/dev/urandom of=$file bs=4k count=1
27573         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27574         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27575         #define OBD_FAIL_OST_RESTART_IO 0x251
27576         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27577         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27578         cp $file $file.0
27579         cancel_lru_locks
27580         sync_all_data
27581         echo 3 > /proc/sys/vm/drop_caches
27582         diff  $file $file.0 || error "data diff"
27583 }
27584 run_test 431 "Restart transaction for IO"
27585
27586 cleanup_test_432() {
27587         do_facet mgs $LCTL nodemap_activate 0
27588         wait_nm_sync active
27589 }
27590
27591 test_432() {
27592         local tmpdir=$TMP/dir432
27593
27594         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27595                 skip "Need MDS version at least 2.14.52"
27596
27597         stack_trap cleanup_test_432 EXIT
27598         mkdir $DIR/$tdir
27599         mkdir $tmpdir
27600
27601         do_facet mgs $LCTL nodemap_activate 1
27602         wait_nm_sync active
27603         do_facet mgs $LCTL nodemap_modify --name default \
27604                 --property admin --value 1
27605         do_facet mgs $LCTL nodemap_modify --name default \
27606                 --property trusted --value 1
27607         cancel_lru_locks mdc
27608         wait_nm_sync default admin_nodemap
27609         wait_nm_sync default trusted_nodemap
27610
27611         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27612                grep -ci "Operation not permitted") -ne 0 ]; then
27613                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27614         fi
27615 }
27616 run_test 432 "mv dir from outside Lustre"
27617
27618 test_433() {
27619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27620
27621         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27622                 skip "inode cache not supported"
27623
27624         $LCTL set_param llite.*.inode_cache=0
27625         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27626
27627         local count=256
27628         local before
27629         local after
27630
27631         cancel_lru_locks mdc
27632         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27633         createmany -m $DIR/$tdir/f $count
27634         createmany -d $DIR/$tdir/d $count
27635         ls -l $DIR/$tdir > /dev/null
27636         stack_trap "rm -rf $DIR/$tdir"
27637
27638         before=$(num_objects)
27639         cancel_lru_locks mdc
27640         after=$(num_objects)
27641
27642         # sometimes even @before is less than 2 * count
27643         while (( before - after < count )); do
27644                 sleep 1
27645                 after=$(num_objects)
27646                 wait=$((wait + 1))
27647                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27648                 if (( wait > 60 )); then
27649                         error "inode slab grew from $before to $after"
27650                 fi
27651         done
27652
27653         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27654 }
27655 run_test 433 "ldlm lock cancel releases dentries and inodes"
27656
27657 test_434() {
27658         local file
27659         local getxattr_count
27660         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27661         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27662
27663         [[ $(getenforce) == "Disabled" ]] ||
27664                 skip "lsm selinux module have to be disabled for this test"
27665
27666         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27667                 error "fail to create $DIR/$tdir/ on MDT0000"
27668
27669         touch $DIR/$tdir/$tfile-{001..100}
27670
27671         # disable the xattr cache
27672         save_lustre_params client "llite.*.xattr_cache" > $p
27673         lctl set_param llite.*.xattr_cache=0
27674         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27675
27676         # clear clients mdc stats
27677         clear_stats $mdc_stat_param ||
27678                 error "fail to clear stats on mdc MDT0000"
27679
27680         for file in $DIR/$tdir/$tfile-{001..100}; do
27681                 getfattr -n security.selinux $file |&
27682                         grep -q "Operation not supported" ||
27683                         error "getxattr on security.selinux should return EOPNOTSUPP"
27684         done
27685
27686         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27687         (( getxattr_count < 100 )) ||
27688                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27689 }
27690 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27691
27692 prep_801() {
27693         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27694         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27695                 skip "Need server version at least 2.9.55"
27696
27697         start_full_debug_logging
27698 }
27699
27700 post_801() {
27701         stop_full_debug_logging
27702 }
27703
27704 barrier_stat() {
27705         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27706                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27707                            awk '/The barrier for/ { print $7 }')
27708                 echo $st
27709         else
27710                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27711                 echo \'$st\'
27712         fi
27713 }
27714
27715 barrier_expired() {
27716         local expired
27717
27718         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27719                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27720                           awk '/will be expired/ { print $7 }')
27721         else
27722                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27723         fi
27724
27725         echo $expired
27726 }
27727
27728 test_801a() {
27729         prep_801
27730
27731         echo "Start barrier_freeze at: $(date)"
27732         #define OBD_FAIL_BARRIER_DELAY          0x2202
27733         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27734         # Do not reduce barrier time - See LU-11873
27735         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27736
27737         sleep 2
27738         local b_status=$(barrier_stat)
27739         echo "Got barrier status at: $(date)"
27740         [ "$b_status" = "'freezing_p1'" ] ||
27741                 error "(1) unexpected barrier status $b_status"
27742
27743         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27744         wait
27745         b_status=$(barrier_stat)
27746         [ "$b_status" = "'frozen'" ] ||
27747                 error "(2) unexpected barrier status $b_status"
27748
27749         local expired=$(barrier_expired)
27750         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27751         sleep $((expired + 3))
27752
27753         b_status=$(barrier_stat)
27754         [ "$b_status" = "'expired'" ] ||
27755                 error "(3) unexpected barrier status $b_status"
27756
27757         # Do not reduce barrier time - See LU-11873
27758         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27759                 error "(4) fail to freeze barrier"
27760
27761         b_status=$(barrier_stat)
27762         [ "$b_status" = "'frozen'" ] ||
27763                 error "(5) unexpected barrier status $b_status"
27764
27765         echo "Start barrier_thaw at: $(date)"
27766         #define OBD_FAIL_BARRIER_DELAY          0x2202
27767         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27768         do_facet mgs $LCTL barrier_thaw $FSNAME &
27769
27770         sleep 2
27771         b_status=$(barrier_stat)
27772         echo "Got barrier status at: $(date)"
27773         [ "$b_status" = "'thawing'" ] ||
27774                 error "(6) unexpected barrier status $b_status"
27775
27776         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27777         wait
27778         b_status=$(barrier_stat)
27779         [ "$b_status" = "'thawed'" ] ||
27780                 error "(7) unexpected barrier status $b_status"
27781
27782         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27783         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27784         do_facet mgs $LCTL barrier_freeze $FSNAME
27785
27786         b_status=$(barrier_stat)
27787         [ "$b_status" = "'failed'" ] ||
27788                 error "(8) unexpected barrier status $b_status"
27789
27790         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27791         do_facet mgs $LCTL barrier_thaw $FSNAME
27792
27793         post_801
27794 }
27795 run_test 801a "write barrier user interfaces and stat machine"
27796
27797 test_801b() {
27798         prep_801
27799
27800         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27801         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27802         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27803         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27804         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27805
27806         cancel_lru_locks mdc
27807
27808         # 180 seconds should be long enough
27809         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27810
27811         local b_status=$(barrier_stat)
27812         [ "$b_status" = "'frozen'" ] ||
27813                 error "(6) unexpected barrier status $b_status"
27814
27815         mkdir $DIR/$tdir/d0/d10 &
27816         mkdir_pid=$!
27817
27818         touch $DIR/$tdir/d1/f13 &
27819         touch_pid=$!
27820
27821         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
27822         ln_pid=$!
27823
27824         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
27825         mv_pid=$!
27826
27827         rm -f $DIR/$tdir/d4/f12 &
27828         rm_pid=$!
27829
27830         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
27831
27832         # To guarantee taht the 'stat' is not blocked
27833         b_status=$(barrier_stat)
27834         [ "$b_status" = "'frozen'" ] ||
27835                 error "(8) unexpected barrier status $b_status"
27836
27837         # let above commands to run at background
27838         sleep 5
27839
27840         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
27841         ps -p $touch_pid || error "(10) touch should be blocked"
27842         ps -p $ln_pid || error "(11) link should be blocked"
27843         ps -p $mv_pid || error "(12) rename should be blocked"
27844         ps -p $rm_pid || error "(13) unlink should be blocked"
27845
27846         b_status=$(barrier_stat)
27847         [ "$b_status" = "'frozen'" ] ||
27848                 error "(14) unexpected barrier status $b_status"
27849
27850         do_facet mgs $LCTL barrier_thaw $FSNAME
27851         b_status=$(barrier_stat)
27852         [ "$b_status" = "'thawed'" ] ||
27853                 error "(15) unexpected barrier status $b_status"
27854
27855         wait $mkdir_pid || error "(16) mkdir should succeed"
27856         wait $touch_pid || error "(17) touch should succeed"
27857         wait $ln_pid || error "(18) link should succeed"
27858         wait $mv_pid || error "(19) rename should succeed"
27859         wait $rm_pid || error "(20) unlink should succeed"
27860
27861         post_801
27862 }
27863 run_test 801b "modification will be blocked by write barrier"
27864
27865 test_801c() {
27866         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27867
27868         prep_801
27869
27870         stop mds2 || error "(1) Fail to stop mds2"
27871
27872         do_facet mgs $LCTL barrier_freeze $FSNAME 30
27873
27874         local b_status=$(barrier_stat)
27875         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
27876                 do_facet mgs $LCTL barrier_thaw $FSNAME
27877                 error "(2) unexpected barrier status $b_status"
27878         }
27879
27880         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27881                 error "(3) Fail to rescan barrier bitmap"
27882
27883         # Do not reduce barrier time - See LU-11873
27884         do_facet mgs $LCTL barrier_freeze $FSNAME 20
27885
27886         b_status=$(barrier_stat)
27887         [ "$b_status" = "'frozen'" ] ||
27888                 error "(4) unexpected barrier status $b_status"
27889
27890         do_facet mgs $LCTL barrier_thaw $FSNAME
27891         b_status=$(barrier_stat)
27892         [ "$b_status" = "'thawed'" ] ||
27893                 error "(5) unexpected barrier status $b_status"
27894
27895         local devname=$(mdsdevname 2)
27896
27897         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
27898
27899         do_facet mgs $LCTL barrier_rescan $FSNAME ||
27900                 error "(7) Fail to rescan barrier bitmap"
27901
27902         post_801
27903 }
27904 run_test 801c "rescan barrier bitmap"
27905
27906 test_802b() {
27907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27908         remote_mds_nodsh && skip "remote MDS with nodsh"
27909
27910         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
27911                 skip "readonly option not available"
27912
27913         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
27914
27915         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
27916                 error "(2) Fail to copy"
27917
27918         # write back all cached data before setting MDT to readonly
27919         cancel_lru_locks
27920         sync_all_data
27921
27922         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
27923         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
27924
27925         echo "Modify should be refused"
27926         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
27927
27928         echo "Read should be allowed"
27929         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
27930                 error "(7) Read should succeed under ro mode"
27931
27932         # disable readonly
27933         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
27934 }
27935 run_test 802b "be able to set MDTs to readonly"
27936
27937 test_803a() {
27938         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27939         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
27940                 skip "MDS needs to be newer than 2.10.54"
27941
27942         mkdir_on_mdt0 $DIR/$tdir
27943         # Create some objects on all MDTs to trigger related logs objects
27944         for idx in $(seq $MDSCOUNT); do
27945                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
27946                         $DIR/$tdir/dir${idx} ||
27947                         error "Fail to create $DIR/$tdir/dir${idx}"
27948         done
27949
27950         wait_delete_completed # ensure old test cleanups are finished
27951         sleep 3
27952         echo "before create:"
27953         $LFS df -i $MOUNT
27954         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27955
27956         for i in {1..10}; do
27957                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
27958                         error "Fail to create $DIR/$tdir/foo$i"
27959         done
27960
27961         # sync ZFS-on-MDS to refresh statfs data
27962         wait_zfs_commit mds1
27963         sleep 3
27964         echo "after create:"
27965         $LFS df -i $MOUNT
27966         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27967
27968         # allow for an llog to be cleaned up during the test
27969         [ $after_used -ge $((before_used + 10 - 1)) ] ||
27970                 error "before ($before_used) + 10 > after ($after_used)"
27971
27972         for i in {1..10}; do
27973                 rm -rf $DIR/$tdir/foo$i ||
27974                         error "Fail to remove $DIR/$tdir/foo$i"
27975         done
27976
27977         # sync ZFS-on-MDS to refresh statfs data
27978         wait_zfs_commit mds1
27979         wait_delete_completed
27980         sleep 3 # avoid MDT return cached statfs
27981         echo "after unlink:"
27982         $LFS df -i $MOUNT
27983         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
27984
27985         # allow for an llog to be created during the test
27986         [ $after_used -le $((before_used + 1)) ] ||
27987                 error "after ($after_used) > before ($before_used) + 1"
27988 }
27989 run_test 803a "verify agent object for remote object"
27990
27991 test_803b() {
27992         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27993         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
27994                 skip "MDS needs to be newer than 2.13.56"
27995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27996
27997         for i in $(seq 0 $((MDSCOUNT - 1))); do
27998                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
27999         done
28000
28001         local before=0
28002         local after=0
28003
28004         local tmp
28005
28006         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28007         for i in $(seq 0 $((MDSCOUNT - 1))); do
28008                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28009                         awk '/getattr/ { print $2 }')
28010                 before=$((before + tmp))
28011         done
28012         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28013         for i in $(seq 0 $((MDSCOUNT - 1))); do
28014                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28015                         awk '/getattr/ { print $2 }')
28016                 after=$((after + tmp))
28017         done
28018
28019         [ $before -eq $after ] || error "getattr count $before != $after"
28020 }
28021 run_test 803b "remote object can getattr from cache"
28022
28023 test_804() {
28024         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28025         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28026                 skip "MDS needs to be newer than 2.10.54"
28027         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28028
28029         mkdir -p $DIR/$tdir
28030         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28031                 error "Fail to create $DIR/$tdir/dir0"
28032
28033         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28034         local dev=$(mdsdevname 2)
28035
28036         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28037                 grep ${fid} || error "NOT found agent entry for dir0"
28038
28039         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28040                 error "Fail to create $DIR/$tdir/dir1"
28041
28042         touch $DIR/$tdir/dir1/foo0 ||
28043                 error "Fail to create $DIR/$tdir/dir1/foo0"
28044         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28045         local rc=0
28046
28047         for idx in $(seq $MDSCOUNT); do
28048                 dev=$(mdsdevname $idx)
28049                 do_facet mds${idx} \
28050                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28051                         grep ${fid} && rc=$idx
28052         done
28053
28054         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28055                 error "Fail to rename foo0 to foo1"
28056         if [ $rc -eq 0 ]; then
28057                 for idx in $(seq $MDSCOUNT); do
28058                         dev=$(mdsdevname $idx)
28059                         do_facet mds${idx} \
28060                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28061                         grep ${fid} && rc=$idx
28062                 done
28063         fi
28064
28065         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28066                 error "Fail to rename foo1 to foo2"
28067         if [ $rc -eq 0 ]; then
28068                 for idx in $(seq $MDSCOUNT); do
28069                         dev=$(mdsdevname $idx)
28070                         do_facet mds${idx} \
28071                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28072                         grep ${fid} && rc=$idx
28073                 done
28074         fi
28075
28076         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28077
28078         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28079                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28080         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28081                 error "Fail to rename foo2 to foo0"
28082         unlink $DIR/$tdir/dir1/foo0 ||
28083                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28084         rm -rf $DIR/$tdir/dir0 ||
28085                 error "Fail to rm $DIR/$tdir/dir0"
28086
28087         for idx in $(seq $MDSCOUNT); do
28088                 rc=0
28089
28090                 stop mds${idx}
28091                 dev=$(mdsdevname $idx)
28092                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28093                         rc=$?
28094                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28095                         error "mount mds$idx failed"
28096                 df $MOUNT > /dev/null 2>&1
28097
28098                 # e2fsck should not return error
28099                 [ $rc -eq 0 ] ||
28100                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28101         done
28102 }
28103 run_test 804 "verify agent entry for remote entry"
28104
28105 cleanup_805() {
28106         do_facet $SINGLEMDS zfs set quota=$old $fsset
28107         unlinkmany $DIR/$tdir/f- 1000000
28108         trap 0
28109 }
28110
28111 test_805() {
28112         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28113         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28114         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28115                 skip "netfree not implemented before 0.7"
28116         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28117                 skip "Need MDS version at least 2.10.57"
28118
28119         local fsset
28120         local freekb
28121         local usedkb
28122         local old
28123         local quota
28124         local pref="osd-zfs.$FSNAME-MDT0000."
28125
28126         # limit available space on MDS dataset to meet nospace issue
28127         # quickly. then ZFS 0.7.2 can use reserved space if asked
28128         # properly (using netfree flag in osd_declare_destroy()
28129         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28130         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28131                 gawk '{print $3}')
28132         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28133         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28134         let "usedkb=usedkb-freekb"
28135         let "freekb=freekb/2"
28136         if let "freekb > 5000"; then
28137                 let "freekb=5000"
28138         fi
28139         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28140         trap cleanup_805 EXIT
28141         mkdir_on_mdt0 $DIR/$tdir
28142         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28143                 error "Can't set PFL layout"
28144         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28145         rm -rf $DIR/$tdir || error "not able to remove"
28146         do_facet $SINGLEMDS zfs set quota=$old $fsset
28147         trap 0
28148 }
28149 run_test 805 "ZFS can remove from full fs"
28150
28151 # Size-on-MDS test
28152 check_lsom_data()
28153 {
28154         local file=$1
28155         local expect=$(stat -c %s $file)
28156
28157         check_lsom_size $1 $expect
28158
28159         local blocks=$($LFS getsom -b $file)
28160         expect=$(stat -c %b $file)
28161         [[ $blocks == $expect ]] ||
28162                 error "$file expected blocks: $expect, got: $blocks"
28163 }
28164
28165 check_lsom_size()
28166 {
28167         local size
28168         local expect=$2
28169
28170         cancel_lru_locks mdc
28171
28172         size=$($LFS getsom -s $1)
28173         [[ $size == $expect ]] ||
28174                 error "$file expected size: $expect, got: $size"
28175 }
28176
28177 test_806() {
28178         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28179                 skip "Need MDS version at least 2.11.52"
28180
28181         local bs=1048576
28182
28183         touch $DIR/$tfile || error "touch $tfile failed"
28184
28185         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28186         save_lustre_params client "llite.*.xattr_cache" > $save
28187         lctl set_param llite.*.xattr_cache=0
28188         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28189
28190         # single-threaded write
28191         echo "Test SOM for single-threaded write"
28192         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28193                 error "write $tfile failed"
28194         check_lsom_size $DIR/$tfile $bs
28195
28196         local num=32
28197         local size=$(($num * $bs))
28198         local offset=0
28199         local i
28200
28201         echo "Test SOM for single client multi-threaded($num) write"
28202         $TRUNCATE $DIR/$tfile 0
28203         for ((i = 0; i < $num; i++)); do
28204                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28205                 local pids[$i]=$!
28206                 offset=$((offset + $bs))
28207         done
28208         for (( i=0; i < $num; i++ )); do
28209                 wait ${pids[$i]}
28210         done
28211         check_lsom_size $DIR/$tfile $size
28212
28213         $TRUNCATE $DIR/$tfile 0
28214         for ((i = 0; i < $num; i++)); do
28215                 offset=$((offset - $bs))
28216                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28217                 local pids[$i]=$!
28218         done
28219         for (( i=0; i < $num; i++ )); do
28220                 wait ${pids[$i]}
28221         done
28222         check_lsom_size $DIR/$tfile $size
28223
28224         # multi-client writes
28225         num=$(get_node_count ${CLIENTS//,/ })
28226         size=$(($num * $bs))
28227         offset=0
28228         i=0
28229
28230         echo "Test SOM for multi-client ($num) writes"
28231         $TRUNCATE $DIR/$tfile 0
28232         for client in ${CLIENTS//,/ }; do
28233                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28234                 local pids[$i]=$!
28235                 i=$((i + 1))
28236                 offset=$((offset + $bs))
28237         done
28238         for (( i=0; i < $num; i++ )); do
28239                 wait ${pids[$i]}
28240         done
28241         check_lsom_size $DIR/$tfile $offset
28242
28243         i=0
28244         $TRUNCATE $DIR/$tfile 0
28245         for client in ${CLIENTS//,/ }; do
28246                 offset=$((offset - $bs))
28247                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28248                 local pids[$i]=$!
28249                 i=$((i + 1))
28250         done
28251         for (( i=0; i < $num; i++ )); do
28252                 wait ${pids[$i]}
28253         done
28254         check_lsom_size $DIR/$tfile $size
28255
28256         # verify truncate
28257         echo "Test SOM for truncate"
28258         $TRUNCATE $DIR/$tfile 1048576
28259         check_lsom_size $DIR/$tfile 1048576
28260         $TRUNCATE $DIR/$tfile 1234
28261         check_lsom_size $DIR/$tfile 1234
28262
28263         # verify SOM blocks count
28264         echo "Verify SOM block count"
28265         $TRUNCATE $DIR/$tfile 0
28266         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28267                 error "failed to write file $tfile"
28268         check_lsom_data $DIR/$tfile
28269 }
28270 run_test 806 "Verify Lazy Size on MDS"
28271
28272 test_807() {
28273         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28274         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28275                 skip "Need MDS version at least 2.11.52"
28276
28277         # Registration step
28278         changelog_register || error "changelog_register failed"
28279         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28280         changelog_users $SINGLEMDS | grep -q $cl_user ||
28281                 error "User $cl_user not found in changelog_users"
28282
28283         rm -rf $DIR/$tdir || error "rm $tdir failed"
28284         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28285         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28286         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28287         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28288                 error "truncate $tdir/trunc failed"
28289
28290         local bs=1048576
28291         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28292                 error "write $tfile failed"
28293
28294         # multi-client wirtes
28295         local num=$(get_node_count ${CLIENTS//,/ })
28296         local offset=0
28297         local i=0
28298
28299         echo "Test SOM for multi-client ($num) writes"
28300         touch $DIR/$tfile || error "touch $tfile failed"
28301         $TRUNCATE $DIR/$tfile 0
28302         for client in ${CLIENTS//,/ }; do
28303                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28304                 local pids[$i]=$!
28305                 i=$((i + 1))
28306                 offset=$((offset + $bs))
28307         done
28308         for (( i=0; i < $num; i++ )); do
28309                 wait ${pids[$i]}
28310         done
28311
28312         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28313         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28314         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28315         check_lsom_data $DIR/$tdir/trunc
28316         check_lsom_data $DIR/$tdir/single_dd
28317         check_lsom_data $DIR/$tfile
28318
28319         rm -rf $DIR/$tdir
28320         # Deregistration step
28321         changelog_deregister || error "changelog_deregister failed"
28322 }
28323 run_test 807 "verify LSOM syncing tool"
28324
28325 check_som_nologged()
28326 {
28327         local lines=$($LFS changelog $FSNAME-MDT0000 |
28328                 grep 'x=trusted.som' | wc -l)
28329         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28330 }
28331
28332 test_808() {
28333         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28334                 skip "Need MDS version at least 2.11.55"
28335
28336         # Registration step
28337         changelog_register || error "changelog_register failed"
28338
28339         touch $DIR/$tfile || error "touch $tfile failed"
28340         check_som_nologged
28341
28342         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28343                 error "write $tfile failed"
28344         check_som_nologged
28345
28346         $TRUNCATE $DIR/$tfile 1234
28347         check_som_nologged
28348
28349         $TRUNCATE $DIR/$tfile 1048576
28350         check_som_nologged
28351
28352         # Deregistration step
28353         changelog_deregister || error "changelog_deregister failed"
28354 }
28355 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28356
28357 check_som_nodata()
28358 {
28359         $LFS getsom $1
28360         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28361 }
28362
28363 test_809() {
28364         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28365                 skip "Need MDS version at least 2.11.56"
28366
28367         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28368                 error "failed to create DoM-only file $DIR/$tfile"
28369         touch $DIR/$tfile || error "touch $tfile failed"
28370         check_som_nodata $DIR/$tfile
28371
28372         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28373                 error "write $tfile failed"
28374         check_som_nodata $DIR/$tfile
28375
28376         $TRUNCATE $DIR/$tfile 1234
28377         check_som_nodata $DIR/$tfile
28378
28379         $TRUNCATE $DIR/$tfile 4097
28380         check_som_nodata $DIR/$file
28381 }
28382 run_test 809 "Verify no SOM xattr store for DoM-only files"
28383
28384 test_810() {
28385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28386         $GSS && skip_env "could not run with gss"
28387         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28388                 skip "OST < 2.12.58 doesn't align checksum"
28389
28390         set_checksums 1
28391         stack_trap "set_checksums $ORIG_CSUM" EXIT
28392         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28393
28394         local csum
28395         local before
28396         local after
28397         for csum in $CKSUM_TYPES; do
28398                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28399                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28400                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28401                         eval set -- $i
28402                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28403                         before=$(md5sum $DIR/$tfile)
28404                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28405                         after=$(md5sum $DIR/$tfile)
28406                         [ "$before" == "$after" ] ||
28407                                 error "$csum: $before != $after bs=$1 seek=$2"
28408                 done
28409         done
28410 }
28411 run_test 810 "partial page writes on ZFS (LU-11663)"
28412
28413 test_812a() {
28414         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28415                 skip "OST < 2.12.51 doesn't support this fail_loc"
28416
28417         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28418         # ensure ost1 is connected
28419         stat $DIR/$tfile >/dev/null || error "can't stat"
28420         wait_osc_import_state client ost1 FULL
28421         # no locks, no reqs to let the connection idle
28422         cancel_lru_locks osc
28423
28424         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28425 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28426         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28427         wait_osc_import_state client ost1 CONNECTING
28428         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28429
28430         stat $DIR/$tfile >/dev/null || error "can't stat file"
28431 }
28432 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28433
28434 test_812b() { # LU-12378
28435         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28436                 skip "OST < 2.12.51 doesn't support this fail_loc"
28437
28438         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28439         # ensure ost1 is connected
28440         stat $DIR/$tfile >/dev/null || error "can't stat"
28441         wait_osc_import_state client ost1 FULL
28442         # no locks, no reqs to let the connection idle
28443         cancel_lru_locks osc
28444
28445         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28446 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28447         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28448         wait_osc_import_state client ost1 CONNECTING
28449         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28450
28451         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28452         wait_osc_import_state client ost1 IDLE
28453 }
28454 run_test 812b "do not drop no resend request for idle connect"
28455
28456 test_812c() {
28457         local old
28458
28459         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28460
28461         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28462         $LFS getstripe $DIR/$tfile
28463         $LCTL set_param osc.*.idle_timeout=10
28464         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28465         # ensure ost1 is connected
28466         stat $DIR/$tfile >/dev/null || error "can't stat"
28467         wait_osc_import_state client ost1 FULL
28468         # no locks, no reqs to let the connection idle
28469         cancel_lru_locks osc
28470
28471 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28472         $LCTL set_param fail_loc=0x80000533
28473         sleep 15
28474         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28475 }
28476 run_test 812c "idle import vs lock enqueue race"
28477
28478 test_813() {
28479         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28480         [ -z "$file_heat_sav" ] && skip "no file heat support"
28481
28482         local readsample
28483         local writesample
28484         local readbyte
28485         local writebyte
28486         local readsample1
28487         local writesample1
28488         local readbyte1
28489         local writebyte1
28490
28491         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28492         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28493
28494         $LCTL set_param -n llite.*.file_heat=1
28495         echo "Turn on file heat"
28496         echo "Period second: $period_second, Decay percentage: $decay_pct"
28497
28498         echo "QQQQ" > $DIR/$tfile
28499         echo "QQQQ" > $DIR/$tfile
28500         echo "QQQQ" > $DIR/$tfile
28501         cat $DIR/$tfile > /dev/null
28502         cat $DIR/$tfile > /dev/null
28503         cat $DIR/$tfile > /dev/null
28504         cat $DIR/$tfile > /dev/null
28505
28506         local out=$($LFS heat_get $DIR/$tfile)
28507
28508         $LFS heat_get $DIR/$tfile
28509         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28510         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28511         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28512         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28513
28514         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28515         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28516         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28517         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28518
28519         sleep $((period_second + 3))
28520         echo "Sleep $((period_second + 3)) seconds..."
28521         # The recursion formula to calculate the heat of the file f is as
28522         # follow:
28523         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28524         # Where Hi is the heat value in the period between time points i*I and
28525         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28526         # to the weight of Ci.
28527         out=$($LFS heat_get $DIR/$tfile)
28528         $LFS heat_get $DIR/$tfile
28529         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28530         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28531         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28532         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28533
28534         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28535                 error "read sample ($readsample) is wrong"
28536         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28537                 error "write sample ($writesample) is wrong"
28538         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28539                 error "read bytes ($readbyte) is wrong"
28540         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28541                 error "write bytes ($writebyte) is wrong"
28542
28543         echo "QQQQ" > $DIR/$tfile
28544         echo "QQQQ" > $DIR/$tfile
28545         echo "QQQQ" > $DIR/$tfile
28546         cat $DIR/$tfile > /dev/null
28547         cat $DIR/$tfile > /dev/null
28548         cat $DIR/$tfile > /dev/null
28549         cat $DIR/$tfile > /dev/null
28550
28551         sleep $((period_second + 3))
28552         echo "Sleep $((period_second + 3)) seconds..."
28553
28554         out=$($LFS heat_get $DIR/$tfile)
28555         $LFS heat_get $DIR/$tfile
28556         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28557         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28558         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28559         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28560
28561         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28562                 4 * $decay_pct) / 100") -eq 1 ] ||
28563                 error "read sample ($readsample1) is wrong"
28564         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28565                 3 * $decay_pct) / 100") -eq 1 ] ||
28566                 error "write sample ($writesample1) is wrong"
28567         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28568                 20 * $decay_pct) / 100") -eq 1 ] ||
28569                 error "read bytes ($readbyte1) is wrong"
28570         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28571                 15 * $decay_pct) / 100") -eq 1 ] ||
28572                 error "write bytes ($writebyte1) is wrong"
28573
28574         echo "Turn off file heat for the file $DIR/$tfile"
28575         $LFS heat_set -o $DIR/$tfile
28576
28577         echo "QQQQ" > $DIR/$tfile
28578         echo "QQQQ" > $DIR/$tfile
28579         echo "QQQQ" > $DIR/$tfile
28580         cat $DIR/$tfile > /dev/null
28581         cat $DIR/$tfile > /dev/null
28582         cat $DIR/$tfile > /dev/null
28583         cat $DIR/$tfile > /dev/null
28584
28585         out=$($LFS heat_get $DIR/$tfile)
28586         $LFS heat_get $DIR/$tfile
28587         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28588         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28589         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28590         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28591
28592         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28593         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28594         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28595         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28596
28597         echo "Trun on file heat for the file $DIR/$tfile"
28598         $LFS heat_set -O $DIR/$tfile
28599
28600         echo "QQQQ" > $DIR/$tfile
28601         echo "QQQQ" > $DIR/$tfile
28602         echo "QQQQ" > $DIR/$tfile
28603         cat $DIR/$tfile > /dev/null
28604         cat $DIR/$tfile > /dev/null
28605         cat $DIR/$tfile > /dev/null
28606         cat $DIR/$tfile > /dev/null
28607
28608         out=$($LFS heat_get $DIR/$tfile)
28609         $LFS heat_get $DIR/$tfile
28610         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28611         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28612         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28613         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28614
28615         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28616         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28617         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28618         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28619
28620         $LFS heat_set -c $DIR/$tfile
28621         $LCTL set_param -n llite.*.file_heat=0
28622         echo "Turn off file heat support for the Lustre filesystem"
28623
28624         echo "QQQQ" > $DIR/$tfile
28625         echo "QQQQ" > $DIR/$tfile
28626         echo "QQQQ" > $DIR/$tfile
28627         cat $DIR/$tfile > /dev/null
28628         cat $DIR/$tfile > /dev/null
28629         cat $DIR/$tfile > /dev/null
28630         cat $DIR/$tfile > /dev/null
28631
28632         out=$($LFS heat_get $DIR/$tfile)
28633         $LFS heat_get $DIR/$tfile
28634         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28635         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28636         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28637         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28638
28639         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28640         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28641         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28642         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28643
28644         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28645         rm -f $DIR/$tfile
28646 }
28647 run_test 813 "File heat verfication"
28648
28649 test_814()
28650 {
28651         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28652         echo -n y >> $DIR/$tfile
28653         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28654         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28655 }
28656 run_test 814 "sparse cp works as expected (LU-12361)"
28657
28658 test_815()
28659 {
28660         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28661         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28662 }
28663 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28664
28665 test_816() {
28666         local ost1_imp=$(get_osc_import_name client ost1)
28667         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28668                          cut -d'.' -f2)
28669
28670         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28671         # ensure ost1 is connected
28672
28673         stat $DIR/$tfile >/dev/null || error "can't stat"
28674         wait_osc_import_state client ost1 FULL
28675         # no locks, no reqs to let the connection idle
28676         cancel_lru_locks osc
28677         lru_resize_disable osc
28678         local before
28679         local now
28680         before=$($LCTL get_param -n \
28681                  ldlm.namespaces.$imp_name.lru_size)
28682
28683         wait_osc_import_state client ost1 IDLE
28684         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28685         now=$($LCTL get_param -n \
28686               ldlm.namespaces.$imp_name.lru_size)
28687         [ $before == $now ] || error "lru_size changed $before != $now"
28688 }
28689 run_test 816 "do not reset lru_resize on idle reconnect"
28690
28691 cleanup_817() {
28692         umount $tmpdir
28693         exportfs -u localhost:$DIR/nfsexp
28694         rm -rf $DIR/nfsexp
28695 }
28696
28697 test_817() {
28698         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28699
28700         mkdir -p $DIR/nfsexp
28701         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28702                 error "failed to export nfs"
28703
28704         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28705         stack_trap cleanup_817 EXIT
28706
28707         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28708                 error "failed to mount nfs to $tmpdir"
28709
28710         cp /bin/true $tmpdir
28711         $DIR/nfsexp/true || error "failed to execute 'true' command"
28712 }
28713 run_test 817 "nfsd won't cache write lock for exec file"
28714
28715 test_818() {
28716         test_mkdir -i0 -c1 $DIR/$tdir
28717         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28718         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28719         stop $SINGLEMDS
28720
28721         # restore osp-syn threads
28722         stack_trap "fail $SINGLEMDS"
28723
28724         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28725         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28726         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28727                 error "start $SINGLEMDS failed"
28728         rm -rf $DIR/$tdir
28729
28730         local testid=$(echo $TESTNAME | tr '_' ' ')
28731
28732         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28733                 grep "run LFSCK" || error "run LFSCK is not suggested"
28734 }
28735 run_test 818 "unlink with failed llog"
28736
28737 test_819a() {
28738         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28739         cancel_lru_locks osc
28740         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28741         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28742         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28743         rm -f $TDIR/$tfile
28744 }
28745 run_test 819a "too big niobuf in read"
28746
28747 test_819b() {
28748         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28749         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28750         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28751         cancel_lru_locks osc
28752         sleep 1
28753         rm -f $TDIR/$tfile
28754 }
28755 run_test 819b "too big niobuf in write"
28756
28757
28758 function test_820_start_ost() {
28759         sleep 5
28760
28761         for num in $(seq $OSTCOUNT); do
28762                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28763         done
28764 }
28765
28766 test_820() {
28767         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28768
28769         mkdir $DIR/$tdir
28770         umount_client $MOUNT || error "umount failed"
28771         for num in $(seq $OSTCOUNT); do
28772                 stop ost$num
28773         done
28774
28775         # mount client with no active OSTs
28776         # so that the client can't initialize max LOV EA size
28777         # from OSC notifications
28778         mount_client $MOUNT || error "mount failed"
28779         # delay OST starting to keep this 0 max EA size for a while
28780         test_820_start_ost &
28781
28782         # create a directory on MDS2
28783         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28784                 error "Failed to create directory"
28785         # open intent should update default EA size
28786         # see mdc_update_max_ea_from_body()
28787         # notice this is the very first RPC to MDS2
28788         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28789         ret=$?
28790         echo $out
28791         # With SSK, this situation can lead to -EPERM being returned.
28792         # In that case, simply retry.
28793         if [ $ret -ne 0 ] && $SHARED_KEY; then
28794                 if echo "$out" | grep -q "not permitted"; then
28795                         cp /etc/services $DIR/$tdir/mds2
28796                         ret=$?
28797                 fi
28798         fi
28799         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28800 }
28801 run_test 820 "update max EA from open intent"
28802
28803 test_823() {
28804         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28805         local OST_MAX_PRECREATE=20000
28806
28807         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28808                 skip "Need MDS version at least 2.14.56"
28809
28810         save_lustre_params mds1 \
28811                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
28812         do_facet $SINGLEMDS "$LCTL set_param -n \
28813                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
28814         do_facet $SINGLEMDS "$LCTL set_param -n \
28815                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
28816
28817         stack_trap "restore_lustre_params < $p; rm $p"
28818
28819         do_facet $SINGLEMDS "$LCTL set_param -n \
28820                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
28821
28822         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28823                       osp.$FSNAME-OST0000*MDT0000.create_count")
28824         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
28825                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
28826         local expect_count=$(((($max/2)/256) * 256))
28827
28828         log "setting create_count to 100200:"
28829         log " -result- count: $count with max: $max, expecting: $expect_count"
28830
28831         [[ $count -eq expect_count ]] ||
28832                 error "Create count not set to max precreate."
28833 }
28834 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
28835
28836 test_831() {
28837         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
28838                 skip "Need MDS version 2.14.56"
28839
28840         local sync_changes=$(do_facet $SINGLEMDS \
28841                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28842
28843         [ "$sync_changes" -gt 100 ] &&
28844                 skip "Sync changes $sync_changes > 100 already"
28845
28846         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28847
28848         $LFS mkdir -i 0 $DIR/$tdir
28849         $LFS setstripe -c 1 -i 0 $DIR/$tdir
28850
28851         save_lustre_params mds1 \
28852                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
28853         save_lustre_params mds1 \
28854                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
28855
28856         do_facet mds1 "$LCTL set_param -n \
28857                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
28858                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
28859         stack_trap "restore_lustre_params < $p" EXIT
28860
28861         createmany -o $DIR/$tdir/f- 1000
28862         unlinkmany $DIR/$tdir/f- 1000 &
28863         local UNLINK_PID=$!
28864
28865         while sleep 1; do
28866                 sync_changes=$(do_facet mds1 \
28867                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
28868                 # the check in the code is racy, fail the test
28869                 # if the value above the limit by 10.
28870                 [ $sync_changes -gt 110 ] && {
28871                         kill -2 $UNLINK_PID
28872                         wait
28873                         error "osp changes throttling failed, $sync_changes>110"
28874                 }
28875                 kill -0 $UNLINK_PID 2> /dev/null || break
28876         done
28877         wait
28878 }
28879 run_test 831 "throttling unlink/setattr queuing on OSP"
28880
28881 test_832() {
28882         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
28883         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
28884                 skip "Need MDS version 2.15.52+"
28885         is_rmentry_supported || skip "rm_entry not supported"
28886
28887         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28888         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
28889         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
28890                 error "mkdir remote_dir failed"
28891         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
28892                 error "mkdir striped_dir failed"
28893         touch $DIR/$tdir/file || error "touch file failed"
28894         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
28895         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
28896 }
28897 run_test 832 "lfs rm_entry"
28898
28899 #
28900 # tests that do cleanup/setup should be run at the end
28901 #
28902
28903 test_900() {
28904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28905         local ls
28906
28907         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
28908         $LCTL set_param fail_loc=0x903
28909
28910         cancel_lru_locks MGC
28911
28912         FAIL_ON_ERROR=true cleanup
28913         FAIL_ON_ERROR=true setup
28914 }
28915 run_test 900 "umount should not race with any mgc requeue thread"
28916
28917 # LUS-6253/LU-11185
28918 test_901() {
28919         local old
28920         local count
28921         local oldc
28922         local newc
28923         local olds
28924         local news
28925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28926
28927         # some get_param have a bug to handle dot in param name
28928         cancel_lru_locks MGC
28929         old=$(mount -t lustre | wc -l)
28930         # 1 config+sptlrpc
28931         # 2 params
28932         # 3 nodemap
28933         # 4 IR
28934         old=$((old * 4))
28935         oldc=0
28936         count=0
28937         while [ $old -ne $oldc ]; do
28938                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28939                 sleep 1
28940                 ((count++))
28941                 if [ $count -ge $TIMEOUT ]; then
28942                         error "too large timeout"
28943                 fi
28944         done
28945         umount_client $MOUNT || error "umount failed"
28946         mount_client $MOUNT || error "mount failed"
28947         cancel_lru_locks MGC
28948         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
28949
28950         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
28951
28952         return 0
28953 }
28954 run_test 901 "don't leak a mgc lock on client umount"
28955
28956 # LU-13377
28957 test_902() {
28958         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
28959                 skip "client does not have LU-13377 fix"
28960         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
28961         $LCTL set_param fail_loc=0x1415
28962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28963         cancel_lru_locks osc
28964         rm -f $DIR/$tfile
28965 }
28966 run_test 902 "test short write doesn't hang lustre"
28967
28968 # LU-14711
28969 test_903() {
28970         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
28971         echo "blah" > $DIR/${tfile}-2
28972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
28973         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
28974         $LCTL set_param fail_loc=0x417 fail_val=20
28975
28976         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
28977         sleep 1 # To start the destroy
28978         wait_destroy_complete 150 || error "Destroy taking too long"
28979         cat $DIR/$tfile > /dev/null || error "Evicted"
28980 }
28981 run_test 903 "Test long page discard does not cause evictions"
28982
28983 test_904() {
28984         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
28985         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
28986                 grep -q project || skip "skip project quota not supported"
28987
28988         local testfile="$DIR/$tdir/$tfile"
28989         local xattr="trusted.projid"
28990         local projid
28991         local mdts=$(comma_list $(mdts_nodes))
28992         local saved=$(do_facet mds1 $LCTL get_param -n \
28993                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
28994
28995         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
28996         stack_trap "do_nodes $mdts $LCTL set_param \
28997                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
28998
28999         mkdir -p $DIR/$tdir
29000         touch $testfile
29001         #hide projid xattr on server
29002         $LFS project -p 1 $testfile ||
29003                 error "set $testfile project id failed"
29004         getfattr -m - $testfile | grep $xattr &&
29005                 error "do not show trusted.projid when disabled on server"
29006         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29007         #should be hidden when projid is 0
29008         $LFS project -p 0 $testfile ||
29009                 error "set $testfile project id failed"
29010         getfattr -m - $testfile | grep $xattr &&
29011                 error "do not show trusted.projid with project ID 0"
29012
29013         #still can getxattr explicitly
29014         projid=$(getfattr -n $xattr $testfile |
29015                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29016         [ $projid == "0" ] ||
29017                 error "projid expected 0 not $projid"
29018
29019         #set the projid via setxattr
29020         setfattr -n $xattr -v "1000" $testfile ||
29021                 error "setattr failed with $?"
29022         projid=($($LFS project $testfile))
29023         [ ${projid[0]} == "1000" ] ||
29024                 error "projid expected 1000 not $projid"
29025
29026         #check the new projid via getxattr
29027         $LFS project -p 1001 $testfile ||
29028                 error "set $testfile project id failed"
29029         getfattr -m - $testfile | grep $xattr ||
29030                 error "should show trusted.projid when project ID != 0"
29031         projid=$(getfattr -n $xattr $testfile |
29032                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29033         [ $projid == "1001" ] ||
29034                 error "projid expected 1001 not $projid"
29035
29036         #try to set invalid projid
29037         setfattr -n $xattr -v "4294967295" $testfile &&
29038                 error "set invalid projid should fail"
29039
29040         #remove the xattr means setting projid to 0
29041         setfattr -x $xattr $testfile ||
29042                 error "setfattr failed with $?"
29043         projid=($($LFS project $testfile))
29044         [ ${projid[0]} == "0" ] ||
29045                 error "projid expected 0 not $projid"
29046
29047         #should be hidden when parent has inherit flag and same projid
29048         $LFS project -srp 1002 $DIR/$tdir ||
29049                 error "set $tdir project id failed"
29050         getfattr -m - $testfile | grep $xattr &&
29051                 error "do not show trusted.projid with inherit flag"
29052
29053         #still can getxattr explicitly
29054         projid=$(getfattr -n $xattr $testfile |
29055                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29056         [ $projid == "1002" ] ||
29057                 error "projid expected 1002 not $projid"
29058 }
29059 run_test 904 "virtual project ID xattr"
29060
29061 # LU-8582
29062 test_905() {
29063         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29064                 skip "lustre < 2.8.54 does not support ladvise"
29065
29066         remote_ost_nodsh && skip "remote OST with nodsh"
29067         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29068
29069         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29070
29071         #define OBD_FAIL_OST_OPCODE 0x253
29072         # OST_LADVISE = 21
29073         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29074         $LFS ladvise -a willread $DIR/$tfile &&
29075                 error "unexpected success of ladvise with fault injection"
29076         $LFS ladvise -a willread $DIR/$tfile |&
29077                 grep -q "Operation not supported"
29078         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29079 }
29080 run_test 905 "bad or new opcode should not stuck client"
29081
29082 test_906() {
29083         grep -q io_uring_setup /proc/kallsyms ||
29084                 skip "Client OS does not support io_uring I/O engine"
29085         io_uring_probe || skip "kernel does not support io_uring fully"
29086         which fio || skip_env "no fio installed"
29087         fio --enghelp | grep -q io_uring ||
29088                 skip_env "fio does not support io_uring I/O engine"
29089
29090         local file=$DIR/$tfile
29091         local ioengine="io_uring"
29092         local numjobs=2
29093         local size=50M
29094
29095         fio --name=seqwrite --ioengine=$ioengine        \
29096                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29097                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29098                 error "fio seqwrite $file failed"
29099
29100         fio --name=seqread --ioengine=$ioengine \
29101                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29102                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29103                 error "fio seqread $file failed"
29104
29105         rm -f $file || error "rm -f $file failed"
29106 }
29107 run_test 906 "Simple test for io_uring I/O engine via fio"
29108
29109 complete $SECONDS
29110 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29111 check_and_cleanup_lustre
29112 if [ "$I_MOUNTED" != "yes" ]; then
29113         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29114 fi
29115 exit_status