Whamcloud - gitweb
LU-17005 obdclass: allow stats header to be disabled
[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-16515 118c 118d
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         always_except LU-9054 312
76 fi
77
78 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
79
80 # Get the SLES distro version
81 #
82 # Returns a version string that should only be used in comparing
83 # strings returned by version_code()
84 sles_version_code()
85 {
86         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
87
88         # All SuSE Linux versions have one decimal. version_code expects two
89         local sles_version=$version.0
90         version_code $sles_version
91 }
92
93 # Check if we are running on Ubuntu or SLES so we can make decisions on
94 # what tests to run
95 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
96         sles_version=$(sles_version_code)
97         [ $sles_version -lt $(version_code 11.4.0) ] &&
98                 always_except LU-4341 170
99
100         [ $sles_version -lt $(version_code 12.0.0) ] &&
101                 always_except LU-3703 234
102 elif [ -r /etc/os-release ]; then
103         if grep -qi ubuntu /etc/os-release; then
104                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
105                                                 -e 's/^VERSION=//p' \
106                                                 /etc/os-release |
107                                                 awk '{ print $1 }'))
108
109                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
110                         always_except LU-10366 410
111                 fi
112         fi
113 fi
114
115 build_test_filter
116 FAIL_ON_ERROR=false
117
118 cleanup() {
119         echo -n "cln.."
120         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
121         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
122 }
123 setup() {
124         echo -n "mnt.."
125         load_modules
126         setupall || exit 10
127         echo "done"
128 }
129
130 check_swap_layouts_support()
131 {
132         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
133                 skip "Does not support layout lock."
134 }
135
136 check_swap_layout_no_dom()
137 {
138         local FOLDER=$1
139         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
140         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
141 }
142
143 check_and_setup_lustre
144 DIR=${DIR:-$MOUNT}
145 assert_DIR
146
147 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
148
149 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
150 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
151 rm -rf $DIR/[Rdfs][0-9]*
152
153 # $RUNAS_ID may get set incorrectly somewhere else
154 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
155         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
156
157 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
158
159 if [ "${ONLY}" = "MOUNT" ] ; then
160         echo "Lustre is up, please go on"
161         exit
162 fi
163
164 echo "preparing for tests involving mounts"
165 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
166 touch $EXT2_DEV
167 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
168 echo # add a newline after mke2fs.
169
170 umask 077
171
172 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
173
174 # ensure all internal functions know we want full debug
175 export PTLDEBUG=all
176 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
177
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare client versions.  Only compare top-3 fields for compatibility
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
233         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "exp version '$exp_client_version'($exp_val) != " \
236                         "'$(lustre_build_version client)'($imp_val)"
237 }
238 run_test 0d "check export proc ============================="
239
240 test_0e() { # LU-13417
241         (( $MDSCOUNT > 1 )) ||
242                 skip "We need at least 2 MDTs for this test"
243
244         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
245                 skip "Need server version at least 2.14.51"
246
247         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
248         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
249
250         [ $default_lmv_count -eq 1 ] ||
251                 error "$MOUNT default stripe count $default_lmv_count"
252
253         [ $default_lmv_index -eq -1 ] ||
254                 error "$MOUNT default stripe index $default_lmv_index"
255
256         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
257         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
258
259         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
260         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
261
262         [ $mdt_index1 -eq $mdt_index2 ] &&
263                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
264
265         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
266 }
267 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
268
269 test_1() {
270         test_mkdir $DIR/$tdir
271         test_mkdir $DIR/$tdir/d2
272         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
273         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
274         rmdir $DIR/$tdir/d2
275         rmdir $DIR/$tdir
276         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
277 }
278 run_test 1 "mkdir; remkdir; rmdir"
279
280 test_2() {
281         test_mkdir $DIR/$tdir
282         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
283         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
284         rm -r $DIR/$tdir
285         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
286 }
287 run_test 2 "mkdir; touch; rmdir; check file"
288
289 test_3() {
290         test_mkdir $DIR/$tdir
291         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
292         touch $DIR/$tdir/$tfile
293         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
294         rm -r $DIR/$tdir
295         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
296 }
297 run_test 3 "mkdir; touch; rmdir; check dir"
298
299 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
300 test_4() {
301         test_mkdir -i 1 $DIR/$tdir
302
303         touch $DIR/$tdir/$tfile ||
304                 error "Create file under remote directory failed"
305
306         rmdir $DIR/$tdir &&
307                 error "Expect error removing in-use dir $DIR/$tdir"
308
309         test -d $DIR/$tdir || error "Remote directory disappeared"
310
311         rm -rf $DIR/$tdir || error "remove remote dir error"
312 }
313 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
314
315 test_5() {
316         test_mkdir $DIR/$tdir
317         test_mkdir $DIR/$tdir/d2
318         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
319         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
320         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
321 }
322 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
323
324 test_6a() {
325         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
326         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
327         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
328                 error "$tfile does not have perm 0666 or UID $UID"
329         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
330         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
331                 error "$tfile should be 0666 and owned by UID $UID"
332 }
333 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
334
335 test_6c() {
336         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
337
338         touch $DIR/$tfile
339         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
340         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
341                 error "$tfile should be owned by UID $RUNAS_ID"
342         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
343         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
344                 error "$tfile should be owned by UID $RUNAS_ID"
345 }
346 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
347
348 test_6e() {
349         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
350
351         touch $DIR/$tfile
352         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
353         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
354                 error "$tfile should be owned by GID $UID"
355         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
356         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
358 }
359 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
360
361 test_6g() {
362         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
363
364         test_mkdir $DIR/$tdir
365         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
366         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
367         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
368         test_mkdir $DIR/$tdir/d/subdir
369         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
370                 error "$tdir/d/subdir should be GID $RUNAS_GID"
371         if [[ $MDSCOUNT -gt 1 ]]; then
372                 # check remote dir sgid inherite
373                 $LFS mkdir -i 0 $DIR/$tdir.local ||
374                         error "mkdir $tdir.local failed"
375                 chmod g+s $DIR/$tdir.local ||
376                         error "chmod $tdir.local failed"
377                 chgrp $RUNAS_GID $DIR/$tdir.local ||
378                         error "chgrp $tdir.local failed"
379                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
380                         error "mkdir $tdir.remote failed"
381                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
382                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
383                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be mode 02755"
385         fi
386 }
387 run_test 6g "verify new dir in sgid dir inherits group"
388
389 test_6h() { # bug 7331
390         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
391
392         touch $DIR/$tfile || error "touch failed"
393         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
394         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
395                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
396         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
397                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
398 }
399 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
400
401 test_7a() {
402         test_mkdir $DIR/$tdir
403         $MCREATE $DIR/$tdir/$tfile
404         chmod 0666 $DIR/$tdir/$tfile
405         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
406                 error "$tdir/$tfile should be mode 0666"
407 }
408 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
409
410 test_7b() {
411         if [ ! -d $DIR/$tdir ]; then
412                 test_mkdir $DIR/$tdir
413         fi
414         $MCREATE $DIR/$tdir/$tfile
415         echo -n foo > $DIR/$tdir/$tfile
416         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
417         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
418 }
419 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
420
421 test_8() {
422         test_mkdir $DIR/$tdir
423         touch $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tfile mode not 0666"
427 }
428 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
429
430 test_9() {
431         test_mkdir $DIR/$tdir
432         test_mkdir $DIR/$tdir/d2
433         test_mkdir $DIR/$tdir/d2/d3
434         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
435 }
436 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
437
438 test_10() {
439         test_mkdir $DIR/$tdir
440         test_mkdir $DIR/$tdir/d2
441         touch $DIR/$tdir/d2/$tfile
442         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
443                 error "$tdir/d2/$tfile not a file"
444 }
445 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
446
447 test_11() {
448         test_mkdir $DIR/$tdir
449         test_mkdir $DIR/$tdir/d2
450         chmod 0666 $DIR/$tdir/d2
451         chmod 0705 $DIR/$tdir/d2
452         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
453                 error "$tdir/d2 mode not 0705"
454 }
455 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
456
457 test_12() {
458         test_mkdir $DIR/$tdir
459         touch $DIR/$tdir/$tfile
460         chmod 0666 $DIR/$tdir/$tfile
461         chmod 0654 $DIR/$tdir/$tfile
462         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
463                 error "$tdir/d2 mode not 0654"
464 }
465 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
466
467 test_13() {
468         test_mkdir $DIR/$tdir
469         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
470         >  $DIR/$tdir/$tfile
471         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
472                 error "$tdir/$tfile size not 0 after truncate"
473 }
474 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
475
476 test_14() {
477         test_mkdir $DIR/$tdir
478         touch $DIR/$tdir/$tfile
479         rm $DIR/$tdir/$tfile
480         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
481 }
482 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
483
484 test_15() {
485         test_mkdir $DIR/$tdir
486         touch $DIR/$tdir/$tfile
487         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
488         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
489                 error "$tdir/${tfile_2} not a file after rename"
490         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
491 }
492 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
493
494 test_16() {
495         test_mkdir $DIR/$tdir
496         touch $DIR/$tdir/$tfile
497         rm -rf $DIR/$tdir/$tfile
498         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
499 }
500 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
501
502 test_17a() {
503         test_mkdir $DIR/$tdir
504         touch $DIR/$tdir/$tfile
505         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
506         ls -l $DIR/$tdir
507         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
508                 error "$tdir/l-exist not a symlink"
509         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not referencing a file"
511         rm -f $DIR/$tdir/l-exist
512         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
513 }
514 run_test 17a "symlinks: create, remove (real)"
515
516 test_17b() {
517         test_mkdir $DIR/$tdir
518         ln -s no-such-file $DIR/$tdir/l-dangle
519         ls -l $DIR/$tdir
520         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
521                 error "$tdir/l-dangle not referencing no-such-file"
522         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing non-existent file"
524         rm -f $DIR/$tdir/l-dangle
525         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
526 }
527 run_test 17b "symlinks: create, remove (dangling)"
528
529 test_17c() { # bug 3440 - don't save failed open RPC for replay
530         test_mkdir $DIR/$tdir
531         ln -s foo $DIR/$tdir/$tfile
532         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
533 }
534 run_test 17c "symlinks: open dangling (should return error)"
535
536 test_17d() {
537         test_mkdir $DIR/$tdir
538         ln -s foo $DIR/$tdir/$tfile
539         touch $DIR/$tdir/$tfile || error "creating to new symlink"
540 }
541 run_test 17d "symlinks: create dangling"
542
543 test_17e() {
544         test_mkdir $DIR/$tdir
545         local foo=$DIR/$tdir/$tfile
546         ln -s $foo $foo || error "create symlink failed"
547         ls -l $foo || error "ls -l failed"
548         ls $foo && error "ls not failed" || true
549 }
550 run_test 17e "symlinks: create recursive symlink (should return error)"
551
552 test_17f() {
553         test_mkdir $DIR/$tdir
554         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
556         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
559         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
560         ls -l  $DIR/$tdir
561 }
562 run_test 17f "symlinks: long and very long symlink name"
563
564 # str_repeat(S, N) generate a string that is string S repeated N times
565 str_repeat() {
566         local s=$1
567         local n=$2
568         local ret=''
569         while [ $((n -= 1)) -ge 0 ]; do
570                 ret=$ret$s
571         done
572         echo $ret
573 }
574
575 # Long symlinks and LU-2241
576 test_17g() {
577         test_mkdir $DIR/$tdir
578         local TESTS="59 60 61 4094 4095"
579
580         # Fix for inode size boundary in 2.1.4
581         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
582                 TESTS="4094 4095"
583
584         # Patch not applied to 2.2 or 2.3 branches
585         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
586         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
587                 TESTS="4094 4095"
588
589         for i in $TESTS; do
590                 local SYMNAME=$(str_repeat 'x' $i)
591                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
592                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
593         done
594 }
595 run_test 17g "symlinks: really long symlink name and inode boundaries"
596
597 test_17h() { #bug 17378
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local mdt_idx
602
603         test_mkdir $DIR/$tdir
604         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
605         $LFS setstripe -c -1 $DIR/$tdir
606         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
607         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
608         touch $DIR/$tdir/$tfile || true
609 }
610 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
611
612 test_17i() { #bug 20018
613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
614         remote_mds_nodsh && skip "remote MDS with nodsh"
615
616         local foo=$DIR/$tdir/$tfile
617         local mdt_idx
618
619         test_mkdir -c1 $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         ln -s $foo $foo || error "create symlink failed"
622 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
624         ls -l $foo && error "error not detected"
625         return 0
626 }
627 run_test 17i "don't panic on short symlink (should return error)"
628
629 test_17k() { #bug 22301
630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
631         [[ -z "$(which rsync 2>/dev/null)" ]] &&
632                 skip "no rsync command"
633         rsync --help | grep -q xattr ||
634                 skip_env "$(rsync --version | head -n1) does not support xattrs"
635         test_mkdir $DIR/$tdir
636         test_mkdir $DIR/$tdir.new
637         touch $DIR/$tdir/$tfile
638         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
639         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
640                 error "rsync failed with xattrs enabled"
641 }
642 run_test 17k "symlinks: rsync with xattrs enabled"
643
644 test_17l() { # LU-279
645         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
646                 skip "no getfattr command"
647
648         test_mkdir $DIR/$tdir
649         touch $DIR/$tdir/$tfile
650         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
651         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
652                 # -h to not follow symlinks. -m '' to list all the xattrs.
653                 # grep to remove first line: '# file: $path'.
654                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
655                 do
656                         lgetxattr_size_check $path $xattr ||
657                                 error "lgetxattr_size_check $path $xattr failed"
658                 done
659         done
660 }
661 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
662
663 # LU-1540
664 test_17m() {
665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
666         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
667         remote_mds_nodsh && skip "remote MDS with nodsh"
668         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
669         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
670                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
671
672         local short_sym="0123456789"
673         local wdir=$DIR/$tdir
674         local i
675
676         test_mkdir $wdir
677         long_sym=$short_sym
678         # create a long symlink file
679         for ((i = 0; i < 4; ++i)); do
680                 long_sym=${long_sym}${long_sym}
681         done
682
683         echo "create 512 short and long symlink files under $wdir"
684         for ((i = 0; i < 256; ++i)); do
685                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
686                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
687         done
688
689         echo "erase them"
690         rm -f $wdir/*
691         sync
692         wait_delete_completed
693
694         echo "recreate the 512 symlink files with a shorter string"
695         for ((i = 0; i < 512; ++i)); do
696                 # rewrite the symlink file with a shorter string
697                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
698                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
699         done
700
701         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
702
703         echo "stop and checking mds${mds_index}:"
704         # e2fsck should not return error
705         stop mds${mds_index}
706         local devname=$(mdsdevname $mds_index)
707         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
708         rc=$?
709
710         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
711                 error "start mds${mds_index} failed"
712         df $MOUNT > /dev/null 2>&1
713         [ $rc -eq 0 ] ||
714                 error "e2fsck detected error for short/long symlink: rc=$rc"
715         rm -f $wdir/*
716 }
717 run_test 17m "run e2fsck against MDT which contains short/long symlink"
718
719 check_fs_consistency_17n() {
720         local mdt_index
721         local rc=0
722
723         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
724         # so it only check MDT1/MDT2 instead of all of MDTs.
725         for mdt_index in 1 2; do
726                 # e2fsck should not return error
727                 stop mds${mdt_index}
728                 local devname=$(mdsdevname $mdt_index)
729                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
730                         rc=$((rc + $?))
731
732                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
733                         error "mount mds$mdt_index failed"
734                 df $MOUNT > /dev/null 2>&1
735         done
736         return $rc
737 }
738
739 test_17n() {
740         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
742         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
743         remote_mds_nodsh && skip "remote MDS with nodsh"
744         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
745         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
746                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
747
748         local i
749
750         test_mkdir $DIR/$tdir
751         for ((i=0; i<10; i++)); do
752                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
753                         error "create remote dir error $i"
754                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
755                         error "create files under remote dir failed $i"
756         done
757
758         check_fs_consistency_17n ||
759                 error "e2fsck report error after create files under remote dir"
760
761         for ((i = 0; i < 10; i++)); do
762                 rm -rf $DIR/$tdir/remote_dir_${i} ||
763                         error "destroy remote dir error $i"
764         done
765
766         check_fs_consistency_17n ||
767                 error "e2fsck report error after unlink files under remote dir"
768
769         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
770                 skip "lustre < 2.4.50 does not support migrate mv"
771
772         for ((i = 0; i < 10; i++)); do
773                 mkdir -p $DIR/$tdir/remote_dir_${i}
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
777                         error "migrate remote dir error $i"
778         done
779         check_fs_consistency_17n || error "e2fsck report error after migration"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n || error "e2fsck report error after unlink"
787 }
788 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
789
790 test_17o() {
791         remote_mds_nodsh && skip "remote MDS with nodsh"
792         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
793                 skip "Need MDS version at least 2.3.64"
794
795         local wdir=$DIR/${tdir}o
796         local mdt_index
797         local rc=0
798
799         test_mkdir $wdir
800         touch $wdir/$tfile
801         mdt_index=$($LFS getstripe -m $wdir/$tfile)
802         mdt_index=$((mdt_index + 1))
803
804         cancel_lru_locks mdc
805         #fail mds will wait the failover finish then set
806         #following fail_loc to avoid interfer the recovery process.
807         fail mds${mdt_index}
808
809         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
810         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
811         ls -l $wdir/$tfile && rc=1
812         do_facet mds${mdt_index} lctl set_param fail_loc=0
813         [[ $rc -eq 0 ]] || error "stat file should fail"
814 }
815 run_test 17o "stat file with incompat LMA feature"
816
817 test_18() {
818         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
819         ls $DIR || error "Failed to ls $DIR: $?"
820 }
821 run_test 18 "touch .../f ; ls ... =============================="
822
823 test_19a() {
824         touch $DIR/$tfile
825         ls -l $DIR
826         rm $DIR/$tfile
827         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
828 }
829 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
830
831 test_19b() {
832         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
833 }
834 run_test 19b "ls -l .../f19 (should return error) =============="
835
836 test_19c() {
837         [ $RUNAS_ID -eq $UID ] &&
838                 skip_env "RUNAS_ID = UID = $UID -- skipping"
839
840         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
841 }
842 run_test 19c "$RUNAS touch .../f19 (should return error) =="
843
844 test_19d() {
845         cat $DIR/f19 && error || true
846 }
847 run_test 19d "cat .../f19 (should return error) =============="
848
849 test_20() {
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
857 }
858 run_test 20 "touch .../f ; ls -l ..."
859
860 test_21() {
861         test_mkdir $DIR/$tdir
862         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
863         ln -s dangle $DIR/$tdir/link
864         echo foo >> $DIR/$tdir/link
865         cat $DIR/$tdir/dangle
866         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
867         $CHECKSTAT -f -t file $DIR/$tdir/link ||
868                 error "$tdir/link not linked to a file"
869 }
870 run_test 21 "write to dangling link"
871
872 test_22() {
873         local wdir=$DIR/$tdir
874         test_mkdir $wdir
875         chown $RUNAS_ID:$RUNAS_GID $wdir
876         (cd $wdir || error "cd $wdir failed";
877                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
878                 $RUNAS tar xf -)
879         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
880         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
881         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
882                 error "checkstat -u failed"
883 }
884 run_test 22 "unpack tar archive as non-root user"
885
886 # was test_23
887 test_23a() {
888         test_mkdir $DIR/$tdir
889         local file=$DIR/$tdir/$tfile
890
891         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
892         openfile -f O_CREAT:O_EXCL $file &&
893                 error "$file recreate succeeded" || true
894 }
895 run_test 23a "O_CREAT|O_EXCL in subdir"
896
897 test_23b() { # bug 18988
898         test_mkdir $DIR/$tdir
899         local file=$DIR/$tdir/$tfile
900
901         rm -f $file
902         echo foo > $file || error "write filed"
903         echo bar >> $file || error "append filed"
904         $CHECKSTAT -s 8 $file || error "wrong size"
905         rm $file
906 }
907 run_test 23b "O_APPEND check"
908
909 # LU-9409, size with O_APPEND and tiny writes
910 test_23c() {
911         local file=$DIR/$tfile
912
913         # single dd
914         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
915         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
916         rm -f $file
917
918         # racing tiny writes
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
920         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
921         wait
922         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
923         rm -f $file
924
925         #racing tiny & normal writes
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
927         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
928         wait
929         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
930         rm -f $file
931
932         #racing tiny & normal writes 2, ugly numbers
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
935         wait
936         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
937         rm -f $file
938 }
939 run_test 23c "O_APPEND size checks for tiny writes"
940
941 # LU-11069 file offset is correct after appending writes
942 test_23d() {
943         local file=$DIR/$tfile
944         local offset
945
946         echo CentaurHauls > $file
947         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
948         if ((offset != 26)); then
949                 error "wrong offset, expected 26, got '$offset'"
950         fi
951 }
952 run_test 23d "file offset is correct after appending writes"
953
954 # rename sanity
955 test_24a() {
956         echo '-- same directory rename'
957         test_mkdir $DIR/$tdir
958         touch $DIR/$tdir/$tfile.1
959         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
960         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
961 }
962 run_test 24a "rename file to non-existent target"
963
964 test_24b() {
965         test_mkdir $DIR/$tdir
966         touch $DIR/$tdir/$tfile.{1,2}
967         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
968         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
969         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
970 }
971 run_test 24b "rename file to existing target"
972
973 test_24c() {
974         test_mkdir $DIR/$tdir
975         test_mkdir $DIR/$tdir/d$testnum.1
976         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
977         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
978         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
979 }
980 run_test 24c "rename directory to non-existent target"
981
982 test_24d() {
983         test_mkdir -c1 $DIR/$tdir
984         test_mkdir -c1 $DIR/$tdir/d$testnum.1
985         test_mkdir -c1 $DIR/$tdir/d$testnum.2
986         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
987         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
988         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
989 }
990 run_test 24d "rename directory to existing target"
991
992 test_24e() {
993         echo '-- cross directory renames --'
994         test_mkdir $DIR/R5a
995         test_mkdir $DIR/R5b
996         touch $DIR/R5a/f
997         mv $DIR/R5a/f $DIR/R5b/g
998         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
999         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1000 }
1001 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1002
1003 test_24f() {
1004         test_mkdir $DIR/R6a
1005         test_mkdir $DIR/R6b
1006         touch $DIR/R6a/f $DIR/R6b/g
1007         mv $DIR/R6a/f $DIR/R6b/g
1008         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1009         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1010 }
1011 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1012
1013 test_24g() {
1014         test_mkdir $DIR/R7a
1015         test_mkdir $DIR/R7b
1016         test_mkdir $DIR/R7a/d
1017         mv $DIR/R7a/d $DIR/R7b/e
1018         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1019         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1020 }
1021 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1022
1023 test_24h() {
1024         test_mkdir -c1 $DIR/R8a
1025         test_mkdir -c1 $DIR/R8b
1026         test_mkdir -c1 $DIR/R8a/d
1027         test_mkdir -c1 $DIR/R8b/e
1028         mrename $DIR/R8a/d $DIR/R8b/e
1029         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1030         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1031 }
1032 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1033
1034 test_24i() {
1035         echo "-- rename error cases"
1036         test_mkdir $DIR/R9
1037         test_mkdir $DIR/R9/a
1038         touch $DIR/R9/f
1039         mrename $DIR/R9/f $DIR/R9/a
1040         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1041         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1042         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1043 }
1044 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1045
1046 test_24j() {
1047         test_mkdir $DIR/R10
1048         mrename $DIR/R10/f $DIR/R10/g
1049         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1050         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1051         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1052 }
1053 run_test 24j "source does not exist ============================"
1054
1055 test_24k() {
1056         test_mkdir $DIR/R11a
1057         test_mkdir $DIR/R11a/d
1058         touch $DIR/R11a/f
1059         mv $DIR/R11a/f $DIR/R11a/d
1060         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1061         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1062 }
1063 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1064
1065 # bug 2429 - rename foo foo foo creates invalid file
1066 test_24l() {
1067         f="$DIR/f24l"
1068         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1069 }
1070 run_test 24l "Renaming a file to itself ========================"
1071
1072 test_24m() {
1073         f="$DIR/f24m"
1074         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1075         # on ext3 this does not remove either the source or target files
1076         # though the "expected" operation would be to remove the source
1077         $CHECKSTAT -t file ${f} || error "${f} missing"
1078         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1079 }
1080 run_test 24m "Renaming a file to a hard link to itself ========="
1081
1082 test_24n() {
1083     f="$DIR/f24n"
1084     # this stats the old file after it was renamed, so it should fail
1085     touch ${f}
1086     $CHECKSTAT ${f} || error "${f} missing"
1087     mv ${f} ${f}.rename
1088     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1089     $CHECKSTAT -a ${f} || error "${f} exists"
1090 }
1091 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1092
1093 test_24o() {
1094         test_mkdir $DIR/$tdir
1095         rename_many -s random -v -n 10 $DIR/$tdir
1096 }
1097 run_test 24o "rename of files during htree split"
1098
1099 test_24p() {
1100         test_mkdir $DIR/R12a
1101         test_mkdir $DIR/R12b
1102         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1103         mrename $DIR/R12a $DIR/R12b
1104         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1105         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1106         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1108 }
1109 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1110
1111 cleanup_multiop_pause() {
1112         trap 0
1113         kill -USR1 $MULTIPID
1114 }
1115
1116 test_24q() {
1117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1118
1119         test_mkdir $DIR/R13a
1120         test_mkdir $DIR/R13b
1121         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1122         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1123         MULTIPID=$!
1124
1125         trap cleanup_multiop_pause EXIT
1126         mrename $DIR/R13a $DIR/R13b
1127         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1128         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1129         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1130         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1131         cleanup_multiop_pause
1132         wait $MULTIPID || error "multiop close failed"
1133 }
1134 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1135
1136 test_24r() { #bug 3789
1137         test_mkdir $DIR/R14a
1138         test_mkdir $DIR/R14a/b
1139         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1140         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1141         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1142 }
1143 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1144
1145 test_24s() {
1146         test_mkdir $DIR/R15a
1147         test_mkdir $DIR/R15a/b
1148         test_mkdir $DIR/R15a/b/c
1149         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1150         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1151         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1152 }
1153 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1154
1155 test_24t() {
1156         test_mkdir $DIR/R16a
1157         test_mkdir $DIR/R16a/b
1158         test_mkdir $DIR/R16a/b/c
1159         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1161         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1162 }
1163 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1164
1165 test_24u() { # bug12192
1166         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1167         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1168 }
1169 run_test 24u "create stripe file"
1170
1171 simple_cleanup_common() {
1172         local createmany=$1
1173         local rc=0
1174
1175         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1176
1177         local start=$SECONDS
1178
1179         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1180         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1181         rc=$?
1182         wait_delete_completed
1183         echo "cleanup time $((SECONDS - start))"
1184         return $rc
1185 }
1186
1187 max_pages_per_rpc() {
1188         local mdtname="$(printf "MDT%04x" ${1:-0})"
1189         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1190 }
1191
1192 test_24v() {
1193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1194
1195         local nrfiles=${COUNT:-100000}
1196         local fname="$DIR/$tdir/$tfile"
1197
1198         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1199         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1200
1201         test_mkdir "$(dirname $fname)"
1202         # assume MDT0000 has the fewest inodes
1203         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1204         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1205         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1206
1207         stack_trap "simple_cleanup_common $nrfiles"
1208
1209         createmany -m "$fname" $nrfiles
1210
1211         cancel_lru_locks mdc
1212         lctl set_param mdc.*.stats clear
1213
1214         # was previously test_24D: LU-6101
1215         # readdir() returns correct number of entries after cursor reload
1216         local num_ls=$(ls $DIR/$tdir | wc -l)
1217         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1218         local num_all=$(ls -a $DIR/$tdir | wc -l)
1219         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1220                 [ $num_all -ne $((nrfiles + 2)) ]; then
1221                         error "Expected $nrfiles files, got $num_ls " \
1222                                 "($num_uniq unique $num_all .&..)"
1223         fi
1224         # LU-5 large readdir
1225         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1226         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1227         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1228         # take into account of overhead in lu_dirpage header and end mark in
1229         # each page, plus one in rpc_num calculation.
1230         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1231         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1232         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1233         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1234         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1235         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1236         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1237         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1238                 error "large readdir doesn't take effect: " \
1239                       "$mds_readpage should be about $rpc_max"
1240 }
1241 run_test 24v "list large directory (test hash collision, b=17560)"
1242
1243 test_24w() { # bug21506
1244         SZ1=234852
1245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1246         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1247         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1248         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1249         [[ "$SZ1" -eq "$SZ2" ]] ||
1250                 error "Error reading at the end of the file $tfile"
1251 }
1252 run_test 24w "Reading a file larger than 4Gb"
1253
1254 test_24x() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1258                 skip "Need MDS version at least 2.7.56"
1259
1260         local MDTIDX=1
1261         local remote_dir=$DIR/$tdir/remote_dir
1262
1263         test_mkdir $DIR/$tdir
1264         $LFS mkdir -i $MDTIDX $remote_dir ||
1265                 error "create remote directory failed"
1266
1267         test_mkdir $DIR/$tdir/src_dir
1268         touch $DIR/$tdir/src_file
1269         test_mkdir $remote_dir/tgt_dir
1270         touch $remote_dir/tgt_file
1271
1272         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1273                 error "rename dir cross MDT failed!"
1274
1275         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1276                 error "rename file cross MDT failed!"
1277
1278         touch $DIR/$tdir/ln_file
1279         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1280                 error "ln file cross MDT failed"
1281
1282         rm -rf $DIR/$tdir || error "Can not delete directories"
1283 }
1284 run_test 24x "cross MDT rename/link"
1285
1286 test_24y() {
1287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1289
1290         local remote_dir=$DIR/$tdir/remote_dir
1291         local mdtidx=1
1292
1293         test_mkdir $DIR/$tdir
1294         $LFS mkdir -i $mdtidx $remote_dir ||
1295                 error "create remote directory failed"
1296
1297         test_mkdir $remote_dir/src_dir
1298         touch $remote_dir/src_file
1299         test_mkdir $remote_dir/tgt_dir
1300         touch $remote_dir/tgt_file
1301
1302         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1303                 error "rename subdir in the same remote dir failed!"
1304
1305         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1306                 error "rename files in the same remote dir failed!"
1307
1308         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1309                 error "link files in the same remote dir failed!"
1310
1311         rm -rf $DIR/$tdir || error "Can not delete directories"
1312 }
1313 run_test 24y "rename/link on the same dir should succeed"
1314
1315 test_24z() {
1316         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1317         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1318                 skip "Need MDS version at least 2.12.51"
1319
1320         local index
1321
1322         for index in 0 1; do
1323                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1324                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1325         done
1326
1327         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1328
1329         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1330         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1331
1332         local mdts=$(comma_list $(mdts_nodes))
1333
1334         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1335         stack_trap "do_nodes $mdts $LCTL \
1336                 set_param mdt.*.enable_remote_rename=1" EXIT
1337
1338         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1339
1340         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1341         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1342 }
1343 run_test 24z "cross-MDT rename is done as cp"
1344
1345 test_24A() { # LU-3182
1346         local NFILES=5000
1347
1348         test_mkdir $DIR/$tdir
1349         stack_trap "simple_cleanup_common $NFILES"
1350         createmany -m $DIR/$tdir/$tfile $NFILES
1351         local t=$(ls $DIR/$tdir | wc -l)
1352         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1353         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1354
1355         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1356                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1357 }
1358 run_test 24A "readdir() returns correct number of entries."
1359
1360 test_24B() { # LU-4805
1361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1362
1363         local count
1364
1365         test_mkdir $DIR/$tdir
1366         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1367                 error "create striped dir failed"
1368
1369         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1370         [ $count -eq 2 ] || error "Expected 2, got $count"
1371
1372         touch $DIR/$tdir/striped_dir/a
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 3 ] || error "Expected 3, got $count"
1376
1377         touch $DIR/$tdir/striped_dir/.f
1378
1379         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1380         [ $count -eq 4 ] || error "Expected 4, got $count"
1381
1382         rm -rf $DIR/$tdir || error "Can not delete directories"
1383 }
1384 run_test 24B "readdir for striped dir return correct number of entries"
1385
1386 test_24C() {
1387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1388
1389         mkdir $DIR/$tdir
1390         mkdir $DIR/$tdir/d0
1391         mkdir $DIR/$tdir/d1
1392
1393         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1394                 error "create striped dir failed"
1395
1396         cd $DIR/$tdir/d0/striped_dir
1397
1398         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1399         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1400         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1401
1402         [ "$d0_ino" = "$parent_ino" ] ||
1403                 error ".. wrong, expect $d0_ino, get $parent_ino"
1404
1405         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1406                 error "mv striped dir failed"
1407
1408         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1409
1410         [ "$d1_ino" = "$parent_ino" ] ||
1411                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1412 }
1413 run_test 24C "check .. in striped dir"
1414
1415 test_24E() {
1416         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1418
1419         mkdir -p $DIR/$tdir
1420         mkdir $DIR/$tdir/src_dir
1421         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1422                 error "create remote source failed"
1423
1424         touch $DIR/$tdir/src_dir/src_child/a
1425
1426         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1427                 error "create remote target dir failed"
1428
1429         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1430                 error "create remote target child failed"
1431
1432         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1433                 error "rename dir cross MDT failed!"
1434
1435         find $DIR/$tdir
1436
1437         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1438                 error "src_child still exists after rename"
1439
1440         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1441                 error "missing file(a) after rename"
1442
1443         rm -rf $DIR/$tdir || error "Can not delete directories"
1444 }
1445 run_test 24E "cross MDT rename/link"
1446
1447 test_24F () {
1448         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1449
1450         local repeats=1000
1451         [ "$SLOW" = "no" ] && repeats=100
1452
1453         mkdir -p $DIR/$tdir
1454
1455         echo "$repeats repeats"
1456         for ((i = 0; i < repeats; i++)); do
1457                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1458                 touch $DIR/$tdir/test/a || error "touch fails"
1459                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1460                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1461         done
1462
1463         true
1464 }
1465 run_test 24F "hash order vs readdir (LU-11330)"
1466
1467 test_24G () {
1468         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1469
1470         local ino1
1471         local ino2
1472
1473         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1474         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1475         touch $DIR/$tdir-0/f1 || error "touch f1"
1476         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1477         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1478         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1479         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1480         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1481 }
1482 run_test 24G "migrate symlink in rename"
1483
1484 test_24H() {
1485         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1486         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1487                 skip "MDT1 should be on another node"
1488
1489         test_mkdir -i 1 -c 1 $DIR/$tdir
1490 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1491         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1492         touch $DIR/$tdir/$tfile || error "touch failed"
1493 }
1494 run_test 24H "repeat FLD_QUERY rpc"
1495
1496 test_25a() {
1497         echo '== symlink sanity ============================================='
1498
1499         test_mkdir $DIR/d25
1500         ln -s d25 $DIR/s25
1501         touch $DIR/s25/foo ||
1502                 error "File creation in symlinked directory failed"
1503 }
1504 run_test 25a "create file in symlinked directory ==============="
1505
1506 test_25b() {
1507         [ ! -d $DIR/d25 ] && test_25a
1508         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1509 }
1510 run_test 25b "lookup file in symlinked directory ==============="
1511
1512 test_26a() {
1513         test_mkdir $DIR/d26
1514         test_mkdir $DIR/d26/d26-2
1515         ln -s d26/d26-2 $DIR/s26
1516         touch $DIR/s26/foo || error "File creation failed"
1517 }
1518 run_test 26a "multiple component symlink ======================="
1519
1520 test_26b() {
1521         test_mkdir -p $DIR/$tdir/d26-2
1522         ln -s $tdir/d26-2/foo $DIR/s26-2
1523         touch $DIR/s26-2 || error "File creation failed"
1524 }
1525 run_test 26b "multiple component symlink at end of lookup ======"
1526
1527 test_26c() {
1528         test_mkdir $DIR/d26.2
1529         touch $DIR/d26.2/foo
1530         ln -s d26.2 $DIR/s26.2-1
1531         ln -s s26.2-1 $DIR/s26.2-2
1532         ln -s s26.2-2 $DIR/s26.2-3
1533         chmod 0666 $DIR/s26.2-3/foo
1534 }
1535 run_test 26c "chain of symlinks"
1536
1537 # recursive symlinks (bug 439)
1538 test_26d() {
1539         ln -s d26-3/foo $DIR/d26-3
1540 }
1541 run_test 26d "create multiple component recursive symlink"
1542
1543 test_26e() {
1544         [ ! -h $DIR/d26-3 ] && test_26d
1545         rm $DIR/d26-3
1546 }
1547 run_test 26e "unlink multiple component recursive symlink"
1548
1549 # recursive symlinks (bug 7022)
1550 test_26f() {
1551         test_mkdir $DIR/$tdir
1552         test_mkdir $DIR/$tdir/$tfile
1553         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1554         test_mkdir -p lndir/bar1
1555         test_mkdir $DIR/$tdir/$tfile/$tfile
1556         cd $tfile                || error "cd $tfile failed"
1557         ln -s .. dotdot          || error "ln dotdot failed"
1558         ln -s dotdot/lndir lndir || error "ln lndir failed"
1559         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1560         output=`ls $tfile/$tfile/lndir/bar1`
1561         [ "$output" = bar1 ] && error "unexpected output"
1562         rm -r $tfile             || error "rm $tfile failed"
1563         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1564 }
1565 run_test 26f "rm -r of a directory which has recursive symlink"
1566
1567 test_27a() {
1568         test_mkdir $DIR/$tdir
1569         $LFS getstripe $DIR/$tdir
1570         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1571         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1572         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1573 }
1574 run_test 27a "one stripe file"
1575
1576 test_27b() {
1577         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1578
1579         test_mkdir $DIR/$tdir
1580         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1581         $LFS getstripe -c $DIR/$tdir/$tfile
1582         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1583                 error "two-stripe file doesn't have two stripes"
1584
1585         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1586 }
1587 run_test 27b "create and write to two stripe file"
1588
1589 # 27c family tests specific striping, setstripe -o
1590 test_27ca() {
1591         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1592         test_mkdir -p $DIR/$tdir
1593         local osts="1"
1594
1595         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1596         $LFS getstripe -i $DIR/$tdir/$tfile
1597         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1598                 error "stripe not on specified OST"
1599
1600         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1601 }
1602 run_test 27ca "one stripe on specified OST"
1603
1604 test_27cb() {
1605         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1606         test_mkdir -p $DIR/$tdir
1607         local osts="1,0"
1608         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1609         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1610         echo "$getstripe"
1611
1612         # Strip getstripe output to a space separated list of OSTs
1613         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1614                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1615         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1616                 error "stripes not on specified OSTs"
1617
1618         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1619 }
1620 run_test 27cb "two stripes on specified OSTs"
1621
1622 test_27cc() {
1623         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1624         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1625                 skip "server does not support overstriping"
1626
1627         test_mkdir -p $DIR/$tdir
1628         local osts="0,0"
1629         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1630         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1631         echo "$getstripe"
1632
1633         # Strip getstripe output to a space separated list of OSTs
1634         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1635                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1636         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1637                 error "stripes not on specified OSTs"
1638
1639         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1640 }
1641 run_test 27cc "two stripes on the same OST"
1642
1643 test_27cd() {
1644         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1645         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1646                 skip "server does not support overstriping"
1647         test_mkdir -p $DIR/$tdir
1648         local osts="0,1,1,0"
1649         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1650         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1651         echo "$getstripe"
1652
1653         # Strip getstripe output to a space separated list of OSTs
1654         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1655                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1656         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1657                 error "stripes not on specified OSTs"
1658
1659         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1660 }
1661 run_test 27cd "four stripes on two OSTs"
1662
1663 test_27ce() {
1664         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1665                 skip_env "too many osts, skipping"
1666         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1667                 skip "server does not support overstriping"
1668         # We do one more stripe than we have OSTs
1669         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1670                 skip_env "ea_inode feature disabled"
1671
1672         test_mkdir -p $DIR/$tdir
1673         local osts=""
1674         for i in $(seq 0 $OSTCOUNT);
1675         do
1676                 osts=$osts"0"
1677                 if [ $i -ne $OSTCOUNT ]; then
1678                         osts=$osts","
1679                 fi
1680         done
1681         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1682         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1683         echo "$getstripe"
1684
1685         # Strip getstripe output to a space separated list of OSTs
1686         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1687                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1688         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1689                 error "stripes not on specified OSTs"
1690
1691         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1692 }
1693 run_test 27ce "more stripes than OSTs with -o"
1694
1695 test_27cf() {
1696         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1697         local pid=0
1698
1699         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1700         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1701         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1702         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1703                 error "failed to set $osp_proc=0"
1704
1705         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1706         pid=$!
1707         sleep 1
1708         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1709         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1710                 error "failed to set $osp_proc=1"
1711         wait $pid
1712         [[ $pid -ne 0 ]] ||
1713                 error "should return error due to $osp_proc=0"
1714 }
1715 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1716
1717 test_27cg() {
1718         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1719                 skip "server does not support overstriping"
1720         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1721         large_xattr_enabled || skip_env "ea_inode feature disabled"
1722
1723         local osts="0"
1724
1725         for ((i=1;i<1000;i++)); do
1726                 osts+=",$((i % OSTCOUNT))"
1727         done
1728
1729         local mdts=$(comma_list $(mdts_nodes))
1730         local before=$(do_nodes $mdts \
1731                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1732                 awk '/many credits/{print $3}' |
1733                 calc_sum)
1734
1735         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1736         $LFS getstripe $DIR/$tfile | grep stripe
1737
1738         rm -f $DIR/$tfile || error "can't unlink"
1739
1740         after=$(do_nodes $mdts \
1741                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1742                 awk '/many credits/{print $3}' |
1743                 calc_sum)
1744
1745         (( before == after )) ||
1746                 error "too many credits happened: $after > $before"
1747 }
1748 run_test 27cg "1000 shouldn't cause too many credits"
1749
1750 test_27d() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1753                 error "setstripe failed"
1754         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1755         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1756 }
1757 run_test 27d "create file with default settings"
1758
1759 test_27e() {
1760         # LU-5839 adds check for existed layout before setting it
1761         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1762                 skip "Need MDS version at least 2.7.56"
1763
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1766         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1767         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1768 }
1769 run_test 27e "setstripe existing file (should return error)"
1770
1771 test_27f() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1774                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1775         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1776                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1777         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1778         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1779 }
1780 run_test 27f "setstripe with bad stripe size (should return error)"
1781
1782 test_27g() {
1783         test_mkdir $DIR/$tdir
1784         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1785         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1786                 error "$DIR/$tdir/$tfile has object"
1787 }
1788 run_test 27g "$LFS getstripe with no objects"
1789
1790 test_27ga() {
1791         test_mkdir $DIR/$tdir
1792         touch $DIR/$tdir/$tfile || error "touch failed"
1793         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1794         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1795         local rc=$?
1796         (( rc == 2 )) || error "getstripe did not return ENOENT"
1797 }
1798 run_test 27ga "$LFS getstripe with missing file (should return error)"
1799
1800 test_27i() {
1801         test_mkdir $DIR/$tdir
1802         touch $DIR/$tdir/$tfile || error "touch failed"
1803         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1804                 error "missing objects"
1805 }
1806 run_test 27i "$LFS getstripe with some objects"
1807
1808 test_27j() {
1809         test_mkdir $DIR/$tdir
1810         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1811                 error "setstripe failed" || true
1812 }
1813 run_test 27j "setstripe with bad stripe offset (should return error)"
1814
1815 test_27k() { # bug 2844
1816         test_mkdir $DIR/$tdir
1817         local file=$DIR/$tdir/$tfile
1818         local ll_max_blksize=$((4 * 1024 * 1024))
1819         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1820         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1821         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1822         dd if=/dev/zero of=$file bs=4k count=1
1823         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1824         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1825 }
1826 run_test 27k "limit i_blksize for broken user apps"
1827
1828 test_27l() {
1829         mcreate $DIR/$tfile || error "creating file"
1830         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1831                 error "setstripe should have failed" || true
1832 }
1833 run_test 27l "check setstripe permissions (should return error)"
1834
1835 test_27m() {
1836         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1837
1838         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1839                 skip_env "multiple clients -- skipping"
1840
1841         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1842                    head -n1)
1843         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1844                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1845         fi
1846         stack_trap simple_cleanup_common
1847         test_mkdir $DIR/$tdir
1848         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1849         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1850                 error "dd should fill OST0"
1851         i=2
1852         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1853                 i=$((i + 1))
1854                 [ $i -gt 256 ] && break
1855         done
1856         i=$((i + 1))
1857         touch $DIR/$tdir/$tfile.$i
1858         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1859             awk '{print $1}'| grep -w "0") ] &&
1860                 error "OST0 was full but new created file still use it"
1861         i=$((i + 1))
1862         touch $DIR/$tdir/$tfile.$i
1863         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1864             awk '{print $1}'| grep -w "0") ] &&
1865                 error "OST0 was full but new created file still use it" || true
1866 }
1867 run_test 27m "create file while OST0 was full"
1868
1869 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1870 # if the OST isn't full anymore.
1871 reset_enospc() {
1872         local ostidx=${1:-""}
1873         local delay
1874         local ready
1875         local get_prealloc
1876
1877         local list=$(comma_list $(osts_nodes))
1878         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1879
1880         do_nodes $list lctl set_param fail_loc=0
1881         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1882         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1883                 awk '{print $1 * 2;exit;}')
1884         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1885                         grep -v \"^0$\""
1886         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1887 }
1888
1889 test_27n() {
1890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1892         remote_mds_nodsh && skip "remote MDS with nodsh"
1893         remote_ost_nodsh && skip "remote OST with nodsh"
1894
1895         reset_enospc
1896         rm -f $DIR/$tdir/$tfile
1897         exhaust_precreations 0 0x80000215
1898         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1899         touch $DIR/$tdir/$tfile || error "touch failed"
1900         $LFS getstripe $DIR/$tdir/$tfile
1901         reset_enospc
1902 }
1903 run_test 27n "create file with some full OSTs"
1904
1905 test_27o() {
1906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1908         remote_mds_nodsh && skip "remote MDS with nodsh"
1909         remote_ost_nodsh && skip "remote OST with nodsh"
1910
1911         reset_enospc
1912         rm -f $DIR/$tdir/$tfile
1913         exhaust_all_precreations 0x215
1914
1915         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1916
1917         reset_enospc
1918         rm -rf $DIR/$tdir/*
1919 }
1920 run_test 27o "create file with all full OSTs (should error)"
1921
1922 function create_and_checktime() {
1923         local fname=$1
1924         local loops=$2
1925         local i
1926
1927         for ((i=0; i < $loops; i++)); do
1928                 local start=$SECONDS
1929                 multiop $fname-$i Oc
1930                 ((SECONDS-start < TIMEOUT)) ||
1931                         error "creation took " $((SECONDS-$start)) && return 1
1932         done
1933 }
1934
1935 test_27oo() {
1936         local mdts=$(comma_list $(mdts_nodes))
1937
1938         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1939                 skip "Need MDS version at least 2.13.57"
1940
1941         local f0=$DIR/${tfile}-0
1942         local f1=$DIR/${tfile}-1
1943
1944         wait_delete_completed
1945
1946         # refill precreated objects
1947         $LFS setstripe -i0 -c1 $f0
1948
1949         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1950         # force QoS allocation policy
1951         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1952         stack_trap "do_nodes $mdts $LCTL set_param \
1953                 lov.*.qos_threshold_rr=$saved" EXIT
1954         sleep_maxage
1955
1956         # one OST is unavailable, but still have few objects preallocated
1957         stop ost1
1958         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1959                 rm -rf $f1 $DIR/$tdir*" EXIT
1960
1961         for ((i=0; i < 7; i++)); do
1962                 mkdir $DIR/$tdir$i || error "can't create dir"
1963                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1964                         error "can't set striping"
1965         done
1966         for ((i=0; i < 7; i++)); do
1967                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1968         done
1969         wait
1970 }
1971 run_test 27oo "don't let few threads to reserve too many objects"
1972
1973 test_27p() {
1974         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1976         remote_mds_nodsh && skip "remote MDS with nodsh"
1977         remote_ost_nodsh && skip "remote OST with nodsh"
1978
1979         reset_enospc
1980         rm -f $DIR/$tdir/$tfile
1981         test_mkdir $DIR/$tdir
1982
1983         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1984         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1985         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1986
1987         exhaust_precreations 0 0x80000215
1988         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1989         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1990         $LFS getstripe $DIR/$tdir/$tfile
1991
1992         reset_enospc
1993 }
1994 run_test 27p "append to a truncated file with some full OSTs"
1995
1996 test_27q() {
1997         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1999         remote_mds_nodsh && skip "remote MDS with nodsh"
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001
2002         reset_enospc
2003         rm -f $DIR/$tdir/$tfile
2004
2005         mkdir_on_mdt0 $DIR/$tdir
2006         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2007         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2008                 error "truncate $DIR/$tdir/$tfile failed"
2009         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2010
2011         exhaust_all_precreations 0x215
2012
2013         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2014         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2015
2016         reset_enospc
2017 }
2018 run_test 27q "append to truncated file with all OSTs full (should error)"
2019
2020 test_27r() {
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2023         remote_mds_nodsh && skip "remote MDS with nodsh"
2024         remote_ost_nodsh && skip "remote OST with nodsh"
2025
2026         reset_enospc
2027         rm -f $DIR/$tdir/$tfile
2028         exhaust_precreations 0 0x80000215
2029
2030         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2031
2032         reset_enospc
2033 }
2034 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2035
2036 test_27s() { # bug 10725
2037         test_mkdir $DIR/$tdir
2038         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2039         local stripe_count=0
2040         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2041         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2042                 error "stripe width >= 2^32 succeeded" || true
2043
2044 }
2045 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2046
2047 test_27t() { # bug 10864
2048         WDIR=$(pwd)
2049         WLFS=$(which lfs)
2050         cd $DIR
2051         touch $tfile
2052         $WLFS getstripe $tfile
2053         cd $WDIR
2054 }
2055 run_test 27t "check that utils parse path correctly"
2056
2057 test_27u() { # bug 4900
2058         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060
2061         local index
2062         local list=$(comma_list $(mdts_nodes))
2063
2064 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2065         do_nodes $list $LCTL set_param fail_loc=0x139
2066         test_mkdir -p $DIR/$tdir
2067         stack_trap "simple_cleanup_common 1000"
2068         createmany -o $DIR/$tdir/$tfile 1000
2069         do_nodes $list $LCTL set_param fail_loc=0
2070
2071         TLOG=$TMP/$tfile.getstripe
2072         $LFS getstripe $DIR/$tdir > $TLOG
2073         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2074         [[ $OBJS -gt 0 ]] &&
2075                 error "$OBJS objects created on OST-0. See $TLOG" ||
2076                 rm -f $TLOG
2077 }
2078 run_test 27u "skip object creation on OSC w/o objects"
2079
2080 test_27v() { # bug 4900
2081         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2083         remote_mds_nodsh && skip "remote MDS with nodsh"
2084         remote_ost_nodsh && skip "remote OST with nodsh"
2085
2086         exhaust_all_precreations 0x215
2087         reset_enospc
2088
2089         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2090
2091         touch $DIR/$tdir/$tfile
2092         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2093         # all except ost1
2094         for (( i=1; i < OSTCOUNT; i++ )); do
2095                 do_facet ost$i lctl set_param fail_loc=0x705
2096         done
2097         local START=`date +%s`
2098         createmany -o $DIR/$tdir/$tfile 32
2099
2100         local FINISH=`date +%s`
2101         local TIMEOUT=`lctl get_param -n timeout`
2102         local PROCESS=$((FINISH - START))
2103         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2104                error "$FINISH - $START >= $TIMEOUT / 2"
2105         sleep $((TIMEOUT / 2 - PROCESS))
2106         reset_enospc
2107 }
2108 run_test 27v "skip object creation on slow OST"
2109
2110 test_27w() { # bug 10997
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2113         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2114                 error "stripe size $size != 65536" || true
2115         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2116                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2117 }
2118 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2119
2120 test_27wa() {
2121         [[ $OSTCOUNT -lt 2 ]] &&
2122                 skip_env "skipping multiple stripe count/offset test"
2123
2124         test_mkdir $DIR/$tdir
2125         for i in $(seq 1 $OSTCOUNT); do
2126                 offset=$((i - 1))
2127                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2128                         error "setstripe -c $i -i $offset failed"
2129                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2130                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2131                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2132                 [ $index -ne $offset ] &&
2133                         error "stripe offset $index != $offset" || true
2134         done
2135 }
2136 run_test 27wa "check $LFS setstripe -c -i options"
2137
2138 test_27x() {
2139         remote_ost_nodsh && skip "remote OST with nodsh"
2140         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2142
2143         OFFSET=$(($OSTCOUNT - 1))
2144         OSTIDX=0
2145         local OST=$(ostname_from_index $OSTIDX)
2146
2147         test_mkdir $DIR/$tdir
2148         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2149         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2150         sleep_maxage
2151         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2152         for i in $(seq 0 $OFFSET); do
2153                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2154                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2155                 error "OST0 was degraded but new created file still use it"
2156         done
2157         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2158 }
2159 run_test 27x "create files while OST0 is degraded"
2160
2161 test_27y() {
2162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2163         remote_mds_nodsh && skip "remote MDS with nodsh"
2164         remote_ost_nodsh && skip "remote OST with nodsh"
2165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2166
2167         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2168         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2169                 osp.$mdtosc.prealloc_last_id)
2170         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2171                 osp.$mdtosc.prealloc_next_id)
2172         local fcount=$((last_id - next_id))
2173         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2174         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2175
2176         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2177                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2178         local OST_DEACTIVE_IDX=-1
2179         local OSC
2180         local OSTIDX
2181         local OST
2182
2183         for OSC in $MDS_OSCS; do
2184                 OST=$(osc_to_ost $OSC)
2185                 OSTIDX=$(index_from_ostuuid $OST)
2186                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2187                         OST_DEACTIVE_IDX=$OSTIDX
2188                 fi
2189                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2190                         echo $OSC "is Deactivated:"
2191                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2192                 fi
2193         done
2194
2195         OSTIDX=$(index_from_ostuuid $OST)
2196         test_mkdir $DIR/$tdir
2197         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2198
2199         for OSC in $MDS_OSCS; do
2200                 OST=$(osc_to_ost $OSC)
2201                 OSTIDX=$(index_from_ostuuid $OST)
2202                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2203                         echo $OST "is degraded:"
2204                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2205                                                 obdfilter.$OST.degraded=1
2206                 fi
2207         done
2208
2209         sleep_maxage
2210         createmany -o $DIR/$tdir/$tfile $fcount
2211
2212         for OSC in $MDS_OSCS; do
2213                 OST=$(osc_to_ost $OSC)
2214                 OSTIDX=$(index_from_ostuuid $OST)
2215                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2216                         echo $OST "is recovered from degraded:"
2217                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2218                                                 obdfilter.$OST.degraded=0
2219                 else
2220                         do_facet $SINGLEMDS lctl --device %$OSC activate
2221                 fi
2222         done
2223
2224         # all osp devices get activated, hence -1 stripe count restored
2225         local stripe_count=0
2226
2227         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2228         # devices get activated.
2229         sleep_maxage
2230         $LFS setstripe -c -1 $DIR/$tfile
2231         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2232         rm -f $DIR/$tfile
2233         [ $stripe_count -ne $OSTCOUNT ] &&
2234                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2235         return 0
2236 }
2237 run_test 27y "create files while OST0 is degraded and the rest inactive"
2238
2239 check_seq_oid()
2240 {
2241         log "check file $1"
2242
2243         lmm_count=$($LFS getstripe -c $1)
2244         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2245         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2246
2247         local old_ifs="$IFS"
2248         IFS=$'[:]'
2249         fid=($($LFS path2fid $1))
2250         IFS="$old_ifs"
2251
2252         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2253         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2254
2255         # compare lmm_seq and lu_fid->f_seq
2256         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2257         # compare lmm_object_id and lu_fid->oid
2258         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2259
2260         # check the trusted.fid attribute of the OST objects of the file
2261         local have_obdidx=false
2262         local stripe_nr=0
2263         $LFS getstripe $1 | while read obdidx oid hex seq; do
2264                 # skip lines up to and including "obdidx"
2265                 [ -z "$obdidx" ] && break
2266                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2267                 $have_obdidx || continue
2268
2269                 local ost=$((obdidx + 1))
2270                 local dev=$(ostdevname $ost)
2271                 local oid_hex
2272
2273                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2274
2275                 seq=$(echo $seq | sed -e "s/^0x//g")
2276                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2277                         oid_hex=$(echo $oid)
2278                 else
2279                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2280                 fi
2281                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2282
2283                 local ff=""
2284                 #
2285                 # Don't unmount/remount the OSTs if we don't need to do that.
2286                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2287                 # update too, until that use mount/ll_decode_filter_fid/mount.
2288                 # Re-enable when debugfs will understand new filter_fid.
2289                 #
2290                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2291                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2292                                 $dev 2>/dev/null" | grep "parent=")
2293                 fi
2294                 if [ -z "$ff" ]; then
2295                         stop ost$ost
2296                         mount_fstype ost$ost
2297                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2298                                 $(facet_mntpt ost$ost)/$obj_file)
2299                         unmount_fstype ost$ost
2300                         start ost$ost $dev $OST_MOUNT_OPTS
2301                         clients_up
2302                 fi
2303
2304                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2305
2306                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2307
2308                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2309                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2310                 #
2311                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2312                 #       stripe_size=1048576 component_id=1 component_start=0 \
2313                 #       component_end=33554432
2314                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2315                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2316                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2317                 local ff_pstripe
2318                 if grep -q 'stripe=' <<<$ff; then
2319                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2320                 else
2321                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2322                         # into f_ver in this case.  See comment on ff_parent.
2323                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2324                 fi
2325
2326                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2327                 [ $ff_pseq = $lmm_seq ] ||
2328                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2329                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2330                 [ $ff_poid = $lmm_oid ] ||
2331                         error "FF parent OID $ff_poid != $lmm_oid"
2332                 (($ff_pstripe == $stripe_nr)) ||
2333                         error "FF stripe $ff_pstripe != $stripe_nr"
2334
2335                 stripe_nr=$((stripe_nr + 1))
2336                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2337                         continue
2338                 if grep -q 'stripe_count=' <<<$ff; then
2339                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2340                                             -e 's/ .*//' <<<$ff)
2341                         [ $lmm_count = $ff_scnt ] ||
2342                                 error "FF stripe count $lmm_count != $ff_scnt"
2343                 fi
2344         done
2345 }
2346
2347 test_27z() {
2348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2349         remote_ost_nodsh && skip "remote OST with nodsh"
2350
2351         test_mkdir $DIR/$tdir
2352         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2353                 { error "setstripe -c -1 failed"; return 1; }
2354         # We need to send a write to every object to get parent FID info set.
2355         # This _should_ also work for setattr, but does not currently.
2356         # touch $DIR/$tdir/$tfile-1 ||
2357         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2358                 { error "dd $tfile-1 failed"; return 2; }
2359         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2360                 { error "setstripe -c -1 failed"; return 3; }
2361         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2362                 { error "dd $tfile-2 failed"; return 4; }
2363
2364         # make sure write RPCs have been sent to OSTs
2365         sync; sleep 5; sync
2366
2367         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2368         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2369 }
2370 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2371
2372 test_27A() { # b=19102
2373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2374
2375         save_layout_restore_at_exit $MOUNT
2376         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2377         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2378                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2379         local default_size=$($LFS getstripe -S $MOUNT)
2380         local default_offset=$($LFS getstripe -i $MOUNT)
2381         local dsize=$(do_facet $SINGLEMDS \
2382                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2383         [ $default_size -eq $dsize ] ||
2384                 error "stripe size $default_size != $dsize"
2385         [ $default_offset -eq -1 ] ||
2386                 error "stripe offset $default_offset != -1"
2387 }
2388 run_test 27A "check filesystem-wide default LOV EA values"
2389
2390 test_27B() { # LU-2523
2391         test_mkdir $DIR/$tdir
2392         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2393         touch $DIR/$tdir/f0
2394         # open f1 with O_LOV_DELAY_CREATE
2395         # rename f0 onto f1
2396         # call setstripe ioctl on open file descriptor for f1
2397         # close
2398         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2399                 $DIR/$tdir/f0
2400
2401         rm -f $DIR/$tdir/f1
2402         # open f1 with O_LOV_DELAY_CREATE
2403         # unlink f1
2404         # call setstripe ioctl on open file descriptor for f1
2405         # close
2406         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2407
2408         # Allow multiop to fail in imitation of NFS's busted semantics.
2409         true
2410 }
2411 run_test 27B "call setstripe on open unlinked file/rename victim"
2412
2413 # 27C family tests full striping and overstriping
2414 test_27Ca() { #LU-2871
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2416
2417         declare -a ost_idx
2418         local index
2419         local found
2420         local i
2421         local j
2422
2423         test_mkdir $DIR/$tdir
2424         cd $DIR/$tdir
2425         for i in $(seq 0 $((OSTCOUNT - 1))); do
2426                 # set stripe across all OSTs starting from OST$i
2427                 $LFS setstripe -i $i -c -1 $tfile$i
2428                 # get striping information
2429                 ost_idx=($($LFS getstripe $tfile$i |
2430                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2431                 echo "OST Index: ${ost_idx[*]}"
2432
2433                 # check the layout
2434                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2435                         error "${#ost_idx[@]} != $OSTCOUNT"
2436
2437                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2438                         found=0
2439                         for j in "${ost_idx[@]}"; do
2440                                 if [ $index -eq $j ]; then
2441                                         found=1
2442                                         break
2443                                 fi
2444                         done
2445                         [ $found = 1 ] ||
2446                                 error "Can not find $index in ${ost_idx[*]}"
2447                 done
2448         done
2449 }
2450 run_test 27Ca "check full striping across all OSTs"
2451
2452 test_27Cb() {
2453         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2454                 skip "server does not support overstriping"
2455         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2456                 skip_env "too many osts, skipping"
2457
2458         test_mkdir -p $DIR/$tdir
2459         local setcount=$(($OSTCOUNT * 2))
2460         [ $setcount -lt 160 ] || large_xattr_enabled ||
2461                 skip_env "ea_inode feature disabled"
2462
2463         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2464                 error "setstripe failed"
2465
2466         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2467         [ $count -eq $setcount ] ||
2468                 error "stripe count $count, should be $setcount"
2469
2470         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2471                 error "overstriped should be set in pattern"
2472
2473         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2474                 error "dd failed"
2475 }
2476 run_test 27Cb "more stripes than OSTs with -C"
2477
2478 test_27Cc() {
2479         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2480                 skip "server does not support overstriping"
2481         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2482
2483         test_mkdir -p $DIR/$tdir
2484         local setcount=$(($OSTCOUNT - 1))
2485
2486         [ $setcount -lt 160 ] || large_xattr_enabled ||
2487                 skip_env "ea_inode feature disabled"
2488
2489         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2490                 error "setstripe failed"
2491
2492         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2493         [ $count -eq $setcount ] ||
2494                 error "stripe count $count, should be $setcount"
2495
2496         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2497                 error "overstriped should not be set in pattern"
2498
2499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2500                 error "dd failed"
2501 }
2502 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2503
2504 test_27Cd() {
2505         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2506                 skip "server does not support overstriping"
2507         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2508         large_xattr_enabled || skip_env "ea_inode feature disabled"
2509
2510         force_new_seq_all
2511
2512         test_mkdir -p $DIR/$tdir
2513         local setcount=$LOV_MAX_STRIPE_COUNT
2514
2515         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2516                 error "setstripe failed"
2517
2518         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2519         [ $count -eq $setcount ] ||
2520                 error "stripe count $count, should be $setcount"
2521
2522         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2523                 error "overstriped should be set in pattern"
2524
2525         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2526                 error "dd failed"
2527
2528         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2529 }
2530 run_test 27Cd "test maximum stripe count"
2531
2532 test_27Ce() {
2533         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2534                 skip "server does not support overstriping"
2535         test_mkdir -p $DIR/$tdir
2536
2537         pool_add $TESTNAME || error "Pool creation failed"
2538         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2539
2540         local setcount=8
2541
2542         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2543                 error "setstripe failed"
2544
2545         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2546         [ $count -eq $setcount ] ||
2547                 error "stripe count $count, should be $setcount"
2548
2549         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2550                 error "overstriped should be set in pattern"
2551
2552         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2553                 error "dd failed"
2554
2555         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2556 }
2557 run_test 27Ce "test pool with overstriping"
2558
2559 test_27Cf() {
2560         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2561                 skip "server does not support overstriping"
2562         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2563                 skip_env "too many osts, skipping"
2564
2565         test_mkdir -p $DIR/$tdir
2566
2567         local setcount=$(($OSTCOUNT * 2))
2568         [ $setcount -lt 160 ] || large_xattr_enabled ||
2569                 skip_env "ea_inode feature disabled"
2570
2571         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2572                 error "setstripe failed"
2573
2574         echo 1 > $DIR/$tdir/$tfile
2575
2576         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2577         [ $count -eq $setcount ] ||
2578                 error "stripe count $count, should be $setcount"
2579
2580         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2581                 error "overstriped should be set in pattern"
2582
2583         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2584                 error "dd failed"
2585
2586         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2587 }
2588 run_test 27Cf "test default inheritance with overstriping"
2589
2590 test_27Cg() {
2591         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2592                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2593
2594         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2595         (( $? != 0 )) || error "must be an error for not existent OST#"
2596 }
2597 run_test 27Cg "test setstripe with wrong OST idx"
2598
2599 test_27D() {
2600         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2601         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2602         remote_mds_nodsh && skip "remote MDS with nodsh"
2603
2604         local POOL=${POOL:-testpool}
2605         local first_ost=0
2606         local last_ost=$(($OSTCOUNT - 1))
2607         local ost_step=1
2608         local ost_list=$(seq $first_ost $ost_step $last_ost)
2609         local ost_range="$first_ost $last_ost $ost_step"
2610
2611         test_mkdir $DIR/$tdir
2612         pool_add $POOL || error "pool_add failed"
2613         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2614
2615         local skip27D
2616         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2617                 skip27D+="-s 29"
2618         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2619                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2620                         skip27D+=" -s 30,31"
2621         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2622           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2623                 skip27D+=" -s 32,33"
2624         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2625                 skip27D+=" -s 34"
2626         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2627                 error "llapi_layout_test failed"
2628
2629         destroy_test_pools || error "destroy test pools failed"
2630 }
2631 run_test 27D "validate llapi_layout API"
2632
2633 # Verify that default_easize is increased from its initial value after
2634 # accessing a widely striped file.
2635 test_27E() {
2636         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2637         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2638                 skip "client does not have LU-3338 fix"
2639
2640         # 72 bytes is the minimum space required to store striping
2641         # information for a file striped across one OST:
2642         # (sizeof(struct lov_user_md_v3) +
2643         #  sizeof(struct lov_user_ost_data_v1))
2644         local min_easize=72
2645         $LCTL set_param -n llite.*.default_easize $min_easize ||
2646                 error "lctl set_param failed"
2647         local easize=$($LCTL get_param -n llite.*.default_easize)
2648
2649         [ $easize -eq $min_easize ] ||
2650                 error "failed to set default_easize"
2651
2652         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2653                 error "setstripe failed"
2654         # In order to ensure stat() call actually talks to MDS we need to
2655         # do something drastic to this file to shake off all lock, e.g.
2656         # rename it (kills lookup lock forcing cache cleaning)
2657         mv $DIR/$tfile $DIR/${tfile}-1
2658         ls -l $DIR/${tfile}-1
2659         rm $DIR/${tfile}-1
2660
2661         easize=$($LCTL get_param -n llite.*.default_easize)
2662
2663         [ $easize -gt $min_easize ] ||
2664                 error "default_easize not updated"
2665 }
2666 run_test 27E "check that default extended attribute size properly increases"
2667
2668 test_27F() { # LU-5346/LU-7975
2669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2670         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2671         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2672                 skip "Need MDS version at least 2.8.51"
2673         remote_ost_nodsh && skip "remote OST with nodsh"
2674
2675         test_mkdir $DIR/$tdir
2676         rm -f $DIR/$tdir/f0
2677         $LFS setstripe -c 2 $DIR/$tdir
2678
2679         # stop all OSTs to reproduce situation for LU-7975 ticket
2680         for num in $(seq $OSTCOUNT); do
2681                 stop ost$num
2682         done
2683
2684         # open/create f0 with O_LOV_DELAY_CREATE
2685         # truncate f0 to a non-0 size
2686         # close
2687         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2688
2689         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2690         # open/write it again to force delayed layout creation
2691         cat /etc/hosts > $DIR/$tdir/f0 &
2692         catpid=$!
2693
2694         # restart OSTs
2695         for num in $(seq $OSTCOUNT); do
2696                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2697                         error "ost$num failed to start"
2698         done
2699
2700         wait $catpid || error "cat failed"
2701
2702         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2703         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2704                 error "wrong stripecount"
2705
2706 }
2707 run_test 27F "Client resend delayed layout creation with non-zero size"
2708
2709 test_27G() { #LU-10629
2710         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2711                 skip "Need MDS version at least 2.11.51"
2712         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2713         remote_mds_nodsh && skip "remote MDS with nodsh"
2714         local POOL=${POOL:-testpool}
2715         local ostrange="0 0 1"
2716
2717         test_mkdir $DIR/$tdir
2718         touch $DIR/$tdir/$tfile.nopool
2719         pool_add $POOL || error "pool_add failed"
2720         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2721         $LFS setstripe -p $POOL $DIR/$tdir
2722
2723         local pool=$($LFS getstripe -p $DIR/$tdir)
2724
2725         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2726         touch $DIR/$tdir/$tfile.default
2727         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2728         $LFS find $DIR/$tdir -type f --pool $POOL
2729         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2730         [[ "$found" == "2" ]] ||
2731                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2732
2733         $LFS setstripe -d $DIR/$tdir
2734
2735         pool=$($LFS getstripe -p -d $DIR/$tdir)
2736
2737         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2738 }
2739 run_test 27G "Clear OST pool from stripe"
2740
2741 test_27H() {
2742         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2743                 skip "Need MDS version newer than 2.11.54"
2744         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2745         test_mkdir $DIR/$tdir
2746         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2747         touch $DIR/$tdir/$tfile
2748         $LFS getstripe -c $DIR/$tdir/$tfile
2749         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2750                 error "two-stripe file doesn't have two stripes"
2751
2752         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2753         $LFS getstripe -y $DIR/$tdir/$tfile
2754         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2755              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2756                 error "expected l_ost_idx: [02]$ not matched"
2757
2758         # make sure ost list has been cleared
2759         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2760         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2761                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2762         touch $DIR/$tdir/f3
2763         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2764 }
2765 run_test 27H "Set specific OSTs stripe"
2766
2767 test_27I() {
2768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2770         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2771                 skip "Need MDS version newer than 2.12.52"
2772         local pool=$TESTNAME
2773         local ostrange="1 1 1"
2774
2775         save_layout_restore_at_exit $MOUNT
2776         $LFS setstripe -c 2 -i 0 $MOUNT
2777         pool_add $pool || error "pool_add failed"
2778         pool_add_targets $pool $ostrange ||
2779                 error "pool_add_targets failed"
2780         test_mkdir $DIR/$tdir
2781         $LFS setstripe -p $pool $DIR/$tdir
2782         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2783         $LFS getstripe $DIR/$tdir/$tfile
2784 }
2785 run_test 27I "check that root dir striping does not break parent dir one"
2786
2787 test_27J() {
2788         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2789                 skip "Need MDS version newer than 2.12.51"
2790
2791         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2792         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2793         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2794            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2795                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2796
2797         test_mkdir $DIR/$tdir
2798         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2799         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2800
2801         # create foreign file (raw way)
2802         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2803                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2804
2805         ! $LFS setstripe --foreign --flags foo \
2806                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2807                         error "creating $tfile with '--flags foo' should fail"
2808
2809         ! $LFS setstripe --foreign --flags 0xffffffff \
2810                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2811                         error "creating $tfile w/ 0xffffffff flags should fail"
2812
2813         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2814                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2815
2816         # verify foreign file (raw way)
2817         parse_foreign_file -f $DIR/$tdir/$tfile |
2818                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2819                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2820         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2821                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_size: 73" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2825         parse_foreign_file -f $DIR/$tdir/$tfile |
2826                 grep "lov_foreign_type: 1" ||
2827                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2828         parse_foreign_file -f $DIR/$tdir/$tfile |
2829                 grep "lov_foreign_flags: 0x0000DA08" ||
2830                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2831         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2832                 grep "lov_foreign_value: 0x" |
2833                 sed -e 's/lov_foreign_value: 0x//')
2834         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2835         [[ $lov = ${lov2// /} ]] ||
2836                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2837
2838         # create foreign file (lfs + API)
2839         $LFS setstripe --foreign=none --flags 0xda08 \
2840                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2841                 error "$DIR/$tdir/${tfile}2: create failed"
2842
2843         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2844                 grep "lfm_magic:.*0x0BD70BD0" ||
2845                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2846         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2847         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2848                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2849         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2851         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2852                 grep "lfm_flags:.*0x0000DA08" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2854         $LFS getstripe $DIR/$tdir/${tfile}2 |
2855                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2856                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2857
2858         # modify striping should fail
2859         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2860                 error "$DIR/$tdir/$tfile: setstripe should fail"
2861         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2862                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2863
2864         # R/W should fail
2865         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2866         cat $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: read should fail"
2868         cat /etc/passwd > $DIR/$tdir/$tfile &&
2869                 error "$DIR/$tdir/$tfile: write should fail"
2870         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2871                 error "$DIR/$tdir/${tfile}2: write should fail"
2872
2873         # chmod should work
2874         chmod 222 $DIR/$tdir/$tfile ||
2875                 error "$DIR/$tdir/$tfile: chmod failed"
2876         chmod 222 $DIR/$tdir/${tfile}2 ||
2877                 error "$DIR/$tdir/${tfile}2: chmod failed"
2878
2879         # chown should work
2880         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2881                 error "$DIR/$tdir/$tfile: chown failed"
2882         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2883                 error "$DIR/$tdir/${tfile}2: chown failed"
2884
2885         # rename should work
2886         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2887                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2888         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2889                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2890
2891         #remove foreign file
2892         rm $DIR/$tdir/${tfile}.new ||
2893                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2894         rm $DIR/$tdir/${tfile}2.new ||
2895                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2896 }
2897 run_test 27J "basic ops on file with foreign LOV"
2898
2899 test_27K() {
2900         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2901                 skip "Need MDS version newer than 2.12.49"
2902
2903         test_mkdir $DIR/$tdir
2904         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2905         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2906
2907         # create foreign dir (raw way)
2908         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2909                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2910
2911         ! $LFS setdirstripe --foreign --flags foo \
2912                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2913                         error "creating $tdir with '--flags foo' should fail"
2914
2915         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2916                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2917                         error "creating $tdir w/ 0xffffffff flags should fail"
2918
2919         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2920                 error "create_foreign_dir FAILED"
2921
2922         # verify foreign dir (raw way)
2923         parse_foreign_dir -d $DIR/$tdir/$tdir |
2924                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2925                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2926         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2927                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2928         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2929                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2930         parse_foreign_dir -d $DIR/$tdir/$tdir |
2931                 grep "lmv_foreign_flags: 55813$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2933         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2934                 grep "lmv_foreign_value: 0x" |
2935                 sed 's/lmv_foreign_value: 0x//')
2936         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2937                 sed 's/ //g')
2938         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2939
2940         # create foreign dir (lfs + API)
2941         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2942                 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/$tdir/${tdir}2: create failed"
2944
2945         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2946
2947         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_magic:.*0x0CD50CD0" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2950         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2951         # - sizeof(lfm_type) - sizeof(lfm_flags)
2952         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2954         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2955                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2956         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2957                 grep "lfm_flags:.*0x0000DA05" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2959         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2962
2963         # file create in dir should fail
2964         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2965         touch $DIR/$tdir/${tdir}2/$tfile &&
2966                 error "$DIR/${tdir}2: file create should fail"
2967
2968         # chmod should work
2969         chmod 777 $DIR/$tdir/$tdir ||
2970                 error "$DIR/$tdir: chmod failed"
2971         chmod 777 $DIR/$tdir/${tdir}2 ||
2972                 error "$DIR/${tdir}2: chmod failed"
2973
2974         # chown should work
2975         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2976                 error "$DIR/$tdir: chown failed"
2977         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2978                 error "$DIR/${tdir}2: chown failed"
2979
2980         # rename should work
2981         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2982                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2983         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2984                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2985
2986         #remove foreign dir
2987         rmdir $DIR/$tdir/${tdir}.new ||
2988                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2989         rmdir $DIR/$tdir/${tdir}2.new ||
2990                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2991 }
2992 run_test 27K "basic ops on dir with foreign LMV"
2993
2994 test_27L() {
2995         remote_mds_nodsh && skip "remote MDS with nodsh"
2996
2997         local POOL=${POOL:-$TESTNAME}
2998
2999         pool_add $POOL || error "pool_add failed"
3000
3001         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3002                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3003                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3004 }
3005 run_test 27L "lfs pool_list gives correct pool name"
3006
3007 test_27M() {
3008         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3009                 skip "Need MDS version >= than 2.12.57"
3010         remote_mds_nodsh && skip "remote MDS with nodsh"
3011         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3012
3013         # Set default striping on directory
3014         local setcount=4
3015         local stripe_opt
3016         local mdts=$(comma_list $(mdts_nodes))
3017
3018         # if we run against a 2.12 server which lacks overstring support
3019         # then the connect_flag will not report overstriping, even if client
3020         # is 2.14+
3021         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3022                 stripe_opt="-C $setcount"
3023         elif (( $OSTCOUNT >= $setcount )); then
3024                 stripe_opt="-c $setcount"
3025         else
3026                 skip "server does not support overstriping"
3027         fi
3028
3029         test_mkdir $DIR/$tdir
3030
3031         # Validate existing append_* params and ensure restore
3032         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3033         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3034         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3035
3036         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3037         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3038         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3039
3040         $LFS setstripe $stripe_opt $DIR/$tdir
3041
3042         echo 1 > $DIR/$tdir/${tfile}.1
3043         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3044         (( $count == $setcount )) ||
3045                 error "(1) stripe count $count, should be $setcount"
3046
3047         local appendcount=$orig_count
3048         echo 1 >> $DIR/$tdir/${tfile}.2_append
3049         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3050         (( $count == $appendcount )) ||
3051                 error "(2)stripe count $count, should be $appendcount for append"
3052
3053         # Disable O_APPEND striping, verify it works
3054         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3055
3056         # Should now get the default striping, which is 4
3057         setcount=4
3058         echo 1 >> $DIR/$tdir/${tfile}.3_append
3059         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3060         (( $count == $setcount )) ||
3061                 error "(3) stripe count $count, should be $setcount"
3062
3063         # Try changing the stripe count for append files
3064         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3065
3066         # Append striping is now 2 (directory default is still 4)
3067         appendcount=2
3068         echo 1 >> $DIR/$tdir/${tfile}.4_append
3069         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3070         (( $count == $appendcount )) ||
3071                 error "(4) stripe count $count, should be $appendcount for append"
3072
3073         # Test append stripe count of -1
3074         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3075         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3076                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3077                 touch $DIR/$tdir/$tfile.specific.{1..128}
3078         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3079
3080         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3081         appendcount=$OSTCOUNT
3082         echo 1 >> $DIR/$tdir/${tfile}.5
3083         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3084         (( $count == $appendcount )) ||
3085                 error "(5) stripe count $count, should be $appendcount for append"
3086
3087         # Set append striping back to default of 1
3088         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3089
3090         # Try a new default striping, PFL + DOM
3091         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3092
3093         # Create normal DOM file, DOM returns stripe count == 0
3094         setcount=0
3095         touch $DIR/$tdir/${tfile}.6
3096         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3097         (( $count == $setcount )) ||
3098                 error "(6) stripe count $count, should be $setcount"
3099
3100         # Show
3101         appendcount=1
3102         echo 1 >> $DIR/$tdir/${tfile}.7_append
3103         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3104         (( $count == $appendcount )) ||
3105                 error "(7) stripe count $count, should be $appendcount for append"
3106
3107         # Clean up DOM layout
3108         $LFS setstripe -d $DIR/$tdir
3109
3110         save_layout_restore_at_exit $MOUNT
3111         # Now test that append striping works when layout is from root
3112         $LFS setstripe -c 2 $MOUNT
3113         # Make a special directory for this
3114         mkdir $DIR/${tdir}/${tdir}.2
3115
3116         # Verify for normal file
3117         setcount=2
3118         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3119         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3120         (( $count == $setcount )) ||
3121                 error "(8) stripe count $count, should be $setcount"
3122
3123         appendcount=1
3124         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3125         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3126         (( $count == $appendcount )) ||
3127                 error "(9) stripe count $count, should be $appendcount for append"
3128
3129         # Now test O_APPEND striping with pools
3130         pool_add $TESTNAME || error "pool creation failed"
3131         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3132         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3133
3134         echo 1 >> $DIR/$tdir/${tfile}.10_append
3135
3136         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3137         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3138
3139         # Check that count is still correct
3140         appendcount=1
3141         echo 1 >> $DIR/$tdir/${tfile}.11_append
3142         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3143         (( $count == $appendcount )) ||
3144                 error "(11) stripe count $count, should be $appendcount for append"
3145
3146         # Disable O_APPEND stripe count, verify pool works separately
3147         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3148
3149         echo 1 >> $DIR/$tdir/${tfile}.12_append
3150
3151         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3152         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3153
3154         # Remove pool setting, verify it's not applied
3155         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3156
3157         echo 1 >> $DIR/$tdir/${tfile}.13_append
3158
3159         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3160         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3161 }
3162 run_test 27M "test O_APPEND striping"
3163
3164 test_27N() {
3165         combined_mgs_mds && skip "needs separate MGS/MDT"
3166
3167         pool_add $TESTNAME || error "pool_add failed"
3168         do_facet mgs "$LCTL pool_list $FSNAME" |
3169                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3170                 error "lctl pool_list on MGS failed"
3171 }
3172 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3173
3174 clean_foreign_symlink() {
3175         trap 0
3176         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3177         for i in $DIR/$tdir/* ; do
3178                 $LFS unlink_foreign $i || true
3179         done
3180 }
3181
3182 test_27O() {
3183         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3184                 skip "Need MDS version newer than 2.12.51"
3185
3186         test_mkdir $DIR/$tdir
3187         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3188         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3189
3190         trap clean_foreign_symlink EXIT
3191
3192         # enable foreign_symlink behaviour
3193         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3194
3195         # foreign symlink LOV format is a partial path by default
3196
3197         # create foreign file (lfs + API)
3198         $LFS setstripe --foreign=symlink --flags 0xda05 \
3199                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3200                 error "$DIR/$tdir/${tfile}: create failed"
3201
3202         $LFS getstripe -v $DIR/$tdir/${tfile} |
3203                 grep "lfm_magic:.*0x0BD70BD0" ||
3204                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3205         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3207         $LFS getstripe -v $DIR/$tdir/${tfile} |
3208                 grep "lfm_flags:.*0x0000DA05" ||
3209                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3210         $LFS getstripe $DIR/$tdir/${tfile} |
3211                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3212                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3213
3214         # modify striping should fail
3215         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3216                 error "$DIR/$tdir/$tfile: setstripe should fail"
3217
3218         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3219         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3220         cat /etc/passwd > $DIR/$tdir/$tfile &&
3221                 error "$DIR/$tdir/$tfile: write should fail"
3222
3223         # rename should succeed
3224         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3225                 error "$DIR/$tdir/$tfile: rename has failed"
3226
3227         #remove foreign_symlink file should fail
3228         rm $DIR/$tdir/${tfile}.new &&
3229                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3230
3231         #test fake symlink
3232         mkdir /tmp/${uuid1} ||
3233                 error "/tmp/${uuid1}: mkdir has failed"
3234         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3235                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3236         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3237         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3239         #read should succeed now
3240         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3241                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3242         #write should succeed now
3243         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3244                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3245         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3247         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3248                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3249
3250         #check that getstripe still works
3251         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3252                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3253
3254         # chmod should still succeed
3255         chmod 644 $DIR/$tdir/${tfile}.new ||
3256                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3257
3258         # chown should still succeed
3259         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3260                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3261
3262         # rename should still succeed
3263         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3264                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3265
3266         #remove foreign_symlink file should still fail
3267         rm $DIR/$tdir/${tfile} &&
3268                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3269
3270         #use special ioctl() to unlink foreign_symlink file
3271         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3272                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3273
3274 }
3275 run_test 27O "basic ops on foreign file of symlink type"
3276
3277 test_27P() {
3278         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3279                 skip "Need MDS version newer than 2.12.49"
3280
3281         test_mkdir $DIR/$tdir
3282         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3283         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3284
3285         trap clean_foreign_symlink EXIT
3286
3287         # enable foreign_symlink behaviour
3288         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3289
3290         # foreign symlink LMV format is a partial path by default
3291
3292         # create foreign dir (lfs + API)
3293         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3294                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3295                 error "$DIR/$tdir/${tdir}: create failed"
3296
3297         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3298
3299         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3300                 grep "lfm_magic:.*0x0CD50CD0" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3302         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3303                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3304         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3305                 grep "lfm_flags:.*0x0000DA05" ||
3306                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3307         $LFS getdirstripe $DIR/$tdir/${tdir} |
3308                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3309                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3310
3311         # file create in dir should fail
3312         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3313         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3314
3315         # rename should succeed
3316         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3317                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3318
3319         #remove foreign_symlink dir should fail
3320         rmdir $DIR/$tdir/${tdir}.new &&
3321                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3322
3323         #test fake symlink
3324         mkdir -p /tmp/${uuid1}/${uuid2} ||
3325                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3326         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3327                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3328         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3329         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3330                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3331         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3332                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3333
3334         #check that getstripe fails now that foreign_symlink enabled
3335         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3336                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3337
3338         # file create in dir should work now
3339         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3340                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3341         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3342                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3343         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3344                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3345
3346         # chmod should still succeed
3347         chmod 755 $DIR/$tdir/${tdir}.new ||
3348                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3349
3350         # chown should still succeed
3351         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3352                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3353
3354         # rename should still succeed
3355         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3356                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3357
3358         #remove foreign_symlink dir should still fail
3359         rmdir $DIR/$tdir/${tdir} &&
3360                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3361
3362         #use special ioctl() to unlink foreign_symlink file
3363         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3364                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3365
3366         #created file should still exist
3367         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3368                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3369         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3370                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3371 }
3372 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3373
3374 test_27Q() {
3375         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3376         stack_trap "rm -f $TMP/$tfile*"
3377
3378         test_mkdir $DIR/$tdir-1
3379         test_mkdir $DIR/$tdir-2
3380
3381         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3382         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3383
3384         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3385         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3386
3387         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3388         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3389
3390         # Create some bad symlinks and ensure that we don't loop
3391         # forever or something. These should return ELOOP (40) and
3392         # ENOENT (2) but I don't want to test for that because there's
3393         # always some weirdo architecture that needs to ruin
3394         # everything by defining these error numbers differently.
3395
3396         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3397         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3398
3399         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3400         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3401
3402         return 0
3403 }
3404 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3405
3406 test_27R() {
3407         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3408                 skip "need MDS 2.14.55 or later"
3409         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3410
3411         local testdir="$DIR/$tdir"
3412         test_mkdir -p $testdir
3413         stack_trap "rm -rf $testdir"
3414         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3415
3416         local f1="$testdir/f1"
3417         touch $f1 || error "failed to touch $f1"
3418         local count=$($LFS getstripe -c $f1)
3419         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3420
3421         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3422         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3423
3424         local maxcount=$(($OSTCOUNT - 1))
3425         local mdts=$(comma_list $(mdts_nodes))
3426         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3427         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3428
3429         local f2="$testdir/f2"
3430         touch $f2 || error "failed to touch $f2"
3431         local count=$($LFS getstripe -c $f2)
3432         (( $count == $maxcount )) || error "wrong stripe count"
3433 }
3434 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3435
3436 test_27T() {
3437         [ $(facet_host client) == $(facet_host ost1) ] &&
3438                 skip "need ost1 and client on different nodes"
3439
3440 #define OBD_FAIL_OSC_NO_GRANT            0x411
3441         $LCTL set_param fail_loc=0x20000411 fail_val=1
3442 #define OBD_FAIL_OST_ENOSPC              0x215
3443         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3444         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3445         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3446                 error "multiop failed"
3447 }
3448 run_test 27T "no eio on close on partial write due to enosp"
3449
3450 test_27U() {
3451         local dir=$DIR/$tdir
3452         local file=$dir/$tfile
3453         local append_pool=${TESTNAME}-append
3454         local normal_pool=${TESTNAME}-normal
3455         local pool
3456         local stripe_count
3457         local stripe_count2
3458         local mdts=$(comma_list $(mdts_nodes))
3459
3460         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3461                 skip "Need MDS version at least 2.15.51 for append pool feature"
3462
3463         # Validate existing append_* params and ensure restore
3464         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3465         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3466         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3467
3468         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3469         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3470         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3471
3472         pool_add $append_pool || error "pool creation failed"
3473         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3474
3475         pool_add $normal_pool || error "pool creation failed"
3476         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3477
3478         test_mkdir $dir
3479         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3480
3481         echo XXX >> $file.1
3482         $LFS getstripe $file.1
3483
3484         pool=$($LFS getstripe -p $file.1)
3485         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3486
3487         stripe_count2=$($LFS getstripe -c $file.1)
3488         ((stripe_count2 == stripe_count)) ||
3489                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3490
3491         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3492
3493         echo XXX >> $file.2
3494         $LFS getstripe $file.2
3495
3496         pool=$($LFS getstripe -p $file.2)
3497         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3498
3499         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3500
3501         echo XXX >> $file.3
3502         $LFS getstripe $file.3
3503
3504         stripe_count2=$($LFS getstripe -c $file.3)
3505         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3506 }
3507 run_test 27U "append pool and stripe count work with composite default layout"
3508
3509 # createtest also checks that device nodes are created and
3510 # then visible correctly (#2091)
3511 test_28() { # bug 2091
3512         test_mkdir $DIR/d28
3513         $CREATETEST $DIR/d28/ct || error "createtest failed"
3514 }
3515 run_test 28 "create/mknod/mkdir with bad file types ============"
3516
3517 test_29() {
3518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3519
3520         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3521                 disable_opencache
3522                 stack_trap "restore_opencache"
3523         }
3524
3525         sync; sleep 1; sync # flush out any dirty pages from previous tests
3526         cancel_lru_locks
3527         test_mkdir $DIR/d29
3528         touch $DIR/d29/foo
3529         log 'first d29'
3530         ls -l $DIR/d29
3531
3532         declare -i LOCKCOUNTORIG=0
3533         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3534                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3535         done
3536         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3537
3538         declare -i LOCKUNUSEDCOUNTORIG=0
3539         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3540                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3541         done
3542
3543         log 'second d29'
3544         ls -l $DIR/d29
3545         log 'done'
3546
3547         declare -i LOCKCOUNTCURRENT=0
3548         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3549                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3550         done
3551
3552         declare -i LOCKUNUSEDCOUNTCURRENT=0
3553         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3554                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3555         done
3556
3557         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3558                 $LCTL set_param -n ldlm.dump_namespaces ""
3559                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3560                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3561                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3562                 return 2
3563         fi
3564         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3565                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3566                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3567                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3568                 return 3
3569         fi
3570 }
3571 run_test 29 "IT_GETATTR regression  ============================"
3572
3573 test_30a() { # was test_30
3574         cp $(which ls) $DIR || cp /bin/ls $DIR
3575         $DIR/ls / || error "Can't execute binary from lustre"
3576         rm $DIR/ls
3577 }
3578 run_test 30a "execute binary from Lustre (execve) =============="
3579
3580 test_30b() {
3581         cp `which ls` $DIR || cp /bin/ls $DIR
3582         chmod go+rx $DIR/ls
3583         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3584         rm $DIR/ls
3585 }
3586 run_test 30b "execute binary from Lustre as non-root ==========="
3587
3588 test_30c() { # b=22376
3589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3590
3591         cp $(which ls) $DIR || cp /bin/ls $DIR
3592         chmod a-rw $DIR/ls
3593         cancel_lru_locks mdc
3594         cancel_lru_locks osc
3595         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3596         rm -f $DIR/ls
3597 }
3598 run_test 30c "execute binary from Lustre without read perms ===="
3599
3600 test_30d() {
3601         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3602
3603         for i in {1..10}; do
3604                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3605                 local PID=$!
3606                 sleep 1
3607                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3608                 wait $PID || error "executing dd from Lustre failed"
3609                 rm -f $DIR/$tfile
3610         done
3611
3612         rm -f $DIR/dd
3613 }
3614 run_test 30d "execute binary from Lustre while clear locks"
3615
3616 test_31a() {
3617         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3618         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3619 }
3620 run_test 31a "open-unlink file =================================="
3621
3622 test_31b() {
3623         touch $DIR/f31 || error "touch $DIR/f31 failed"
3624         ln $DIR/f31 $DIR/f31b || error "ln failed"
3625         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3626         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3627 }
3628 run_test 31b "unlink file with multiple links while open ======="
3629
3630 test_31c() {
3631         touch $DIR/f31 || error "touch $DIR/f31 failed"
3632         ln $DIR/f31 $DIR/f31c || error "ln failed"
3633         multiop_bg_pause $DIR/f31 O_uc ||
3634                 error "multiop_bg_pause for $DIR/f31 failed"
3635         MULTIPID=$!
3636         $MULTIOP $DIR/f31c Ouc
3637         kill -USR1 $MULTIPID
3638         wait $MULTIPID
3639 }
3640 run_test 31c "open-unlink file with multiple links ============="
3641
3642 test_31d() {
3643         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3644         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3645 }
3646 run_test 31d "remove of open directory ========================="
3647
3648 test_31e() { # bug 2904
3649         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3650 }
3651 run_test 31e "remove of open non-empty directory ==============="
3652
3653 test_31f() { # bug 4554
3654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3655
3656         set -vx
3657         test_mkdir $DIR/d31f
3658         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3659         cp /etc/hosts $DIR/d31f
3660         ls -l $DIR/d31f
3661         $LFS getstripe $DIR/d31f/hosts
3662         multiop_bg_pause $DIR/d31f D_c || return 1
3663         MULTIPID=$!
3664
3665         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3666         test_mkdir $DIR/d31f
3667         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3668         cp /etc/hosts $DIR/d31f
3669         ls -l $DIR/d31f
3670         $LFS getstripe $DIR/d31f/hosts
3671         multiop_bg_pause $DIR/d31f D_c || return 1
3672         MULTIPID2=$!
3673
3674         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3675         wait $MULTIPID || error "first opendir $MULTIPID failed"
3676
3677         sleep 6
3678
3679         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3680         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3681         set +vx
3682 }
3683 run_test 31f "remove of open directory with open-unlink file ==="
3684
3685 test_31g() {
3686         echo "-- cross directory link --"
3687         test_mkdir -c1 $DIR/${tdir}ga
3688         test_mkdir -c1 $DIR/${tdir}gb
3689         touch $DIR/${tdir}ga/f
3690         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3691         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3692         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3693         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3694         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3695 }
3696 run_test 31g "cross directory link==============="
3697
3698 test_31h() {
3699         echo "-- cross directory link --"
3700         test_mkdir -c1 $DIR/${tdir}
3701         test_mkdir -c1 $DIR/${tdir}/dir
3702         touch $DIR/${tdir}/f
3703         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3704         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3705         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3706         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3707         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3708 }
3709 run_test 31h "cross directory link under child==============="
3710
3711 test_31i() {
3712         echo "-- cross directory link --"
3713         test_mkdir -c1 $DIR/$tdir
3714         test_mkdir -c1 $DIR/$tdir/dir
3715         touch $DIR/$tdir/dir/f
3716         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3717         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3718         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3719         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3720         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3721 }
3722 run_test 31i "cross directory link under parent==============="
3723
3724 test_31j() {
3725         test_mkdir -c1 -p $DIR/$tdir
3726         test_mkdir -c1 -p $DIR/$tdir/dir1
3727         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3728         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3729         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3730         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3731         return 0
3732 }
3733 run_test 31j "link for directory==============="
3734
3735 test_31k() {
3736         test_mkdir -c1 -p $DIR/$tdir
3737         touch $DIR/$tdir/s
3738         touch $DIR/$tdir/exist
3739         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3740         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3741         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3742         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3743         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3744         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3745         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3746         return 0
3747 }
3748 run_test 31k "link to file: the same, non-existing, dir==============="
3749
3750 test_31l() {
3751         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3752
3753         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3754         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3755                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3756
3757         touch $DIR/$tfile || error "create failed"
3758         mkdir $DIR/$tdir || error "mkdir failed"
3759         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3760 }
3761 run_test 31l "link to file: target dir has trailing slash"
3762
3763 test_31m() {
3764         mkdir $DIR/d31m
3765         touch $DIR/d31m/s
3766         mkdir $DIR/d31m2
3767         touch $DIR/d31m2/exist
3768         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3769         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3770         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3771         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3772         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3773         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3774         return 0
3775 }
3776 run_test 31m "link to file: the same, non-existing, dir==============="
3777
3778 test_31n() {
3779         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3780         nlink=$(stat --format=%h $DIR/$tfile)
3781         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3782         local fd=$(free_fd)
3783         local cmd="exec $fd<$DIR/$tfile"
3784         eval $cmd
3785         cmd="exec $fd<&-"
3786         trap "eval $cmd" EXIT
3787         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3788         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3789         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3790         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3791         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3792         eval $cmd
3793 }
3794 run_test 31n "check link count of unlinked file"
3795
3796 link_one() {
3797         local tempfile=$(mktemp $1_XXXXXX)
3798         mlink $tempfile $1 2> /dev/null &&
3799                 echo "$BASHPID: link $tempfile to $1 succeeded"
3800         munlink $tempfile
3801 }
3802
3803 test_31o() { # LU-2901
3804         test_mkdir $DIR/$tdir
3805         for LOOP in $(seq 100); do
3806                 rm -f $DIR/$tdir/$tfile*
3807                 for THREAD in $(seq 8); do
3808                         link_one $DIR/$tdir/$tfile.$LOOP &
3809                 done
3810                 wait
3811                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3812                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3813                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3814                         break || true
3815         done
3816 }
3817 run_test 31o "duplicate hard links with same filename"
3818
3819 test_31p() {
3820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3821
3822         test_mkdir $DIR/$tdir
3823         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3824         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3825
3826         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3827                 error "open unlink test1 failed"
3828         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3829                 error "open unlink test2 failed"
3830
3831         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3832                 error "test1 still exists"
3833         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3834                 error "test2 still exists"
3835 }
3836 run_test 31p "remove of open striped directory"
3837
3838 test_31q() {
3839         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3840
3841         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3842         index=$($LFS getdirstripe -i $DIR/$tdir)
3843         [ $index -eq 3 ] || error "first stripe index $index != 3"
3844         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3845         [ $index -eq 1 ] || error "second stripe index $index != 1"
3846
3847         # when "-c <stripe_count>" is set, the number of MDTs specified after
3848         # "-i" should equal to the stripe count
3849         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3850 }
3851 run_test 31q "create striped directory on specific MDTs"
3852
3853 #LU-14949
3854 test_31r() {
3855         touch $DIR/$tfile.target
3856         touch $DIR/$tfile.source
3857
3858         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3859         $LCTL set_param fail_loc=0x1419 fail_val=3
3860         cat $DIR/$tfile.target &
3861         CATPID=$!
3862
3863         # Guarantee open is waiting before we get here
3864         sleep 1
3865         mv $DIR/$tfile.source $DIR/$tfile.target
3866
3867         wait $CATPID
3868         RC=$?
3869         if [[ $RC -ne 0 ]]; then
3870                 error "open with cat failed, rc=$RC"
3871         fi
3872 }
3873 run_test 31r "open-rename(replace) race"
3874
3875 cleanup_test32_mount() {
3876         local rc=0
3877         trap 0
3878         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3879         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3880         losetup -d $loopdev || true
3881         rm -rf $DIR/$tdir
3882         return $rc
3883 }
3884
3885 test_32a() {
3886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3887
3888         echo "== more mountpoints and symlinks ================="
3889         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3890         trap cleanup_test32_mount EXIT
3891         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3892         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3893                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3894         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3895                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3896         cleanup_test32_mount
3897 }
3898 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3899
3900 test_32b() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3909                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3910         cleanup_test32_mount
3911 }
3912 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3913
3914 test_32c() {
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3918         trap cleanup_test32_mount EXIT
3919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3920         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3921                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3922         test_mkdir -p $DIR/$tdir/d2/test_dir
3923         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3924                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3925         cleanup_test32_mount
3926 }
3927 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3928
3929 test_32d() {
3930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3931
3932         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3933         trap cleanup_test32_mount EXIT
3934         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3935         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3936                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3937         test_mkdir -p $DIR/$tdir/d2/test_dir
3938         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3939                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3940         cleanup_test32_mount
3941 }
3942 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3943
3944 test_32e() {
3945         rm -fr $DIR/$tdir
3946         test_mkdir -p $DIR/$tdir/tmp
3947         local tmp_dir=$DIR/$tdir/tmp
3948         ln -s $DIR/$tdir $tmp_dir/symlink11
3949         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3950         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3951         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3952 }
3953 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3954
3955 test_32f() {
3956         rm -fr $DIR/$tdir
3957         test_mkdir -p $DIR/$tdir/tmp
3958         local tmp_dir=$DIR/$tdir/tmp
3959         ln -s $DIR/$tdir $tmp_dir/symlink11
3960         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3961         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3962         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3963 }
3964 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3965
3966 test_32g() {
3967         local tmp_dir=$DIR/$tdir/tmp
3968         test_mkdir -p $tmp_dir
3969         test_mkdir $DIR/${tdir}2
3970         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3971         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3972         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3973         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3974         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3975         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3976 }
3977 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3978
3979 test_32h() {
3980         rm -fr $DIR/$tdir $DIR/${tdir}2
3981         tmp_dir=$DIR/$tdir/tmp
3982         test_mkdir -p $tmp_dir
3983         test_mkdir $DIR/${tdir}2
3984         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3985         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3986         ls $tmp_dir/symlink12 || error "listing symlink12"
3987         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3988 }
3989 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3990
3991 test_32i() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3995         trap cleanup_test32_mount EXIT
3996         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3997         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3998                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3999         touch $DIR/$tdir/test_file
4000         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4001                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4002         cleanup_test32_mount
4003 }
4004 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4005
4006 test_32j() {
4007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4008
4009         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4010         trap cleanup_test32_mount EXIT
4011         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4012         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4013                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4014         touch $DIR/$tdir/test_file
4015         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4016                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4017         cleanup_test32_mount
4018 }
4019 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4020
4021 test_32k() {
4022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4023
4024         rm -fr $DIR/$tdir
4025         trap cleanup_test32_mount EXIT
4026         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4027         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4028                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4029         test_mkdir -p $DIR/$tdir/d2
4030         touch $DIR/$tdir/d2/test_file || error "touch failed"
4031         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4032                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4033         cleanup_test32_mount
4034 }
4035 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4036
4037 test_32l() {
4038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4039
4040         rm -fr $DIR/$tdir
4041         trap cleanup_test32_mount EXIT
4042         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4043         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4044                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4045         test_mkdir -p $DIR/$tdir/d2
4046         touch $DIR/$tdir/d2/test_file || error "touch failed"
4047         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4048                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4049         cleanup_test32_mount
4050 }
4051 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4052
4053 test_32m() {
4054         rm -fr $DIR/d32m
4055         test_mkdir -p $DIR/d32m/tmp
4056         TMP_DIR=$DIR/d32m/tmp
4057         ln -s $DIR $TMP_DIR/symlink11
4058         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4059         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4060                 error "symlink11 not a link"
4061         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4062                 error "symlink01 not a link"
4063 }
4064 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4065
4066 test_32n() {
4067         rm -fr $DIR/d32n
4068         test_mkdir -p $DIR/d32n/tmp
4069         TMP_DIR=$DIR/d32n/tmp
4070         ln -s $DIR $TMP_DIR/symlink11
4071         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4072         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4073         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4074 }
4075 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4076
4077 test_32o() {
4078         touch $DIR/$tfile
4079         test_mkdir -p $DIR/d32o/tmp
4080         TMP_DIR=$DIR/d32o/tmp
4081         ln -s $DIR/$tfile $TMP_DIR/symlink12
4082         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4083         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4084                 error "symlink12 not a link"
4085         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4086         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4087                 error "$DIR/d32o/tmp/symlink12 not file type"
4088         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4089                 error "$DIR/d32o/symlink02 not file type"
4090 }
4091 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4092
4093 test_32p() {
4094         log 32p_1
4095         rm -fr $DIR/d32p
4096         log 32p_2
4097         rm -f $DIR/$tfile
4098         log 32p_3
4099         touch $DIR/$tfile
4100         log 32p_4
4101         test_mkdir -p $DIR/d32p/tmp
4102         log 32p_5
4103         TMP_DIR=$DIR/d32p/tmp
4104         log 32p_6
4105         ln -s $DIR/$tfile $TMP_DIR/symlink12
4106         log 32p_7
4107         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4108         log 32p_8
4109         cat $DIR/d32p/tmp/symlink12 ||
4110                 error "Can't open $DIR/d32p/tmp/symlink12"
4111         log 32p_9
4112         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4113         log 32p_10
4114 }
4115 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4116
4117 test_32q() {
4118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4119
4120         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4121         trap cleanup_test32_mount EXIT
4122         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4123         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4124         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4125                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4126         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4127         cleanup_test32_mount
4128 }
4129 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4130
4131 test_32r() {
4132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4133
4134         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4135         trap cleanup_test32_mount EXIT
4136         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4137         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4138         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4139                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4140         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4141         cleanup_test32_mount
4142 }
4143 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4144
4145 test_33aa() {
4146         rm -f $DIR/$tfile
4147         touch $DIR/$tfile
4148         chmod 444 $DIR/$tfile
4149         chown $RUNAS_ID $DIR/$tfile
4150         log 33_1
4151         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4152         log 33_2
4153 }
4154 run_test 33aa "write file with mode 444 (should return error)"
4155
4156 test_33a() {
4157         rm -fr $DIR/$tdir
4158         test_mkdir $DIR/$tdir
4159         chown $RUNAS_ID $DIR/$tdir
4160         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4161                 error "$RUNAS create $tdir/$tfile failed"
4162         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4163                 error "open RDWR" || true
4164 }
4165 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4166
4167 test_33b() {
4168         rm -fr $DIR/$tdir
4169         test_mkdir $DIR/$tdir
4170         chown $RUNAS_ID $DIR/$tdir
4171         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4172 }
4173 run_test 33b "test open file with malformed flags (No panic)"
4174
4175 test_33c() {
4176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4177         remote_ost_nodsh && skip "remote OST with nodsh"
4178
4179         local ostnum
4180         local ostname
4181         local write_bytes
4182         local all_zeros
4183
4184         all_zeros=true
4185         test_mkdir $DIR/$tdir
4186         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4187
4188         sync
4189         for ostnum in $(seq $OSTCOUNT); do
4190                 # test-framework's OST numbering is one-based, while Lustre's
4191                 # is zero-based
4192                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4193                 # check if at least some write_bytes stats are counted
4194                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4195                               obdfilter.$ostname.stats |
4196                               awk '/^write_bytes/ {print $7}' )
4197                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4198                 if (( ${write_bytes:-0} > 0 )); then
4199                         all_zeros=false
4200                         break
4201                 fi
4202         done
4203
4204         $all_zeros || return 0
4205
4206         # Write four bytes
4207         echo foo > $DIR/$tdir/bar
4208         # Really write them
4209         sync
4210
4211         # Total up write_bytes after writing.  We'd better find non-zeros.
4212         for ostnum in $(seq $OSTCOUNT); do
4213                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4214                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4215                               obdfilter/$ostname/stats |
4216                               awk '/^write_bytes/ {print $7}' )
4217                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4218                 if (( ${write_bytes:-0} > 0 )); then
4219                         all_zeros=false
4220                         break
4221                 fi
4222         done
4223
4224         if $all_zeros; then
4225                 for ostnum in $(seq $OSTCOUNT); do
4226                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4227                         echo "Check write_bytes is in obdfilter.*.stats:"
4228                         do_facet ost$ostnum lctl get_param -n \
4229                                 obdfilter.$ostname.stats
4230                 done
4231                 error "OST not keeping write_bytes stats (b=22312)"
4232         fi
4233 }
4234 run_test 33c "test write_bytes stats"
4235
4236 test_33d() {
4237         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4239
4240         local MDTIDX=1
4241         local remote_dir=$DIR/$tdir/remote_dir
4242
4243         test_mkdir $DIR/$tdir
4244         $LFS mkdir -i $MDTIDX $remote_dir ||
4245                 error "create remote directory failed"
4246
4247         touch $remote_dir/$tfile
4248         chmod 444 $remote_dir/$tfile
4249         chown $RUNAS_ID $remote_dir/$tfile
4250
4251         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4252
4253         chown $RUNAS_ID $remote_dir
4254         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4255                                         error "create" || true
4256         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4257                                     error "open RDWR" || true
4258         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4259 }
4260 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4261
4262 test_33e() {
4263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4264
4265         mkdir $DIR/$tdir
4266
4267         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4268         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4269         mkdir $DIR/$tdir/local_dir
4270
4271         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4272         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4273         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4274
4275         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4276                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4277
4278         rmdir $DIR/$tdir/* || error "rmdir failed"
4279
4280         umask 777
4281         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4282         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4283         mkdir $DIR/$tdir/local_dir
4284
4285         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4286         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4287         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4288
4289         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4290                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4291
4292         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4293
4294         umask 000
4295         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4296         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4297         mkdir $DIR/$tdir/local_dir
4298
4299         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4300         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4301         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4302
4303         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4304                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4305 }
4306 run_test 33e "mkdir and striped directory should have same mode"
4307
4308 cleanup_33f() {
4309         trap 0
4310         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4311 }
4312
4313 test_33f() {
4314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4315         remote_mds_nodsh && skip "remote MDS with nodsh"
4316
4317         mkdir $DIR/$tdir
4318         chmod go+rwx $DIR/$tdir
4319         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4320         trap cleanup_33f EXIT
4321
4322         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4323                 error "cannot create striped directory"
4324
4325         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4326                 error "cannot create files in striped directory"
4327
4328         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4329                 error "cannot remove files in striped directory"
4330
4331         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4332                 error "cannot remove striped directory"
4333
4334         cleanup_33f
4335 }
4336 run_test 33f "nonroot user can create, access, and remove a striped directory"
4337
4338 test_33g() {
4339         mkdir -p $DIR/$tdir/dir2
4340
4341         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4342         echo $err
4343         [[ $err =~ "exists" ]] || error "Not exists error"
4344 }
4345 run_test 33g "nonroot user create already existing root created file"
4346
4347 sub_33h() {
4348         local hash_type=$1
4349         local count=250
4350
4351         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4352                 error "lfs mkdir -H $hash_type $tdir failed"
4353         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4354
4355         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4356         local index2
4357         local fname
4358
4359         for fname in $DIR/$tdir/$tfile.bak \
4360                      $DIR/$tdir/$tfile.SAV \
4361                      $DIR/$tdir/$tfile.orig \
4362                      $DIR/$tdir/$tfile~; do
4363                 touch $fname || error "touch $fname failed"
4364                 index2=$($LFS getstripe -m $fname)
4365                 (( $index == $index2 )) ||
4366                         error "$fname MDT index mismatch $index != $index2"
4367         done
4368
4369         local failed=0
4370         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4371         local pattern
4372
4373         for pattern in ${patterns[*]}; do
4374                 echo "pattern $pattern"
4375                 fname=$DIR/$tdir/$pattern
4376                 for (( i = 0; i < $count; i++ )); do
4377                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4378                                 error "mktemp $DIR/$tdir/$pattern failed"
4379                         index2=$($LFS getstripe -m $fname)
4380                         (( $index == $index2 )) && continue
4381
4382                         failed=$((failed + 1))
4383                         echo "$fname MDT index mismatch $index != $index2"
4384                 done
4385         done
4386
4387         echo "$failed/$count MDT index mismatches, expect ~2-4"
4388         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4389
4390         local same=0
4391         local expect
4392
4393         # verify that "crush" is still broken with all files on same MDT,
4394         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4395         [[ "$hash_type" == "crush" ]] && expect=$count ||
4396                 expect=$((count / MDSCOUNT))
4397
4398         # crush2 doesn't put all-numeric suffixes on the same MDT,
4399         # filename like $tfile.12345678 should *not* be considered temp
4400         for pattern in ${patterns[*]}; do
4401                 local base=${pattern%%X*}
4402                 local suff=${pattern#$base}
4403
4404                 echo "pattern $pattern"
4405                 for (( i = 0; i < $count; i++ )); do
4406                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4407                         touch $fname || error "touch $fname failed"
4408                         index2=$($LFS getstripe -m $fname)
4409                         (( $index != $index2 )) && continue
4410
4411                         same=$((same + 1))
4412                 done
4413         done
4414
4415         # the number of "bad" hashes is random, as it depends on the random
4416         # filenames generated by "mktemp".  Allow some margin in the results.
4417         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4418         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4419            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4420                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4421         same=0
4422
4423         # crush2 doesn't put suffixes with special characters on the same MDT
4424         # filename like $tfile.txt.1234 should *not* be considered temp
4425         for pattern in ${patterns[*]}; do
4426                 local base=${pattern%%X*}
4427                 local suff=${pattern#$base}
4428
4429                 pattern=$base...${suff/XXX}
4430                 echo "pattern=$pattern"
4431                 for (( i = 0; i < $count; i++ )); do
4432                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4433                                 error "touch $fname failed"
4434                         index2=$($LFS getstripe -m $fname)
4435                         (( $index != $index2 )) && continue
4436
4437                         same=$((same + 1))
4438                 done
4439         done
4440
4441         # the number of "bad" hashes is random, as it depends on the random
4442         # filenames generated by "mktemp".  Allow some margin in the results.
4443         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4444         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4445            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4446                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4447 }
4448
4449 test_33h() {
4450         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4451         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4452                 skip "Need MDS version at least 2.13.50"
4453
4454         sub_33h crush
4455 }
4456 run_test 33h "temp file is located on the same MDT as target (crush)"
4457
4458 test_33hh() {
4459         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4460         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4461         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4462                 skip "Need MDS version at least 2.15.0 for crush2"
4463
4464         sub_33h crush2
4465 }
4466 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4467
4468 test_33i()
4469 {
4470         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4471
4472         local FNAME=$(str_repeat 'f' 250)
4473
4474         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4475         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4476
4477         local count
4478         local total
4479
4480         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4481
4482         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4483
4484         lctl --device %$MDC deactivate
4485         stack_trap "lctl --device %$MDC activate"
4486         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4487         total=$(\ls -l $DIR/$tdir | wc -l)
4488         # "ls -l" will list total in the first line
4489         total=$((total - 1))
4490         (( total + count == 1000 )) ||
4491                 error "ls list $total files, $count files on MDT1"
4492 }
4493 run_test 33i "striped directory can be accessed when one MDT is down"
4494
4495 test_33j() {
4496         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4497
4498         mkdir -p $DIR/$tdir/
4499
4500         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4501                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4502
4503         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4504                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4505
4506         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4507                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4508
4509         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4510                 error "-D was not specified, but still failed"
4511 }
4512 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4513
4514 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4515 test_34a() {
4516         rm -f $DIR/f34
4517         $MCREATE $DIR/f34 || error "mcreate failed"
4518         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4519                 error "getstripe failed"
4520         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4521         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4522                 error "getstripe failed"
4523         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4524                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4525 }
4526 run_test 34a "truncate file that has not been opened ==========="
4527
4528 test_34b() {
4529         [ ! -f $DIR/f34 ] && test_34a
4530         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4531                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4532         $OPENFILE -f O_RDONLY $DIR/f34
4533         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4534                 error "getstripe failed"
4535         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4536                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4537 }
4538 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4539
4540 test_34c() {
4541         [ ! -f $DIR/f34 ] && test_34a
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4543                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4544         $OPENFILE -f O_RDWR $DIR/f34
4545         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4546                 error "$LFS getstripe failed"
4547         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4548                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4549 }
4550 run_test 34c "O_RDWR opening file-with-size works =============="
4551
4552 test_34d() {
4553         [ ! -f $DIR/f34 ] && test_34a
4554         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4555                 error "dd failed"
4556         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4557                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4558         rm $DIR/f34
4559 }
4560 run_test 34d "write to sparse file ============================="
4561
4562 test_34e() {
4563         rm -f $DIR/f34e
4564         $MCREATE $DIR/f34e || error "mcreate failed"
4565         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4566         $CHECKSTAT -s 1000 $DIR/f34e ||
4567                 error "Size of $DIR/f34e not equal to 1000 bytes"
4568         $OPENFILE -f O_RDWR $DIR/f34e
4569         $CHECKSTAT -s 1000 $DIR/f34e ||
4570                 error "Size of $DIR/f34e not equal to 1000 bytes"
4571 }
4572 run_test 34e "create objects, some with size and some without =="
4573
4574 test_34f() { # bug 6242, 6243
4575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4576
4577         SIZE34F=48000
4578         rm -f $DIR/f34f
4579         $MCREATE $DIR/f34f || error "mcreate failed"
4580         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4581         dd if=$DIR/f34f of=$TMP/f34f
4582         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4583         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4584         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4585         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4586         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4587 }
4588 run_test 34f "read from a file with no objects until EOF ======="
4589
4590 test_34g() {
4591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4592
4593         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4594                 error "dd failed"
4595         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4596         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4597                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4598         cancel_lru_locks osc
4599         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4600                 error "wrong size after lock cancel"
4601
4602         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4603         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4604                 error "expanding truncate failed"
4605         cancel_lru_locks osc
4606         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4607                 error "wrong expanded size after lock cancel"
4608 }
4609 run_test 34g "truncate long file ==============================="
4610
4611 test_34h() {
4612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4613
4614         local gid=10
4615         local sz=1000
4616
4617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4618         sync # Flush the cache so that multiop below does not block on cache
4619              # flush when getting the group lock
4620         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4621         MULTIPID=$!
4622
4623         # Since just timed wait is not good enough, let's do a sync write
4624         # that way we are sure enough time for a roundtrip + processing
4625         # passed + 2 seconds of extra margin.
4626         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4627         rm $DIR/${tfile}-1
4628         sleep 2
4629
4630         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4631                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4632                 kill -9 $MULTIPID
4633         fi
4634         wait $MULTIPID
4635         local nsz=`stat -c %s $DIR/$tfile`
4636         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4637 }
4638 run_test 34h "ftruncate file under grouplock should not block"
4639
4640 test_35a() {
4641         cp /bin/sh $DIR/f35a
4642         chmod 444 $DIR/f35a
4643         chown $RUNAS_ID $DIR/f35a
4644         $RUNAS $DIR/f35a && error || true
4645         rm $DIR/f35a
4646 }
4647 run_test 35a "exec file with mode 444 (should return and not leak)"
4648
4649 test_36a() {
4650         rm -f $DIR/f36
4651         utime $DIR/f36 || error "utime failed for MDS"
4652 }
4653 run_test 36a "MDS utime check (mknod, utime)"
4654
4655 test_36b() {
4656         echo "" > $DIR/f36
4657         utime $DIR/f36 || error "utime failed for OST"
4658 }
4659 run_test 36b "OST utime check (open, utime)"
4660
4661 test_36c() {
4662         rm -f $DIR/d36/f36
4663         test_mkdir $DIR/d36
4664         chown $RUNAS_ID $DIR/d36
4665         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4666 }
4667 run_test 36c "non-root MDS utime check (mknod, utime)"
4668
4669 test_36d() {
4670         [ ! -d $DIR/d36 ] && test_36c
4671         echo "" > $DIR/d36/f36
4672         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4673 }
4674 run_test 36d "non-root OST utime check (open, utime)"
4675
4676 test_36e() {
4677         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4678
4679         test_mkdir $DIR/$tdir
4680         touch $DIR/$tdir/$tfile
4681         $RUNAS utime $DIR/$tdir/$tfile &&
4682                 error "utime worked, expected failure" || true
4683 }
4684 run_test 36e "utime on non-owned file (should return error)"
4685
4686 subr_36fh() {
4687         local fl="$1"
4688         local LANG_SAVE=$LANG
4689         local LC_LANG_SAVE=$LC_LANG
4690         export LANG=C LC_LANG=C # for date language
4691
4692         DATESTR="Dec 20  2000"
4693         test_mkdir $DIR/$tdir
4694         lctl set_param fail_loc=$fl
4695         date; date +%s
4696         cp /etc/hosts $DIR/$tdir/$tfile
4697         sync & # write RPC generated with "current" inode timestamp, but delayed
4698         sleep 1
4699         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4700         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4701         cancel_lru_locks $OSC
4702         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4703         date; date +%s
4704         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4705                 echo "BEFORE: $LS_BEFORE" && \
4706                 echo "AFTER : $LS_AFTER" && \
4707                 echo "WANT  : $DATESTR" && \
4708                 error "$DIR/$tdir/$tfile timestamps changed" || true
4709
4710         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4711 }
4712
4713 test_36f() {
4714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4715
4716         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4717         subr_36fh "0x80000214"
4718 }
4719 run_test 36f "utime on file racing with OST BRW write =========="
4720
4721 test_36g() {
4722         remote_ost_nodsh && skip "remote OST with nodsh"
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4725                 skip "Need MDS version at least 2.12.51"
4726
4727         local fmd_max_age
4728         local fmd
4729         local facet="ost1"
4730         local tgt="obdfilter"
4731
4732         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4733
4734         test_mkdir $DIR/$tdir
4735         fmd_max_age=$(do_facet $facet \
4736                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4737                 head -n 1")
4738
4739         echo "FMD max age: ${fmd_max_age}s"
4740         touch $DIR/$tdir/$tfile
4741         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4742                 gawk '{cnt=cnt+$1}  END{print cnt}')
4743         echo "FMD before: $fmd"
4744         [[ $fmd == 0 ]] &&
4745                 error "FMD wasn't create by touch"
4746         sleep $((fmd_max_age + 12))
4747         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4748                 gawk '{cnt=cnt+$1}  END{print cnt}')
4749         echo "FMD after: $fmd"
4750         [[ $fmd == 0 ]] ||
4751                 error "FMD wasn't expired by ping"
4752 }
4753 run_test 36g "FMD cache expiry ====================="
4754
4755 test_36h() {
4756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4757
4758         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4759         subr_36fh "0x80000227"
4760 }
4761 run_test 36h "utime on file racing with OST BRW write =========="
4762
4763 test_36i() {
4764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4765
4766         test_mkdir $DIR/$tdir
4767         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4768
4769         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4770         local new_mtime=$((mtime + 200))
4771
4772         #change Modify time of striped dir
4773         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4774                         error "change mtime failed"
4775
4776         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4777
4778         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4779 }
4780 run_test 36i "change mtime on striped directory"
4781
4782 # test_37 - duplicate with tests 32q 32r
4783
4784 test_38() {
4785         local file=$DIR/$tfile
4786         touch $file
4787         openfile -f O_DIRECTORY $file
4788         local RC=$?
4789         local ENOTDIR=20
4790         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4791         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4792 }
4793 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4794
4795 test_39a() { # was test_39
4796         touch $DIR/$tfile
4797         touch $DIR/${tfile}2
4798 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4799 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4800 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4801         sleep 2
4802         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4803         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4804                 echo "mtime"
4805                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4806                 echo "atime"
4807                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4808                 echo "ctime"
4809                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4810                 error "O_TRUNC didn't change timestamps"
4811         fi
4812 }
4813 run_test 39a "mtime changed on create"
4814
4815 test_39b() {
4816         test_mkdir -c1 $DIR/$tdir
4817         cp -p /etc/passwd $DIR/$tdir/fopen
4818         cp -p /etc/passwd $DIR/$tdir/flink
4819         cp -p /etc/passwd $DIR/$tdir/funlink
4820         cp -p /etc/passwd $DIR/$tdir/frename
4821         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4822
4823         sleep 1
4824         echo "aaaaaa" >> $DIR/$tdir/fopen
4825         echo "aaaaaa" >> $DIR/$tdir/flink
4826         echo "aaaaaa" >> $DIR/$tdir/funlink
4827         echo "aaaaaa" >> $DIR/$tdir/frename
4828
4829         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4830         local link_new=`stat -c %Y $DIR/$tdir/flink`
4831         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4832         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4833
4834         cat $DIR/$tdir/fopen > /dev/null
4835         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4836         rm -f $DIR/$tdir/funlink2
4837         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4838
4839         for (( i=0; i < 2; i++ )) ; do
4840                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4841                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4842                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4843                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4844
4845                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4846                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4847                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4848                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4849
4850                 cancel_lru_locks $OSC
4851                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4852         done
4853 }
4854 run_test 39b "mtime change on open, link, unlink, rename  ======"
4855
4856 # this should be set to past
4857 TEST_39_MTIME=`date -d "1 year ago" +%s`
4858
4859 # bug 11063
4860 test_39c() {
4861         touch $DIR1/$tfile
4862         sleep 2
4863         local mtime0=`stat -c %Y $DIR1/$tfile`
4864
4865         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4866         local mtime1=`stat -c %Y $DIR1/$tfile`
4867         [ "$mtime1" = $TEST_39_MTIME ] || \
4868                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4869
4870         local d1=`date +%s`
4871         echo hello >> $DIR1/$tfile
4872         local d2=`date +%s`
4873         local mtime2=`stat -c %Y $DIR1/$tfile`
4874         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4875                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4876
4877         mv $DIR1/$tfile $DIR1/$tfile-1
4878
4879         for (( i=0; i < 2; i++ )) ; do
4880                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4881                 [ "$mtime2" = "$mtime3" ] || \
4882                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4883
4884                 cancel_lru_locks $OSC
4885                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4886         done
4887 }
4888 run_test 39c "mtime change on rename ==========================="
4889
4890 # bug 21114
4891 test_39d() {
4892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4893
4894         touch $DIR1/$tfile
4895         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4896
4897         for (( i=0; i < 2; i++ )) ; do
4898                 local mtime=`stat -c %Y $DIR1/$tfile`
4899                 [ $mtime = $TEST_39_MTIME ] || \
4900                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4901
4902                 cancel_lru_locks $OSC
4903                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4904         done
4905 }
4906 run_test 39d "create, utime, stat =============================="
4907
4908 # bug 21114
4909 test_39e() {
4910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4911
4912         touch $DIR1/$tfile
4913         local mtime1=`stat -c %Y $DIR1/$tfile`
4914
4915         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4916
4917         for (( i=0; i < 2; i++ )) ; do
4918                 local mtime2=`stat -c %Y $DIR1/$tfile`
4919                 [ $mtime2 = $TEST_39_MTIME ] || \
4920                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4921
4922                 cancel_lru_locks $OSC
4923                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4924         done
4925 }
4926 run_test 39e "create, stat, utime, stat ========================"
4927
4928 # bug 21114
4929 test_39f() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         touch $DIR1/$tfile
4933         mtime1=`stat -c %Y $DIR1/$tfile`
4934
4935         sleep 2
4936         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4937
4938         for (( i=0; i < 2; i++ )) ; do
4939                 local mtime2=`stat -c %Y $DIR1/$tfile`
4940                 [ $mtime2 = $TEST_39_MTIME ] || \
4941                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39f "create, stat, sleep, utime, stat ================="
4948
4949 # bug 11063
4950 test_39g() {
4951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4952
4953         echo hello >> $DIR1/$tfile
4954         local mtime1=`stat -c %Y $DIR1/$tfile`
4955
4956         sleep 2
4957         chmod o+r $DIR1/$tfile
4958
4959         for (( i=0; i < 2; i++ )) ; do
4960                 local mtime2=`stat -c %Y $DIR1/$tfile`
4961                 [ "$mtime1" = "$mtime2" ] || \
4962                         error "lost mtime: $mtime2, should be $mtime1"
4963
4964                 cancel_lru_locks $OSC
4965                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4966         done
4967 }
4968 run_test 39g "write, chmod, stat ==============================="
4969
4970 # bug 11063
4971 test_39h() {
4972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4973
4974         touch $DIR1/$tfile
4975         sleep 1
4976
4977         local d1=`date`
4978         echo hello >> $DIR1/$tfile
4979         local mtime1=`stat -c %Y $DIR1/$tfile`
4980
4981         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4982         local d2=`date`
4983         if [ "$d1" != "$d2" ]; then
4984                 echo "write and touch not within one second"
4985         else
4986                 for (( i=0; i < 2; i++ )) ; do
4987                         local mtime2=`stat -c %Y $DIR1/$tfile`
4988                         [ "$mtime2" = $TEST_39_MTIME ] || \
4989                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4990
4991                         cancel_lru_locks $OSC
4992                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4993                 done
4994         fi
4995 }
4996 run_test 39h "write, utime within one second, stat ============="
4997
4998 test_39i() {
4999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5000
5001         touch $DIR1/$tfile
5002         sleep 1
5003
5004         echo hello >> $DIR1/$tfile
5005         local mtime1=`stat -c %Y $DIR1/$tfile`
5006
5007         mv $DIR1/$tfile $DIR1/$tfile-1
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5011
5012                 [ "$mtime1" = "$mtime2" ] || \
5013                         error "lost mtime: $mtime2, should be $mtime1"
5014
5015                 cancel_lru_locks $OSC
5016                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5017         done
5018 }
5019 run_test 39i "write, rename, stat =============================="
5020
5021 test_39j() {
5022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5023
5024         start_full_debug_logging
5025         touch $DIR1/$tfile
5026         sleep 1
5027
5028         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5029         lctl set_param fail_loc=0x80000412
5030         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5031                 error "multiop failed"
5032         local multipid=$!
5033         local mtime1=`stat -c %Y $DIR1/$tfile`
5034
5035         mv $DIR1/$tfile $DIR1/$tfile-1
5036
5037         kill -USR1 $multipid
5038         wait $multipid || error "multiop close failed"
5039
5040         for (( i=0; i < 2; i++ )) ; do
5041                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5042                 [ "$mtime1" = "$mtime2" ] ||
5043                         error "mtime is lost on close: $mtime2, " \
5044                               "should be $mtime1"
5045
5046                 cancel_lru_locks
5047                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5048         done
5049         lctl set_param fail_loc=0
5050         stop_full_debug_logging
5051 }
5052 run_test 39j "write, rename, close, stat ======================="
5053
5054 test_39k() {
5055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5056
5057         touch $DIR1/$tfile
5058         sleep 1
5059
5060         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5061         local multipid=$!
5062         local mtime1=`stat -c %Y $DIR1/$tfile`
5063
5064         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5065
5066         kill -USR1 $multipid
5067         wait $multipid || error "multiop close failed"
5068
5069         for (( i=0; i < 2; i++ )) ; do
5070                 local mtime2=`stat -c %Y $DIR1/$tfile`
5071
5072                 [ "$mtime2" = $TEST_39_MTIME ] || \
5073                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5074
5075                 cancel_lru_locks
5076                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5077         done
5078 }
5079 run_test 39k "write, utime, close, stat ========================"
5080
5081 # this should be set to future
5082 TEST_39_ATIME=`date -d "1 year" +%s`
5083
5084 test_39l() {
5085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5086         remote_mds_nodsh && skip "remote MDS with nodsh"
5087
5088         local atime_diff=$(do_facet $SINGLEMDS \
5089                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5090         rm -rf $DIR/$tdir
5091         mkdir_on_mdt0 $DIR/$tdir
5092
5093         # test setting directory atime to future
5094         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5095         local atime=$(stat -c %X $DIR/$tdir)
5096         [ "$atime" = $TEST_39_ATIME ] ||
5097                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5098
5099         # test setting directory atime from future to now
5100         local now=$(date +%s)
5101         touch -a -d @$now $DIR/$tdir
5102
5103         atime=$(stat -c %X $DIR/$tdir)
5104         [ "$atime" -eq "$now"  ] ||
5105                 error "atime is not updated from future: $atime, $now"
5106
5107         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5108         sleep 3
5109
5110         # test setting directory atime when now > dir atime + atime_diff
5111         local d1=$(date +%s)
5112         ls $DIR/$tdir
5113         local d2=$(date +%s)
5114         cancel_lru_locks mdc
5115         atime=$(stat -c %X $DIR/$tdir)
5116         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5117                 error "atime is not updated  : $atime, should be $d2"
5118
5119         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5120         sleep 3
5121
5122         # test not setting directory atime when now < dir atime + atime_diff
5123         ls $DIR/$tdir
5124         cancel_lru_locks mdc
5125         atime=$(stat -c %X $DIR/$tdir)
5126         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5127                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5128
5129         do_facet $SINGLEMDS \
5130                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5131 }
5132 run_test 39l "directory atime update ==========================="
5133
5134 test_39m() {
5135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5136
5137         touch $DIR1/$tfile
5138         sleep 2
5139         local far_past_mtime=$(date -d "May 29 1953" +%s)
5140         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5141
5142         touch -m -d @$far_past_mtime $DIR1/$tfile
5143         touch -a -d @$far_past_atime $DIR1/$tfile
5144
5145         for (( i=0; i < 2; i++ )) ; do
5146                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5147                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5148                         error "atime or mtime set incorrectly"
5149
5150                 cancel_lru_locks $OSC
5151                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5152         done
5153 }
5154 run_test 39m "test atime and mtime before 1970"
5155
5156 test_39n() { # LU-3832
5157         remote_mds_nodsh && skip "remote MDS with nodsh"
5158
5159         local atime_diff=$(do_facet $SINGLEMDS \
5160                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5161         local atime0
5162         local atime1
5163         local atime2
5164
5165         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5166
5167         rm -rf $DIR/$tfile
5168         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5169         atime0=$(stat -c %X $DIR/$tfile)
5170
5171         sleep 5
5172         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5173         atime1=$(stat -c %X $DIR/$tfile)
5174
5175         sleep 5
5176         cancel_lru_locks mdc
5177         cancel_lru_locks osc
5178         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5179         atime2=$(stat -c %X $DIR/$tfile)
5180
5181         do_facet $SINGLEMDS \
5182                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5183
5184         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5185         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5186 }
5187 run_test 39n "check that O_NOATIME is honored"
5188
5189 test_39o() {
5190         TESTDIR=$DIR/$tdir/$tfile
5191         [ -e $TESTDIR ] && rm -rf $TESTDIR
5192         mkdir -p $TESTDIR
5193         cd $TESTDIR
5194         links1=2
5195         ls
5196         mkdir a b
5197         ls
5198         links2=$(stat -c %h .)
5199         [ $(($links1 + 2)) != $links2 ] &&
5200                 error "wrong links count $(($links1 + 2)) != $links2"
5201         rmdir b
5202         links3=$(stat -c %h .)
5203         [ $(($links1 + 1)) != $links3 ] &&
5204                 error "wrong links count $links1 != $links3"
5205         return 0
5206 }
5207 run_test 39o "directory cached attributes updated after create"
5208
5209 test_39p() {
5210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5211
5212         local MDTIDX=1
5213         TESTDIR=$DIR/$tdir/$tdir
5214         [ -e $TESTDIR ] && rm -rf $TESTDIR
5215         test_mkdir -p $TESTDIR
5216         cd $TESTDIR
5217         links1=2
5218         ls
5219         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5220         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5221         ls
5222         links2=$(stat -c %h .)
5223         [ $(($links1 + 2)) != $links2 ] &&
5224                 error "wrong links count $(($links1 + 2)) != $links2"
5225         rmdir remote_dir2
5226         links3=$(stat -c %h .)
5227         [ $(($links1 + 1)) != $links3 ] &&
5228                 error "wrong links count $links1 != $links3"
5229         return 0
5230 }
5231 run_test 39p "remote directory cached attributes updated after create ========"
5232
5233 test_39r() {
5234         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5235                 skip "no atime update on old OST"
5236         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5237                 skip_env "ldiskfs only test"
5238         fi
5239
5240         local saved_adiff
5241         saved_adiff=$(do_facet ost1 \
5242                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5243         stack_trap "do_facet ost1 \
5244                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5245
5246         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5247
5248         $LFS setstripe -i 0 $DIR/$tfile
5249         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5250                 error "can't write initial file"
5251         cancel_lru_locks osc
5252
5253         # exceed atime_diff and access file
5254         sleep 10
5255         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5256                 error "can't udpate atime"
5257
5258         local atime_cli=$(stat -c %X $DIR/$tfile)
5259         echo "client atime: $atime_cli"
5260         # allow atime update to be written to device
5261         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5262         sleep 5
5263
5264         local ostdev=$(ostdevname 1)
5265         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5266         local seq=${fid[3]#0x}
5267         local oid=${fid[1]}
5268         local oid_hex
5269
5270         if [ $seq == 0 ]; then
5271                 oid_hex=${fid[1]}
5272         else
5273                 oid_hex=${fid[2]#0x}
5274         fi
5275         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5276         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5277
5278         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5279         local atime_ost=$(do_facet ost1 "$cmd" |&
5280                           awk -F'[: ]' '/atime:/ { print $4 }')
5281         (( atime_cli == atime_ost )) ||
5282                 error "atime on client $atime_cli != ost $atime_ost"
5283 }
5284 run_test 39r "lazy atime update on OST"
5285
5286 test_39q() { # LU-8041
5287         local testdir=$DIR/$tdir
5288         mkdir -p $testdir
5289         multiop_bg_pause $testdir D_c || error "multiop failed"
5290         local multipid=$!
5291         cancel_lru_locks mdc
5292         kill -USR1 $multipid
5293         local atime=$(stat -c %X $testdir)
5294         [ "$atime" -ne 0 ] || error "atime is zero"
5295 }
5296 run_test 39q "close won't zero out atime"
5297
5298 test_39s() {
5299         local atime0
5300         local atime1
5301         local atime2
5302         local atime3
5303         local atime4
5304
5305         umount_client $MOUNT
5306         mount_client $MOUNT relatime
5307
5308         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5309         atime0=$(stat -c %X $DIR/$tfile)
5310
5311         # First read updates atime
5312         sleep 1
5313         cat $DIR/$tfile >/dev/null
5314         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5315
5316         # Next reads do not update atime
5317         sleep 1
5318         cat $DIR/$tfile >/dev/null
5319         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5320
5321         # If mtime is greater than atime, atime is updated
5322         sleep 1
5323         touch -m $DIR/$tfile # (mtime = now)
5324         sleep 1
5325         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5326         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5327
5328         # Next reads do not update atime
5329         sleep 1
5330         cat $DIR/$tfile >/dev/null
5331         atime4=$(stat -c %X $DIR/$tfile)
5332
5333         # Remount the client to clear 'relatime' option
5334         remount_client $MOUNT
5335
5336         (( atime0 < atime1 )) ||
5337                 error "atime $atime0 should be smaller than $atime1"
5338         (( atime1 == atime2 )) ||
5339                 error "atime $atime1 was updated to $atime2"
5340         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5341         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5342 }
5343 run_test 39s "relatime is supported"
5344
5345 test_40() {
5346         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5347         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5348                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5349         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5350                 error "$tfile is not 4096 bytes in size"
5351 }
5352 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5353
5354 test_41() {
5355         # bug 1553
5356         small_write $DIR/f41 18
5357 }
5358 run_test 41 "test small file write + fstat ====================="
5359
5360 count_ost_writes() {
5361         lctl get_param -n ${OSC}.*.stats |
5362                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5363                         END { printf("%0.0f", writes) }'
5364 }
5365
5366 # decent default
5367 WRITEBACK_SAVE=500
5368 DIRTY_RATIO_SAVE=40
5369 MAX_DIRTY_RATIO=50
5370 BG_DIRTY_RATIO_SAVE=10
5371 MAX_BG_DIRTY_RATIO=25
5372
5373 start_writeback() {
5374         trap 0
5375         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5376         # dirty_ratio, dirty_background_ratio
5377         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5378                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5379                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5380                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5381         else
5382                 # if file not here, we are a 2.4 kernel
5383                 kill -CONT `pidof kupdated`
5384         fi
5385 }
5386
5387 stop_writeback() {
5388         # setup the trap first, so someone cannot exit the test at the
5389         # exact wrong time and mess up a machine
5390         trap start_writeback EXIT
5391         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5392         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5393                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5394                 sysctl -w vm.dirty_writeback_centisecs=0
5395                 sysctl -w vm.dirty_writeback_centisecs=0
5396                 # save and increase /proc/sys/vm/dirty_ratio
5397                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5398                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5399                 # save and increase /proc/sys/vm/dirty_background_ratio
5400                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5401                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5402         else
5403                 # if file not here, we are a 2.4 kernel
5404                 kill -STOP `pidof kupdated`
5405         fi
5406 }
5407
5408 # ensure that all stripes have some grant before we test client-side cache
5409 setup_test42() {
5410         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5411                 dd if=/dev/zero of=$i bs=4k count=1
5412                 rm $i
5413         done
5414 }
5415
5416 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5417 # file truncation, and file removal.
5418 test_42a() {
5419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5420
5421         setup_test42
5422         cancel_lru_locks $OSC
5423         stop_writeback
5424         sync; sleep 1; sync # just to be safe
5425         BEFOREWRITES=`count_ost_writes`
5426         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5427         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5428         AFTERWRITES=`count_ost_writes`
5429         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5430                 error "$BEFOREWRITES < $AFTERWRITES"
5431         start_writeback
5432 }
5433 run_test 42a "ensure that we don't flush on close"
5434
5435 test_42b() {
5436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5437
5438         setup_test42
5439         cancel_lru_locks $OSC
5440         stop_writeback
5441         sync
5442         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5443         BEFOREWRITES=$(count_ost_writes)
5444         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5445         AFTERWRITES=$(count_ost_writes)
5446         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5447                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5448         fi
5449         BEFOREWRITES=$(count_ost_writes)
5450         sync || error "sync: $?"
5451         AFTERWRITES=$(count_ost_writes)
5452         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5453                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5454         fi
5455         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5456         start_writeback
5457         return 0
5458 }
5459 run_test 42b "test destroy of file with cached dirty data ======"
5460
5461 # if these tests just want to test the effect of truncation,
5462 # they have to be very careful.  consider:
5463 # - the first open gets a {0,EOF}PR lock
5464 # - the first write conflicts and gets a {0, count-1}PW
5465 # - the rest of the writes are under {count,EOF}PW
5466 # - the open for truncate tries to match a {0,EOF}PR
5467 #   for the filesize and cancels the PWs.
5468 # any number of fixes (don't get {0,EOF} on open, match
5469 # composite locks, do smarter file size management) fix
5470 # this, but for now we want these tests to verify that
5471 # the cancellation with truncate intent works, so we
5472 # start the file with a full-file pw lock to match against
5473 # until the truncate.
5474 trunc_test() {
5475         test=$1
5476         file=$DIR/$test
5477         offset=$2
5478         cancel_lru_locks $OSC
5479         stop_writeback
5480         # prime the file with 0,EOF PW to match
5481         touch $file
5482         $TRUNCATE $file 0
5483         sync; sync
5484         # now the real test..
5485         dd if=/dev/zero of=$file bs=1024 count=100
5486         BEFOREWRITES=`count_ost_writes`
5487         $TRUNCATE $file $offset
5488         cancel_lru_locks $OSC
5489         AFTERWRITES=`count_ost_writes`
5490         start_writeback
5491 }
5492
5493 test_42c() {
5494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5495
5496         trunc_test 42c 1024
5497         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5498                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5499         rm $file
5500 }
5501 run_test 42c "test partial truncate of file with cached dirty data"
5502
5503 test_42d() {
5504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5505
5506         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5507         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5508         $LCTL set_param debug=+cache
5509
5510         trunc_test 42d 0
5511         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5512                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5513         rm $file
5514 }
5515 run_test 42d "test complete truncate of file with cached dirty data"
5516
5517 test_42e() { # bug22074
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         local TDIR=$DIR/${tdir}e
5521         local pages=16 # hardcoded 16 pages, don't change it.
5522         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5523         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5524         local max_dirty_mb
5525         local warmup_files
5526
5527         test_mkdir $DIR/${tdir}e
5528         $LFS setstripe -c 1 $TDIR
5529         createmany -o $TDIR/f $files
5530
5531         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5532
5533         # we assume that with $OSTCOUNT files, at least one of them will
5534         # be allocated on OST0.
5535         warmup_files=$((OSTCOUNT * max_dirty_mb))
5536         createmany -o $TDIR/w $warmup_files
5537
5538         # write a large amount of data into one file and sync, to get good
5539         # avail_grant number from OST.
5540         for ((i=0; i<$warmup_files; i++)); do
5541                 idx=$($LFS getstripe -i $TDIR/w$i)
5542                 [ $idx -ne 0 ] && continue
5543                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5544                 break
5545         done
5546         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5547         sync
5548         $LCTL get_param $proc_osc0/cur_dirty_bytes
5549         $LCTL get_param $proc_osc0/cur_grant_bytes
5550
5551         # create as much dirty pages as we can while not to trigger the actual
5552         # RPCs directly. but depends on the env, VFS may trigger flush during this
5553         # period, hopefully we are good.
5554         for ((i=0; i<$warmup_files; i++)); do
5555                 idx=$($LFS getstripe -i $TDIR/w$i)
5556                 [ $idx -ne 0 ] && continue
5557                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5558         done
5559         $LCTL get_param $proc_osc0/cur_dirty_bytes
5560         $LCTL get_param $proc_osc0/cur_grant_bytes
5561
5562         # perform the real test
5563         $LCTL set_param $proc_osc0/rpc_stats 0
5564         for ((;i<$files; i++)); do
5565                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5566                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5567         done
5568         sync
5569         $LCTL get_param $proc_osc0/rpc_stats
5570
5571         local percent=0
5572         local have_ppr=false
5573         $LCTL get_param $proc_osc0/rpc_stats |
5574                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5575                         # skip lines until we are at the RPC histogram data
5576                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5577                         $have_ppr || continue
5578
5579                         # we only want the percent stat for < 16 pages
5580                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5581
5582                         percent=$((percent + WPCT))
5583                         if [[ $percent -gt 15 ]]; then
5584                                 error "less than 16-pages write RPCs" \
5585                                       "$percent% > 15%"
5586                                 break
5587                         fi
5588                 done
5589         rm -rf $TDIR
5590 }
5591 run_test 42e "verify sub-RPC writes are not done synchronously"
5592
5593 test_43A() { # was test_43
5594         test_mkdir $DIR/$tdir
5595         cp -p /bin/ls $DIR/$tdir/$tfile
5596         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5597         pid=$!
5598         # give multiop a chance to open
5599         sleep 1
5600
5601         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5602         kill -USR1 $pid
5603         # Wait for multiop to exit
5604         wait $pid
5605 }
5606 run_test 43A "execution of file opened for write should return -ETXTBSY"
5607
5608 test_43a() {
5609         test_mkdir $DIR/$tdir
5610         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5611         $DIR/$tdir/sleep 60 &
5612         SLEEP_PID=$!
5613         # Make sure exec of $tdir/sleep wins race with truncate
5614         sleep 1
5615         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5616         kill $SLEEP_PID
5617 }
5618 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5619
5620 test_43b() {
5621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5622
5623         test_mkdir $DIR/$tdir
5624         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5625         $DIR/$tdir/sleep 60 &
5626         SLEEP_PID=$!
5627         # Make sure exec of $tdir/sleep wins race with truncate
5628         sleep 1
5629         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5630         kill $SLEEP_PID
5631 }
5632 run_test 43b "truncate of file being executed should return -ETXTBSY"
5633
5634 test_43c() {
5635         local testdir="$DIR/$tdir"
5636         test_mkdir $testdir
5637         cp $SHELL $testdir/
5638         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5639                 ( cd $testdir && md5sum -c )
5640 }
5641 run_test 43c "md5sum of copy into lustre"
5642
5643 test_44A() { # was test_44
5644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5645
5646         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5647         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5648 }
5649 run_test 44A "zero length read from a sparse stripe"
5650
5651 test_44a() {
5652         local nstripe=$($LFS getstripe -c -d $DIR)
5653         [ -z "$nstripe" ] && skip "can't get stripe info"
5654         [[ $nstripe -gt $OSTCOUNT ]] &&
5655                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5656
5657         local stride=$($LFS getstripe -S -d $DIR)
5658         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5659                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5660         fi
5661
5662         OFFSETS="0 $((stride/2)) $((stride-1))"
5663         for offset in $OFFSETS; do
5664                 for i in $(seq 0 $((nstripe-1))); do
5665                         local GLOBALOFFSETS=""
5666                         # size in Bytes
5667                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5668                         local myfn=$DIR/d44a-$size
5669                         echo "--------writing $myfn at $size"
5670                         ll_sparseness_write $myfn $size ||
5671                                 error "ll_sparseness_write"
5672                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5673                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5674                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5675
5676                         for j in $(seq 0 $((nstripe-1))); do
5677                                 # size in Bytes
5678                                 size=$((((j + $nstripe )*$stride + $offset)))
5679                                 ll_sparseness_write $myfn $size ||
5680                                         error "ll_sparseness_write"
5681                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5682                         done
5683                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5684                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5685                         rm -f $myfn
5686                 done
5687         done
5688 }
5689 run_test 44a "test sparse pwrite ==============================="
5690
5691 dirty_osc_total() {
5692         tot=0
5693         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5694                 tot=$(($tot + $d))
5695         done
5696         echo $tot
5697 }
5698 do_dirty_record() {
5699         before=`dirty_osc_total`
5700         echo executing "\"$*\""
5701         eval $*
5702         after=`dirty_osc_total`
5703         echo before $before, after $after
5704 }
5705 test_45() {
5706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5707
5708         f="$DIR/f45"
5709         # Obtain grants from OST if it supports it
5710         echo blah > ${f}_grant
5711         stop_writeback
5712         sync
5713         do_dirty_record "echo blah > $f"
5714         [[ $before -eq $after ]] && error "write wasn't cached"
5715         do_dirty_record "> $f"
5716         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5717         do_dirty_record "echo blah > $f"
5718         [[ $before -eq $after ]] && error "write wasn't cached"
5719         do_dirty_record "sync"
5720         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5721         do_dirty_record "echo blah > $f"
5722         [[ $before -eq $after ]] && error "write wasn't cached"
5723         do_dirty_record "cancel_lru_locks osc"
5724         [[ $before -gt $after ]] ||
5725                 error "lock cancellation didn't lower dirty count"
5726         start_writeback
5727 }
5728 run_test 45 "osc io page accounting ============================"
5729
5730 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5731 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5732 # objects offset and an assert hit when an rpc was built with 1023's mapped
5733 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5734 test_46() {
5735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5736
5737         f="$DIR/f46"
5738         stop_writeback
5739         sync
5740         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5741         sync
5742         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5743         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5744         sync
5745         start_writeback
5746 }
5747 run_test 46 "dirtying a previously written page ================"
5748
5749 # test_47 is removed "Device nodes check" is moved to test_28
5750
5751 test_48a() { # bug 2399
5752         [ "$mds1_FSTYPE" = "zfs" ] &&
5753         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5754                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5755
5756         test_mkdir $DIR/$tdir
5757         cd $DIR/$tdir
5758         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5759         test_mkdir $DIR/$tdir
5760         touch foo || error "'touch foo' failed after recreating cwd"
5761         test_mkdir bar
5762         touch .foo || error "'touch .foo' failed after recreating cwd"
5763         test_mkdir .bar
5764         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5765         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5766         cd . || error "'cd .' failed after recreating cwd"
5767         mkdir . && error "'mkdir .' worked after recreating cwd"
5768         rmdir . && error "'rmdir .' worked after recreating cwd"
5769         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5770         cd .. || error "'cd ..' failed after recreating cwd"
5771 }
5772 run_test 48a "Access renamed working dir (should return errors)="
5773
5774 test_48b() { # bug 2399
5775         rm -rf $DIR/$tdir
5776         test_mkdir $DIR/$tdir
5777         cd $DIR/$tdir
5778         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5779         touch foo && error "'touch foo' worked after removing cwd"
5780         mkdir foo && error "'mkdir foo' worked after removing cwd"
5781         touch .foo && error "'touch .foo' worked after removing cwd"
5782         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5783         ls . > /dev/null && error "'ls .' worked after removing cwd"
5784         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5785         mkdir . && error "'mkdir .' worked after removing cwd"
5786         rmdir . && error "'rmdir .' worked after removing cwd"
5787         ln -s . foo && error "'ln -s .' worked after removing cwd"
5788         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5789 }
5790 run_test 48b "Access removed working dir (should return errors)="
5791
5792 test_48c() { # bug 2350
5793         #lctl set_param debug=-1
5794         #set -vx
5795         rm -rf $DIR/$tdir
5796         test_mkdir -p $DIR/$tdir/dir
5797         cd $DIR/$tdir/dir
5798         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5799         $TRACE touch foo && error "touch foo worked after removing cwd"
5800         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5801         touch .foo && error "touch .foo worked after removing cwd"
5802         mkdir .foo && error "mkdir .foo worked after removing cwd"
5803         $TRACE ls . && error "'ls .' worked after removing cwd"
5804         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5805         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5806         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5807         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5808         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5809 }
5810 run_test 48c "Access removed working subdir (should return errors)"
5811
5812 test_48d() { # bug 2350
5813         #lctl set_param debug=-1
5814         #set -vx
5815         rm -rf $DIR/$tdir
5816         test_mkdir -p $DIR/$tdir/dir
5817         cd $DIR/$tdir/dir
5818         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5819         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5820         $TRACE touch foo && error "'touch foo' worked after removing parent"
5821         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5822         touch .foo && error "'touch .foo' worked after removing parent"
5823         mkdir .foo && error "mkdir .foo worked after removing parent"
5824         $TRACE ls . && error "'ls .' worked after removing parent"
5825         $TRACE ls .. && error "'ls ..' worked after removing parent"
5826         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5827         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5828         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5829         true
5830 }
5831 run_test 48d "Access removed parent subdir (should return errors)"
5832
5833 test_48e() { # bug 4134
5834         #lctl set_param debug=-1
5835         #set -vx
5836         rm -rf $DIR/$tdir
5837         test_mkdir -p $DIR/$tdir/dir
5838         cd $DIR/$tdir/dir
5839         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5840         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5841         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5842         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5843         # On a buggy kernel addition of "touch foo" after cd .. will
5844         # produce kernel oops in lookup_hash_it
5845         touch ../foo && error "'cd ..' worked after recreate parent"
5846         cd $DIR
5847         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5848 }
5849 run_test 48e "Access to recreated parent subdir (should return errors)"
5850
5851 test_48f() {
5852         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5853                 skip "need MDS >= 2.13.55"
5854         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5855         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5856                 skip "needs different host for mdt1 mdt2"
5857         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5858
5859         $LFS mkdir -i0 $DIR/$tdir
5860         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5861
5862         for d in sub1 sub2 sub3; do
5863                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5864                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5865                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5866         done
5867
5868         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5869 }
5870 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5871
5872 test_49() { # LU-1030
5873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5874         remote_ost_nodsh && skip "remote OST with nodsh"
5875
5876         # get ost1 size - $FSNAME-OST0000
5877         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5878                 awk '{ print $4 }')
5879         # write 800M at maximum
5880         [[ $ost1_size -lt 2 ]] && ost1_size=2
5881         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5882
5883         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5884         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5885         local dd_pid=$!
5886
5887         # change max_pages_per_rpc while writing the file
5888         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5889         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5890         # loop until dd process exits
5891         while ps ax -opid | grep -wq $dd_pid; do
5892                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5893                 sleep $((RANDOM % 5 + 1))
5894         done
5895         # restore original max_pages_per_rpc
5896         $LCTL set_param $osc1_mppc=$orig_mppc
5897         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5898 }
5899 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5900
5901 test_50() {
5902         # bug 1485
5903         test_mkdir $DIR/$tdir
5904         cd $DIR/$tdir
5905         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5906 }
5907 run_test 50 "special situations: /proc symlinks  ==============="
5908
5909 test_51a() {    # was test_51
5910         # bug 1516 - create an empty entry right after ".." then split dir
5911         test_mkdir -c1 $DIR/$tdir
5912         touch $DIR/$tdir/foo
5913         $MCREATE $DIR/$tdir/bar
5914         rm $DIR/$tdir/foo
5915         createmany -m $DIR/$tdir/longfile 201
5916         FNUM=202
5917         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5918                 $MCREATE $DIR/$tdir/longfile$FNUM
5919                 FNUM=$(($FNUM + 1))
5920                 echo -n "+"
5921         done
5922         echo
5923         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5924 }
5925 run_test 51a "special situations: split htree with empty entry =="
5926
5927 cleanup_print_lfs_df () {
5928         trap 0
5929         $LFS df
5930         $LFS df -i
5931 }
5932
5933 test_51b() {
5934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5935
5936         local dir=$DIR/$tdir
5937         local nrdirs=$((65536 + 100))
5938
5939         # cleanup the directory
5940         rm -fr $dir
5941
5942         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5943
5944         $LFS df
5945         $LFS df -i
5946         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5947         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5948         [[ $numfree -lt $nrdirs ]] &&
5949                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5950
5951         # need to check free space for the directories as well
5952         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5953         numfree=$(( blkfree / $(fs_inode_ksize) ))
5954         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5955
5956         trap cleanup_print_lfs_df EXIT
5957
5958         # create files
5959         createmany -d $dir/d $nrdirs || {
5960                 unlinkmany $dir/d $nrdirs
5961                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5962         }
5963
5964         # really created :
5965         nrdirs=$(ls -U $dir | wc -l)
5966
5967         # unlink all but 100 subdirectories, then check it still works
5968         local left=100
5969         local delete=$((nrdirs - left))
5970
5971         $LFS df
5972         $LFS df -i
5973
5974         # for ldiskfs the nlink count should be 1, but this is OSD specific
5975         # and so this is listed for informational purposes only
5976         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5977         unlinkmany -d $dir/d $delete ||
5978                 error "unlink of first $delete subdirs failed"
5979
5980         echo "nlink between: $(stat -c %h $dir)"
5981         local found=$(ls -U $dir | wc -l)
5982         [ $found -ne $left ] &&
5983                 error "can't find subdirs: found only $found, expected $left"
5984
5985         unlinkmany -d $dir/d $delete $left ||
5986                 error "unlink of second $left subdirs failed"
5987         # regardless of whether the backing filesystem tracks nlink accurately
5988         # or not, the nlink count shouldn't be more than "." and ".." here
5989         local after=$(stat -c %h $dir)
5990         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5991                 echo "nlink after: $after"
5992
5993         cleanup_print_lfs_df
5994 }
5995 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5996
5997 test_51d_sub() {
5998         local stripecount=$1
5999         local nfiles=$2
6000
6001         log "create files with stripecount=$stripecount"
6002         $LFS setstripe -C $stripecount $DIR/$tdir
6003         createmany -o $DIR/$tdir/t- $nfiles
6004         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6005         for ((n = 0; n < $OSTCOUNT; n++)); do
6006                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6007                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6008                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6009                             '($1 == '$n') { objs += 1 } \
6010                             END { printf("%0.0f", objs) }')
6011                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6012         done
6013         unlinkmany $DIR/$tdir/t- $nfiles
6014         rm  -f $TMP/$tfile
6015
6016         local nlast
6017         local min=4
6018         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6019
6020         # For some combinations of stripecount and OSTCOUNT current code
6021         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6022         # than others. Rather than skipping this test entirely, check that
6023         # and keep testing to ensure imbalance does not get worse. LU-15282
6024         (( (OSTCOUNT == 6 && stripecount == 4) ||
6025            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6026            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6027         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6028                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6029                         { $LFS df && $LFS df -i &&
6030                         error "stripecount=$stripecount: " \
6031                               "OST $n has fewer objects vs. OST $nlast " \
6032                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6033                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6034                         { $LFS df && $LFS df -i &&
6035                         error "stripecount=$stripecount: " \
6036                               "OST $n has more objects vs. OST $nlast " \
6037                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6038
6039                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6040                         { $LFS df && $LFS df -i &&
6041                         error "stripecount=$stripecount: " \
6042                               "OST $n has fewer #0 objects vs. OST $nlast " \
6043                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6044                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6045                         { $LFS df && $LFS df -i &&
6046                         error "stripecount=$stripecount: " \
6047                               "OST $n has more #0 objects vs. OST $nlast " \
6048                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6049         done
6050 }
6051
6052 test_51d() {
6053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6054         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6055
6056         local stripecount
6057         local per_ost=100
6058         local nfiles=$((per_ost * OSTCOUNT))
6059         local mdts=$(comma_list $(mdts_nodes))
6060         local param="osp.*.create_count"
6061         local qos_old=$(do_facet mds1 \
6062                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6063
6064         do_nodes $mdts \
6065                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6066         stack_trap "do_nodes $mdts \
6067                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6068
6069         test_mkdir $DIR/$tdir
6070         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6071         (( dirstripes > 0 )) || dirstripes=1
6072
6073         # Ensure enough OST objects precreated for tests to pass without
6074         # running out of objects.  This is an LOV r-r OST algorithm test,
6075         # not an OST object precreation test.
6076         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6077         (( old >= nfiles )) ||
6078         {
6079                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6080
6081                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6082                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6083
6084                 # trigger precreation from all MDTs for all OSTs
6085                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6086                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6087                 done
6088         }
6089
6090         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6091                 sleep 8  # allow object precreation to catch up
6092                 test_51d_sub $stripecount $nfiles
6093         done
6094 }
6095 run_test 51d "check LOV round-robin OST object distribution"
6096
6097 test_51e() {
6098         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6099                 skip_env "ldiskfs only test"
6100         fi
6101
6102         test_mkdir -c1 $DIR/$tdir
6103         test_mkdir -c1 $DIR/$tdir/d0
6104
6105         touch $DIR/$tdir/d0/foo
6106         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6107                 error "file exceed 65000 nlink limit!"
6108         unlinkmany $DIR/$tdir/d0/f- 65001
6109         return 0
6110 }
6111 run_test 51e "check file nlink limit"
6112
6113 test_51f() {
6114         test_mkdir $DIR/$tdir
6115
6116         local max=100000
6117         local ulimit_old=$(ulimit -n)
6118         local spare=20 # number of spare fd's for scripts/libraries, etc.
6119         local mdt=$($LFS getstripe -m $DIR/$tdir)
6120         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6121
6122         echo "MDT$mdt numfree=$numfree, max=$max"
6123         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6124         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6125                 while ! ulimit -n $((numfree + spare)); do
6126                         numfree=$((numfree * 3 / 4))
6127                 done
6128                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6129         else
6130                 echo "left ulimit at $ulimit_old"
6131         fi
6132
6133         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6134                 unlinkmany $DIR/$tdir/f $numfree
6135                 error "create+open $numfree files in $DIR/$tdir failed"
6136         }
6137         ulimit -n $ulimit_old
6138
6139         # if createmany exits at 120s there will be fewer than $numfree files
6140         unlinkmany $DIR/$tdir/f $numfree || true
6141 }
6142 run_test 51f "check many open files limit"
6143
6144 test_52a() {
6145         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6146         test_mkdir $DIR/$tdir
6147         touch $DIR/$tdir/foo
6148         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6149         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6150         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6151         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6152         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6153                                         error "link worked"
6154         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6155         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6156         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6157                                                      error "lsattr"
6158         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6159         cp -r $DIR/$tdir $TMP/
6160         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6161 }
6162 run_test 52a "append-only flag test (should return errors)"
6163
6164 test_52b() {
6165         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6166         test_mkdir $DIR/$tdir
6167         touch $DIR/$tdir/foo
6168         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6169         cat test > $DIR/$tdir/foo && error "cat test worked"
6170         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6171         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6172         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6173                                         error "link worked"
6174         echo foo >> $DIR/$tdir/foo && error "echo worked"
6175         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6176         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6177         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6178         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6179                                                         error "lsattr"
6180         chattr -i $DIR/$tdir/foo || error "chattr failed"
6181
6182         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6183 }
6184 run_test 52b "immutable flag test (should return errors) ======="
6185
6186 test_53() {
6187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6188         remote_mds_nodsh && skip "remote MDS with nodsh"
6189         remote_ost_nodsh && skip "remote OST with nodsh"
6190
6191         local param
6192         local param_seq
6193         local ostname
6194         local mds_last
6195         local mds_last_seq
6196         local ost_last
6197         local ost_last_seq
6198         local ost_last_id
6199         local ostnum
6200         local node
6201         local found=false
6202         local support_last_seq=true
6203
6204         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6205                 support_last_seq=false
6206
6207         # only test MDT0000
6208         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6209         local value
6210         for value in $(do_facet $SINGLEMDS \
6211                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6212                 param=$(echo ${value[0]} | cut -d "=" -f1)
6213                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6214
6215                 if $support_last_seq; then
6216                         param_seq=$(echo $param |
6217                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6218                         mds_last_seq=$(do_facet $SINGLEMDS \
6219                                        $LCTL get_param -n $param_seq)
6220                 fi
6221                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6222
6223                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6224                 node=$(facet_active_host ost$((ostnum+1)))
6225                 param="obdfilter.$ostname.last_id"
6226                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6227                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6228                         ost_last_id=$ost_last
6229
6230                         if $support_last_seq; then
6231                                 ost_last_id=$(echo $ost_last |
6232                                               awk -F':' '{print $2}' |
6233                                               sed -e "s/^0x//g")
6234                                 ost_last_seq=$(echo $ost_last |
6235                                                awk -F':' '{print $1}')
6236                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6237                         fi
6238
6239                         if [[ $ost_last_id != $mds_last ]]; then
6240                                 error "$ost_last_id != $mds_last"
6241                         else
6242                                 found=true
6243                                 break
6244                         fi
6245                 done
6246         done
6247         $found || error "can not match last_seq/last_id for $mdtosc"
6248         return 0
6249 }
6250 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6251
6252 test_54a() {
6253         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6254
6255         LANG=C $SOCKETSERVER $DIR/socket ||
6256                 error "$SOCKETSERVER $DIR/socket failed: $?"
6257         LANG=C $SOCKETCLIENT $DIR/socket ||
6258                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6259         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6260 }
6261 run_test 54a "unix domain socket test =========================="
6262
6263 test_54b() {
6264         f="$DIR/f54b"
6265         mknod $f c 1 3
6266         chmod 0666 $f
6267         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6268 }
6269 run_test 54b "char device works in lustre ======================"
6270
6271 find_loop_dev() {
6272         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6273         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6274         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6275
6276         for i in $(seq 3 7); do
6277                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6278                 LOOPDEV=$LOOPBASE$i
6279                 LOOPNUM=$i
6280                 break
6281         done
6282 }
6283
6284 cleanup_54c() {
6285         local rc=0
6286         loopdev="$DIR/loop54c"
6287
6288         trap 0
6289         $UMOUNT $DIR/$tdir || rc=$?
6290         losetup -d $loopdev || true
6291         losetup -d $LOOPDEV || true
6292         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6293         return $rc
6294 }
6295
6296 test_54c() {
6297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6298
6299         loopdev="$DIR/loop54c"
6300
6301         find_loop_dev
6302         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6303         trap cleanup_54c EXIT
6304         mknod $loopdev b 7 $LOOPNUM
6305         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6306         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6307         losetup $loopdev $DIR/$tfile ||
6308                 error "can't set up $loopdev for $DIR/$tfile"
6309         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6310         test_mkdir $DIR/$tdir
6311         mount -t ext2 $loopdev $DIR/$tdir ||
6312                 error "error mounting $loopdev on $DIR/$tdir"
6313         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6314                 error "dd write"
6315         df $DIR/$tdir
6316         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6317                 error "dd read"
6318         cleanup_54c
6319 }
6320 run_test 54c "block device works in lustre ====================="
6321
6322 test_54d() {
6323         local pipe="$DIR/$tfile.pipe"
6324         local string="aaaaaa"
6325
6326         mknod $pipe p
6327         echo -n "$string" > $pipe &
6328         local result=$(cat $pipe)
6329         [[ "$result" == "$string" ]] || error "$result != $string"
6330 }
6331 run_test 54d "fifo device works in lustre ======================"
6332
6333 test_54e() {
6334         f="$DIR/f54e"
6335         string="aaaaaa"
6336         cp -aL /dev/console $f
6337         echo $string > $f || error "echo $string to $f failed"
6338 }
6339 run_test 54e "console/tty device works in lustre ======================"
6340
6341 test_56a() {
6342         local numfiles=3
6343         local numdirs=2
6344         local dir=$DIR/$tdir
6345
6346         rm -rf $dir
6347         test_mkdir -p $dir/dir
6348         for i in $(seq $numfiles); do
6349                 touch $dir/file$i
6350                 touch $dir/dir/file$i
6351         done
6352
6353         local numcomp=$($LFS getstripe --component-count $dir)
6354
6355         [[ $numcomp == 0 ]] && numcomp=1
6356
6357         # test lfs getstripe with --recursive
6358         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6359
6360         [[ $filenum -eq $((numfiles * 2)) ]] ||
6361                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6362         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6363         [[ $filenum -eq $numfiles ]] ||
6364                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6365         echo "$LFS getstripe showed obdidx or l_ost_idx"
6366
6367         # test lfs getstripe with file instead of dir
6368         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6369         [[ $filenum -eq 1 ]] ||
6370                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6371         echo "$LFS getstripe file1 passed"
6372
6373         #test lfs getstripe with --verbose
6374         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6375         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6376                 error "$LFS getstripe --verbose $dir: "\
6377                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6378         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6379                 error "$LFS getstripe $dir: showed lmm_magic"
6380
6381         #test lfs getstripe with -v prints lmm_fid
6382         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6383         local countfids=$((numdirs + numfiles * numcomp))
6384         [[ $filenum -eq $countfids ]] ||
6385                 error "$LFS getstripe -v $dir: "\
6386                       "got $filenum want $countfids lmm_fid"
6387         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6388                 error "$LFS getstripe $dir: showed lmm_fid by default"
6389         echo "$LFS getstripe --verbose passed"
6390
6391         #check for FID information
6392         local fid1=$($LFS getstripe --fid $dir/file1)
6393         local fid2=$($LFS getstripe --verbose $dir/file1 |
6394                      awk '/lmm_fid: / { print $2; exit; }')
6395         local fid3=$($LFS path2fid $dir/file1)
6396
6397         [ "$fid1" != "$fid2" ] &&
6398                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6399         [ "$fid1" != "$fid3" ] &&
6400                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6401         echo "$LFS getstripe --fid passed"
6402
6403         #test lfs getstripe with --obd
6404         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6405                 error "$LFS getstripe --obd wrong_uuid: should return error"
6406
6407         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6408
6409         local ostidx=1
6410         local obduuid=$(ostuuid_from_index $ostidx)
6411         local found=$($LFS getstripe -r --obd $obduuid $dir |
6412                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6413
6414         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6415         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6416                 ((filenum--))
6417         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6418                 ((filenum--))
6419
6420         [[ $found -eq $filenum ]] ||
6421                 error "$LFS getstripe --obd: found $found expect $filenum"
6422         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6423                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6424                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6425                 error "$LFS getstripe --obd: should not show file on other obd"
6426         echo "$LFS getstripe --obd passed"
6427 }
6428 run_test 56a "check $LFS getstripe"
6429
6430 test_56b() {
6431         local dir=$DIR/$tdir
6432         local numdirs=3
6433
6434         test_mkdir $dir
6435         for i in $(seq $numdirs); do
6436                 test_mkdir $dir/dir$i
6437         done
6438
6439         # test lfs getdirstripe default mode is non-recursion, which is
6440         # different from lfs getstripe
6441         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6442
6443         [[ $dircnt -eq 1 ]] ||
6444                 error "$LFS getdirstripe: found $dircnt, not 1"
6445         dircnt=$($LFS getdirstripe --recursive $dir |
6446                 grep -c lmv_stripe_count)
6447         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6448                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6449 }
6450 run_test 56b "check $LFS getdirstripe"
6451
6452 test_56bb() {
6453         verify_yaml_available || skip_env "YAML verification not installed"
6454         local output_file=$DIR/$tfile.out
6455
6456         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6457
6458         cat $output_file
6459         cat $output_file | verify_yaml || error "layout is not valid YAML"
6460 }
6461 run_test 56bb "check $LFS getdirstripe layout is YAML"
6462
6463 test_56c() {
6464         remote_ost_nodsh && skip "remote OST with nodsh"
6465
6466         local ost_idx=0
6467         local ost_name=$(ostname_from_index $ost_idx)
6468         local old_status=$(ost_dev_status $ost_idx)
6469         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6470
6471         [[ -z "$old_status" ]] ||
6472                 skip_env "OST $ost_name is in $old_status status"
6473
6474         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6475         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6476                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6477         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6478                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6479                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6480         fi
6481
6482         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6483                 error "$LFS df -v showing inactive devices"
6484         sleep_maxage
6485
6486         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6487
6488         [[ "$new_status" =~ "D" ]] ||
6489                 error "$ost_name status is '$new_status', missing 'D'"
6490         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6491                 [[ "$new_status" =~ "N" ]] ||
6492                         error "$ost_name status is '$new_status', missing 'N'"
6493         fi
6494         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6495                 [[ "$new_status" =~ "f" ]] ||
6496                         error "$ost_name status is '$new_status', missing 'f'"
6497         fi
6498
6499         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6500         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6501                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6502         [[ -z "$p" ]] && restore_lustre_params < $p || true
6503         sleep_maxage
6504
6505         new_status=$(ost_dev_status $ost_idx)
6506         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6507                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6508         # can't check 'f' as devices may actually be on flash
6509 }
6510 run_test 56c "check 'lfs df' showing device status"
6511
6512 test_56d() {
6513         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6514         local osts=$($LFS df -v $MOUNT | grep -c OST)
6515
6516         $LFS df $MOUNT
6517
6518         (( mdts == MDSCOUNT )) ||
6519                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6520         (( osts == OSTCOUNT )) ||
6521                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6522 }
6523 run_test 56d "'lfs df -v' prints only configured devices"
6524
6525 test_56e() {
6526         err_enoent=2 # No such file or directory
6527         err_eopnotsupp=95 # Operation not supported
6528
6529         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6530         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6531
6532         # Check for handling of path not exists
6533         output=$($LFS df $enoent_mnt 2>&1)
6534         ret=$?
6535
6536         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6537         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6538                 error "expect failure $err_enoent, not $ret"
6539
6540         # Check for handling of non-Lustre FS
6541         output=$($LFS df $notsup_mnt)
6542         ret=$?
6543
6544         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6545         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6546                 error "expect success $err_eopnotsupp, not $ret"
6547
6548         # Check for multiple LustreFS argument
6549         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6550         ret=$?
6551
6552         [[ $output -eq 3 && $ret -eq 0 ]] ||
6553                 error "expect success 3, not $output, rc = $ret"
6554
6555         # Check for correct non-Lustre FS handling among multiple
6556         # LustreFS argument
6557         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6558                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6559         ret=$?
6560
6561         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6562                 error "expect success 2, not $output, rc = $ret"
6563 }
6564 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6565
6566 NUMFILES=3
6567 NUMDIRS=3
6568 setup_56() {
6569         local local_tdir="$1"
6570         local local_numfiles="$2"
6571         local local_numdirs="$3"
6572         local dir_params="$4"
6573         local dir_stripe_params="$5"
6574
6575         if [ ! -d "$local_tdir" ] ; then
6576                 test_mkdir -p $dir_stripe_params $local_tdir
6577                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6578                 for i in $(seq $local_numfiles) ; do
6579                         touch $local_tdir/file$i
6580                 done
6581                 for i in $(seq $local_numdirs) ; do
6582                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6583                         for j in $(seq $local_numfiles) ; do
6584                                 touch $local_tdir/dir$i/file$j
6585                         done
6586                 done
6587         fi
6588 }
6589
6590 setup_56_special() {
6591         local local_tdir=$1
6592         local local_numfiles=$2
6593         local local_numdirs=$3
6594
6595         setup_56 $local_tdir $local_numfiles $local_numdirs
6596
6597         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6598                 for i in $(seq $local_numfiles) ; do
6599                         mknod $local_tdir/loop${i}b b 7 $i
6600                         mknod $local_tdir/null${i}c c 1 3
6601                         ln -s $local_tdir/file1 $local_tdir/link${i}
6602                 done
6603                 for i in $(seq $local_numdirs) ; do
6604                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6605                         mknod $local_tdir/dir$i/null${i}c c 1 3
6606                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6607                 done
6608         fi
6609 }
6610
6611 test_56g() {
6612         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6613         local expected=$(($NUMDIRS + 2))
6614
6615         setup_56 $dir $NUMFILES $NUMDIRS
6616
6617         # test lfs find with -name
6618         for i in $(seq $NUMFILES) ; do
6619                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6620
6621                 [ $nums -eq $expected ] ||
6622                         error "lfs find -name '*$i' $dir wrong: "\
6623                               "found $nums, expected $expected"
6624         done
6625 }
6626 run_test 56g "check lfs find -name"
6627
6628 test_56h() {
6629         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6630         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6631
6632         setup_56 $dir $NUMFILES $NUMDIRS
6633
6634         # test lfs find with ! -name
6635         for i in $(seq $NUMFILES) ; do
6636                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6637
6638                 [ $nums -eq $expected ] ||
6639                         error "lfs find ! -name '*$i' $dir wrong: "\
6640                               "found $nums, expected $expected"
6641         done
6642 }
6643 run_test 56h "check lfs find ! -name"
6644
6645 test_56i() {
6646         local dir=$DIR/$tdir
6647
6648         test_mkdir $dir
6649
6650         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6651         local out=$($cmd)
6652
6653         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6654 }
6655 run_test 56i "check 'lfs find -ost UUID' skips directories"
6656
6657 test_56j() {
6658         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6659
6660         setup_56_special $dir $NUMFILES $NUMDIRS
6661
6662         local expected=$((NUMDIRS + 1))
6663         local cmd="$LFS find -type d $dir"
6664         local nums=$($cmd | wc -l)
6665
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668 }
6669 run_test 56j "check lfs find -type d"
6670
6671 test_56k() {
6672         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6673
6674         setup_56_special $dir $NUMFILES $NUMDIRS
6675
6676         local expected=$(((NUMDIRS + 1) * NUMFILES))
6677         local cmd="$LFS find -type f $dir"
6678         local nums=$($cmd | wc -l)
6679
6680         [ $nums -eq $expected ] ||
6681                 error "'$cmd' wrong: found $nums, expected $expected"
6682 }
6683 run_test 56k "check lfs find -type f"
6684
6685 test_56l() {
6686         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6687
6688         setup_56_special $dir $NUMFILES $NUMDIRS
6689
6690         local expected=$((NUMDIRS + NUMFILES))
6691         local cmd="$LFS find -type b $dir"
6692         local nums=$($cmd | wc -l)
6693
6694         [ $nums -eq $expected ] ||
6695                 error "'$cmd' wrong: found $nums, expected $expected"
6696 }
6697 run_test 56l "check lfs find -type b"
6698
6699 test_56m() {
6700         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6701
6702         setup_56_special $dir $NUMFILES $NUMDIRS
6703
6704         local expected=$((NUMDIRS + NUMFILES))
6705         local cmd="$LFS find -type c $dir"
6706         local nums=$($cmd | wc -l)
6707         [ $nums -eq $expected ] ||
6708                 error "'$cmd' wrong: found $nums, expected $expected"
6709 }
6710 run_test 56m "check lfs find -type c"
6711
6712 test_56n() {
6713         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6714         setup_56_special $dir $NUMFILES $NUMDIRS
6715
6716         local expected=$((NUMDIRS + NUMFILES))
6717         local cmd="$LFS find -type l $dir"
6718         local nums=$($cmd | wc -l)
6719
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722 }
6723 run_test 56n "check lfs find -type l"
6724
6725 test_56o() {
6726         local dir=$DIR/$tdir
6727
6728         setup_56 $dir $NUMFILES $NUMDIRS
6729         utime $dir/file1 > /dev/null || error "utime (1)"
6730         utime $dir/file2 > /dev/null || error "utime (2)"
6731         utime $dir/dir1 > /dev/null || error "utime (3)"
6732         utime $dir/dir2 > /dev/null || error "utime (4)"
6733         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6734         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6735
6736         local expected=4
6737         local nums=$($LFS find -mtime +0 $dir | wc -l)
6738
6739         [ $nums -eq $expected ] ||
6740                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6741
6742         expected=12
6743         cmd="$LFS find -mtime 0 $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56o "check lfs find -mtime for old files"
6749
6750 test_56ob() {
6751         local dir=$DIR/$tdir
6752         local expected=1
6753         local count=0
6754
6755         # just to make sure there is something that won't be found
6756         test_mkdir $dir
6757         touch $dir/$tfile.now
6758
6759         for age in year week day hour min; do
6760                 count=$((count + 1))
6761
6762                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6763                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6764                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6765
6766                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6767                 local nums=$($cmd | wc -l)
6768                 [ $nums -eq $expected ] ||
6769                         error "'$cmd' wrong: found $nums, expected $expected"
6770
6771                 cmd="$LFS find $dir -atime $count${age:0:1}"
6772                 nums=$($cmd | wc -l)
6773                 [ $nums -eq $expected ] ||
6774                         error "'$cmd' wrong: found $nums, expected $expected"
6775         done
6776
6777         sleep 2
6778         cmd="$LFS find $dir -ctime +1s -type f"
6779         nums=$($cmd | wc -l)
6780         (( $nums == $count * 2 + 1)) ||
6781                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6782 }
6783 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6784
6785 test_newerXY_base() {
6786         local x=$1
6787         local y=$2
6788         local dir=$DIR/$tdir
6789         local ref
6790         local negref
6791
6792         if [ $y == "t" ]; then
6793                 if [ $x == "b" ]; then
6794                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6795                 else
6796                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6797                 fi
6798         else
6799                 ref=$DIR/$tfile.newer.$x$y
6800                 touch $ref || error "touch $ref failed"
6801         fi
6802
6803         echo "before = $ref"
6804         sleep 2
6805         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6806         sleep 2
6807         if [ $y == "t" ]; then
6808                 if [ $x == "b" ]; then
6809                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6810                 else
6811                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6812                 fi
6813         else
6814                 negref=$DIR/$tfile.negnewer.$x$y
6815                 touch $negref || error "touch $negref failed"
6816         fi
6817
6818         echo "after = $negref"
6819         local cmd="$LFS find $dir -newer$x$y $ref"
6820         local nums=$(eval $cmd | wc -l)
6821         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6822
6823         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6824                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6825
6826         cmd="$LFS find $dir ! -newer$x$y $negref"
6827         nums=$(eval $cmd | wc -l)
6828         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6829                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6830
6831         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6832         nums=$(eval $cmd | wc -l)
6833         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6834                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6835
6836         rm -rf $DIR/*
6837 }
6838
6839 test_56oc() {
6840         test_newerXY_base "a" "a"
6841         test_newerXY_base "a" "m"
6842         test_newerXY_base "a" "c"
6843         test_newerXY_base "m" "a"
6844         test_newerXY_base "m" "m"
6845         test_newerXY_base "m" "c"
6846         test_newerXY_base "c" "a"
6847         test_newerXY_base "c" "m"
6848         test_newerXY_base "c" "c"
6849
6850         test_newerXY_base "a" "t"
6851         test_newerXY_base "m" "t"
6852         test_newerXY_base "c" "t"
6853
6854         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6855            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6856                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6857
6858         test_newerXY_base "b" "b"
6859         test_newerXY_base "b" "t"
6860 }
6861 run_test 56oc "check lfs find -newerXY work"
6862
6863 test_56od() {
6864         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6865                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6866
6867         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6868                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6869
6870         local dir=$DIR/$tdir
6871         local ref=$DIR/$tfile.ref
6872         local negref=$DIR/$tfile.negref
6873
6874         mkdir $dir || error "mkdir $dir failed"
6875         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6876         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6877         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6878         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6879         touch $ref || error "touch $ref failed"
6880         # sleep 3 seconds at least
6881         sleep 3
6882
6883         local before=$(do_facet mds1 date +%s)
6884         local skew=$(($(date +%s) - before + 1))
6885
6886         if (( skew < 0 && skew > -5 )); then
6887                 sleep $((0 - skew + 1))
6888                 skew=0
6889         fi
6890
6891         # Set the dir stripe params to limit files all on MDT0,
6892         # otherwise we need to calc the max clock skew between
6893         # the client and MDTs.
6894         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6895         sleep 2
6896         touch $negref || error "touch $negref failed"
6897
6898         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6899         local nums=$($cmd | wc -l)
6900         local expected=$(((NUMFILES + 1) * NUMDIRS))
6901
6902         [ $nums -eq $expected ] ||
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904
6905         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6906         nums=$($cmd | wc -l)
6907         expected=$((NUMFILES + 1))
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910
6911         [ $skew -lt 0 ] && return
6912
6913         local after=$(do_facet mds1 date +%s)
6914         local age=$((after - before + 1 + skew))
6915
6916         cmd="$LFS find $dir -btime -${age}s -type f"
6917         nums=$($cmd | wc -l)
6918         expected=$(((NUMFILES + 1) * NUMDIRS))
6919
6920         echo "Clock skew between client and server: $skew, age:$age"
6921         [ $nums -eq $expected ] ||
6922                 error "'$cmd' wrong: found $nums, expected $expected"
6923
6924         expected=$(($NUMDIRS + 1))
6925         cmd="$LFS find $dir -btime -${age}s -type d"
6926         nums=$($cmd | wc -l)
6927         [ $nums -eq $expected ] ||
6928                 error "'$cmd' wrong: found $nums, expected $expected"
6929         rm -f $ref $negref || error "Failed to remove $ref $negref"
6930 }
6931 run_test 56od "check lfs find -btime with units"
6932
6933 test_56p() {
6934         [ $RUNAS_ID -eq $UID ] &&
6935                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6936
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir $NUMFILES $NUMDIRS
6940         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6941
6942         local expected=$NUMFILES
6943         local cmd="$LFS find -uid $RUNAS_ID $dir"
6944         local nums=$($cmd | wc -l)
6945
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948
6949         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6950         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6951         nums=$($cmd | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954 }
6955 run_test 56p "check lfs find -uid and ! -uid"
6956
6957 test_56q() {
6958         [ $RUNAS_ID -eq $UID ] &&
6959                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6960
6961         local dir=$DIR/$tdir
6962
6963         setup_56 $dir $NUMFILES $NUMDIRS
6964         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6965
6966         local expected=$NUMFILES
6967         local cmd="$LFS find -gid $RUNAS_GID $dir"
6968         local nums=$($cmd | wc -l)
6969
6970         [ $nums -eq $expected ] ||
6971                 error "'$cmd' wrong: found $nums, expected $expected"
6972
6973         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6974         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6975         nums=$($cmd | wc -l)
6976         [ $nums -eq $expected ] ||
6977                 error "'$cmd' wrong: found $nums, expected $expected"
6978 }
6979 run_test 56q "check lfs find -gid and ! -gid"
6980
6981 test_56r() {
6982         local dir=$DIR/$tdir
6983
6984         setup_56 $dir $NUMFILES $NUMDIRS
6985
6986         local expected=12
6987         local cmd="$LFS find -size 0 -type f -lazy $dir"
6988         local nums=$($cmd | wc -l)
6989
6990         [ $nums -eq $expected ] ||
6991                 error "'$cmd' wrong: found $nums, expected $expected"
6992         cmd="$LFS find -size 0 -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996
6997         expected=0
6998         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6999         nums=$($cmd | wc -l)
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002         cmd="$LFS find ! -size 0 -type f $dir"
7003         nums=$($cmd | wc -l)
7004         [ $nums -eq $expected ] ||
7005                 error "'$cmd' wrong: found $nums, expected $expected"
7006
7007         echo "test" > $dir/$tfile
7008         echo "test2" > $dir/$tfile.2 && sync
7009         expected=1
7010         cmd="$LFS find -size 5 -type f -lazy $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014         cmd="$LFS find -size 5 -type f $dir"
7015         nums=$($cmd | wc -l)
7016         [ $nums -eq $expected ] ||
7017                 error "'$cmd' wrong: found $nums, expected $expected"
7018
7019         expected=1
7020         cmd="$LFS find -size +5 -type f -lazy $dir"
7021         nums=$($cmd | wc -l)
7022         [ $nums -eq $expected ] ||
7023                 error "'$cmd' wrong: found $nums, expected $expected"
7024         cmd="$LFS find -size +5 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=2
7030         cmd="$LFS find -size +0 -type f -lazy $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034         cmd="$LFS find -size +0 -type f $dir"
7035         nums=$($cmd | wc -l)
7036         [ $nums -eq $expected ] ||
7037                 error "'$cmd' wrong: found $nums, expected $expected"
7038
7039         expected=2
7040         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7041         nums=$($cmd | wc -l)
7042         [ $nums -eq $expected ] ||
7043                 error "'$cmd' wrong: found $nums, expected $expected"
7044         cmd="$LFS find ! -size -5 -type f $dir"
7045         nums=$($cmd | wc -l)
7046         [ $nums -eq $expected ] ||
7047                 error "'$cmd' wrong: found $nums, expected $expected"
7048
7049         expected=12
7050         cmd="$LFS find -size -5 -type f -lazy $dir"
7051         nums=$($cmd | wc -l)
7052         [ $nums -eq $expected ] ||
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054         cmd="$LFS find -size -5 -type f $dir"
7055         nums=$($cmd | wc -l)
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058 }
7059 run_test 56r "check lfs find -size works"
7060
7061 test_56ra_sub() {
7062         local expected=$1
7063         local glimpses=$2
7064         local cmd="$3"
7065
7066         cancel_lru_locks $OSC
7067
7068         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7069         local nums=$($cmd | wc -l)
7070
7071         [ $nums -eq $expected ] ||
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073
7074         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7075
7076         if (( rpcs_before + glimpses != rpcs_after )); then
7077                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7078                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7079
7080                 if [[ $glimpses == 0 ]]; then
7081                         error "'$cmd' should not send glimpse RPCs to OST"
7082                 else
7083                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7084                 fi
7085         fi
7086 }
7087
7088 test_56ra() {
7089         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7090                 skip "MDS < 2.12.58 doesn't return LSOM data"
7091         local dir=$DIR/$tdir
7092         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7093
7094         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7095
7096         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7097         $LCTL set_param -n llite.*.statahead_agl=0
7098         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7099
7100         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7101         # open and close all files to ensure LSOM is updated
7102         cancel_lru_locks $OSC
7103         find $dir -type f | xargs cat > /dev/null
7104
7105         #   expect_found  glimpse_rpcs  command_to_run
7106         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7107         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7108         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7109         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7110
7111         echo "test" > $dir/$tfile
7112         echo "test2" > $dir/$tfile.2 && sync
7113         cancel_lru_locks $OSC
7114         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7115
7116         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7117         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7118         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7119         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7120
7121         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7122         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7123         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7124         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7125         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7126         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7127 }
7128 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7129
7130 test_56rb() {
7131         local dir=$DIR/$tdir
7132         local tmp=$TMP/$tfile.log
7133         local mdt_idx;
7134
7135         test_mkdir -p $dir || error "failed to mkdir $dir"
7136         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7137                 error "failed to setstripe $dir/$tfile"
7138         mdt_idx=$($LFS getdirstripe -i $dir)
7139         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7140
7141         stack_trap "rm -f $tmp" EXIT
7142         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7143         ! grep -q obd_uuid $tmp ||
7144                 error "failed to find --size +100K --ost 0 $dir"
7145         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7146         ! grep -q obd_uuid $tmp ||
7147                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7148 }
7149 run_test 56rb "check lfs find --size --ost/--mdt works"
7150
7151 test_56rc() {
7152         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7153         local dir=$DIR/$tdir
7154         local found
7155
7156         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7157         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7158         (( $MDSCOUNT > 2 )) &&
7159                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7160         mkdir $dir/$tdir-{1..10}
7161         touch $dir/$tfile-{1..10}
7162
7163         found=$($LFS find $dir --mdt-count 2 | wc -l)
7164         expect=11
7165         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7166
7167         found=$($LFS find $dir -T +1 | wc -l)
7168         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7169         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7170
7171         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7172         expect=11
7173         (( $found == $expect )) || error "found $found all_char, expect $expect"
7174
7175         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7176         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7177         (( $found == $expect )) || error "found $found all_char, expect $expect"
7178 }
7179 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7180
7181 test_56rd() {
7182         local dir=$DIR/$tdir
7183
7184         test_mkdir $dir
7185         rm -f $dir/*
7186
7187         mkfifo $dir/fifo || error "failed to create fifo file"
7188         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7189                 error "should not fail even cannot get projid from pipe file"
7190         found=$($LFS find $dir -t p --printf "%y")
7191         [[ "p" == $found ]] || error "found $found, expect p"
7192
7193         mknod $dir/chardev c 1 5 ||
7194                 error "failed to create character device file"
7195         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7196                 error "should not fail even cannot get projid from chardev file"
7197         found=$($LFS find $dir -t c --printf "%y")
7198         [[ "c" == $found ]] || error "found $found, expect c"
7199
7200         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7201         (( found == 2 )) || error "unable to list all files"
7202 }
7203 run_test 56rd "check lfs find --printf special files"
7204
7205 test_56s() { # LU-611 #LU-9369
7206         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7207
7208         local dir=$DIR/$tdir
7209         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7210
7211         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7212         for i in $(seq $NUMDIRS); do
7213                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7214         done
7215
7216         local expected=$NUMDIRS
7217         local cmd="$LFS find -c $OSTCOUNT $dir"
7218         local nums=$($cmd | wc -l)
7219
7220         [ $nums -eq $expected ] || {
7221                 $LFS getstripe -R $dir
7222                 error "'$cmd' wrong: found $nums, expected $expected"
7223         }
7224
7225         expected=$((NUMDIRS + onestripe))
7226         cmd="$LFS find -stripe-count +0 -type f $dir"
7227         nums=$($cmd | wc -l)
7228         [ $nums -eq $expected ] || {
7229                 $LFS getstripe -R $dir
7230                 error "'$cmd' wrong: found $nums, expected $expected"
7231         }
7232
7233         expected=$onestripe
7234         cmd="$LFS find -stripe-count 1 -type f $dir"
7235         nums=$($cmd | wc -l)
7236         [ $nums -eq $expected ] || {
7237                 $LFS getstripe -R $dir
7238                 error "'$cmd' wrong: found $nums, expected $expected"
7239         }
7240
7241         cmd="$LFS find -stripe-count -2 -type f $dir"
7242         nums=$($cmd | wc -l)
7243         [ $nums -eq $expected ] || {
7244                 $LFS getstripe -R $dir
7245                 error "'$cmd' wrong: found $nums, expected $expected"
7246         }
7247
7248         expected=0
7249         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7250         nums=$($cmd | wc -l)
7251         [ $nums -eq $expected ] || {
7252                 $LFS getstripe -R $dir
7253                 error "'$cmd' wrong: found $nums, expected $expected"
7254         }
7255 }
7256 run_test 56s "check lfs find -stripe-count works"
7257
7258 test_56t() { # LU-611 #LU-9369
7259         local dir=$DIR/$tdir
7260
7261         setup_56 $dir 0 $NUMDIRS
7262         for i in $(seq $NUMDIRS); do
7263                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7264         done
7265
7266         local expected=$NUMDIRS
7267         local cmd="$LFS find -S 8M $dir"
7268         local nums=$($cmd | wc -l)
7269
7270         [ $nums -eq $expected ] || {
7271                 $LFS getstripe -R $dir
7272                 error "'$cmd' wrong: found $nums, expected $expected"
7273         }
7274         rm -rf $dir
7275
7276         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7277
7278         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7279
7280         expected=$(((NUMDIRS + 1) * NUMFILES))
7281         cmd="$LFS find -stripe-size 512k -type f $dir"
7282         nums=$($cmd | wc -l)
7283         [ $nums -eq $expected ] ||
7284                 error "'$cmd' wrong: found $nums, expected $expected"
7285
7286         cmd="$LFS find -stripe-size +320k -type f $dir"
7287         nums=$($cmd | wc -l)
7288         [ $nums -eq $expected ] ||
7289                 error "'$cmd' wrong: found $nums, expected $expected"
7290
7291         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7292         cmd="$LFS find -stripe-size +200k -type f $dir"
7293         nums=$($cmd | wc -l)
7294         [ $nums -eq $expected ] ||
7295                 error "'$cmd' wrong: found $nums, expected $expected"
7296
7297         cmd="$LFS find -stripe-size -640k -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] ||
7300                 error "'$cmd' wrong: found $nums, expected $expected"
7301
7302         expected=4
7303         cmd="$LFS find -stripe-size 256k -type f $dir"
7304         nums=$($cmd | wc -l)
7305         [ $nums -eq $expected ] ||
7306                 error "'$cmd' wrong: found $nums, expected $expected"
7307
7308         cmd="$LFS find -stripe-size -320k -type f $dir"
7309         nums=$($cmd | wc -l)
7310         [ $nums -eq $expected ] ||
7311                 error "'$cmd' wrong: found $nums, expected $expected"
7312
7313         expected=0
7314         cmd="$LFS find -stripe-size 1024k -type f $dir"
7315         nums=$($cmd | wc -l)
7316         [ $nums -eq $expected ] ||
7317                 error "'$cmd' wrong: found $nums, expected $expected"
7318 }
7319 run_test 56t "check lfs find -stripe-size works"
7320
7321 test_56u() { # LU-611
7322         local dir=$DIR/$tdir
7323
7324         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7325
7326         if [[ $OSTCOUNT -gt 1 ]]; then
7327                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7328                 onestripe=4
7329         else
7330                 onestripe=0
7331         fi
7332
7333         local expected=$(((NUMDIRS + 1) * NUMFILES))
7334         local cmd="$LFS find -stripe-index 0 -type f $dir"
7335         local nums=$($cmd | wc -l)
7336
7337         [ $nums -eq $expected ] ||
7338                 error "'$cmd' wrong: found $nums, expected $expected"
7339
7340         expected=$onestripe
7341         cmd="$LFS find -stripe-index 1 -type f $dir"
7342         nums=$($cmd | wc -l)
7343         [ $nums -eq $expected ] ||
7344                 error "'$cmd' wrong: found $nums, expected $expected"
7345
7346         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7347         nums=$($cmd | wc -l)
7348         [ $nums -eq $expected ] ||
7349                 error "'$cmd' wrong: found $nums, expected $expected"
7350
7351         expected=0
7352         # This should produce an error and not return any files
7353         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7354         nums=$($cmd 2>/dev/null | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         if [[ $OSTCOUNT -gt 1 ]]; then
7359                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7360                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7361                 nums=$($cmd | wc -l)
7362                 [ $nums -eq $expected ] ||
7363                         error "'$cmd' wrong: found $nums, expected $expected"
7364         fi
7365 }
7366 run_test 56u "check lfs find -stripe-index works"
7367
7368 test_56v() {
7369         local mdt_idx=0
7370         local dir=$DIR/$tdir
7371
7372         setup_56 $dir $NUMFILES $NUMDIRS
7373
7374         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7375         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7376
7377         for file in $($LFS find -m $UUID $dir); do
7378                 file_midx=$($LFS getstripe -m $file)
7379                 [ $file_midx -eq $mdt_idx ] ||
7380                         error "lfs find -m $UUID != getstripe -m $file_midx"
7381         done
7382 }
7383 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7384
7385 test_56wa() {
7386         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7388
7389         local dir=$DIR/$tdir
7390
7391         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7392         stack_trap "rm -rf $dir"
7393
7394         local stripe_size=$($LFS getstripe -S -d $dir) ||
7395                 error "$LFS getstripe -S -d $dir failed"
7396         stripe_size=${stripe_size%% *}
7397
7398         local file_size=$((stripe_size * OSTCOUNT))
7399         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7400         local required_space=$((file_num * file_size))
7401         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7402                            head -n1)
7403         (( free_space >= required_space / 1024 )) ||
7404                 skip_env "need $required_space, have $free_space kbytes"
7405
7406         local dd_bs=65536
7407         local dd_count=$((file_size / dd_bs))
7408
7409         # write data into the files
7410         local i
7411         local j
7412         local file
7413
7414         for ((i = 1; i <= NUMFILES; i++ )); do
7415                 file=$dir/file$i
7416                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7417                         error "write data into $file failed"
7418         done
7419         for ((i = 1; i <= NUMDIRS; i++ )); do
7420                 for ((j = 1; j <= NUMFILES; j++ )); do
7421                         file=$dir/dir$i/file$j
7422                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7423                                 error "write data into $file failed"
7424                 done
7425         done
7426
7427         # $LFS_MIGRATE will fail if hard link migration is unsupported
7428         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7429                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7430                         error "creating links to $dir/dir1/file1 failed"
7431         fi
7432
7433         local expected=-1
7434
7435         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7436
7437         # lfs_migrate file
7438         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7439
7440         echo "$cmd"
7441         eval $cmd || error "$cmd failed"
7442
7443         check_stripe_count $dir/file1 $expected
7444
7445         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7446                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7447                 # OST 1 if it is on OST 0. This file is small enough to
7448                 # be on only one stripe.
7449                 file=$dir/migr_1_ost
7450                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7451                         error "write data into $file failed"
7452                 local obdidx=$($LFS getstripe -i $file)
7453                 local oldmd5=$(md5sum $file)
7454                 local newobdidx=0
7455
7456                 (( obdidx != 0 )) || newobdidx=1
7457                 cmd="$LFS migrate -i $newobdidx $file"
7458                 echo $cmd
7459                 eval $cmd || error "$cmd failed"
7460
7461                 local realobdix=$($LFS getstripe -i $file)
7462                 local newmd5=$(md5sum $file)
7463
7464                 (( $newobdidx == $realobdix )) ||
7465                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7466                 [[ "$oldmd5" == "$newmd5" ]] ||
7467                         error "md5sum differ: $oldmd5, $newmd5"
7468         fi
7469
7470         # lfs_migrate dir
7471         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7472         echo "$cmd"
7473         eval $cmd || error "$cmd failed"
7474
7475         for (( j = 1; j <= NUMFILES; j++ )); do
7476                 check_stripe_count $dir/dir1/file$j $expected
7477         done
7478
7479         # lfs_migrate works with lfs find
7480         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7481              $LFS_MIGRATE -y -c $expected"
7482         echo "$cmd"
7483         eval $cmd || error "$cmd failed"
7484
7485         for (( i = 2; i <= NUMFILES; i++ )); do
7486                 check_stripe_count $dir/file$i $expected
7487         done
7488         for (( i = 2; i <= NUMDIRS; i++ )); do
7489                 for (( j = 1; j <= NUMFILES; j++ )); do
7490                         check_stripe_count $dir/dir$i/file$j $expected
7491                 done
7492         done
7493 }
7494 run_test 56wa "check lfs_migrate -c stripe_count works"
7495
7496 test_56wb() {
7497         local file1=$DIR/$tdir/file1
7498         local create_pool=false
7499         local initial_pool=$($LFS getstripe -p $DIR)
7500         local pool_list=()
7501         local pool=""
7502
7503         echo -n "Creating test dir..."
7504         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7505         echo "done."
7506
7507         echo -n "Creating test file..."
7508         touch $file1 || error "cannot create file"
7509         echo "done."
7510
7511         echo -n "Detecting existing pools..."
7512         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7513
7514         if [ ${#pool_list[@]} -gt 0 ]; then
7515                 echo "${pool_list[@]}"
7516                 for thispool in "${pool_list[@]}"; do
7517                         if [[ -z "$initial_pool" ||
7518                               "$initial_pool" != "$thispool" ]]; then
7519                                 pool="$thispool"
7520                                 echo "Using existing pool '$pool'"
7521                                 break
7522                         fi
7523                 done
7524         else
7525                 echo "none detected."
7526         fi
7527         if [ -z "$pool" ]; then
7528                 pool=${POOL:-testpool}
7529                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7530                 echo -n "Creating pool '$pool'..."
7531                 create_pool=true
7532                 pool_add $pool &> /dev/null ||
7533                         error "pool_add failed"
7534                 echo "done."
7535
7536                 echo -n "Adding target to pool..."
7537                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7538                         error "pool_add_targets failed"
7539                 echo "done."
7540         fi
7541
7542         echo -n "Setting pool using -p option..."
7543         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7544                 error "migrate failed rc = $?"
7545         echo "done."
7546
7547         echo -n "Verifying test file is in pool after migrating..."
7548         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7549                 error "file was not migrated to pool $pool"
7550         echo "done."
7551
7552         echo -n "Removing test file from pool '$pool'..."
7553         # "lfs migrate $file" won't remove the file from the pool
7554         # until some striping information is changed.
7555         $LFS migrate -c 1 $file1 &> /dev/null ||
7556                 error "cannot remove from pool"
7557         [ "$($LFS getstripe -p $file1)" ] &&
7558                 error "pool still set"
7559         echo "done."
7560
7561         echo -n "Setting pool using --pool option..."
7562         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7563                 error "migrate failed rc = $?"
7564         echo "done."
7565
7566         # Clean up
7567         rm -f $file1
7568         if $create_pool; then
7569                 destroy_test_pools 2> /dev/null ||
7570                         error "destroy test pools failed"
7571         fi
7572 }
7573 run_test 56wb "check lfs_migrate pool support"
7574
7575 test_56wc() {
7576         local file1="$DIR/$tdir/$tfile"
7577         local md5
7578         local parent_ssize
7579         local parent_scount
7580         local cur_ssize
7581         local cur_scount
7582         local orig_ssize
7583         local new_scount
7584         local cur_comp
7585
7586         echo -n "Creating test dir..."
7587         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7588         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7589                 error "cannot set stripe by '-S 1M -c 1'"
7590         echo "done"
7591
7592         echo -n "Setting initial stripe for test file..."
7593         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7594                 error "cannot set stripe"
7595         cur_ssize=$($LFS getstripe -S "$file1")
7596         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7597         echo "done."
7598
7599         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7600         stack_trap "rm -f $file1"
7601         md5="$(md5sum $file1)"
7602
7603         # File currently set to -S 512K -c 1
7604
7605         # Ensure -c and -S options are rejected when -R is set
7606         echo -n "Verifying incompatible options are detected..."
7607         $LFS_MIGRATE -R -c 1 "$file1" &&
7608                 error "incompatible -R and -c options not detected"
7609         $LFS_MIGRATE -R -S 1M "$file1" &&
7610                 error "incompatible -R and -S options not detected"
7611         $LFS_MIGRATE -R -p pool "$file1" &&
7612                 error "incompatible -R and -p options not detected"
7613         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7614                 error "incompatible -R and -E options not detected"
7615         $LFS_MIGRATE -R -A "$file1" &&
7616                 error "incompatible -R and -A options not detected"
7617         $LFS_MIGRATE -A -c 1 "$file1" &&
7618                 error "incompatible -A and -c options not detected"
7619         $LFS_MIGRATE -A -S 1M "$file1" &&
7620                 error "incompatible -A and -S options not detected"
7621         $LFS_MIGRATE -A -p pool "$file1" &&
7622                 error "incompatible -A and -p options not detected"
7623         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7624                 error "incompatible -A and -E options not detected"
7625         echo "done."
7626
7627         # Ensure unrecognized options are passed through to 'lfs migrate'
7628         echo -n "Verifying -S option is passed through to lfs migrate..."
7629         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7630         cur_ssize=$($LFS getstripe -S "$file1")
7631         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7632         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7633         echo "done."
7634
7635         # File currently set to -S 1M -c 1
7636
7637         # Ensure long options are supported
7638         echo -n "Verifying long options supported..."
7639         $LFS_MIGRATE --non-block "$file1" ||
7640                 error "long option without argument not supported"
7641         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7642                 error "long option with argument not supported"
7643         cur_ssize=$($LFS getstripe -S "$file1")
7644         (( cur_ssize == 524288 )) ||
7645                 error "migrate --stripe-size $cur_ssize != 524288"
7646         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7647         echo "done."
7648
7649         # File currently set to -S 512K -c 1
7650
7651         if (( OSTCOUNT > 1 )); then
7652                 echo -n "Verifying explicit stripe count can be set..."
7653                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7654                 cur_scount=$($LFS getstripe -c "$file1")
7655                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7656                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7657                         error "file data has changed (3)"
7658                 echo "done."
7659         fi
7660
7661         # File currently set to -S 512K -c 1 or -S 512K -c 2
7662
7663         # Ensure parent striping is used if -R is set, and no stripe
7664         # count or size is specified
7665         echo -n "Setting stripe for parent directory..."
7666         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7667                 error "cannot set stripe '-S 2M -c 1'"
7668         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7669         echo "done."
7670
7671         echo -n "Verifying restripe option uses parent stripe settings..."
7672         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7673         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7674         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7675         cur_ssize=$($LFS getstripe -S "$file1")
7676         (( cur_ssize == parent_ssize )) ||
7677                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7678         cur_scount=$($LFS getstripe -c "$file1")
7679         (( cur_scount == parent_scount )) ||
7680                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7681         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7682         echo "done."
7683
7684         # File currently set to -S 1M -c 1
7685
7686         # Ensure striping is preserved if -R is not set, and no stripe
7687         # count or size is specified
7688         echo -n "Verifying striping size preserved when not specified..."
7689         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7690         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7691                 error "cannot set stripe on parent directory"
7692         $LFS_MIGRATE "$file1" || error "migrate failed"
7693         cur_ssize=$($LFS getstripe -S "$file1")
7694         (( cur_ssize == orig_ssize )) ||
7695                 error "migrate by default $cur_ssize != $orig_ssize"
7696         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7697         echo "done."
7698
7699         # Ensure file name properly detected when final option has no argument
7700         echo -n "Verifying file name properly detected..."
7701         $LFS_MIGRATE "$file1" ||
7702                 error "file name interpreted as option argument"
7703         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7704         echo "done."
7705
7706         # Ensure PFL arguments are passed through properly
7707         echo -n "Verifying PFL options passed through..."
7708         new_scount=$(((OSTCOUNT + 1) / 2))
7709         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7710                 error "migrate PFL arguments failed"
7711         cur_comp=$($LFS getstripe --comp-count $file1)
7712         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7713         cur_scount=$($LFS getstripe --stripe-count $file1)
7714         (( cur_scount == new_scount)) ||
7715                 error "PFL stripe count $cur_scount != $new_scount"
7716         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7717         echo "done."
7718 }
7719 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7720
7721 test_56wd() {
7722         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7723
7724         local file1=$DIR/$tdir/$tfile
7725
7726         echo -n "Creating test dir..."
7727         test_mkdir $DIR/$tdir || error "cannot create dir"
7728         echo "done."
7729
7730         echo -n "Creating test file..."
7731         echo "$tfile" > $file1
7732         echo "done."
7733
7734         # Ensure 'lfs migrate' will fail by using a non-existent option,
7735         # and make sure rsync is not called to recover
7736         echo -n "Make sure --no-rsync option works..."
7737         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7738                 grep -q 'refusing to fall back to rsync' ||
7739                 error "rsync was called with --no-rsync set"
7740         echo "done."
7741
7742         # Ensure rsync is called without trying 'lfs migrate' first
7743         echo -n "Make sure --rsync option works..."
7744         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7745                 grep -q 'falling back to rsync' &&
7746                 error "lfs migrate was called with --rsync set"
7747         echo "done."
7748 }
7749 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7750
7751 test_56we() {
7752         local td=$DIR/$tdir
7753         local tf=$td/$tfile
7754
7755         test_mkdir $td || error "cannot create $td"
7756         touch $tf || error "cannot touch $tf"
7757
7758         echo -n "Make sure --non-direct|-D works..."
7759         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7760                 grep -q "lfs migrate --non-direct" ||
7761                 error "--non-direct option cannot work correctly"
7762         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7763                 grep -q "lfs migrate -D" ||
7764                 error "-D option cannot work correctly"
7765         echo "done."
7766 }
7767 run_test 56we "check lfs_migrate --non-direct|-D support"
7768
7769 test_56x() {
7770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7771         check_swap_layouts_support
7772
7773         local dir=$DIR/$tdir
7774         local ref1=/etc/passwd
7775         local file1=$dir/file1
7776
7777         test_mkdir $dir || error "creating dir $dir"
7778         $LFS setstripe -c 2 $file1
7779         cp $ref1 $file1
7780         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7781         stripe=$($LFS getstripe -c $file1)
7782         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7783         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7784
7785         # clean up
7786         rm -f $file1
7787 }
7788 run_test 56x "lfs migration support"
7789
7790 test_56xa() {
7791         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7792         check_swap_layouts_support
7793
7794         local dir=$DIR/$tdir/$testnum
7795
7796         test_mkdir -p $dir
7797
7798         local ref1=/etc/passwd
7799         local file1=$dir/file1
7800
7801         $LFS setstripe -c 2 $file1
7802         cp $ref1 $file1
7803         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7804
7805         local stripe=$($LFS getstripe -c $file1)
7806
7807         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7808         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7809
7810         # clean up
7811         rm -f $file1
7812 }
7813 run_test 56xa "lfs migration --block support"
7814
7815 check_migrate_links() {
7816         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7817         local dir="$1"
7818         local file1="$dir/file1"
7819         local begin="$2"
7820         local count="$3"
7821         local runas="$4"
7822         local total_count=$(($begin + $count - 1))
7823         local symlink_count=10
7824         local uniq_count=10
7825
7826         if [ ! -f "$file1" ]; then
7827                 echo -n "creating initial file..."
7828                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7829                         error "cannot setstripe initial file"
7830                 echo "done"
7831
7832                 echo -n "creating symlinks..."
7833                 for s in $(seq 1 $symlink_count); do
7834                         ln -s "$file1" "$dir/slink$s" ||
7835                                 error "cannot create symlinks"
7836                 done
7837                 echo "done"
7838
7839                 echo -n "creating nonlinked files..."
7840                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7841                         error "cannot create nonlinked files"
7842                 echo "done"
7843         fi
7844
7845         # create hard links
7846         if [ ! -f "$dir/file$total_count" ]; then
7847                 echo -n "creating hard links $begin:$total_count..."
7848                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7849                         /dev/null || error "cannot create hard links"
7850                 echo "done"
7851         fi
7852
7853         echo -n "checking number of hard links listed in xattrs..."
7854         local fid=$($LFS getstripe -F "$file1")
7855         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7856
7857         echo "${#paths[*]}"
7858         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7859                         skip "hard link list has unexpected size, skipping test"
7860         fi
7861         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7862                         error "link names should exceed xattrs size"
7863         fi
7864
7865         echo -n "migrating files..."
7866         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7867         local rc=$?
7868         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7869         echo "done"
7870
7871         # make sure all links have been properly migrated
7872         echo -n "verifying files..."
7873         fid=$($LFS getstripe -F "$file1") ||
7874                 error "cannot get fid for file $file1"
7875         for i in $(seq 2 $total_count); do
7876                 local fid2=$($LFS getstripe -F $dir/file$i)
7877
7878                 [ "$fid2" == "$fid" ] ||
7879                         error "migrated hard link has mismatched FID"
7880         done
7881
7882         # make sure hard links were properly detected, and migration was
7883         # performed only once for the entire link set; nonlinked files should
7884         # also be migrated
7885         local actual=$(grep -c 'done' <<< "$migrate_out")
7886         local expected=$(($uniq_count + 1))
7887
7888         [ "$actual" -eq  "$expected" ] ||
7889                 error "hard links individually migrated ($actual != $expected)"
7890
7891         # make sure the correct number of hard links are present
7892         local hardlinks=$(stat -c '%h' "$file1")
7893
7894         [ $hardlinks -eq $total_count ] ||
7895                 error "num hard links $hardlinks != $total_count"
7896         echo "done"
7897
7898         return 0
7899 }
7900
7901 test_56xb() {
7902         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7903                 skip "Need MDS version at least 2.10.55"
7904
7905         local dir="$DIR/$tdir"
7906
7907         test_mkdir "$dir" || error "cannot create dir $dir"
7908
7909         echo "testing lfs migrate mode when all links fit within xattrs"
7910         check_migrate_links "$dir" 2 99
7911
7912         echo "testing rsync mode when all links fit within xattrs"
7913         check_migrate_links --rsync "$dir" 2 99
7914
7915         echo "testing lfs migrate mode when all links do not fit within xattrs"
7916         check_migrate_links "$dir" 101 100
7917
7918         echo "testing rsync mode when all links do not fit within xattrs"
7919         check_migrate_links --rsync "$dir" 101 100
7920
7921         chown -R $RUNAS_ID $dir
7922         echo "testing non-root lfs migrate mode when not all links are in xattr"
7923         check_migrate_links "$dir" 101 100 "$RUNAS"
7924
7925         # clean up
7926         rm -rf $dir
7927 }
7928 run_test 56xb "lfs migration hard link support"
7929
7930 test_56xc() {
7931         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7932
7933         local dir="$DIR/$tdir"
7934
7935         test_mkdir "$dir" || error "cannot create dir $dir"
7936
7937         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7938         echo -n "Setting initial stripe for 20MB test file..."
7939         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7940                 error "cannot setstripe 20MB file"
7941         echo "done"
7942         echo -n "Sizing 20MB test file..."
7943         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7944         echo "done"
7945         echo -n "Verifying small file autostripe count is 1..."
7946         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7947                 error "cannot migrate 20MB file"
7948         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7949                 error "cannot get stripe for $dir/20mb"
7950         [ $stripe_count -eq 1 ] ||
7951                 error "unexpected stripe count $stripe_count for 20MB file"
7952         rm -f "$dir/20mb"
7953         echo "done"
7954
7955         # Test 2: File is small enough to fit within the available space on
7956         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7957         # have at least an additional 1KB for each desired stripe for test 3
7958         echo -n "Setting stripe for 1GB test file..."
7959         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7960         echo "done"
7961         echo -n "Sizing 1GB test file..."
7962         # File size is 1GB + 3KB
7963         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7964         echo "done"
7965
7966         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7967         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7968         if (( avail > 524288 * OSTCOUNT )); then
7969                 echo -n "Migrating 1GB file..."
7970                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7971                         error "cannot migrate 1GB file"
7972                 echo "done"
7973                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7974                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7975                         error "cannot getstripe for 1GB file"
7976                 [ $stripe_count -eq 2 ] ||
7977                         error "unexpected stripe count $stripe_count != 2"
7978                 echo "done"
7979         fi
7980
7981         # Test 3: File is too large to fit within the available space on
7982         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7983         if [ $OSTCOUNT -ge 3 ]; then
7984                 # The required available space is calculated as
7985                 # file size (1GB + 3KB) / OST count (3).
7986                 local kb_per_ost=349526
7987
7988                 echo -n "Migrating 1GB file with limit..."
7989                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7990                         error "cannot migrate 1GB file with limit"
7991                 echo "done"
7992
7993                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7994                 echo -n "Verifying 1GB autostripe count with limited space..."
7995                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7996                         error "unexpected stripe count $stripe_count (min 3)"
7997                 echo "done"
7998         fi
7999
8000         # clean up
8001         rm -rf $dir
8002 }
8003 run_test 56xc "lfs migration autostripe"
8004
8005 test_56xd() {
8006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8007
8008         local dir=$DIR/$tdir
8009         local f_mgrt=$dir/$tfile.mgrt
8010         local f_yaml=$dir/$tfile.yaml
8011         local f_copy=$dir/$tfile.copy
8012         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8013         local layout_copy="-c 2 -S 2M -i 1"
8014         local yamlfile=$dir/yamlfile
8015         local layout_before;
8016         local layout_after;
8017
8018         test_mkdir "$dir" || error "cannot create dir $dir"
8019         stack_trap "rm -rf $dir"
8020         $LFS setstripe $layout_yaml $f_yaml ||
8021                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8022         $LFS getstripe --yaml $f_yaml > $yamlfile
8023         $LFS setstripe $layout_copy $f_copy ||
8024                 error "cannot setstripe $f_copy with layout $layout_copy"
8025         touch $f_mgrt
8026         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8027
8028         # 1. test option --yaml
8029         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8030                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8031         layout_before=$(get_layout_param $f_yaml)
8032         layout_after=$(get_layout_param $f_mgrt)
8033         [ "$layout_after" == "$layout_before" ] ||
8034                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8035
8036         # 2. test option --copy
8037         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8038                 error "cannot migrate $f_mgrt with --copy $f_copy"
8039         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8040         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8041         [ "$layout_after" == "$layout_before" ] ||
8042                 error "lfs_migrate --copy: $layout_after != $layout_before"
8043 }
8044 run_test 56xd "check lfs_migrate --yaml and --copy support"
8045
8046 test_56xe() {
8047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8048
8049         local dir=$DIR/$tdir
8050         local f_comp=$dir/$tfile
8051         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8052         local layout_before=""
8053         local layout_after=""
8054
8055         test_mkdir "$dir" || error "cannot create dir $dir"
8056         stack_trap "rm -rf $dir"
8057         $LFS setstripe $layout $f_comp ||
8058                 error "cannot setstripe $f_comp with layout $layout"
8059         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8060         dd if=/dev/zero of=$f_comp bs=1M count=4
8061
8062         # 1. migrate a comp layout file by lfs_migrate
8063         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8064         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8065         [ "$layout_before" == "$layout_after" ] ||
8066                 error "lfs_migrate: $layout_before != $layout_after"
8067
8068         # 2. migrate a comp layout file by lfs migrate
8069         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8070         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8071         [ "$layout_before" == "$layout_after" ] ||
8072                 error "lfs migrate: $layout_before != $layout_after"
8073 }
8074 run_test 56xe "migrate a composite layout file"
8075
8076 test_56xf() {
8077         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8078
8079         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8080                 skip "Need server version at least 2.13.53"
8081
8082         local dir=$DIR/$tdir
8083         local f_comp=$dir/$tfile
8084         local layout="-E 1M -c1 -E -1 -c2"
8085         local fid_before=""
8086         local fid_after=""
8087
8088         test_mkdir "$dir" || error "cannot create dir $dir"
8089         stack_trap "rm -rf $dir"
8090         $LFS setstripe $layout $f_comp ||
8091                 error "cannot setstripe $f_comp with layout $layout"
8092         fid_before=$($LFS getstripe --fid $f_comp)
8093         dd if=/dev/zero of=$f_comp bs=1M count=4
8094
8095         # 1. migrate a comp layout file to a comp layout
8096         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8097         fid_after=$($LFS getstripe --fid $f_comp)
8098         [ "$fid_before" == "$fid_after" ] ||
8099                 error "comp-to-comp migrate: $fid_before != $fid_after"
8100
8101         # 2. migrate a comp layout file to a plain layout
8102         $LFS migrate -c2 $f_comp ||
8103                 error "cannot migrate $f_comp by lfs migrate"
8104         fid_after=$($LFS getstripe --fid $f_comp)
8105         [ "$fid_before" == "$fid_after" ] ||
8106                 error "comp-to-plain migrate: $fid_before != $fid_after"
8107
8108         # 3. migrate a plain layout file to a comp layout
8109         $LFS migrate $layout $f_comp ||
8110                 error "cannot migrate $f_comp by lfs migrate"
8111         fid_after=$($LFS getstripe --fid $f_comp)
8112         [ "$fid_before" == "$fid_after" ] ||
8113                 error "plain-to-comp migrate: $fid_before != $fid_after"
8114 }
8115 run_test 56xf "FID is not lost during migration of a composite layout file"
8116
8117 check_file_ost_range() {
8118         local file="$1"
8119         shift
8120         local range="$*"
8121         local -a file_range
8122         local idx
8123
8124         file_range=($($LFS getstripe -y "$file" |
8125                 awk '/l_ost_idx:/ { print $NF }'))
8126
8127         if [[ "${#file_range[@]}" = 0 ]]; then
8128                 echo "No osts found for $file"
8129                 return 1
8130         fi
8131
8132         for idx in "${file_range[@]}"; do
8133                 [[ " $range " =~ " $idx " ]] ||
8134                         return 1
8135         done
8136
8137         return 0
8138 }
8139
8140 sub_test_56xg() {
8141         local stripe_opt="$1"
8142         local pool="$2"
8143         shift 2
8144         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8145
8146         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8147                 error "Fail to migrate $tfile on $pool"
8148         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8149                 error "$tfile is not in pool $pool"
8150         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8151                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8152 }
8153
8154 test_56xg() {
8155         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8156         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8157         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8158                 skip "Need MDS version newer than 2.14.52"
8159
8160         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8161         local -a pool_ranges=("0 0" "1 1" "0 1")
8162
8163         # init pools
8164         for i in "${!pool_names[@]}"; do
8165                 pool_add ${pool_names[$i]} ||
8166                         error "pool_add failed (pool: ${pool_names[$i]})"
8167                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8168                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8169         done
8170
8171         # init the file to migrate
8172         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8173                 error "Unable to create $tfile on OST1"
8174         stack_trap "rm -f $DIR/$tfile"
8175         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8176                 error "Unable to write on $tfile"
8177
8178         echo "1. migrate $tfile on pool ${pool_names[0]}"
8179         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8180
8181         echo "2. migrate $tfile on pool ${pool_names[2]}"
8182         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8183
8184         echo "3. migrate $tfile on pool ${pool_names[1]}"
8185         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8186
8187         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8188         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8189         echo
8190
8191         # Clean pools
8192         destroy_test_pools ||
8193                 error "pool_destroy failed"
8194 }
8195 run_test 56xg "lfs migrate pool support"
8196
8197 test_56xh() {
8198         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8199
8200         local size_mb=25
8201         local file1=$DIR/$tfile
8202         local tmp1=$TMP/$tfile.tmp
8203
8204         $LFS setstripe -c 2 $file1
8205
8206         stack_trap "rm -f $file1 $tmp1"
8207         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8208                         error "error creating $tmp1"
8209         ls -lsh $tmp1
8210         cp $tmp1 $file1
8211
8212         local start=$SECONDS
8213
8214         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8215                 error "migrate failed rc = $?"
8216
8217         local elapsed=$((SECONDS - start))
8218
8219         # with 1MB/s, elapsed should equal size_mb
8220         (( elapsed >= size_mb * 95 / 100 )) ||
8221                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8222
8223         (( elapsed <= size_mb * 120 / 100 )) ||
8224                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8225
8226         (( elapsed <= size_mb * 350 / 100 )) ||
8227                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8228
8229         stripe=$($LFS getstripe -c $file1)
8230         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8231         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8232
8233         # Clean up file (since it is multiple MB)
8234         rm -f $file1 $tmp1
8235 }
8236 run_test 56xh "lfs migrate bandwidth limitation support"
8237
8238 test_56xi() {
8239         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8240         verify_yaml_available || skip_env "YAML verification not installed"
8241
8242         local size_mb=5
8243         local file1=$DIR/$tfile.1
8244         local file2=$DIR/$tfile.2
8245         local file3=$DIR/$tfile.3
8246         local output_file=$DIR/$tfile.out
8247         local tmp1=$TMP/$tfile.tmp
8248
8249         $LFS setstripe -c 2 $file1
8250         $LFS setstripe -c 2 $file2
8251         $LFS setstripe -c 2 $file3
8252
8253         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8254         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8255                         error "error creating $tmp1"
8256         ls -lsh $tmp1
8257         cp $tmp1 $file1
8258         cp $tmp1 $file2
8259         cp $tmp1 $file3
8260
8261         $LFS migrate --stats --stats-interval=1 \
8262                 -c 1 $file1 $file2 $file3 1> $output_file ||
8263                 error "migrate failed rc = $?"
8264
8265         cat $output_file
8266         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8267
8268         # Clean up file (since it is multiple MB)
8269         rm -f $file1 $file2 $file3 $tmp1 $output_file
8270 }
8271 run_test 56xi "lfs migrate stats support"
8272
8273 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8274         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8275
8276         local file=$DIR/$tfile
8277         local linkdir=$DIR/$tdir
8278
8279         test_mkdir $linkdir || error "fail to create $linkdir"
8280         $LFS setstripe -i 0 -c 1 -S1M $file
8281         stack_trap "rm -rf $file $linkdir"
8282         dd if=/dev/urandom of=$file bs=1M count=10 ||
8283                 error "fail to create $file"
8284
8285         # Create file links
8286         local cpts
8287         local threads_max
8288         local nlinks
8289
8290         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8291         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8292         (( nlinks = thread_max * 3 / 2 / cpts))
8293
8294         echo "create $nlinks hard links of $file"
8295         createmany -l $file $linkdir/link $nlinks
8296
8297         # Parallel migrates (should not block)
8298         local i
8299         for ((i = 0; i < nlinks; i++)); do
8300                 echo $linkdir/link$i
8301         done | xargs -n1 -P $nlinks $LFS migrate -c2
8302
8303         local stripe_count
8304         stripe_count=$($LFS getstripe -c $file) ||
8305                 error "fail to get stripe count on $file"
8306
8307         ((stripe_count == 2)) ||
8308                 error "fail to migrate $file (stripe_count = $stripe_count)"
8309 }
8310 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8311
8312 test_56xk() {
8313         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8314
8315         local size_mb=5
8316         local file1=$DIR/$tfile
8317
8318         stack_trap "rm -f $file1"
8319         $LFS setstripe -c 1 $file1
8320         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8321                 error "error creating $file1"
8322         $LFS mirror extend -N $file1 || error "can't mirror"
8323         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8324                 error "can't dd"
8325         $LFS getstripe $file1 | grep stale ||
8326                 error "one component must be stale"
8327
8328         local start=$SECONDS
8329         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8330                 error "migrate failed rc = $?"
8331         local elapsed=$((SECONDS - start))
8332         $LFS getstripe $file1 | grep stale &&
8333                 error "all components must be sync"
8334
8335         # with 1MB/s, elapsed should equal size_mb
8336         (( elapsed >= size_mb * 95 / 100 )) ||
8337                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8338
8339         (( elapsed <= size_mb * 120 / 100 )) ||
8340                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8341
8342         (( elapsed <= size_mb * 350 / 100 )) ||
8343                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8344 }
8345 run_test 56xk "lfs mirror resync bandwidth limitation support"
8346
8347 test_56xl() {
8348         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8349         verify_yaml_available || skip_env "YAML verification not installed"
8350
8351         local size_mb=5
8352         local file1=$DIR/$tfile.1
8353         local output_file=$DIR/$tfile.out
8354
8355         stack_trap "rm -f $file1"
8356         $LFS setstripe -c 1 $file1
8357         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8358                 error "error creating $file1"
8359         $LFS mirror extend -N $file1 || error "can't mirror"
8360         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8361                 error "can't dd"
8362         $LFS getstripe $file1 | grep stale ||
8363                 error "one component must be stale"
8364         $LFS getstripe $file1
8365
8366         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8367                 error "resync failed rc = $?"
8368         $LFS getstripe $file1 | grep stale &&
8369                 error "all components must be sync"
8370
8371         cat $output_file
8372         cat $output_file | verify_yaml || error "stats is not valid YAML"
8373 }
8374 run_test 56xl "lfs mirror resync stats support"
8375
8376 test_56y() {
8377         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8378                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8379
8380         local res=""
8381         local dir=$DIR/$tdir
8382         local f1=$dir/file1
8383         local f2=$dir/file2
8384
8385         test_mkdir -p $dir || error "creating dir $dir"
8386         touch $f1 || error "creating std file $f1"
8387         $MULTIOP $f2 H2c || error "creating released file $f2"
8388
8389         # a directory can be raid0, so ask only for files
8390         res=$($LFS find $dir -L raid0 -type f | wc -l)
8391         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8392
8393         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8394         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8395
8396         # only files can be released, so no need to force file search
8397         res=$($LFS find $dir -L released)
8398         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8399
8400         res=$($LFS find $dir -type f \! -L released)
8401         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8402 }
8403 run_test 56y "lfs find -L raid0|released"
8404
8405 test_56z() { # LU-4824
8406         # This checks to make sure 'lfs find' continues after errors
8407         # There are two classes of errors that should be caught:
8408         # - If multiple paths are provided, all should be searched even if one
8409         #   errors out
8410         # - If errors are encountered during the search, it should not terminate
8411         #   early
8412         local dir=$DIR/$tdir
8413         local i
8414
8415         test_mkdir $dir
8416         for i in d{0..9}; do
8417                 test_mkdir $dir/$i
8418                 touch $dir/$i/$tfile
8419         done
8420         $LFS find $DIR/non_existent_dir $dir &&
8421                 error "$LFS find did not return an error"
8422         # Make a directory unsearchable. This should NOT be the last entry in
8423         # directory order.  Arbitrarily pick the 6th entry
8424         chmod 700 $($LFS find $dir -type d | sed '6!d')
8425
8426         $RUNAS $LFS find $DIR/non_existent $dir
8427         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8428
8429         # The user should be able to see 10 directories and 9 files
8430         (( count == 19 )) ||
8431                 error "$LFS find found $count != 19 entries after error"
8432 }
8433 run_test 56z "lfs find should continue after an error"
8434
8435 test_56aa() { # LU-5937
8436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8437
8438         local dir=$DIR/$tdir
8439
8440         mkdir $dir
8441         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8442
8443         createmany -o $dir/striped_dir/${tfile}- 1024
8444         local dirs=$($LFS find --size +8k $dir/)
8445
8446         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8447 }
8448 run_test 56aa "lfs find --size under striped dir"
8449
8450 test_56ab() { # LU-10705
8451         test_mkdir $DIR/$tdir
8452         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8453         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8454         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8455         # Flush writes to ensure valid blocks.  Need to be more thorough for
8456         # ZFS, since blocks are not allocated/returned to client immediately.
8457         sync_all_data
8458         wait_zfs_commit ost1 2
8459         cancel_lru_locks osc
8460         ls -ls $DIR/$tdir
8461
8462         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8463
8464         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8465
8466         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8467         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8468
8469         rm -f $DIR/$tdir/$tfile.[123]
8470 }
8471 run_test 56ab "lfs find --blocks"
8472
8473 # LU-11188
8474 test_56aca() {
8475         local dir="$DIR/$tdir"
8476         local perms=(001 002 003 004 005 006 007
8477                      010 020 030 040 050 060 070
8478                      100 200 300 400 500 600 700
8479                      111 222 333 444 555 666 777)
8480         local perm_minus=(8 8 4 8 4 4 2
8481                           8 8 4 8 4 4 2
8482                           8 8 4 8 4 4 2
8483                           4 4 2 4 2 2 1)
8484         local perm_slash=(8  8 12  8 12 12 14
8485                           8  8 12  8 12 12 14
8486                           8  8 12  8 12 12 14
8487                          16 16 24 16 24 24 28)
8488
8489         test_mkdir "$dir"
8490         for perm in ${perms[*]}; do
8491                 touch "$dir/$tfile.$perm"
8492                 chmod $perm "$dir/$tfile.$perm"
8493         done
8494
8495         for ((i = 0; i < ${#perms[*]}; i++)); do
8496                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8497                 (( $num == 1 )) ||
8498                         error "lfs find -perm ${perms[i]}:"\
8499                               "$num != 1"
8500
8501                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8502                 (( $num == ${perm_minus[i]} )) ||
8503                         error "lfs find -perm -${perms[i]}:"\
8504                               "$num != ${perm_minus[i]}"
8505
8506                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8507                 (( $num == ${perm_slash[i]} )) ||
8508                         error "lfs find -perm /${perms[i]}:"\
8509                               "$num != ${perm_slash[i]}"
8510         done
8511 }
8512 run_test 56aca "check lfs find -perm with octal representation"
8513
8514 test_56acb() {
8515         local dir=$DIR/$tdir
8516         # p is the permission of write and execute for user, group and other
8517         # without the umask. It is used to test +wx.
8518         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8519         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8520         local symbolic=(+t  a+t u+t g+t o+t
8521                         g+s u+s o+s +s o+sr
8522                         o=r,ug+o,u+w
8523                         u+ g+ o+ a+ ugo+
8524                         u- g- o- a- ugo-
8525                         u= g= o= a= ugo=
8526                         o=r,ug+o,u+w u=r,a+u,u+w
8527                         g=r,ugo=g,u+w u+x,+X +X
8528                         u+x,u+X u+X u+x,g+X o+r,+X
8529                         u+x,go+X +wx +rwx)
8530
8531         test_mkdir $dir
8532         for perm in ${perms[*]}; do
8533                 touch "$dir/$tfile.$perm"
8534                 chmod $perm "$dir/$tfile.$perm"
8535         done
8536
8537         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8538                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8539
8540                 (( $num == 1 )) ||
8541                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8542         done
8543 }
8544 run_test 56acb "check lfs find -perm with symbolic representation"
8545
8546 test_56acc() {
8547         local dir=$DIR/$tdir
8548         local tests="17777 787 789 abcd
8549                 ug=uu ug=a ug=gu uo=ou urw
8550                 u+xg+x a=r,u+x,"
8551
8552         test_mkdir $dir
8553         for err in $tests; do
8554                 if $LFS find $dir -perm $err 2>/dev/null; then
8555                         error "lfs find -perm $err: parsing should have failed"
8556                 fi
8557         done
8558 }
8559 run_test 56acc "check parsing error for lfs find -perm"
8560
8561 test_56ba() {
8562         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8563                 skip "Need MDS version at least 2.10.50"
8564
8565         # Create composite files with one component
8566         local dir=$DIR/$tdir
8567
8568         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8569         # Create composite files with three components
8570         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8571         # LU-16904 Create plain layout files
8572         lfs setstripe -c 1 $dir/$tfile-{1..10}
8573
8574         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8575
8576         [[ $nfiles == 10 ]] ||
8577                 error "lfs find -E 1M found $nfiles != 10 files"
8578
8579         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8580         [[ $nfiles == 25 ]] ||
8581                 error "lfs find ! -E 1M found $nfiles != 25 files"
8582
8583         # All files have a component that starts at 0
8584         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8585         [[ $nfiles == 35 ]] ||
8586                 error "lfs find --component-start 0 - $nfiles != 35 files"
8587
8588         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8589         [[ $nfiles == 15 ]] ||
8590                 error "lfs find --component-start 2M - $nfiles != 15 files"
8591
8592         # All files created here have a componenet that does not starts at 2M
8593         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8594         [[ $nfiles == 35 ]] ||
8595                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8596
8597         # Find files with a specified number of components
8598         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8599         [[ $nfiles == 15 ]] ||
8600                 error "lfs find --component-count 3 - $nfiles != 15 files"
8601
8602         # Remember non-composite files have a component count of zero
8603         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8604         [[ $nfiles == 10 ]] ||
8605                 error "lfs find --component-count 0 - $nfiles != 10 files"
8606
8607         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8608         [[ $nfiles == 20 ]] ||
8609                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8610
8611         # All files have a flag called "init"
8612         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8613         [[ $nfiles == 35 ]] ||
8614                 error "lfs find --component-flags init - $nfiles != 35 files"
8615
8616         # Multi-component files will have a component not initialized
8617         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8618         [[ $nfiles == 15 ]] ||
8619                 error "lfs find !--component-flags init - $nfiles != 15 files"
8620
8621         rm -rf $dir
8622
8623 }
8624 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8625
8626 test_56ca() {
8627         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8628                 skip "Need MDS version at least 2.10.57"
8629
8630         local td=$DIR/$tdir
8631         local tf=$td/$tfile
8632         local dir
8633         local nfiles
8634         local cmd
8635         local i
8636         local j
8637
8638         # create mirrored directories and mirrored files
8639         mkdir $td || error "mkdir $td failed"
8640         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8641         createmany -o $tf- 10 || error "create $tf- failed"
8642
8643         for i in $(seq 2); do
8644                 dir=$td/dir$i
8645                 mkdir $dir || error "mkdir $dir failed"
8646                 $LFS mirror create -N$((3 + i)) $dir ||
8647                         error "create mirrored dir $dir failed"
8648                 createmany -o $dir/$tfile- 10 ||
8649                         error "create $dir/$tfile- failed"
8650         done
8651
8652         # change the states of some mirrored files
8653         echo foo > $tf-6
8654         for i in $(seq 2); do
8655                 dir=$td/dir$i
8656                 for j in $(seq 4 9); do
8657                         echo foo > $dir/$tfile-$j
8658                 done
8659         done
8660
8661         # find mirrored files with specific mirror count
8662         cmd="$LFS find --mirror-count 3 --type f $td"
8663         nfiles=$($cmd | wc -l)
8664         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8665
8666         cmd="$LFS find ! --mirror-count 3 --type f $td"
8667         nfiles=$($cmd | wc -l)
8668         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8669
8670         cmd="$LFS find --mirror-count +2 --type f $td"
8671         nfiles=$($cmd | wc -l)
8672         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8673
8674         cmd="$LFS find --mirror-count -6 --type f $td"
8675         nfiles=$($cmd | wc -l)
8676         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8677
8678         # find mirrored files with specific file state
8679         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8680         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8681
8682         cmd="$LFS find --mirror-state=ro --type f $td"
8683         nfiles=$($cmd | wc -l)
8684         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8685
8686         cmd="$LFS find ! --mirror-state=ro --type f $td"
8687         nfiles=$($cmd | wc -l)
8688         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8689
8690         cmd="$LFS find --mirror-state=wp --type f $td"
8691         nfiles=$($cmd | wc -l)
8692         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8693
8694         cmd="$LFS find ! --mirror-state=sp --type f $td"
8695         nfiles=$($cmd | wc -l)
8696         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8697 }
8698 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8699
8700 test_56da() { # LU-14179
8701         local path=$DIR/$tdir
8702
8703         test_mkdir $path
8704         cd $path
8705
8706         local longdir=$(str_repeat 'a' 255)
8707
8708         for i in {1..15}; do
8709                 path=$path/$longdir
8710                 test_mkdir $longdir
8711                 cd $longdir
8712         done
8713
8714         local len=${#path}
8715         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8716
8717         test_mkdir $lastdir
8718         cd $lastdir
8719         # PATH_MAX-1
8720         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8721
8722         # NAME_MAX
8723         touch $(str_repeat 'f' 255)
8724
8725         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8726                 error "lfs find reported an error"
8727
8728         rm -rf $DIR/$tdir
8729 }
8730 run_test 56da "test lfs find with long paths"
8731
8732 test_56ea() { #LU-10378
8733         local path=$DIR/$tdir
8734         local pool=$TESTNAME
8735
8736         # Create ost pool
8737         pool_add $pool || error "pool_add $pool failed"
8738         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8739                 error "adding targets to $pool failed"
8740
8741         # Set default pool on directory before creating file
8742         mkdir $path || error "mkdir $path failed"
8743         $LFS setstripe -p $pool $path ||
8744                 error "set OST pool on $pool failed"
8745         touch $path/$tfile || error "touch $path/$tfile failed"
8746
8747         # Compare basic file attributes from -printf and stat
8748         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8749         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8750
8751         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8752                 error "Attrs from lfs find and stat don't match"
8753
8754         # Compare Lustre attributes from lfs find and lfs getstripe
8755         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8756         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8757         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8758         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8759         local fpool=$($LFS getstripe --pool $path/$tfile)
8760         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8761
8762         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8763                 error "Attrs from lfs find and lfs getstripe don't match"
8764
8765         # Verify behavior for unknown escape/format sequences
8766         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8767
8768         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8769                 error "Escape/format codes don't match"
8770 }
8771 run_test 56ea "test lfs find -printf option"
8772
8773 test_56eb() {
8774         local dir=$DIR/$tdir
8775         local subdir_1=$dir/subdir_1
8776
8777         test_mkdir -p $subdir_1
8778         ln -s subdir_1 $dir/link_1
8779
8780         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8781                 error "symlink is not followed"
8782
8783         $LFS getstripe --no-follow $dir |
8784                 grep "^$dir/link_1 has no stripe info$" ||
8785                 error "symlink should not have stripe info"
8786
8787         touch $dir/testfile
8788         ln -s testfile $dir/file_link_2
8789
8790         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8791                 error "symlink is not followed"
8792
8793         $LFS getstripe --no-follow $dir |
8794                 grep "^$dir/file_link_2 has no stripe info$" ||
8795                 error "symlink should not have stripe info"
8796 }
8797 run_test 56eb "check lfs getstripe on symlink"
8798
8799 test_56ec() {
8800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8801         local dir=$DIR/$tdir
8802         local srcfile=$dir/srcfile
8803         local srcyaml=$dir/srcyaml
8804         local destfile=$dir/destfile
8805
8806         test_mkdir -p $dir
8807
8808         $LFS setstripe -i 1 $srcfile
8809         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8810         # if the setstripe yaml parsing fails for any reason, the command can
8811         # randomly assign the correct OST index, leading to an erroneous
8812         # success. but the chance of false success is low enough that a
8813         # regression should still be quickly caught.
8814         $LFS setstripe --yaml=$srcyaml $destfile
8815
8816         local srcindex=$($LFS getstripe -i $srcfile)
8817         local destindex=$($LFS getstripe -i $destfile)
8818
8819         if [[ ! $srcindex -eq $destindex ]]; then
8820                 error "setstripe did not set OST index correctly"
8821         fi
8822 }
8823 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8824
8825 test_56eda() {
8826         local dir=$DIR/$tdir
8827         local subdir=$dir/subdir
8828         local file1=$dir/$tfile
8829         local file2=$dir/$tfile\2
8830         local link=$dir/$tfile-link
8831         local nfiles
8832
8833         test_mkdir -p $dir
8834         $LFS setdirstripe -c1 $subdir
8835         touch $file1
8836         touch $file2
8837         ln $file2 $link
8838
8839         nfiles=$($LFS find --links 1 $dir | wc -l)
8840         (( $nfiles == 1 )) ||
8841                 error "lfs find --links expected 1 file, got $nfiles"
8842
8843         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8844         (( $nfiles == 2 )) ||
8845                 error "lfs find --links expected 2 files, got $nfiles"
8846
8847         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8848         (( $nfiles == 1 )) ||
8849                 error "lfs find --links expected 1 directory, got $nfiles"
8850 }
8851 run_test 56eda "check lfs find --links"
8852
8853 test_56edb() {
8854         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8855
8856         local dir=$DIR/$tdir
8857         local stripedir=$dir/stripedir
8858         local nfiles
8859
8860         test_mkdir -p $dir
8861
8862         $LFS setdirstripe -c2 $stripedir
8863
8864         $LFS getdirstripe $stripedir
8865
8866         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8867         (( $nfiles == 1 )) ||
8868                 error "lfs find --links expected 1 directory, got $nfiles"
8869 }
8870 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8871
8872 test_56ef() {
8873         local dir=$DIR/$tdir
8874         local dir1=$dir/d1
8875         local dir2=$dir/d2
8876         local nfiles
8877
8878         test_mkdir -p $dir
8879
8880         mkdir $dir1
8881         mkdir $dir2
8882
8883         touch $dir1/f
8884         touch $dir2/f
8885
8886         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8887         (( $nfiles == 2 )) ||
8888                 error "(1) lfs find expected 2 files, got $nfiles"
8889
8890         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8891         (( $nfiles == 2 )) ||
8892                 error "(2) lfs find expected 2 files, got $nfiles"
8893
8894         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8895         (( $nfiles == 2 )) ||
8896                 error "(3) lfs find expected 2 files, got $nfiles"
8897 }
8898 run_test 56ef "lfs find with multiple paths"
8899
8900 test_57a() {
8901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8902         # note test will not do anything if MDS is not local
8903         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8904                 skip_env "ldiskfs only test"
8905         fi
8906         remote_mds_nodsh && skip "remote MDS with nodsh"
8907
8908         local MNTDEV="osd*.*MDT*.mntdev"
8909         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8910         [ -z "$DEV" ] && error "can't access $MNTDEV"
8911         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8912                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8913                         error "can't access $DEV"
8914                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8915                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8916                 rm $TMP/t57a.dump
8917         done
8918 }
8919 run_test 57a "verify MDS filesystem created with large inodes =="
8920
8921 test_57b() {
8922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8923         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8924                 skip_env "ldiskfs only test"
8925         fi
8926         remote_mds_nodsh && skip "remote MDS with nodsh"
8927
8928         local dir=$DIR/$tdir
8929         local filecount=100
8930         local file1=$dir/f1
8931         local fileN=$dir/f$filecount
8932
8933         rm -rf $dir || error "removing $dir"
8934         test_mkdir -c1 $dir
8935         local mdtidx=$($LFS getstripe -m $dir)
8936         local mdtname=MDT$(printf %04x $mdtidx)
8937         local facet=mds$((mdtidx + 1))
8938
8939         echo "mcreating $filecount files"
8940         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8941
8942         # verify that files do not have EAs yet
8943         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8944                 error "$file1 has an EA"
8945         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8946                 error "$fileN has an EA"
8947
8948         sync
8949         sleep 1
8950         df $dir  #make sure we get new statfs data
8951         local mdsfree=$(do_facet $facet \
8952                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8953         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8954         local file
8955
8956         echo "opening files to create objects/EAs"
8957         for file in $(seq -f $dir/f%g 1 $filecount); do
8958                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8959                         error "opening $file"
8960         done
8961
8962         # verify that files have EAs now
8963         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
8964                 error "$file1 missing EA"
8965         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
8966                 error "$fileN missing EA"
8967
8968         sleep 1  #make sure we get new statfs data
8969         df $dir
8970         local mdsfree2=$(do_facet $facet \
8971                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8972         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8973
8974         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8975                 if [ "$mdsfree" != "$mdsfree2" ]; then
8976                         error "MDC before $mdcfree != after $mdcfree2"
8977                 else
8978                         echo "MDC before $mdcfree != after $mdcfree2"
8979                         echo "unable to confirm if MDS has large inodes"
8980                 fi
8981         fi
8982         rm -rf $dir
8983 }
8984 run_test 57b "default LOV EAs are stored inside large inodes ==="
8985
8986 test_58() {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988         [ -z "$(which wiretest 2>/dev/null)" ] &&
8989                         skip_env "could not find wiretest"
8990
8991         wiretest
8992 }
8993 run_test 58 "verify cross-platform wire constants =============="
8994
8995 test_59() {
8996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8997
8998         echo "touch 130 files"
8999         createmany -o $DIR/f59- 130
9000         echo "rm 130 files"
9001         unlinkmany $DIR/f59- 130
9002         sync
9003         # wait for commitment of removal
9004         wait_delete_completed
9005 }
9006 run_test 59 "verify cancellation of llog records async ========="
9007
9008 TEST60_HEAD="test_60 run $RANDOM"
9009 test_60a() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011         remote_mgs_nodsh && skip "remote MGS with nodsh"
9012         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9013                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9014                         skip_env "missing subtest run-llog.sh"
9015
9016         log "$TEST60_HEAD - from kernel mode"
9017         do_facet mgs "$LCTL dk > /dev/null"
9018         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9019         do_facet mgs $LCTL dk > $TMP/$tfile
9020
9021         # LU-6388: test llog_reader
9022         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9023         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9024         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9025                         skip_env "missing llog_reader"
9026         local fstype=$(facet_fstype mgs)
9027         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9028                 skip_env "Only for ldiskfs or zfs type mgs"
9029
9030         local mntpt=$(facet_mntpt mgs)
9031         local mgsdev=$(mgsdevname 1)
9032         local fid_list
9033         local fid
9034         local rec_list
9035         local rec
9036         local rec_type
9037         local obj_file
9038         local path
9039         local seq
9040         local oid
9041         local pass=true
9042
9043         #get fid and record list
9044         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9045                 tail -n 4))
9046         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9047                 tail -n 4))
9048         #remount mgs as ldiskfs or zfs type
9049         stop mgs || error "stop mgs failed"
9050         mount_fstype mgs || error "remount mgs failed"
9051         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9052                 fid=${fid_list[i]}
9053                 rec=${rec_list[i]}
9054                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9055                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9056                 oid=$((16#$oid))
9057
9058                 case $fstype in
9059                         ldiskfs )
9060                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9061                         zfs )
9062                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9063                 esac
9064                 echo "obj_file is $obj_file"
9065                 do_facet mgs $llog_reader $obj_file
9066
9067                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9068                         awk '{ print $3 }' | sed -e "s/^type=//g")
9069                 if [ $rec_type != $rec ]; then
9070                         echo "FAILED test_60a wrong record type $rec_type," \
9071                               "should be $rec"
9072                         pass=false
9073                         break
9074                 fi
9075
9076                 #check obj path if record type is LLOG_LOGID_MAGIC
9077                 if [ "$rec" == "1064553b" ]; then
9078                         path=$(do_facet mgs $llog_reader $obj_file |
9079                                 grep "path=" | awk '{ print $NF }' |
9080                                 sed -e "s/^path=//g")
9081                         if [ $obj_file != $mntpt/$path ]; then
9082                                 echo "FAILED test_60a wrong obj path" \
9083                                       "$montpt/$path, should be $obj_file"
9084                                 pass=false
9085                                 break
9086                         fi
9087                 fi
9088         done
9089         rm -f $TMP/$tfile
9090         #restart mgs before "error", otherwise it will block the next test
9091         stop mgs || error "stop mgs failed"
9092         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9093         $pass || error "test failed, see FAILED test_60a messages for specifics"
9094 }
9095 run_test 60a "llog_test run from kernel module and test llog_reader"
9096
9097 test_60b() { # bug 6411
9098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9099
9100         dmesg > $DIR/$tfile
9101         LLOG_COUNT=$(do_facet mgs dmesg |
9102                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9103                           /llog_[a-z]*.c:[0-9]/ {
9104                                 if (marker)
9105                                         from_marker++
9106                                 from_begin++
9107                           }
9108                           END {
9109                                 if (marker)
9110                                         print from_marker
9111                                 else
9112                                         print from_begin
9113                           }")
9114
9115         [[ $LLOG_COUNT -gt 120 ]] &&
9116                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9117 }
9118 run_test 60b "limit repeated messages from CERROR/CWARN"
9119
9120 test_60c() {
9121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9122
9123         echo "create 5000 files"
9124         createmany -o $DIR/f60c- 5000
9125 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9126         lctl set_param fail_loc=0x80000137
9127         unlinkmany $DIR/f60c- 5000
9128         lctl set_param fail_loc=0
9129 }
9130 run_test 60c "unlink file when mds full"
9131
9132 test_60d() {
9133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9134
9135         SAVEPRINTK=$(lctl get_param -n printk)
9136         # verify "lctl mark" is even working"
9137         MESSAGE="test message ID $RANDOM $$"
9138         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9139         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9140
9141         lctl set_param printk=0 || error "set lnet.printk failed"
9142         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9143         MESSAGE="new test message ID $RANDOM $$"
9144         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9145         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9146         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9147
9148         lctl set_param -n printk="$SAVEPRINTK"
9149 }
9150 run_test 60d "test printk console message masking"
9151
9152 test_60e() {
9153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9154         remote_mds_nodsh && skip "remote MDS with nodsh"
9155
9156         touch $DIR/$tfile
9157 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9158         do_facet mds1 lctl set_param fail_loc=0x15b
9159         rm $DIR/$tfile
9160 }
9161 run_test 60e "no space while new llog is being created"
9162
9163 test_60f() {
9164         local old_path=$($LCTL get_param -n debug_path)
9165
9166         stack_trap "$LCTL set_param debug_path=$old_path"
9167         stack_trap "rm -f $TMP/$tfile*"
9168         rm -f $TMP/$tfile* 2> /dev/null
9169         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9170         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9171         test_mkdir $DIR/$tdir
9172         # retry in case the open is cached and not released
9173         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9174                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9175                 sleep 0.1
9176         done
9177         ls $TMP/$tfile*
9178         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9179 }
9180 run_test 60f "change debug_path works"
9181
9182 test_60g() {
9183         local pid
9184         local i
9185
9186         test_mkdir -c $MDSCOUNT $DIR/$tdir
9187
9188         (
9189                 local index=0
9190                 while true; do
9191                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9192                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9193                                 2>/dev/null
9194                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9195                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9196                         index=$((index + 1))
9197                 done
9198         ) &
9199
9200         pid=$!
9201
9202         for i in {0..100}; do
9203                 # define OBD_FAIL_OSD_TXN_START    0x19a
9204                 local index=$((i % MDSCOUNT + 1))
9205
9206                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9207                         > /dev/null
9208                 sleep 0.01
9209         done
9210
9211         kill -9 $pid
9212
9213         for i in $(seq $MDSCOUNT); do
9214                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9215         done
9216
9217         mkdir $DIR/$tdir/new || error "mkdir failed"
9218         rmdir $DIR/$tdir/new || error "rmdir failed"
9219
9220         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9221                 -t namespace
9222         for i in $(seq $MDSCOUNT); do
9223                 wait_update_facet mds$i "$LCTL get_param -n \
9224                         mdd.$(facet_svc mds$i).lfsck_namespace |
9225                         awk '/^status/ { print \\\$2 }'" "completed"
9226         done
9227
9228         ls -R $DIR/$tdir
9229         rm -rf $DIR/$tdir || error "rmdir failed"
9230 }
9231 run_test 60g "transaction abort won't cause MDT hung"
9232
9233 test_60h() {
9234         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9235                 skip "Need MDS version at least 2.12.52"
9236         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9237
9238         local f
9239
9240         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9241         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9242         for fail_loc in 0x80000188 0x80000189; do
9243                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9244                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9245                         error "mkdir $dir-$fail_loc failed"
9246                 for i in {0..10}; do
9247                         # create may fail on missing stripe
9248                         echo $i > $DIR/$tdir-$fail_loc/$i
9249                 done
9250                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9251                         error "getdirstripe $tdir-$fail_loc failed"
9252                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9253                         error "migrate $tdir-$fail_loc failed"
9254                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9255                         error "getdirstripe $tdir-$fail_loc failed"
9256                 pushd $DIR/$tdir-$fail_loc
9257                 for f in *; do
9258                         echo $f | cmp $f - || error "$f data mismatch"
9259                 done
9260                 popd
9261                 rm -rf $DIR/$tdir-$fail_loc
9262         done
9263 }
9264 run_test 60h "striped directory with missing stripes can be accessed"
9265
9266 function t60i_load() {
9267         mkdir $DIR/$tdir
9268         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9269         $LCTL set_param fail_loc=0x131c fail_val=1
9270         for ((i=0; i<5000; i++)); do
9271                 touch $DIR/$tdir/f$i
9272         done
9273 }
9274
9275 test_60i() {
9276         changelog_register || error "changelog_register failed"
9277         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9278         changelog_users $SINGLEMDS | grep -q $cl_user ||
9279                 error "User $cl_user not found in changelog_users"
9280         changelog_chmask "ALL"
9281         t60i_load &
9282         local PID=$!
9283         for((i=0; i<100; i++)); do
9284                 changelog_dump >/dev/null ||
9285                         error "can't read changelog"
9286         done
9287         kill $PID
9288         wait $PID
9289         changelog_deregister || error "changelog_deregister failed"
9290         $LCTL set_param fail_loc=0
9291 }
9292 run_test 60i "llog: new record vs reader race"
9293
9294 test_60j() {
9295         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9296                 skip "need MDS version at least 2.15.50"
9297         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9298         remote_mds_nodsh && skip "remote MDS with nodsh"
9299         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9300
9301         changelog_users $SINGLEMDS | grep "^cl" &&
9302                 skip "active changelog user"
9303
9304         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9305
9306         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9307                 skip_env "missing llog_reader"
9308
9309         mkdir_on_mdt0 $DIR/$tdir
9310
9311         local f=$DIR/$tdir/$tfile
9312         local mdt_dev
9313         local tmpfile
9314         local plain
9315
9316         changelog_register || error "cannot register changelog user"
9317
9318         # set changelog_mask to ALL
9319         changelog_chmask "ALL"
9320         changelog_clear
9321
9322         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9323         unlinkmany ${f}- 100 || error "unlinkmany failed"
9324
9325         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9326         mdt_dev=$(facet_device $SINGLEMDS)
9327
9328         do_facet $SINGLEMDS sync
9329         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9330                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9331                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9332
9333         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9334
9335         # if $tmpfile is not on EXT3 filesystem for some reason
9336         [[ ${plain:0:1} == 'O' ]] ||
9337                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9338
9339         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9340                 $mdt_dev; stat -c %s $tmpfile")
9341         echo "Truncate llog from $size to $((size - size % 8192))"
9342         size=$((size - size % 8192))
9343         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9344         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9345                 grep -c 'in bitmap only')
9346         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9347
9348         size=$((size - 9000))
9349         echo "Corrupt llog in the middle at $size"
9350         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9351                 count=333 conv=notrunc
9352         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9353                 grep -c 'next chunk')
9354         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9355 }
9356 run_test 60j "llog_reader reports corruptions"
9357
9358 test_61a() {
9359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9360
9361         f="$DIR/f61"
9362         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9363         cancel_lru_locks osc
9364         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9365         sync
9366 }
9367 run_test 61a "mmap() writes don't make sync hang ================"
9368
9369 test_61b() {
9370         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9371 }
9372 run_test 61b "mmap() of unstriped file is successful"
9373
9374 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9375 # Though this test is irrelevant anymore, it helped to reveal some
9376 # other grant bugs (LU-4482), let's keep it.
9377 test_63a() {   # was test_63
9378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9379
9380         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9381
9382         for i in `seq 10` ; do
9383                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9384                 sleep 5
9385                 kill $!
9386                 sleep 1
9387         done
9388
9389         rm -f $DIR/f63 || true
9390 }
9391 run_test 63a "Verify oig_wait interruption does not crash ======="
9392
9393 # bug 2248 - async write errors didn't return to application on sync
9394 # bug 3677 - async write errors left page locked
9395 test_63b() {
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397
9398         debugsave
9399         lctl set_param debug=-1
9400
9401         # ensure we have a grant to do async writes
9402         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9403         rm $DIR/$tfile
9404
9405         sync    # sync lest earlier test intercept the fail_loc
9406
9407         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9408         lctl set_param fail_loc=0x80000406
9409         $MULTIOP $DIR/$tfile Owy && \
9410                 error "sync didn't return ENOMEM"
9411         sync; sleep 2; sync     # do a real sync this time to flush page
9412         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9413                 error "locked page left in cache after async error" || true
9414         debugrestore
9415 }
9416 run_test 63b "async write errors should be returned to fsync ==="
9417
9418 test_64a () {
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420
9421         lfs df $DIR
9422         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9423 }
9424 run_test 64a "verify filter grant calculations (in kernel) ====="
9425
9426 test_64b () {
9427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9428
9429         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9430 }
9431 run_test 64b "check out-of-space detection on client"
9432
9433 test_64c() {
9434         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9435 }
9436 run_test 64c "verify grant shrink"
9437
9438 import_param() {
9439         local tgt=$1
9440         local param=$2
9441
9442         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9443 }
9444
9445 # this does exactly what osc_request.c:osc_announce_cached() does in
9446 # order to calculate max amount of grants to ask from server
9447 want_grant() {
9448         local tgt=$1
9449
9450         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9451         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9452
9453         ((rpc_in_flight++));
9454         nrpages=$((nrpages * rpc_in_flight))
9455
9456         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9457
9458         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9459
9460         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9461         local undirty=$((nrpages * PAGE_SIZE))
9462
9463         local max_extent_pages
9464         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9465         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9466         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9467         local grant_extent_tax
9468         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9469
9470         undirty=$((undirty + nrextents * grant_extent_tax))
9471
9472         echo $undirty
9473 }
9474
9475 # this is size of unit for grant allocation. It should be equal to
9476 # what tgt_grant.c:tgt_grant_chunk() calculates
9477 grant_chunk() {
9478         local tgt=$1
9479         local max_brw_size
9480         local grant_extent_tax
9481
9482         max_brw_size=$(import_param $tgt max_brw_size)
9483
9484         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9485
9486         echo $(((max_brw_size + grant_extent_tax) * 2))
9487 }
9488
9489 test_64d() {
9490         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9491                 skip "OST < 2.10.55 doesn't limit grants enough"
9492
9493         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9494
9495         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9496                 skip "no grant_param connect flag"
9497
9498         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9499
9500         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9501         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9502
9503
9504         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9505         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9506
9507         $LFS setstripe $DIR/$tfile -i 0 -c 1
9508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9509         ddpid=$!
9510
9511         while kill -0 $ddpid; do
9512                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9513
9514                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9515                         kill $ddpid
9516                         error "cur_grant $cur_grant > $max_cur_granted"
9517                 fi
9518
9519                 sleep 1
9520         done
9521 }
9522 run_test 64d "check grant limit exceed"
9523
9524 check_grants() {
9525         local tgt=$1
9526         local expected=$2
9527         local msg=$3
9528         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9529
9530         ((cur_grants == expected)) ||
9531                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9532 }
9533
9534 round_up_p2() {
9535         echo $((($1 + $2 - 1) & ~($2 - 1)))
9536 }
9537
9538 test_64e() {
9539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9540         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9541                 skip "Need OSS version at least 2.11.56"
9542
9543         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9544         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9545         $LCTL set_param debug=+cache
9546
9547         # Remount client to reset grant
9548         remount_client $MOUNT || error "failed to remount client"
9549         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9550
9551         local init_grants=$(import_param $osc_tgt initial_grant)
9552
9553         check_grants $osc_tgt $init_grants "init grants"
9554
9555         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9556         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9557         local gbs=$(import_param $osc_tgt grant_block_size)
9558
9559         # write random number of bytes from max_brw_size / 4 to max_brw_size
9560         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9561         # align for direct io
9562         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9563         # round to grant consumption unit
9564         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9565
9566         local grants=$((wb_round_up + extent_tax))
9567
9568         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9569         stack_trap "rm -f $DIR/$tfile"
9570
9571         # define OBD_FAIL_TGT_NO_GRANT 0x725
9572         # make the server not grant more back
9573         do_facet ost1 $LCTL set_param fail_loc=0x725
9574         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9575
9576         do_facet ost1 $LCTL set_param fail_loc=0
9577
9578         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9579
9580         rm -f $DIR/$tfile || error "rm failed"
9581
9582         # Remount client to reset grant
9583         remount_client $MOUNT || error "failed to remount client"
9584         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9585
9586         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9587
9588         # define OBD_FAIL_TGT_NO_GRANT 0x725
9589         # make the server not grant more back
9590         do_facet ost1 $LCTL set_param fail_loc=0x725
9591         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9592         do_facet ost1 $LCTL set_param fail_loc=0
9593
9594         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9595 }
9596 run_test 64e "check grant consumption (no grant allocation)"
9597
9598 test_64f() {
9599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9600
9601         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9602         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9603         $LCTL set_param debug=+cache
9604
9605         # Remount client to reset grant
9606         remount_client $MOUNT || error "failed to remount client"
9607         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9608
9609         local init_grants=$(import_param $osc_tgt initial_grant)
9610         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9611         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9612         local gbs=$(import_param $osc_tgt grant_block_size)
9613         local chunk=$(grant_chunk $osc_tgt)
9614
9615         # write random number of bytes from max_brw_size / 4 to max_brw_size
9616         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9617         # align for direct io
9618         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9619         # round to grant consumption unit
9620         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9621
9622         local grants=$((wb_round_up + extent_tax))
9623
9624         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9625         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9626                 error "error writing to $DIR/$tfile"
9627
9628         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9629                 "direct io with grant allocation"
9630
9631         rm -f $DIR/$tfile || error "rm failed"
9632
9633         # Remount client to reset grant
9634         remount_client $MOUNT || error "failed to remount client"
9635         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9636
9637         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9638
9639         local cmd="oO_WRONLY:w${write_bytes}_yc"
9640
9641         $MULTIOP $DIR/$tfile $cmd &
9642         MULTIPID=$!
9643         sleep 1
9644
9645         check_grants $osc_tgt $((init_grants - grants)) \
9646                 "buffered io, not write rpc"
9647
9648         kill -USR1 $MULTIPID
9649         wait
9650
9651         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9652                 "buffered io, one RPC"
9653 }
9654 run_test 64f "check grant consumption (with grant allocation)"
9655
9656 test_64g() {
9657         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9658                 skip "Need MDS version at least 2.14.56"
9659
9660         local mdts=$(comma_list $(mdts_nodes))
9661
9662         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9663                         tr '\n' ' ')
9664         stack_trap "$LCTL set_param $old"
9665
9666         # generate dirty pages and increase dirty granted on MDT
9667         stack_trap "rm -f $DIR/$tfile-*"
9668         for (( i = 0; i < 10; i++)); do
9669                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9670                         error "can't set stripe"
9671                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9672                         error "can't dd"
9673                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9674                         $LFS getstripe $DIR/$tfile-$i
9675                         error "not DoM file"
9676                 }
9677         done
9678
9679         # flush dirty pages
9680         sync
9681
9682         # wait until grant shrink reset grant dirty on MDTs
9683         for ((i = 0; i < 120; i++)); do
9684                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9685                         awk '{sum=sum+$1} END {print sum}')
9686                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9687                 echo "$grant_dirty grants, $vm_dirty pages"
9688                 (( grant_dirty + vm_dirty == 0 )) && break
9689                 (( i == 3 )) && sync &&
9690                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9691                 sleep 1
9692         done
9693
9694         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9695                 awk '{sum=sum+$1} END {print sum}')
9696         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9697 }
9698 run_test 64g "grant shrink on MDT"
9699
9700 test_64h() {
9701         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9702                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9703
9704         local instance=$($LFS getname -i $DIR)
9705         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9706         local num_exps=$(do_facet ost1 \
9707             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9708         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9709         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9710         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9711
9712         # 10MiB is for file to be written, max_brw_size * 16 *
9713         # num_exps is space reserve so that tgt_grant_shrink() decided
9714         # to not shrink
9715         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9716         (( avail * 1024 < expect )) &&
9717                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9718
9719         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9720         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9721         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9722         $LCTL set_param osc.*OST0000*.grant_shrink=1
9723         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9724
9725         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9726         stack_trap "rm -f $DIR/$tfile"
9727         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9728
9729         # drop cache so that coming read would do rpc
9730         cancel_lru_locks osc
9731
9732         # shrink interval is set to 10, pause for 7 seconds so that
9733         # grant thread did not wake up yet but coming read entered
9734         # shrink mode for rpc (osc_should_shrink_grant())
9735         sleep 7
9736
9737         declare -a cur_grant_bytes
9738         declare -a tot_granted
9739         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9740         tot_granted[0]=$(do_facet ost1 \
9741             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9742
9743         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9744
9745         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9746         tot_granted[1]=$(do_facet ost1 \
9747             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9748
9749         # grant change should be equal on both sides
9750         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9751                 tot_granted[0] - tot_granted[1])) ||
9752                 error "grant change mismatch, "                                \
9753                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9754                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9755 }
9756 run_test 64h "grant shrink on read"
9757
9758 test_64i() {
9759         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9760                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9761
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763         remote_ost_nodsh && skip "remote OSTs with nodsh"
9764
9765         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9766         stack_trap "rm -f $DIR/$tfile"
9767
9768         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9769
9770         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9771         local instance=$($LFS getname -i $DIR)
9772
9773         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9774         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9775
9776         # shrink grants and simulate rpc loss
9777         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9778         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9779         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9780
9781         fail ost1
9782
9783         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9784
9785         local testid=$(echo $TESTNAME | tr '_' ' ')
9786
9787         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9788                 grep "GRANT, real grant" &&
9789                 error "client has more grants then it owns" || true
9790 }
9791 run_test 64i "shrink on reconnect"
9792
9793 # bug 1414 - set/get directories' stripe info
9794 test_65a() {
9795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9796
9797         test_mkdir $DIR/$tdir
9798         touch $DIR/$tdir/f1
9799         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9800 }
9801 run_test 65a "directory with no stripe info"
9802
9803 test_65b() {
9804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9805
9806         test_mkdir $DIR/$tdir
9807         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9808
9809         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9810                                                 error "setstripe"
9811         touch $DIR/$tdir/f2
9812         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9813 }
9814 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9815
9816 test_65c() {
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9819
9820         test_mkdir $DIR/$tdir
9821         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9822
9823         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9824                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9825         touch $DIR/$tdir/f3
9826         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9827 }
9828 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9829
9830 test_65d() {
9831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9832
9833         test_mkdir $DIR/$tdir
9834         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9835         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9836
9837         if [[ $STRIPECOUNT -le 0 ]]; then
9838                 sc=1
9839         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9840                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9841                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9842         else
9843                 sc=$(($STRIPECOUNT - 1))
9844         fi
9845         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9846         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9847         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9848                 error "lverify failed"
9849 }
9850 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9851
9852 test_65e() {
9853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9854
9855         # LU-16904 delete layout when root is set as PFL layout
9856         save_layout_restore_at_exit $MOUNT
9857         $LFS setstripe -d $MOUNT || error "setstripe failed"
9858
9859         test_mkdir $DIR/$tdir
9860
9861         $LFS setstripe $DIR/$tdir || error "setstripe"
9862         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9863                                         error "no stripe info failed"
9864         touch $DIR/$tdir/f6
9865         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9866 }
9867 run_test 65e "directory setstripe defaults"
9868
9869 test_65f() {
9870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9871
9872         test_mkdir $DIR/${tdir}f
9873         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9874                 error "setstripe succeeded" || true
9875 }
9876 run_test 65f "dir setstripe permission (should return error) ==="
9877
9878 test_65g() {
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880
9881         # LU-16904 delete layout when root is set as PFL layout
9882         save_layout_restore_at_exit $MOUNT
9883         $LFS setstripe -d $MOUNT || error "setstripe failed"
9884
9885         test_mkdir $DIR/$tdir
9886         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9887
9888         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9889                 error "setstripe -S failed"
9890         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9891         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9892                 error "delete default stripe failed"
9893 }
9894 run_test 65g "directory setstripe -d"
9895
9896 test_65h() {
9897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9898
9899         test_mkdir $DIR/$tdir
9900         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9901
9902         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9903                 error "setstripe -S failed"
9904         test_mkdir $DIR/$tdir/dd1
9905         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9906                 error "stripe info inherit failed"
9907 }
9908 run_test 65h "directory stripe info inherit ===================="
9909
9910 test_65i() {
9911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9912
9913         save_layout_restore_at_exit $MOUNT
9914
9915         # bug6367: set non-default striping on root directory
9916         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9917
9918         # bug12836: getstripe on -1 default directory striping
9919         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9920
9921         # bug12836: getstripe -v on -1 default directory striping
9922         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9923
9924         # bug12836: new find on -1 default directory striping
9925         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9926 }
9927 run_test 65i "various tests to set root directory striping"
9928
9929 test_65j() { # bug6367
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931
9932         sync; sleep 1
9933
9934         # if we aren't already remounting for each test, do so for this test
9935         if [ "$I_MOUNTED" = "yes" ]; then
9936                 cleanup || error "failed to unmount"
9937                 setup
9938         fi
9939
9940         save_layout_restore_at_exit $MOUNT
9941
9942         $LFS setstripe -d $MOUNT || error "setstripe failed"
9943 }
9944 run_test 65j "set default striping on root directory (bug 6367)="
9945
9946 cleanup_65k() {
9947         rm -rf $DIR/$tdir
9948         wait_delete_completed
9949         do_facet $SINGLEMDS "lctl set_param -n \
9950                 osp.$ost*MDT0000.max_create_count=$max_count"
9951         do_facet $SINGLEMDS "lctl set_param -n \
9952                 osp.$ost*MDT0000.create_count=$count"
9953         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9954         echo $INACTIVE_OSC "is Activate"
9955
9956         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9957 }
9958
9959 test_65k() { # bug11679
9960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9961         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9962         remote_mds_nodsh && skip "remote MDS with nodsh"
9963
9964         local disable_precreate=true
9965         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9966                 disable_precreate=false
9967
9968         echo "Check OST status: "
9969         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9970                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9971
9972         for OSC in $MDS_OSCS; do
9973                 echo $OSC "is active"
9974                 do_facet $SINGLEMDS lctl --device %$OSC activate
9975         done
9976
9977         for INACTIVE_OSC in $MDS_OSCS; do
9978                 local ost=$(osc_to_ost $INACTIVE_OSC)
9979                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9980                                lov.*md*.target_obd |
9981                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9982
9983                 mkdir -p $DIR/$tdir
9984                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9985                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9986
9987                 echo "Deactivate: " $INACTIVE_OSC
9988                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9989
9990                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9991                               osp.$ost*MDT0000.create_count")
9992                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9993                                   osp.$ost*MDT0000.max_create_count")
9994                 $disable_precreate &&
9995                         do_facet $SINGLEMDS "lctl set_param -n \
9996                                 osp.$ost*MDT0000.max_create_count=0"
9997
9998                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9999                         [ -f $DIR/$tdir/$idx ] && continue
10000                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10001                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10002                                 { cleanup_65k;
10003                                   error "setstripe $idx should succeed"; }
10004                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10005                 done
10006                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10007                 rmdir $DIR/$tdir
10008
10009                 do_facet $SINGLEMDS "lctl set_param -n \
10010                         osp.$ost*MDT0000.max_create_count=$max_count"
10011                 do_facet $SINGLEMDS "lctl set_param -n \
10012                         osp.$ost*MDT0000.create_count=$count"
10013                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10014                 echo $INACTIVE_OSC "is Activate"
10015
10016                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10017         done
10018 }
10019 run_test 65k "validate manual striping works properly with deactivated OSCs"
10020
10021 test_65l() { # bug 12836
10022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10023
10024         test_mkdir -p $DIR/$tdir/test_dir
10025         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10026         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10027 }
10028 run_test 65l "lfs find on -1 stripe dir ========================"
10029
10030 test_65m() {
10031         local layout=$(save_layout $MOUNT)
10032         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10033                 restore_layout $MOUNT $layout
10034                 error "setstripe should fail by non-root users"
10035         }
10036         true
10037 }
10038 run_test 65m "normal user can't set filesystem default stripe"
10039
10040 test_65n() {
10041         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10042         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10043                 skip "Need MDS version at least 2.12.50"
10044         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10045
10046         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10047         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10048         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10049
10050         save_layout_restore_at_exit $MOUNT
10051
10052         # new subdirectory under root directory should not inherit
10053         # the default layout from root
10054         # LU-16904 check if the root is set as PFL layout
10055         local numcomp=$($LFS getstripe --component-count $MOUNT)
10056
10057         if [[ $numcomp -eq 0 ]]; then
10058                 local dir1=$MOUNT/$tdir-1
10059                 mkdir $dir1 || error "mkdir $dir1 failed"
10060                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10061                         error "$dir1 shouldn't have LOV EA"
10062         fi
10063
10064         # delete the default layout on root directory
10065         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10066
10067         local dir2=$MOUNT/$tdir-2
10068         mkdir $dir2 || error "mkdir $dir2 failed"
10069         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10070                 error "$dir2 shouldn't have LOV EA"
10071
10072         # set a new striping pattern on root directory
10073         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10074         local new_def_stripe_size=$((def_stripe_size * 2))
10075         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10076                 error "set stripe size on $MOUNT failed"
10077
10078         # new file created in $dir2 should inherit the new stripe size from
10079         # the filesystem default
10080         local file2=$dir2/$tfile-2
10081         touch $file2 || error "touch $file2 failed"
10082
10083         local file2_stripe_size=$($LFS getstripe -S $file2)
10084         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10085         {
10086                 echo "file2_stripe_size: '$file2_stripe_size'"
10087                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10088                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10089         }
10090
10091         local dir3=$MOUNT/$tdir-3
10092         mkdir $dir3 || error "mkdir $dir3 failed"
10093         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10094         # the root layout, which is the actual default layout that will be used
10095         # when new files are created in $dir3.
10096         local dir3_layout=$(get_layout_param $dir3)
10097         local root_dir_layout=$(get_layout_param $MOUNT)
10098         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10099         {
10100                 echo "dir3_layout: '$dir3_layout'"
10101                 echo "root_dir_layout: '$root_dir_layout'"
10102                 error "$dir3 should show the default layout from $MOUNT"
10103         }
10104
10105         # set OST pool on root directory
10106         local pool=$TESTNAME
10107         pool_add $pool || error "add $pool failed"
10108         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10109                 error "add targets to $pool failed"
10110
10111         $LFS setstripe -p $pool $MOUNT ||
10112                 error "set OST pool on $MOUNT failed"
10113
10114         # new file created in $dir3 should inherit the pool from
10115         # the filesystem default
10116         local file3=$dir3/$tfile-3
10117         touch $file3 || error "touch $file3 failed"
10118
10119         local file3_pool=$($LFS getstripe -p $file3)
10120         [[ "$file3_pool" = "$pool" ]] ||
10121                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10122
10123         local dir4=$MOUNT/$tdir-4
10124         mkdir $dir4 || error "mkdir $dir4 failed"
10125         local dir4_layout=$(get_layout_param $dir4)
10126         root_dir_layout=$(get_layout_param $MOUNT)
10127         echo "$LFS getstripe -d $dir4"
10128         $LFS getstripe -d $dir4
10129         echo "$LFS getstripe -d $MOUNT"
10130         $LFS getstripe -d $MOUNT
10131         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10132         {
10133                 echo "dir4_layout: '$dir4_layout'"
10134                 echo "root_dir_layout: '$root_dir_layout'"
10135                 error "$dir4 should show the default layout from $MOUNT"
10136         }
10137
10138         # new file created in $dir4 should inherit the pool from
10139         # the filesystem default
10140         local file4=$dir4/$tfile-4
10141         touch $file4 || error "touch $file4 failed"
10142
10143         local file4_pool=$($LFS getstripe -p $file4)
10144         [[ "$file4_pool" = "$pool" ]] ||
10145                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10146
10147         # new subdirectory under non-root directory should inherit
10148         # the default layout from its parent directory
10149         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10150                 error "set directory layout on $dir4 failed"
10151
10152         local dir5=$dir4/$tdir-5
10153         mkdir $dir5 || error "mkdir $dir5 failed"
10154
10155         dir4_layout=$(get_layout_param $dir4)
10156         local dir5_layout=$(get_layout_param $dir5)
10157         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10158         {
10159                 echo "dir4_layout: '$dir4_layout'"
10160                 echo "dir5_layout: '$dir5_layout'"
10161                 error "$dir5 should inherit the default layout from $dir4"
10162         }
10163
10164         # though subdir under ROOT doesn't inherit default layout, but
10165         # its sub dir/file should be created with default layout.
10166         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10167         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10168                 skip "Need MDS version at least 2.12.59"
10169
10170         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10171         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10172         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10173
10174         if [ $default_lmv_hash == "none" ]; then
10175                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10176         else
10177                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10178                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10179         fi
10180
10181         $LFS setdirstripe -D -c 2 $MOUNT ||
10182                 error "setdirstripe -D -c 2 failed"
10183         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10184         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10185         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10186
10187         # $dir4 layout includes pool
10188         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10189         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10190                 error "pool lost on setstripe"
10191         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10192         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10193                 error "pool lost on compound layout setstripe"
10194 }
10195 run_test 65n "don't inherit default layout from root for new subdirectories"
10196
10197 test_65o() {
10198         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10199                 skip "need MDS version at least 2.14.57"
10200
10201         # set OST pool on root directory
10202         local pool=$TESTNAME
10203
10204         pool_add $pool || error "add $pool failed"
10205         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10206                 error "add targets to $pool failed"
10207
10208         local dir1=$MOUNT/$tdir
10209
10210         mkdir $dir1 || error "mkdir $dir1 failed"
10211
10212         # set a new striping pattern on root directory
10213         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10214
10215         $LFS setstripe -p $pool $dir1 ||
10216                 error "set directory layout on $dir1 failed"
10217
10218         # $dir1 layout includes pool
10219         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10220         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10221                 error "pool lost on setstripe"
10222         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10223         $LFS getstripe $dir1
10224         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10225                 error "pool lost on compound layout setstripe"
10226
10227         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10228                 error "setdirstripe failed on sub-dir with inherited pool"
10229         $LFS getstripe $dir1/dir2
10230         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10231                 error "pool lost on compound layout setdirstripe"
10232
10233         $LFS setstripe -E -1 -c 1 $dir1
10234         $LFS getstripe -d $dir1
10235         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10236                 error "pool lost on setstripe"
10237 }
10238 run_test 65o "pool inheritance for mdt component"
10239
10240 test_65p () { # LU-16152
10241         local src_dir=$DIR/$tdir/src_dir
10242         local dst_dir=$DIR/$tdir/dst_dir
10243         local yaml_file=$DIR/$tdir/layout.yaml
10244         local border
10245
10246         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10247                 skip "Need at least version 2.15.51"
10248
10249         test_mkdir -p $src_dir
10250         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10251                 error "failed to setstripe"
10252         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10253                 error "failed to getstripe"
10254
10255         test_mkdir -p $dst_dir
10256         $LFS setstripe --yaml $yaml_file $dst_dir ||
10257                 error "failed to setstripe with yaml file"
10258         border=$($LFS getstripe -d $dst_dir |
10259                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10260                 error "failed to getstripe"
10261
10262         # 2048M is 0x80000000, or 2147483648
10263         (( $border == 2147483648 )) ||
10264                 error "failed to handle huge number in yaml layout"
10265 }
10266 run_test 65p "setstripe with yaml file and huge number"
10267
10268 # bug 2543 - update blocks count on client
10269 test_66() {
10270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10271
10272         local COUNT=${COUNT:-8}
10273         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10274         sync; sync_all_data; sync; sync_all_data
10275         cancel_lru_locks osc
10276         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10277         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10278 }
10279 run_test 66 "update inode blocks count on client ==============="
10280
10281 meminfo() {
10282         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10283 }
10284
10285 swap_used() {
10286         swapon -s | awk '($1 == "'$1'") { print $4 }'
10287 }
10288
10289 # bug5265, obdfilter oa2dentry return -ENOENT
10290 # #define OBD_FAIL_SRV_ENOENT 0x217
10291 test_69() {
10292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10293         remote_ost_nodsh && skip "remote OST with nodsh"
10294
10295         f="$DIR/$tfile"
10296         $LFS setstripe -c 1 -i 0 $f
10297         stack_trap "rm -f $f ${f}.2"
10298
10299         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10300
10301         do_facet ost1 lctl set_param fail_loc=0x217
10302         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10303         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10304
10305         do_facet ost1 lctl set_param fail_loc=0
10306         $DIRECTIO write $f 0 2 || error "write error"
10307
10308         cancel_lru_locks osc
10309         $DIRECTIO read $f 0 1 || error "read error"
10310
10311         do_facet ost1 lctl set_param fail_loc=0x217
10312         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10313
10314         do_facet ost1 lctl set_param fail_loc=0
10315 }
10316 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10317
10318 test_71() {
10319         test_mkdir $DIR/$tdir
10320         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10321         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10322 }
10323 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10324
10325 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10327         [ "$RUNAS_ID" = "$UID" ] &&
10328                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10329         # Check that testing environment is properly set up. Skip if not
10330         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10331                 skip_env "User $RUNAS_ID does not exist - skipping"
10332
10333         touch $DIR/$tfile
10334         chmod 777 $DIR/$tfile
10335         chmod ug+s $DIR/$tfile
10336         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10337                 error "$RUNAS dd $DIR/$tfile failed"
10338         # See if we are still setuid/sgid
10339         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10340                 error "S/gid is not dropped on write"
10341         # Now test that MDS is updated too
10342         cancel_lru_locks mdc
10343         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10344                 error "S/gid is not dropped on MDS"
10345         rm -f $DIR/$tfile
10346 }
10347 run_test 72a "Test that remove suid works properly (bug5695) ===="
10348
10349 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10350         local perm
10351
10352         [ "$RUNAS_ID" = "$UID" ] &&
10353                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10354         [ "$RUNAS_ID" -eq 0 ] &&
10355                 skip_env "RUNAS_ID = 0 -- skipping"
10356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10357         # Check that testing environment is properly set up. Skip if not
10358         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10359                 skip_env "User $RUNAS_ID does not exist - skipping"
10360
10361         touch $DIR/${tfile}-f{g,u}
10362         test_mkdir $DIR/${tfile}-dg
10363         test_mkdir $DIR/${tfile}-du
10364         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10365         chmod g+s $DIR/${tfile}-{f,d}g
10366         chmod u+s $DIR/${tfile}-{f,d}u
10367         for perm in 777 2777 4777; do
10368                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10369                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10370                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10371                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10372         done
10373         true
10374 }
10375 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10376
10377 # bug 3462 - multiple simultaneous MDC requests
10378 test_73() {
10379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10380
10381         test_mkdir $DIR/d73-1
10382         test_mkdir $DIR/d73-2
10383         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10384         pid1=$!
10385
10386         lctl set_param fail_loc=0x80000129
10387         $MULTIOP $DIR/d73-1/f73-2 Oc &
10388         sleep 1
10389         lctl set_param fail_loc=0
10390
10391         $MULTIOP $DIR/d73-2/f73-3 Oc &
10392         pid3=$!
10393
10394         kill -USR1 $pid1
10395         wait $pid1 || return 1
10396
10397         sleep 25
10398
10399         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10400         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10401         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10402
10403         rm -rf $DIR/d73-*
10404 }
10405 run_test 73 "multiple MDC requests (should not deadlock)"
10406
10407 test_74a() { # bug 6149, 6184
10408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10409
10410         touch $DIR/f74a
10411         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10412         #
10413         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10414         # will spin in a tight reconnection loop
10415         $LCTL set_param fail_loc=0x8000030e
10416         # get any lock that won't be difficult - lookup works.
10417         ls $DIR/f74a
10418         $LCTL set_param fail_loc=0
10419         rm -f $DIR/f74a
10420         true
10421 }
10422 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10423
10424 test_74b() { # bug 13310
10425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10426
10427         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10428         #
10429         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10430         # will spin in a tight reconnection loop
10431         $LCTL set_param fail_loc=0x8000030e
10432         # get a "difficult" lock
10433         touch $DIR/f74b
10434         $LCTL set_param fail_loc=0
10435         rm -f $DIR/f74b
10436         true
10437 }
10438 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10439
10440 test_74c() {
10441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10442
10443         #define OBD_FAIL_LDLM_NEW_LOCK
10444         $LCTL set_param fail_loc=0x319
10445         touch $DIR/$tfile && error "touch successful"
10446         $LCTL set_param fail_loc=0
10447         true
10448 }
10449 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10450
10451 slab_lic=/sys/kernel/slab/lustre_inode_cache
10452 num_objects() {
10453         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10454         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10455                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10456 }
10457
10458 test_76a() { # Now for b=20433, added originally in b=1443
10459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10460
10461         cancel_lru_locks osc
10462         # there may be some slab objects cached per core
10463         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10464         local before=$(num_objects)
10465         local count=$((512 * cpus))
10466         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10467         local margin=$((count / 10))
10468         if [[ -f $slab_lic/aliases ]]; then
10469                 local aliases=$(cat $slab_lic/aliases)
10470                 (( aliases > 0 )) && margin=$((margin * aliases))
10471         fi
10472
10473         echo "before slab objects: $before"
10474         for i in $(seq $count); do
10475                 touch $DIR/$tfile
10476                 rm -f $DIR/$tfile
10477         done
10478         cancel_lru_locks osc
10479         local after=$(num_objects)
10480         echo "created: $count, after slab objects: $after"
10481         # shared slab counts are not very accurate, allow significant margin
10482         # the main goal is that the cache growth is not permanently > $count
10483         while (( after > before + margin )); do
10484                 sleep 1
10485                 after=$(num_objects)
10486                 wait=$((wait + 1))
10487                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10488                 if (( wait > 60 )); then
10489                         error "inode slab grew from $before+$margin to $after"
10490                 fi
10491         done
10492 }
10493 run_test 76a "confirm clients recycle inodes properly ===="
10494
10495 test_76b() {
10496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10497         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10498
10499         local count=512
10500         local before=$(num_objects)
10501
10502         for i in $(seq $count); do
10503                 mkdir $DIR/$tdir
10504                 rmdir $DIR/$tdir
10505         done
10506
10507         local after=$(num_objects)
10508         local wait=0
10509
10510         while (( after > before )); do
10511                 sleep 1
10512                 after=$(num_objects)
10513                 wait=$((wait + 1))
10514                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10515                 if (( wait > 60 )); then
10516                         error "inode slab grew from $before to $after"
10517                 fi
10518         done
10519
10520         echo "slab objects before: $before, after: $after"
10521 }
10522 run_test 76b "confirm clients recycle directory inodes properly ===="
10523
10524 export ORIG_CSUM=""
10525 set_checksums()
10526 {
10527         # Note: in sptlrpc modes which enable its own bulk checksum, the
10528         # original crc32_le bulk checksum will be automatically disabled,
10529         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10530         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10531         # In this case set_checksums() will not be no-op, because sptlrpc
10532         # bulk checksum will be enabled all through the test.
10533
10534         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10535         lctl set_param -n osc.*.checksums $1
10536         return 0
10537 }
10538
10539 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10540                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10541 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10542                              tr -d [] | head -n1)}
10543 set_checksum_type()
10544 {
10545         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10546         rc=$?
10547         log "set checksum type to $1, rc = $rc"
10548         return $rc
10549 }
10550
10551 get_osc_checksum_type()
10552 {
10553         # arugment 1: OST name, like OST0000
10554         ost=$1
10555         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10556                         sed 's/.*\[\(.*\)\].*/\1/g')
10557         rc=$?
10558         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10559         echo $checksum_type
10560 }
10561
10562 F77_TMP=$TMP/f77-temp
10563 F77SZ=8
10564 setup_f77() {
10565         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10566                 error "error writing to $F77_TMP"
10567 }
10568
10569 test_77a() { # bug 10889
10570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10571         $GSS && skip_env "could not run with gss"
10572
10573         [ ! -f $F77_TMP ] && setup_f77
10574         set_checksums 1
10575         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10576         set_checksums 0
10577         rm -f $DIR/$tfile
10578 }
10579 run_test 77a "normal checksum read/write operation"
10580
10581 test_77b() { # bug 10889
10582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10583         $GSS && skip_env "could not run with gss"
10584
10585         [ ! -f $F77_TMP ] && setup_f77
10586         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10587         $LCTL set_param fail_loc=0x80000409
10588         set_checksums 1
10589
10590         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10591                 error "dd error: $?"
10592         $LCTL set_param fail_loc=0
10593
10594         for algo in $CKSUM_TYPES; do
10595                 cancel_lru_locks osc
10596                 set_checksum_type $algo
10597                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10598                 $LCTL set_param fail_loc=0x80000408
10599                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10600                 $LCTL set_param fail_loc=0
10601         done
10602         set_checksums 0
10603         set_checksum_type $ORIG_CSUM_TYPE
10604         rm -f $DIR/$tfile
10605 }
10606 run_test 77b "checksum error on client write, read"
10607
10608 cleanup_77c() {
10609         trap 0
10610         set_checksums 0
10611         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10612         $check_ost &&
10613                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10614         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10615         $check_ost && [ -n "$ost_file_prefix" ] &&
10616                 do_facet ost1 rm -f ${ost_file_prefix}\*
10617 }
10618
10619 test_77c() {
10620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10621         $GSS && skip_env "could not run with gss"
10622         remote_ost_nodsh && skip "remote OST with nodsh"
10623
10624         local bad1
10625         local osc_file_prefix
10626         local osc_file
10627         local check_ost=false
10628         local ost_file_prefix
10629         local ost_file
10630         local orig_cksum
10631         local dump_cksum
10632         local fid
10633
10634         # ensure corruption will occur on first OSS/OST
10635         $LFS setstripe -i 0 $DIR/$tfile
10636
10637         [ ! -f $F77_TMP ] && setup_f77
10638         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10639                 error "dd write error: $?"
10640         fid=$($LFS path2fid $DIR/$tfile)
10641
10642         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10643         then
10644                 check_ost=true
10645                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10646                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10647         else
10648                 echo "OSS do not support bulk pages dump upon error"
10649         fi
10650
10651         osc_file_prefix=$($LCTL get_param -n debug_path)
10652         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10653
10654         trap cleanup_77c EXIT
10655
10656         set_checksums 1
10657         # enable bulk pages dump upon error on Client
10658         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10659         # enable bulk pages dump upon error on OSS
10660         $check_ost &&
10661                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10662
10663         # flush Client cache to allow next read to reach OSS
10664         cancel_lru_locks osc
10665
10666         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10667         $LCTL set_param fail_loc=0x80000408
10668         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10669         $LCTL set_param fail_loc=0
10670
10671         rm -f $DIR/$tfile
10672
10673         # check cksum dump on Client
10674         osc_file=$(ls ${osc_file_prefix}*)
10675         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10676         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10677         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10678         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10679         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10680                      cksum)
10681         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10682         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10683                 error "dump content does not match on Client"
10684
10685         $check_ost || skip "No need to check cksum dump on OSS"
10686
10687         # check cksum dump on OSS
10688         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10689         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10690         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10691         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10692         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10693                 error "dump content does not match on OSS"
10694
10695         cleanup_77c
10696 }
10697 run_test 77c "checksum error on client read with debug"
10698
10699 test_77d() { # bug 10889
10700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10701         $GSS && skip_env "could not run with gss"
10702
10703         stack_trap "rm -f $DIR/$tfile"
10704         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10705         $LCTL set_param fail_loc=0x80000409
10706         set_checksums 1
10707         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10708                 error "direct write: rc=$?"
10709         $LCTL set_param fail_loc=0
10710         set_checksums 0
10711
10712         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10713         $LCTL set_param fail_loc=0x80000408
10714         set_checksums 1
10715         cancel_lru_locks osc
10716         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10717                 error "direct read: rc=$?"
10718         $LCTL set_param fail_loc=0
10719         set_checksums 0
10720 }
10721 run_test 77d "checksum error on OST direct write, read"
10722
10723 test_77f() { # bug 10889
10724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10725         $GSS && skip_env "could not run with gss"
10726
10727         set_checksums 1
10728         stack_trap "rm -f $DIR/$tfile"
10729         for algo in $CKSUM_TYPES; do
10730                 cancel_lru_locks osc
10731                 set_checksum_type $algo
10732                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10733                 $LCTL set_param fail_loc=0x409
10734                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10735                         error "direct write succeeded"
10736                 $LCTL set_param fail_loc=0
10737         done
10738         set_checksum_type $ORIG_CSUM_TYPE
10739         set_checksums 0
10740 }
10741 run_test 77f "repeat checksum error on write (expect error)"
10742
10743 test_77g() { # bug 10889
10744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10745         $GSS && skip_env "could not run with gss"
10746         remote_ost_nodsh && skip "remote OST with nodsh"
10747
10748         [ ! -f $F77_TMP ] && setup_f77
10749
10750         local file=$DIR/$tfile
10751         stack_trap "rm -f $file" EXIT
10752
10753         $LFS setstripe -c 1 -i 0 $file
10754         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10755         do_facet ost1 lctl set_param fail_loc=0x8000021a
10756         set_checksums 1
10757         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10758                 error "write error: rc=$?"
10759         do_facet ost1 lctl set_param fail_loc=0
10760         set_checksums 0
10761
10762         cancel_lru_locks osc
10763         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10764         do_facet ost1 lctl set_param fail_loc=0x8000021b
10765         set_checksums 1
10766         cmp $F77_TMP $file || error "file compare failed"
10767         do_facet ost1 lctl set_param fail_loc=0
10768         set_checksums 0
10769 }
10770 run_test 77g "checksum error on OST write, read"
10771
10772 test_77k() { # LU-10906
10773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10774         $GSS && skip_env "could not run with gss"
10775
10776         local cksum_param="osc.$FSNAME*.checksums"
10777         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10778         local checksum
10779         local i
10780
10781         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10782         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10783         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10784
10785         for i in 0 1; do
10786                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10787                         error "failed to set checksum=$i on MGS"
10788                 wait_update $HOSTNAME "$get_checksum" $i
10789                 #remount
10790                 echo "remount client, checksum should be $i"
10791                 remount_client $MOUNT || error "failed to remount client"
10792                 checksum=$(eval $get_checksum)
10793                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10794         done
10795         # remove persistent param to avoid races with checksum mountopt below
10796         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10797                 error "failed to delete checksum on MGS"
10798
10799         for opt in "checksum" "nochecksum"; do
10800                 #remount with mount option
10801                 echo "remount client with option $opt, checksum should be $i"
10802                 umount_client $MOUNT || error "failed to umount client"
10803                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10804                         error "failed to mount client with option '$opt'"
10805                 checksum=$(eval $get_checksum)
10806                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10807                 i=$((i - 1))
10808         done
10809
10810         remount_client $MOUNT || error "failed to remount client"
10811 }
10812 run_test 77k "enable/disable checksum correctly"
10813
10814 test_77l() {
10815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10816         $GSS && skip_env "could not run with gss"
10817
10818         set_checksums 1
10819         stack_trap "set_checksums $ORIG_CSUM" EXIT
10820         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10821
10822         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10823
10824         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10825         for algo in $CKSUM_TYPES; do
10826                 set_checksum_type $algo || error "fail to set checksum type $algo"
10827                 osc_algo=$(get_osc_checksum_type OST0000)
10828                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10829
10830                 # no locks, no reqs to let the connection idle
10831                 cancel_lru_locks osc
10832                 lru_resize_disable osc
10833                 wait_osc_import_state client ost1 IDLE
10834
10835                 # ensure ost1 is connected
10836                 stat $DIR/$tfile >/dev/null || error "can't stat"
10837                 wait_osc_import_state client ost1 FULL
10838
10839                 osc_algo=$(get_osc_checksum_type OST0000)
10840                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10841         done
10842         return 0
10843 }
10844 run_test 77l "preferred checksum type is remembered after reconnected"
10845
10846 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10847 rm -f $F77_TMP
10848 unset F77_TMP
10849
10850 test_77m() {
10851         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10852                 skip "Need at least version 2.14.52"
10853         local param=checksum_speed
10854
10855         $LCTL get_param $param || error "reading $param failed"
10856
10857         csum_speeds=$($LCTL get_param -n $param)
10858
10859         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10860                 error "known checksum types are missing"
10861 }
10862 run_test 77m "Verify checksum_speed is correctly read"
10863
10864 check_filefrag_77n() {
10865         local nr_ext=0
10866         local starts=()
10867         local ends=()
10868
10869         while read extidx a b start end rest; do
10870                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10871                         nr_ext=$(( $nr_ext + 1 ))
10872                         starts+=( ${start%..} )
10873                         ends+=( ${end%:} )
10874                 fi
10875         done < <( filefrag -sv $1 )
10876
10877         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10878         return 1
10879 }
10880
10881 test_77n() {
10882         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10883
10884         touch $DIR/$tfile
10885         $TRUNCATE $DIR/$tfile 0
10886         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10887         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10888         check_filefrag_77n $DIR/$tfile ||
10889                 skip "$tfile blocks not contiguous around hole"
10890
10891         set_checksums 1
10892         stack_trap "set_checksums $ORIG_CSUM" EXIT
10893         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10894         stack_trap "rm -f $DIR/$tfile"
10895
10896         for algo in $CKSUM_TYPES; do
10897                 if [[ "$algo" =~ ^t10 ]]; then
10898                         set_checksum_type $algo ||
10899                                 error "fail to set checksum type $algo"
10900                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10901                                 error "fail to read $tfile with $algo"
10902                 fi
10903         done
10904         rm -f $DIR/$tfile
10905         return 0
10906 }
10907 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10908
10909 test_77o() {
10910         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10911                 skip "Need MDS version at least 2.14.55"
10912         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10913                 skip "Need OST version at least 2.14.55"
10914         local ofd=obdfilter
10915         local mdt=mdt
10916
10917         # print OST checksum_type
10918         echo "$ofd.$FSNAME-*.checksum_type:"
10919         do_nodes $(comma_list $(osts_nodes)) \
10920                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10921
10922         # print MDT checksum_type
10923         echo "$mdt.$FSNAME-*.checksum_type:"
10924         do_nodes $(comma_list $(mdts_nodes)) \
10925                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10926
10927         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10928                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10929
10930         (( $o_count == $OSTCOUNT )) ||
10931                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10932
10933         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10934                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10935
10936         (( $m_count == $MDSCOUNT )) ||
10937                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10938 }
10939 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10940
10941 cleanup_test_78() {
10942         trap 0
10943         rm -f $DIR/$tfile
10944 }
10945
10946 test_78() { # bug 10901
10947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10948         remote_ost || skip_env "local OST"
10949
10950         NSEQ=5
10951         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10952         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10953         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10954         echo "MemTotal: $MEMTOTAL"
10955
10956         # reserve 256MB of memory for the kernel and other running processes,
10957         # and then take 1/2 of the remaining memory for the read/write buffers.
10958         if [ $MEMTOTAL -gt 512 ] ;then
10959                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10960         else
10961                 # for those poor memory-starved high-end clusters...
10962                 MEMTOTAL=$((MEMTOTAL / 2))
10963         fi
10964         echo "Mem to use for directio: $MEMTOTAL"
10965
10966         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10967         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10968         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10969         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10970                 head -n1)
10971         echo "Smallest OST: $SMALLESTOST"
10972         [[ $SMALLESTOST -lt 10240 ]] &&
10973                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10974
10975         trap cleanup_test_78 EXIT
10976
10977         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10978                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10979
10980         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10981         echo "File size: $F78SIZE"
10982         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10983         for i in $(seq 1 $NSEQ); do
10984                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10985                 echo directIO rdwr round $i of $NSEQ
10986                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10987         done
10988
10989         cleanup_test_78
10990 }
10991 run_test 78 "handle large O_DIRECT writes correctly ============"
10992
10993 test_79() { # bug 12743
10994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10995
10996         wait_delete_completed
10997
10998         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10999         BKFREE=$(calc_osc_kbytes kbytesfree)
11000         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11001
11002         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11003         DFTOTAL=`echo $STRING | cut -d, -f1`
11004         DFUSED=`echo $STRING  | cut -d, -f2`
11005         DFAVAIL=`echo $STRING | cut -d, -f3`
11006         DFFREE=$(($DFTOTAL - $DFUSED))
11007
11008         ALLOWANCE=$((64 * $OSTCOUNT))
11009
11010         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11011            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11012                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11013         fi
11014         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11015            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11016                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11017         fi
11018         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11019            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11020                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11021         fi
11022 }
11023 run_test 79 "df report consistency check ======================="
11024
11025 test_80() { # bug 10718
11026         remote_ost_nodsh && skip "remote OST with nodsh"
11027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11028
11029         # relax strong synchronous semantics for slow backends like ZFS
11030         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11031                 local soc="obdfilter.*.sync_lock_cancel"
11032                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11033
11034                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11035                 if [ -z "$save" ]; then
11036                         soc="obdfilter.*.sync_on_lock_cancel"
11037                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11038                 fi
11039
11040                 if [ "$save" != "never" ]; then
11041                         local hosts=$(comma_list $(osts_nodes))
11042
11043                         do_nodes $hosts $LCTL set_param $soc=never
11044                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11045                 fi
11046         fi
11047
11048         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11049         sync; sleep 1; sync
11050         local before=$(date +%s)
11051         cancel_lru_locks osc
11052         local after=$(date +%s)
11053         local diff=$((after - before))
11054         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11055
11056         rm -f $DIR/$tfile
11057 }
11058 run_test 80 "Page eviction is equally fast at high offsets too"
11059
11060 test_81a() { # LU-456
11061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11062         remote_ost_nodsh && skip "remote OST with nodsh"
11063
11064         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11065         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11066         do_facet ost1 lctl set_param fail_loc=0x80000228
11067
11068         # write should trigger a retry and success
11069         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11070         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11071         RC=$?
11072         if [ $RC -ne 0 ] ; then
11073                 error "write should success, but failed for $RC"
11074         fi
11075 }
11076 run_test 81a "OST should retry write when get -ENOSPC ==============="
11077
11078 test_81b() { # LU-456
11079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11080         remote_ost_nodsh && skip "remote OST with nodsh"
11081
11082         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11083         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11084         do_facet ost1 lctl set_param fail_loc=0x228
11085
11086         # write should retry several times and return -ENOSPC finally
11087         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11088         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11089         RC=$?
11090         ENOSPC=28
11091         if [ $RC -ne $ENOSPC ] ; then
11092                 error "dd should fail for -ENOSPC, but succeed."
11093         fi
11094 }
11095 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11096
11097 test_99() {
11098         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11099
11100         test_mkdir $DIR/$tdir.cvsroot
11101         chown $RUNAS_ID $DIR/$tdir.cvsroot
11102
11103         cd $TMP
11104         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11105
11106         cd /etc/init.d
11107         # some versions of cvs import exit(1) when asked to import links or
11108         # files they can't read.  ignore those files.
11109         local toignore=$(find . -type l -printf '-I %f\n' -o \
11110                          ! -perm /4 -printf '-I %f\n')
11111         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11112                 $tdir.reposname vtag rtag
11113
11114         cd $DIR
11115         test_mkdir $DIR/$tdir.reposname
11116         chown $RUNAS_ID $DIR/$tdir.reposname
11117         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11118
11119         cd $DIR/$tdir.reposname
11120         $RUNAS touch foo99
11121         $RUNAS cvs add -m 'addmsg' foo99
11122         $RUNAS cvs update
11123         $RUNAS cvs commit -m 'nomsg' foo99
11124         rm -fr $DIR/$tdir.cvsroot
11125 }
11126 run_test 99 "cvs strange file/directory operations"
11127
11128 test_100() {
11129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11130         [[ "$NETTYPE" =~ tcp ]] ||
11131                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11132         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11133         remote_ost_nodsh && skip "remote OST with nodsh"
11134         remote_mds_nodsh && skip "remote MDS with nodsh"
11135         remote_servers || skip "useless for local single node setup"
11136
11137         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11138                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11139
11140                 rc=0
11141                 if (( ${LOCAL/*:/} >= 1024 )); then
11142                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11143                         ss -tna
11144                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11145                 fi
11146         done
11147         (( $rc == 0 )) || error "privileged port not found" )
11148 }
11149 run_test 100 "check local port using privileged port"
11150
11151 function get_named_value()
11152 {
11153     local tag=$1
11154
11155     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11156 }
11157
11158 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11159                    awk '/^max_cached_mb/ { print $2 }')
11160
11161 cleanup_101a() {
11162         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11163         trap 0
11164 }
11165
11166 test_101a() {
11167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11168
11169         local s
11170         local discard
11171         local nreads=10000
11172         local cache_limit=32
11173
11174         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11175         trap cleanup_101a EXIT
11176         $LCTL set_param -n llite.*.read_ahead_stats=0
11177         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11178
11179         #
11180         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11181         #
11182         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11183         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11184
11185         discard=0
11186         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11187                    get_named_value 'read.but.discarded'); do
11188                         discard=$(($discard + $s))
11189         done
11190         cleanup_101a
11191
11192         $LCTL get_param osc.*-osc*.rpc_stats
11193         $LCTL get_param llite.*.read_ahead_stats
11194
11195         # Discard is generally zero, but sometimes a few random reads line up
11196         # and trigger larger readahead, which is wasted & leads to discards.
11197         if [[ $(($discard)) -gt $nreads ]]; then
11198                 error "too many ($discard) discarded pages"
11199         fi
11200         rm -f $DIR/$tfile || true
11201 }
11202 run_test 101a "check read-ahead for random reads"
11203
11204 setup_test101bc() {
11205         test_mkdir $DIR/$tdir
11206         local ssize=$1
11207         local FILE_LENGTH=$2
11208         STRIPE_OFFSET=0
11209
11210         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11211
11212         local list=$(comma_list $(osts_nodes))
11213         set_osd_param $list '' read_cache_enable 0
11214         set_osd_param $list '' writethrough_cache_enable 0
11215
11216         trap cleanup_test101bc EXIT
11217         # prepare the read-ahead file
11218         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11219
11220         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11221                                 count=$FILE_SIZE_MB 2> /dev/null
11222
11223 }
11224
11225 cleanup_test101bc() {
11226         trap 0
11227         rm -rf $DIR/$tdir
11228         rm -f $DIR/$tfile
11229
11230         local list=$(comma_list $(osts_nodes))
11231         set_osd_param $list '' read_cache_enable 1
11232         set_osd_param $list '' writethrough_cache_enable 1
11233 }
11234
11235 calc_total() {
11236         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11237 }
11238
11239 ra_check_101() {
11240         local read_size=$1
11241         local stripe_size=$2
11242         local stride_length=$((stripe_size / read_size))
11243         local stride_width=$((stride_length * OSTCOUNT))
11244         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11245                                 (stride_width - stride_length) ))
11246         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11247                   get_named_value 'read.but.discarded' | calc_total)
11248
11249         if [[ $discard -gt $discard_limit ]]; then
11250                 $LCTL get_param llite.*.read_ahead_stats
11251                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11252         else
11253                 echo "Read-ahead success for size ${read_size}"
11254         fi
11255 }
11256
11257 test_101b() {
11258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11259         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11260
11261         local STRIPE_SIZE=1048576
11262         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11263
11264         if [ $SLOW == "yes" ]; then
11265                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11266         else
11267                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11268         fi
11269
11270         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11271
11272         # prepare the read-ahead file
11273         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11274         cancel_lru_locks osc
11275         for BIDX in 2 4 8 16 32 64 128 256
11276         do
11277                 local BSIZE=$((BIDX*4096))
11278                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11279                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11280                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11281                 $LCTL set_param -n llite.*.read_ahead_stats=0
11282                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11283                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11284                 cancel_lru_locks osc
11285                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11286         done
11287         cleanup_test101bc
11288         true
11289 }
11290 run_test 101b "check stride-io mode read-ahead ================="
11291
11292 test_101c() {
11293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11294
11295         local STRIPE_SIZE=1048576
11296         local FILE_LENGTH=$((STRIPE_SIZE*100))
11297         local nreads=10000
11298         local rsize=65536
11299         local osc_rpc_stats
11300
11301         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11302
11303         cancel_lru_locks osc
11304         $LCTL set_param osc.*.rpc_stats=0
11305         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11306         $LCTL get_param osc.*.rpc_stats
11307         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11308                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11309                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11310                 local size
11311
11312                 if [ $lines -le 20 ]; then
11313                         echo "continue debug"
11314                         continue
11315                 fi
11316                 for size in 1 2 4 8; do
11317                         local rpc=$(echo "$stats" |
11318                                     awk '($1 == "'$size':") {print $2; exit; }')
11319                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11320                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11321                 done
11322                 echo "$osc_rpc_stats check passed!"
11323         done
11324         cleanup_test101bc
11325         true
11326 }
11327 run_test 101c "check stripe_size aligned read-ahead"
11328
11329 test_101d() {
11330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11331
11332         local file=$DIR/$tfile
11333         local sz_MB=${FILESIZE_101d:-80}
11334         local ra_MB=${READAHEAD_MB:-40}
11335
11336         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11337         [ $free_MB -lt $sz_MB ] &&
11338                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11339
11340         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11341         $LFS setstripe -c -1 $file || error "setstripe failed"
11342
11343         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11344         echo Cancel LRU locks on lustre client to flush the client cache
11345         cancel_lru_locks osc
11346
11347         echo Disable read-ahead
11348         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11349         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11350         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11351         $LCTL get_param -n llite.*.max_read_ahead_mb
11352
11353         echo "Reading the test file $file with read-ahead disabled"
11354         local sz_KB=$((sz_MB * 1024 / 4))
11355         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11356         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11357         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11358                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11359
11360         echo "Cancel LRU locks on lustre client to flush the client cache"
11361         cancel_lru_locks osc
11362         echo Enable read-ahead with ${ra_MB}MB
11363         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11364
11365         echo "Reading the test file $file with read-ahead enabled"
11366         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11367                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11368
11369         echo "read-ahead disabled time read $raOFF"
11370         echo "read-ahead enabled time read $raON"
11371
11372         rm -f $file
11373         wait_delete_completed
11374
11375         # use awk for this check instead of bash because it handles decimals
11376         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11377                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11378 }
11379 run_test 101d "file read with and without read-ahead enabled"
11380
11381 test_101e() {
11382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11383
11384         local file=$DIR/$tfile
11385         local size_KB=500  #KB
11386         local count=100
11387         local bsize=1024
11388
11389         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11390         local need_KB=$((count * size_KB))
11391         [[ $free_KB -le $need_KB ]] &&
11392                 skip_env "Need free space $need_KB, have $free_KB"
11393
11394         echo "Creating $count ${size_KB}K test files"
11395         for ((i = 0; i < $count; i++)); do
11396                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11397         done
11398
11399         echo "Cancel LRU locks on lustre client to flush the client cache"
11400         cancel_lru_locks $OSC
11401
11402         echo "Reset readahead stats"
11403         $LCTL set_param -n llite.*.read_ahead_stats=0
11404
11405         for ((i = 0; i < $count; i++)); do
11406                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11407         done
11408
11409         $LCTL get_param llite.*.max_cached_mb
11410         $LCTL get_param llite.*.read_ahead_stats
11411         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11412                      get_named_value 'misses' | calc_total)
11413
11414         for ((i = 0; i < $count; i++)); do
11415                 rm -rf $file.$i 2>/dev/null
11416         done
11417
11418         #10000 means 20% reads are missing in readahead
11419         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11420 }
11421 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11422
11423 test_101f() {
11424         which iozone || skip_env "no iozone installed"
11425
11426         local old_debug=$($LCTL get_param debug)
11427         old_debug=${old_debug#*=}
11428         $LCTL set_param debug="reada mmap"
11429
11430         # create a test file
11431         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11432
11433         echo Cancel LRU locks on lustre client to flush the client cache
11434         cancel_lru_locks osc
11435
11436         echo Reset readahead stats
11437         $LCTL set_param -n llite.*.read_ahead_stats=0
11438
11439         echo mmap read the file with small block size
11440         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11441                 > /dev/null 2>&1
11442
11443         echo checking missing pages
11444         $LCTL get_param llite.*.read_ahead_stats
11445         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11446                         get_named_value 'misses' | calc_total)
11447
11448         $LCTL set_param debug="$old_debug"
11449         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11450         rm -f $DIR/$tfile
11451 }
11452 run_test 101f "check mmap read performance"
11453
11454 test_101g_brw_size_test() {
11455         local mb=$1
11456         local pages=$((mb * 1048576 / PAGE_SIZE))
11457         local file=$DIR/$tfile
11458
11459         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11460                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11461         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11462                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11463                         return 2
11464         done
11465
11466         stack_trap "rm -f $file" EXIT
11467         $LCTL set_param -n osc.*.rpc_stats=0
11468
11469         # 10 RPCs should be enough for the test
11470         local count=10
11471         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11472                 { error "dd write ${mb} MB blocks failed"; return 3; }
11473         cancel_lru_locks osc
11474         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11475                 { error "dd write ${mb} MB blocks failed"; return 4; }
11476
11477         # calculate number of full-sized read and write RPCs
11478         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11479                 sed -n '/pages per rpc/,/^$/p' |
11480                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11481                 END { print reads,writes }'))
11482         # allow one extra full-sized read RPC for async readahead
11483         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11484                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11485         [[ ${rpcs[1]} == $count ]] ||
11486                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11487 }
11488
11489 test_101g() {
11490         remote_ost_nodsh && skip "remote OST with nodsh"
11491
11492         local rpcs
11493         local osts=$(get_facets OST)
11494         local list=$(comma_list $(osts_nodes))
11495         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11496         local brw_size="obdfilter.*.brw_size"
11497
11498         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11499
11500         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11501
11502         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11503                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11504                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11505            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11506                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11507                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11508
11509                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11510                         suffix="M"
11511
11512                 if [[ $orig_mb -lt 16 ]]; then
11513                         save_lustre_params $osts "$brw_size" > $p
11514                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11515                                 error "set 16MB RPC size failed"
11516
11517                         echo "remount client to enable new RPC size"
11518                         remount_client $MOUNT || error "remount_client failed"
11519                 fi
11520
11521                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11522                 # should be able to set brw_size=12, but no rpc_stats for that
11523                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11524         fi
11525
11526         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11527
11528         if [[ $orig_mb -lt 16 ]]; then
11529                 restore_lustre_params < $p
11530                 remount_client $MOUNT || error "remount_client restore failed"
11531         fi
11532
11533         rm -f $p $DIR/$tfile
11534 }
11535 run_test 101g "Big bulk(4/16 MiB) readahead"
11536
11537 test_101h() {
11538         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11539
11540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11541                 error "dd 70M file failed"
11542         echo Cancel LRU locks on lustre client to flush the client cache
11543         cancel_lru_locks osc
11544
11545         echo "Reset readahead stats"
11546         $LCTL set_param -n llite.*.read_ahead_stats 0
11547
11548         echo "Read 10M of data but cross 64M bundary"
11549         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11550         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11551                      get_named_value 'misses' | calc_total)
11552         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11553         rm -f $p $DIR/$tfile
11554 }
11555 run_test 101h "Readahead should cover current read window"
11556
11557 test_101i() {
11558         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11559                 error "dd 10M file failed"
11560
11561         local max_per_file_mb=$($LCTL get_param -n \
11562                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11563         cancel_lru_locks osc
11564         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11565         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11566                 error "set max_read_ahead_per_file_mb to 1 failed"
11567
11568         echo "Reset readahead stats"
11569         $LCTL set_param llite.*.read_ahead_stats=0
11570
11571         dd if=$DIR/$tfile of=/dev/null bs=2M
11572
11573         $LCTL get_param llite.*.read_ahead_stats
11574         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11575                      awk '/misses/ { print $2 }')
11576         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11577         rm -f $DIR/$tfile
11578 }
11579 run_test 101i "allow current readahead to exceed reservation"
11580
11581 test_101j() {
11582         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11583                 error "setstripe $DIR/$tfile failed"
11584         local file_size=$((1048576 * 16))
11585         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11586         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11587
11588         echo Disable read-ahead
11589         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11590
11591         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11592         for blk in $PAGE_SIZE 1048576 $file_size; do
11593                 cancel_lru_locks osc
11594                 echo "Reset readahead stats"
11595                 $LCTL set_param -n llite.*.read_ahead_stats=0
11596                 local count=$(($file_size / $blk))
11597                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11598                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11599                              get_named_value 'failed.to.fast.read' | calc_total)
11600                 $LCTL get_param -n llite.*.read_ahead_stats
11601                 [ $miss -eq $count ] || error "expected $count got $miss"
11602         done
11603
11604         rm -f $p $DIR/$tfile
11605 }
11606 run_test 101j "A complete read block should be submitted when no RA"
11607
11608 test_readahead_base() {
11609         local file=$DIR/$tfile
11610         local size=$1
11611         local iosz
11612         local ramax
11613         local ranum
11614
11615         $LCTL set_param -n llite.*.read_ahead_stats=0
11616         # The first page is not accounted into readahead
11617         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11618         iosz=$(((size + 1048575) / 1048576 * 1048576))
11619         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11620
11621         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11622         fallocate -l $size $file || error "failed to fallocate $file"
11623         cancel_lru_locks osc
11624         $MULTIOP $file or${iosz}c || error "failed to read $file"
11625         $LCTL get_param -n llite.*.read_ahead_stats
11626         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11627                 awk '/readahead.pages/ { print $7 }' | calc_total)
11628         (( $ranum <= $ramax )) ||
11629                 error "read-ahead pages is $ranum more than $ramax"
11630         rm -rf $file || error "failed to remove $file"
11631 }
11632
11633 test_101m()
11634 {
11635         local file=$DIR/$tfile
11636         local ramax
11637         local ranum
11638         local size
11639         local iosz
11640
11641         check_set_fallocate_or_skip
11642         stack_trap "rm -f $file" EXIT
11643
11644         test_readahead_base 4096
11645
11646         # file size: 16K = 16384
11647         test_readahead_base 16384
11648         test_readahead_base 16385
11649         test_readahead_base 16383
11650
11651         # file size: 1M + 1 = 1048576 + 1
11652         test_readahead_base 1048577
11653         # file size: 1M + 16K
11654         test_readahead_base $((1048576 + 16384))
11655
11656         # file size: stripe_size * (stripe_count - 1) + 16K
11657         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11658         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11659         # file size: stripe_size * stripe_count + 16K
11660         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11661         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11662         # file size: 2 * stripe_size * stripe_count + 16K
11663         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11664         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11665 }
11666 run_test 101m "read ahead for small file and last stripe of the file"
11667
11668 setup_test102() {
11669         test_mkdir $DIR/$tdir
11670         chown $RUNAS_ID $DIR/$tdir
11671         STRIPE_SIZE=65536
11672         STRIPE_OFFSET=1
11673         STRIPE_COUNT=$OSTCOUNT
11674         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11675
11676         trap cleanup_test102 EXIT
11677         cd $DIR
11678         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11679         cd $DIR/$tdir
11680         for num in 1 2 3 4; do
11681                 for count in $(seq 1 $STRIPE_COUNT); do
11682                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11683                                 local size=`expr $STRIPE_SIZE \* $num`
11684                                 local file=file"$num-$idx-$count"
11685                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11686                         done
11687                 done
11688         done
11689
11690         cd $DIR
11691         $1 tar cf $TMP/f102.tar $tdir --xattrs
11692 }
11693
11694 cleanup_test102() {
11695         trap 0
11696         rm -f $TMP/f102.tar
11697         rm -rf $DIR/d0.sanity/d102
11698 }
11699
11700 test_102a() {
11701         [ "$UID" != 0 ] && skip "must run as root"
11702         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11703                 skip_env "must have user_xattr"
11704
11705         [ -z "$(which setfattr 2>/dev/null)" ] &&
11706                 skip_env "could not find setfattr"
11707
11708         local testfile=$DIR/$tfile
11709
11710         touch $testfile
11711         echo "set/get xattr..."
11712         setfattr -n trusted.name1 -v value1 $testfile ||
11713                 error "setfattr -n trusted.name1=value1 $testfile failed"
11714         getfattr -n trusted.name1 $testfile 2> /dev/null |
11715           grep "trusted.name1=.value1" ||
11716                 error "$testfile missing trusted.name1=value1"
11717
11718         setfattr -n user.author1 -v author1 $testfile ||
11719                 error "setfattr -n user.author1=author1 $testfile failed"
11720         getfattr -n user.author1 $testfile 2> /dev/null |
11721           grep "user.author1=.author1" ||
11722                 error "$testfile missing trusted.author1=author1"
11723
11724         echo "listxattr..."
11725         setfattr -n trusted.name2 -v value2 $testfile ||
11726                 error "$testfile unable to set trusted.name2"
11727         setfattr -n trusted.name3 -v value3 $testfile ||
11728                 error "$testfile unable to set trusted.name3"
11729         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11730             grep "trusted.name" | wc -l) -eq 3 ] ||
11731                 error "$testfile missing 3 trusted.name xattrs"
11732
11733         setfattr -n user.author2 -v author2 $testfile ||
11734                 error "$testfile unable to set user.author2"
11735         setfattr -n user.author3 -v author3 $testfile ||
11736                 error "$testfile unable to set user.author3"
11737         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11738             grep "user.author" | wc -l) -eq 3 ] ||
11739                 error "$testfile missing 3 user.author xattrs"
11740
11741         echo "remove xattr..."
11742         setfattr -x trusted.name1 $testfile ||
11743                 error "$testfile error deleting trusted.name1"
11744         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11745                 error "$testfile did not delete trusted.name1 xattr"
11746
11747         setfattr -x user.author1 $testfile ||
11748                 error "$testfile error deleting user.author1"
11749         echo "set lustre special xattr ..."
11750         $LFS setstripe -c1 $testfile
11751         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11752                 awk -F "=" '/trusted.lov/ { print $2 }' )
11753         setfattr -n "trusted.lov" -v $lovea $testfile ||
11754                 error "$testfile doesn't ignore setting trusted.lov again"
11755         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11756                 error "$testfile allow setting invalid trusted.lov"
11757         rm -f $testfile
11758 }
11759 run_test 102a "user xattr test =================================="
11760
11761 check_102b_layout() {
11762         local layout="$*"
11763         local testfile=$DIR/$tfile
11764
11765         echo "test layout '$layout'"
11766         $LFS setstripe $layout $testfile || error "setstripe failed"
11767         $LFS getstripe -y $testfile
11768
11769         echo "get/set/list trusted.lov xattr ..." # b=10930
11770         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11771         [[ "$value" =~ "trusted.lov" ]] ||
11772                 error "can't get trusted.lov from $testfile"
11773         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11774                 error "getstripe failed"
11775
11776         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11777
11778         value=$(cut -d= -f2 <<<$value)
11779         # LU-13168: truncated xattr should fail if short lov_user_md header
11780         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11781                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11782         for len in $lens; do
11783                 echo "setfattr $len $testfile.2"
11784                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11785                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11786         done
11787         local stripe_size=$($LFS getstripe -S $testfile.2)
11788         local stripe_count=$($LFS getstripe -c $testfile.2)
11789         [[ $stripe_size -eq 65536 ]] ||
11790                 error "stripe size $stripe_size != 65536"
11791         [[ $stripe_count -eq $stripe_count_orig ]] ||
11792                 error "stripe count $stripe_count != $stripe_count_orig"
11793         rm $testfile $testfile.2
11794 }
11795
11796 test_102b() {
11797         [ -z "$(which setfattr 2>/dev/null)" ] &&
11798                 skip_env "could not find setfattr"
11799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11800
11801         # check plain layout
11802         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11803
11804         # and also check composite layout
11805         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11806
11807 }
11808 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11809
11810 test_102c() {
11811         [ -z "$(which setfattr 2>/dev/null)" ] &&
11812                 skip_env "could not find setfattr"
11813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11814
11815         # b10930: get/set/list lustre.lov xattr
11816         echo "get/set/list lustre.lov xattr ..."
11817         test_mkdir $DIR/$tdir
11818         chown $RUNAS_ID $DIR/$tdir
11819         local testfile=$DIR/$tdir/$tfile
11820         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11821                 error "setstripe failed"
11822         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11823                 error "getstripe failed"
11824         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11825         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11826
11827         local testfile2=${testfile}2
11828         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11829                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11830
11831         $RUNAS $MCREATE $testfile2
11832         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11833         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11834         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11835         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11836         [ $stripe_count -eq $STRIPECOUNT ] ||
11837                 error "stripe count $stripe_count != $STRIPECOUNT"
11838 }
11839 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11840
11841 compare_stripe_info1() {
11842         local stripe_index_all_zero=true
11843
11844         for num in 1 2 3 4; do
11845                 for count in $(seq 1 $STRIPE_COUNT); do
11846                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11847                                 local size=$((STRIPE_SIZE * num))
11848                                 local file=file"$num-$offset-$count"
11849                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11850                                 [[ $stripe_size -ne $size ]] &&
11851                                     error "$file: size $stripe_size != $size"
11852                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11853                                 # allow fewer stripes to be created, ORI-601
11854                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11855                                     error "$file: count $stripe_count != $count"
11856                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11857                                 [[ $stripe_index -ne 0 ]] &&
11858                                         stripe_index_all_zero=false
11859                         done
11860                 done
11861         done
11862         $stripe_index_all_zero &&
11863                 error "all files are being extracted starting from OST index 0"
11864         return 0
11865 }
11866
11867 have_xattrs_include() {
11868         tar --help | grep -q xattrs-include &&
11869                 echo --xattrs-include="lustre.*"
11870 }
11871
11872 test_102d() {
11873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11874         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11875
11876         XINC=$(have_xattrs_include)
11877         setup_test102
11878         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11879         cd $DIR/$tdir/$tdir
11880         compare_stripe_info1
11881 }
11882 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11883
11884 test_102f() {
11885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11886         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11887
11888         XINC=$(have_xattrs_include)
11889         setup_test102
11890         test_mkdir $DIR/$tdir.restore
11891         cd $DIR
11892         tar cf - --xattrs $tdir | tar xf - \
11893                 -C $DIR/$tdir.restore --xattrs $XINC
11894         cd $DIR/$tdir.restore/$tdir
11895         compare_stripe_info1
11896 }
11897 run_test 102f "tar copy files, not keep osts"
11898
11899 grow_xattr() {
11900         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11901                 skip "must have user_xattr"
11902         [ -z "$(which setfattr 2>/dev/null)" ] &&
11903                 skip_env "could not find setfattr"
11904         [ -z "$(which getfattr 2>/dev/null)" ] &&
11905                 skip_env "could not find getfattr"
11906
11907         local xsize=${1:-1024}  # in bytes
11908         local file=$DIR/$tfile
11909         local value="$(generate_string $xsize)"
11910         local xbig=trusted.big
11911         local toobig=$2
11912
11913         touch $file
11914         log "save $xbig on $file"
11915         if [ -z "$toobig" ]
11916         then
11917                 setfattr -n $xbig -v $value $file ||
11918                         error "saving $xbig on $file failed"
11919         else
11920                 setfattr -n $xbig -v $value $file &&
11921                         error "saving $xbig on $file succeeded"
11922                 return 0
11923         fi
11924
11925         local orig=$(get_xattr_value $xbig $file)
11926         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11927
11928         local xsml=trusted.sml
11929         log "save $xsml on $file"
11930         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11931
11932         local new=$(get_xattr_value $xbig $file)
11933         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11934
11935         log "grow $xsml on $file"
11936         setfattr -n $xsml -v "$value" $file ||
11937                 error "growing $xsml on $file failed"
11938
11939         new=$(get_xattr_value $xbig $file)
11940         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11941         log "$xbig still valid after growing $xsml"
11942
11943         rm -f $file
11944 }
11945
11946 test_102h() { # bug 15777
11947         grow_xattr 1024
11948 }
11949 run_test 102h "grow xattr from inside inode to external block"
11950
11951 test_102ha() {
11952         large_xattr_enabled || skip_env "ea_inode feature disabled"
11953
11954         echo "setting xattr of max xattr size: $(max_xattr_size)"
11955         grow_xattr $(max_xattr_size)
11956
11957         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11958         echo "This should fail:"
11959         grow_xattr $(($(max_xattr_size) + 10)) 1
11960 }
11961 run_test 102ha "grow xattr from inside inode to external inode"
11962
11963 test_102i() { # bug 17038
11964         [ -z "$(which getfattr 2>/dev/null)" ] &&
11965                 skip "could not find getfattr"
11966
11967         touch $DIR/$tfile
11968         ln -s $DIR/$tfile $DIR/${tfile}link
11969         getfattr -n trusted.lov $DIR/$tfile ||
11970                 error "lgetxattr on $DIR/$tfile failed"
11971         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11972                 grep -i "no such attr" ||
11973                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11974         rm -f $DIR/$tfile $DIR/${tfile}link
11975 }
11976 run_test 102i "lgetxattr test on symbolic link ============"
11977
11978 test_102j() {
11979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11980         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11981
11982         XINC=$(have_xattrs_include)
11983         setup_test102 "$RUNAS"
11984         chown $RUNAS_ID $DIR/$tdir
11985         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11986         cd $DIR/$tdir/$tdir
11987         compare_stripe_info1 "$RUNAS"
11988 }
11989 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11990
11991 test_102k() {
11992         [ -z "$(which setfattr 2>/dev/null)" ] &&
11993                 skip "could not find setfattr"
11994
11995         touch $DIR/$tfile
11996         # b22187 just check that does not crash for regular file.
11997         setfattr -n trusted.lov $DIR/$tfile
11998         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11999         local test_kdir=$DIR/$tdir
12000         test_mkdir $test_kdir
12001         local default_size=$($LFS getstripe -S $test_kdir)
12002         local default_count=$($LFS getstripe -c $test_kdir)
12003         local default_offset=$($LFS getstripe -i $test_kdir)
12004         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12005                 error 'dir setstripe failed'
12006         setfattr -n trusted.lov $test_kdir
12007         local stripe_size=$($LFS getstripe -S $test_kdir)
12008         local stripe_count=$($LFS getstripe -c $test_kdir)
12009         local stripe_offset=$($LFS getstripe -i $test_kdir)
12010         [ $stripe_size -eq $default_size ] ||
12011                 error "stripe size $stripe_size != $default_size"
12012         [ $stripe_count -eq $default_count ] ||
12013                 error "stripe count $stripe_count != $default_count"
12014         [ $stripe_offset -eq $default_offset ] ||
12015                 error "stripe offset $stripe_offset != $default_offset"
12016         rm -rf $DIR/$tfile $test_kdir
12017 }
12018 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12019
12020 test_102l() {
12021         [ -z "$(which getfattr 2>/dev/null)" ] &&
12022                 skip "could not find getfattr"
12023
12024         # LU-532 trusted. xattr is invisible to non-root
12025         local testfile=$DIR/$tfile
12026
12027         touch $testfile
12028
12029         echo "listxattr as user..."
12030         chown $RUNAS_ID $testfile
12031         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12032             grep -q "trusted" &&
12033                 error "$testfile trusted xattrs are user visible"
12034
12035         return 0;
12036 }
12037 run_test 102l "listxattr size test =================================="
12038
12039 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12040         local path=$DIR/$tfile
12041         touch $path
12042
12043         listxattr_size_check $path || error "listattr_size_check $path failed"
12044 }
12045 run_test 102m "Ensure listxattr fails on small bufffer ========"
12046
12047 cleanup_test102
12048
12049 getxattr() { # getxattr path name
12050         # Return the base64 encoding of the value of xattr name on path.
12051         local path=$1
12052         local name=$2
12053
12054         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12055         # file: $path
12056         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12057         #
12058         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12059
12060         getfattr --absolute-names --encoding=base64 --name=$name $path |
12061                 awk -F= -v name=$name '$1 == name {
12062                         print substr($0, index($0, "=") + 1);
12063         }'
12064 }
12065
12066 test_102n() { # LU-4101 mdt: protect internal xattrs
12067         [ -z "$(which setfattr 2>/dev/null)" ] &&
12068                 skip "could not find setfattr"
12069         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12070         then
12071                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12072         fi
12073
12074         local file0=$DIR/$tfile.0
12075         local file1=$DIR/$tfile.1
12076         local xattr0=$TMP/$tfile.0
12077         local xattr1=$TMP/$tfile.1
12078         local namelist="lov lma lmv link fid version som hsm"
12079         local name
12080         local value
12081
12082         rm -rf $file0 $file1 $xattr0 $xattr1
12083         touch $file0 $file1
12084
12085         # Get 'before' xattrs of $file1.
12086         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12087
12088         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12089                 namelist+=" lfsck_namespace"
12090         for name in $namelist; do
12091                 # Try to copy xattr from $file0 to $file1.
12092                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12093
12094                 setfattr --name=trusted.$name --value="$value" $file1 ||
12095                         error "setxattr 'trusted.$name' failed"
12096
12097                 # Try to set a garbage xattr.
12098                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12099
12100                 if [[ x$name == "xlov" ]]; then
12101                         setfattr --name=trusted.lov --value="$value" $file1 &&
12102                         error "setxattr invalid 'trusted.lov' success"
12103                 else
12104                         setfattr --name=trusted.$name --value="$value" $file1 ||
12105                                 error "setxattr invalid 'trusted.$name' failed"
12106                 fi
12107
12108                 # Try to remove the xattr from $file1. We don't care if this
12109                 # appears to succeed or fail, we just don't want there to be
12110                 # any changes or crashes.
12111                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12112         done
12113
12114         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12115         then
12116                 name="lfsck_ns"
12117                 # Try to copy xattr from $file0 to $file1.
12118                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12119
12120                 setfattr --name=trusted.$name --value="$value" $file1 ||
12121                         error "setxattr 'trusted.$name' failed"
12122
12123                 # Try to set a garbage xattr.
12124                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12125
12126                 setfattr --name=trusted.$name --value="$value" $file1 ||
12127                         error "setxattr 'trusted.$name' failed"
12128
12129                 # Try to remove the xattr from $file1. We don't care if this
12130                 # appears to succeed or fail, we just don't want there to be
12131                 # any changes or crashes.
12132                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12133         fi
12134
12135         # Get 'after' xattrs of file1.
12136         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12137
12138         if ! diff $xattr0 $xattr1; then
12139                 error "before and after xattrs of '$file1' differ"
12140         fi
12141
12142         rm -rf $file0 $file1 $xattr0 $xattr1
12143
12144         return 0
12145 }
12146 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12147
12148 test_102p() { # LU-4703 setxattr did not check ownership
12149         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12150                 skip "MDS needs to be at least 2.5.56"
12151
12152         local testfile=$DIR/$tfile
12153
12154         touch $testfile
12155
12156         echo "setfacl as user..."
12157         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12158         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12159
12160         echo "setfattr as user..."
12161         setfacl -m "u:$RUNAS_ID:---" $testfile
12162         $RUNAS setfattr -x system.posix_acl_access $testfile
12163         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12164 }
12165 run_test 102p "check setxattr(2) correctly fails without permission"
12166
12167 test_102q() {
12168         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12169                 skip "MDS needs to be at least 2.6.92"
12170
12171         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12172 }
12173 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12174
12175 test_102r() {
12176         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12177                 skip "MDS needs to be at least 2.6.93"
12178
12179         touch $DIR/$tfile || error "touch"
12180         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12181         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12182         rm $DIR/$tfile || error "rm"
12183
12184         #normal directory
12185         mkdir -p $DIR/$tdir || error "mkdir"
12186         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12187         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12188         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12189                 error "$testfile error deleting user.author1"
12190         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12191                 grep "user.$(basename $tdir)" &&
12192                 error "$tdir did not delete user.$(basename $tdir)"
12193         rmdir $DIR/$tdir || error "rmdir"
12194
12195         #striped directory
12196         test_mkdir $DIR/$tdir
12197         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12198         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12199         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12200                 error "$testfile error deleting user.author1"
12201         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12202                 grep "user.$(basename $tdir)" &&
12203                 error "$tdir did not delete user.$(basename $tdir)"
12204         rmdir $DIR/$tdir || error "rm striped dir"
12205 }
12206 run_test 102r "set EAs with empty values"
12207
12208 test_102s() {
12209         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12210                 skip "MDS needs to be at least 2.11.52"
12211
12212         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12213
12214         save_lustre_params client "llite.*.xattr_cache" > $save
12215
12216         for cache in 0 1; do
12217                 lctl set_param llite.*.xattr_cache=$cache
12218
12219                 rm -f $DIR/$tfile
12220                 touch $DIR/$tfile || error "touch"
12221                 for prefix in lustre security system trusted user; do
12222                         # Note getxattr() may fail with 'Operation not
12223                         # supported' or 'No such attribute' depending
12224                         # on prefix and cache.
12225                         getfattr -n $prefix.n102s $DIR/$tfile &&
12226                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12227                 done
12228         done
12229
12230         restore_lustre_params < $save
12231 }
12232 run_test 102s "getting nonexistent xattrs should fail"
12233
12234 test_102t() {
12235         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12236                 skip "MDS needs to be at least 2.11.52"
12237
12238         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12239
12240         save_lustre_params client "llite.*.xattr_cache" > $save
12241
12242         for cache in 0 1; do
12243                 lctl set_param llite.*.xattr_cache=$cache
12244
12245                 for buf_size in 0 256; do
12246                         rm -f $DIR/$tfile
12247                         touch $DIR/$tfile || error "touch"
12248                         setfattr -n user.multiop $DIR/$tfile
12249                         $MULTIOP $DIR/$tfile oa$buf_size ||
12250                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12251                 done
12252         done
12253
12254         restore_lustre_params < $save
12255 }
12256 run_test 102t "zero length xattr values handled correctly"
12257
12258 run_acl_subtest()
12259 {
12260         local test=$LUSTRE/tests/acl/$1.test
12261         local tmp=$(mktemp -t $1-XXXXXX).test
12262         local bin=$2
12263         local dmn=$3
12264         local grp=$4
12265         local nbd=$5
12266         export LANG=C
12267
12268
12269         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12270         local sedgroups="-e s/:users/:$grp/g"
12271         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12272
12273         sed $sedusers $sedgroups < $test > $tmp
12274         stack_trap "rm -f $tmp"
12275         [[ -s $tmp ]] || error "sed failed to create test script"
12276
12277         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12278         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12279 }
12280
12281 test_103a() {
12282         [ "$UID" != 0 ] && skip "must run as root"
12283         $GSS && skip_env "could not run under gss"
12284         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12285                 skip_env "must have acl enabled"
12286         which setfacl || skip_env "could not find setfacl"
12287         remote_mds_nodsh && skip "remote MDS with nodsh"
12288
12289         local mdts=$(comma_list $(mdts_nodes))
12290         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12291
12292         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12293         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12294
12295         ACLBIN=${ACLBIN:-"bin"}
12296         ACLDMN=${ACLDMN:-"daemon"}
12297         ACLGRP=${ACLGRP:-"users"}
12298         ACLNBD=${ACLNBD:-"nobody"}
12299
12300         if ! id $ACLBIN ||
12301            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12302                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12303                 ACLBIN=$USER0
12304                 if ! id $ACLBIN ; then
12305                         cat /etc/passwd
12306                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12307                 fi
12308         fi
12309         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12310            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12311                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12312                 ACLDMN=$USER1
12313                 if ! id $ACLDMN ; then
12314                         cat /etc/passwd
12315                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12316                 fi
12317         fi
12318         if ! getent group $ACLGRP; then
12319                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12320                 ACLGRP="$TSTUSR"
12321                 if ! getent group $ACLGRP; then
12322                         echo "cannot find group '$ACLGRP', adding it"
12323                         cat /etc/group
12324                         add_group 60000 $ACLGRP
12325                 fi
12326         fi
12327
12328         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12329         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12330         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12331
12332         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12333                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12334                 ACLGRP="$TSTUSR"
12335                 if ! getent group $ACLGRP; then
12336                         echo "cannot find group '$ACLGRP', adding it"
12337                         cat /etc/group
12338                         add_group 60000 $ACLGRP
12339                 fi
12340                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12341                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12342                         cat /etc/group
12343                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12344                 fi
12345         fi
12346
12347         gpasswd -a $ACLDMN $ACLBIN ||
12348                 error "setting client group failed"             # LU-5641
12349         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12350                 error "setting MDS group failed"                # LU-5641
12351
12352         declare -a identity_old
12353
12354         for num in $(seq $MDSCOUNT); do
12355                 switch_identity $num true || identity_old[$num]=$?
12356         done
12357
12358         SAVE_UMASK=$(umask)
12359         umask 0022
12360         mkdir -p $DIR/$tdir
12361         cd $DIR/$tdir
12362
12363         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12364         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12365         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12366         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12367         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12368         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12369         if ! id -u $ACLNBD ||
12370            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12371                 ACLNBD="nfsnobody"
12372                 if ! id -u $ACLNBD; then
12373                         ACLNBD=""
12374                 fi
12375         fi
12376         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12377                 add_group $(id -u $ACLNBD) $ACLNBD
12378                 if ! getent group $ACLNBD; then
12379                         ACLNBD=""
12380                 fi
12381         fi
12382         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12383            [[ -n "$ACLNBD" ]] && which setfattr; then
12384                 run_acl_subtest permissions_xattr \
12385                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12386         elif [[ -z "$ACLNBD" ]]; then
12387                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12388         else
12389                 echo "skip 'permission_xattr' test - missing setfattr command"
12390         fi
12391         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12392
12393         # inheritance test got from HP
12394         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12395         chmod +x make-tree || error "chmod +x failed"
12396         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12397         rm -f make-tree
12398
12399         echo "LU-974 ignore umask when acl is enabled..."
12400         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12401         if [ $MDSCOUNT -ge 2 ]; then
12402                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12403         fi
12404
12405         echo "LU-2561 newly created file is same size as directory..."
12406         if [ "$mds1_FSTYPE" != "zfs" ]; then
12407                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12408         else
12409                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12410         fi
12411
12412         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12413
12414         cd $SAVE_PWD
12415         umask $SAVE_UMASK
12416
12417         for num in $(seq $MDSCOUNT); do
12418                 if [ "${identity_old[$num]}" = 1 ]; then
12419                         switch_identity $num false || identity_old[$num]=$?
12420                 fi
12421         done
12422 }
12423 run_test 103a "acl test"
12424
12425 test_103b() {
12426         declare -a pids
12427         local U
12428
12429         stack_trap "rm -f $DIR/$tfile.*"
12430         for U in {0..511}; do
12431                 {
12432                 local O=$(printf "%04o" $U)
12433
12434                 umask $(printf "%04o" $((511 ^ $O)))
12435                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12436                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12437
12438                 (( $S == ($O & 0666) )) ||
12439                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12440
12441                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12442                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12443                 (( $S == ($O & 0666) )) ||
12444                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12445
12446                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12447                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12448                 (( $S == ($O & 0666) )) ||
12449                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12450                 rm -f $DIR/$tfile.[smp]$0
12451                 } &
12452                 local pid=$!
12453
12454                 # limit the concurrently running threads to 64. LU-11878
12455                 local idx=$((U % 64))
12456                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12457                 pids[idx]=$pid
12458         done
12459         wait
12460 }
12461 run_test 103b "umask lfs setstripe"
12462
12463 test_103c() {
12464         mkdir -p $DIR/$tdir
12465         cp -rp $DIR/$tdir $DIR/$tdir.bak
12466
12467         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12468                 error "$DIR/$tdir shouldn't contain default ACL"
12469         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12470                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12471         true
12472 }
12473 run_test 103c "'cp -rp' won't set empty acl"
12474
12475 test_103e() {
12476         local numacl
12477         local fileacl
12478         local saved_debug=$($LCTL get_param -n debug)
12479
12480         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12481                 skip "MDS needs to be at least 2.14.52"
12482
12483         large_xattr_enabled || skip_env "ea_inode feature disabled"
12484
12485         mkdir -p $DIR/$tdir
12486         # add big LOV EA to cause reply buffer overflow earlier
12487         $LFS setstripe -C 1000 $DIR/$tdir
12488         lctl set_param mdc.*-mdc*.stats=clear
12489
12490         $LCTL set_param debug=0
12491         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12492         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12493
12494         # add a large number of default ACLs (expect 8000+ for 2.13+)
12495         for U in {2..7000}; do
12496                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12497                         error "Able to add just $U default ACLs"
12498         done
12499         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12500         echo "$numacl default ACLs created"
12501
12502         stat $DIR/$tdir || error "Cannot stat directory"
12503         # check file creation
12504         touch $DIR/$tdir/$tfile ||
12505                 error "failed to create $tfile with $numacl default ACLs"
12506         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12507         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12508         echo "$fileacl ACLs were inherited"
12509         (( $fileacl == $numacl )) ||
12510                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12511         # check that new ACLs creation adds new ACLs to inherited ACLs
12512         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12513                 error "Cannot set new ACL"
12514         numacl=$((numacl + 1))
12515         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12516         (( $fileacl == $numacl )) ||
12517                 error "failed to add new ACL: $fileacl != $numacl as expected"
12518         # adds more ACLs to a file to reach their maximum at 8000+
12519         numacl=0
12520         for U in {20000..25000}; do
12521                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12522                 numacl=$((numacl + 1))
12523         done
12524         echo "Added $numacl more ACLs to the file"
12525         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12526         echo "Total $fileacl ACLs in file"
12527         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12528         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12529         rmdir $DIR/$tdir || error "Cannot remove directory"
12530 }
12531 run_test 103e "inheritance of big amount of default ACLs"
12532
12533 test_103f() {
12534         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12535                 skip "MDS needs to be at least 2.14.51"
12536
12537         large_xattr_enabled || skip_env "ea_inode feature disabled"
12538
12539         # enable changelog to consume more internal MDD buffers
12540         changelog_register
12541
12542         mkdir -p $DIR/$tdir
12543         # add big LOV EA
12544         $LFS setstripe -C 1000 $DIR/$tdir
12545         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12546         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12547         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12548         rmdir $DIR/$tdir || error "Cannot remove directory"
12549 }
12550 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12551
12552 test_104a() {
12553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12554
12555         touch $DIR/$tfile
12556         lfs df || error "lfs df failed"
12557         lfs df -ih || error "lfs df -ih failed"
12558         lfs df -h $DIR || error "lfs df -h $DIR failed"
12559         lfs df -i $DIR || error "lfs df -i $DIR failed"
12560         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12561         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12562
12563         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12564         lctl --device %$OSC deactivate
12565         lfs df || error "lfs df with deactivated OSC failed"
12566         lctl --device %$OSC activate
12567         # wait the osc back to normal
12568         wait_osc_import_ready client ost
12569
12570         lfs df || error "lfs df with reactivated OSC failed"
12571         rm -f $DIR/$tfile
12572 }
12573 run_test 104a "lfs df [-ih] [path] test ========================="
12574
12575 test_104b() {
12576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12577         [ $RUNAS_ID -eq $UID ] &&
12578                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12579
12580         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12581                         grep "Permission denied" | wc -l)))
12582         if [ $denied_cnt -ne 0 ]; then
12583                 error "lfs check servers test failed"
12584         fi
12585 }
12586 run_test 104b "$RUNAS lfs check servers test ===================="
12587
12588 #
12589 # Verify $1 is within range of $2.
12590 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12591 # $1 is <= 2% of $2. Else Fail.
12592 #
12593 value_in_range() {
12594         # Strip all units (M, G, T)
12595         actual=$(echo $1 | tr -d A-Z)
12596         expect=$(echo $2 | tr -d A-Z)
12597
12598         expect_lo=$(($expect * 98 / 100)) # 2% below
12599         expect_hi=$(($expect * 102 / 100)) # 2% above
12600
12601         # permit 2% drift above and below
12602         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12603 }
12604
12605 test_104c() {
12606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12607         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12608
12609         local ost_param="osd-zfs.$FSNAME-OST0000."
12610         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12611         local ofacets=$(get_facets OST)
12612         local mfacets=$(get_facets MDS)
12613         local saved_ost_blocks=
12614         local saved_mdt_blocks=
12615
12616         echo "Before recordsize change"
12617         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12618         df=($(df -h | grep "$MOUNT"$))
12619
12620         # For checking.
12621         echo "lfs output : ${lfs_df[*]}"
12622         echo "df  output : ${df[*]}"
12623
12624         for facet in ${ofacets//,/ }; do
12625                 if [ -z $saved_ost_blocks ]; then
12626                         saved_ost_blocks=$(do_facet $facet \
12627                                 lctl get_param -n $ost_param.blocksize)
12628                         echo "OST Blocksize: $saved_ost_blocks"
12629                 fi
12630                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12631                 do_facet $facet zfs set recordsize=32768 $ost
12632         done
12633
12634         # BS too small. Sufficient for functional testing.
12635         for facet in ${mfacets//,/ }; do
12636                 if [ -z $saved_mdt_blocks ]; then
12637                         saved_mdt_blocks=$(do_facet $facet \
12638                                 lctl get_param -n $mdt_param.blocksize)
12639                         echo "MDT Blocksize: $saved_mdt_blocks"
12640                 fi
12641                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12642                 do_facet $facet zfs set recordsize=32768 $mdt
12643         done
12644
12645         # Give new values chance to reflect change
12646         sleep 2
12647
12648         echo "After recordsize change"
12649         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12650         df_after=($(df -h | grep "$MOUNT"$))
12651
12652         # For checking.
12653         echo "lfs output : ${lfs_df_after[*]}"
12654         echo "df  output : ${df_after[*]}"
12655
12656         # Verify lfs df
12657         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12658                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12659         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12660                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12661         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12662                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12663
12664         # Verify df
12665         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12666                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12667         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12668                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12669         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12670                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12671
12672         # Restore MDT recordize back to original
12673         for facet in ${mfacets//,/ }; do
12674                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12675                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12676         done
12677
12678         # Restore OST recordize back to original
12679         for facet in ${ofacets//,/ }; do
12680                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12681                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12682         done
12683
12684         return 0
12685 }
12686 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12687
12688 test_104d() {
12689         (( $RUNAS_ID != $UID )) ||
12690                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12691
12692         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12693                 skip "lustre version doesn't support lctl dl with non-root"
12694
12695         # debugfs only allows root users to access files, so the
12696         # previous move of the "devices" file to debugfs broke
12697         # "lctl dl" for non-root users. The LU-9680 Netlink
12698         # interface again allows non-root users to list devices.
12699         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12700                 error "lctl dl doesn't work for non root"
12701
12702         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12703         [ "$ost_count" -eq $OSTCOUNT ]  ||
12704                 error "lctl dl reports wrong number of OST devices"
12705
12706         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12707         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12708                 error "lctl dl reports wrong number of MDT devices"
12709 }
12710 run_test 104d "$RUNAS lctl dl test"
12711
12712 test_105a() {
12713         # doesn't work on 2.4 kernels
12714         touch $DIR/$tfile
12715         if $(flock_is_enabled); then
12716                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12717         else
12718                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12719         fi
12720         rm -f $DIR/$tfile
12721 }
12722 run_test 105a "flock when mounted without -o flock test ========"
12723
12724 test_105b() {
12725         touch $DIR/$tfile
12726         if $(flock_is_enabled); then
12727                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12728         else
12729                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12730         fi
12731         rm -f $DIR/$tfile
12732 }
12733 run_test 105b "fcntl when mounted without -o flock test ========"
12734
12735 test_105c() {
12736         touch $DIR/$tfile
12737         if $(flock_is_enabled); then
12738                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12739         else
12740                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12741         fi
12742         rm -f $DIR/$tfile
12743 }
12744 run_test 105c "lockf when mounted without -o flock test"
12745
12746 test_105d() { # bug 15924
12747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12748
12749         test_mkdir $DIR/$tdir
12750         flock_is_enabled || skip_env "mount w/o flock enabled"
12751         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12752         $LCTL set_param fail_loc=0x80000315
12753         flocks_test 2 $DIR/$tdir
12754 }
12755 run_test 105d "flock race (should not freeze) ========"
12756
12757 test_105e() { # bug 22660 && 22040
12758         flock_is_enabled || skip_env "mount w/o flock enabled"
12759
12760         touch $DIR/$tfile
12761         flocks_test 3 $DIR/$tfile
12762 }
12763 run_test 105e "Two conflicting flocks from same process"
12764
12765 test_106() { #bug 10921
12766         test_mkdir $DIR/$tdir
12767         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12768         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12769 }
12770 run_test 106 "attempt exec of dir followed by chown of that dir"
12771
12772 test_107() {
12773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12774
12775         CDIR=`pwd`
12776         local file=core
12777
12778         cd $DIR
12779         rm -f $file
12780
12781         local save_pattern=$(sysctl -n kernel.core_pattern)
12782         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12783         sysctl -w kernel.core_pattern=$file
12784         sysctl -w kernel.core_uses_pid=0
12785
12786         ulimit -c unlimited
12787         sleep 60 &
12788         SLEEPPID=$!
12789
12790         sleep 1
12791
12792         kill -s 11 $SLEEPPID
12793         wait $SLEEPPID
12794         if [ -e $file ]; then
12795                 size=`stat -c%s $file`
12796                 [ $size -eq 0 ] && error "Fail to create core file $file"
12797         else
12798                 error "Fail to create core file $file"
12799         fi
12800         rm -f $file
12801         sysctl -w kernel.core_pattern=$save_pattern
12802         sysctl -w kernel.core_uses_pid=$save_uses_pid
12803         cd $CDIR
12804 }
12805 run_test 107 "Coredump on SIG"
12806
12807 test_110() {
12808         test_mkdir $DIR/$tdir
12809         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12810         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12811                 error "mkdir with 256 char should fail, but did not"
12812         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12813                 error "create with 255 char failed"
12814         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12815                 error "create with 256 char should fail, but did not"
12816
12817         ls -l $DIR/$tdir
12818         rm -rf $DIR/$tdir
12819 }
12820 run_test 110 "filename length checking"
12821
12822 test_116a() { # was previously test_116()
12823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12824         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12825         remote_mds_nodsh && skip "remote MDS with nodsh"
12826
12827         echo -n "Free space priority "
12828         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12829                 head -n1
12830         declare -a AVAIL
12831         free_min_max
12832
12833         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12834         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12835         stack_trap simple_cleanup_common
12836
12837         # Check if we need to generate uneven OSTs
12838         test_mkdir -p $DIR/$tdir/OST${MINI}
12839         local FILL=$((MINV / 4))
12840         local DIFF=$((MAXV - MINV))
12841         local DIFF2=$((DIFF * 100 / MINV))
12842
12843         local threshold=$(do_facet $SINGLEMDS \
12844                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12845         threshold=${threshold%%%}
12846         echo -n "Check for uneven OSTs: "
12847         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12848
12849         if [[ $DIFF2 -gt $threshold ]]; then
12850                 echo "ok"
12851                 echo "Don't need to fill OST$MINI"
12852         else
12853                 # generate uneven OSTs. Write 2% over the QOS threshold value
12854                 echo "no"
12855                 DIFF=$((threshold - DIFF2 + 2))
12856                 DIFF2=$((MINV * DIFF / 100))
12857                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12858                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12859                         error "setstripe failed"
12860                 DIFF=$((DIFF2 / 2048))
12861                 i=0
12862                 while [ $i -lt $DIFF ]; do
12863                         i=$((i + 1))
12864                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12865                                 bs=2M count=1 2>/dev/null
12866                         echo -n .
12867                 done
12868                 echo .
12869                 sync
12870                 sleep_maxage
12871                 free_min_max
12872         fi
12873
12874         DIFF=$((MAXV - MINV))
12875         DIFF2=$((DIFF * 100 / MINV))
12876         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12877         if [ $DIFF2 -gt $threshold ]; then
12878                 echo "ok"
12879         else
12880                 skip "QOS imbalance criteria not met"
12881         fi
12882
12883         MINI1=$MINI
12884         MINV1=$MINV
12885         MAXI1=$MAXI
12886         MAXV1=$MAXV
12887
12888         # now fill using QOS
12889         $LFS setstripe -c 1 $DIR/$tdir
12890         FILL=$((FILL / 200))
12891         if [ $FILL -gt 600 ]; then
12892                 FILL=600
12893         fi
12894         echo "writing $FILL files to QOS-assigned OSTs"
12895         i=0
12896         while [ $i -lt $FILL ]; do
12897                 i=$((i + 1))
12898                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12899                         count=1 2>/dev/null
12900                 echo -n .
12901         done
12902         echo "wrote $i 200k files"
12903         sync
12904         sleep_maxage
12905
12906         echo "Note: free space may not be updated, so measurements might be off"
12907         free_min_max
12908         DIFF2=$((MAXV - MINV))
12909         echo "free space delta: orig $DIFF final $DIFF2"
12910         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12911         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12912         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12913         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12914         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12915         if [[ $DIFF -gt 0 ]]; then
12916                 FILL=$((DIFF2 * 100 / DIFF - 100))
12917                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12918         fi
12919
12920         # Figure out which files were written where
12921         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12922                awk '/'$MINI1': / {print $2; exit}')
12923         echo $UUID
12924         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12925         echo "$MINC files created on smaller OST $MINI1"
12926         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12927                awk '/'$MAXI1': / {print $2; exit}')
12928         echo $UUID
12929         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12930         echo "$MAXC files created on larger OST $MAXI1"
12931         if [[ $MINC -gt 0 ]]; then
12932                 FILL=$((MAXC * 100 / MINC - 100))
12933                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12934         fi
12935         [[ $MAXC -gt $MINC ]] ||
12936                 error_ignore LU-9 "stripe QOS didn't balance free space"
12937 }
12938 run_test 116a "stripe QOS: free space balance ==================="
12939
12940 test_116b() { # LU-2093
12941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12942         remote_mds_nodsh && skip "remote MDS with nodsh"
12943
12944 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12945         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12946                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12947         [ -z "$old_rr" ] && skip "no QOS"
12948         do_facet $SINGLEMDS lctl set_param \
12949                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12950         mkdir -p $DIR/$tdir
12951         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12952         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12953         do_facet $SINGLEMDS lctl set_param fail_loc=0
12954         rm -rf $DIR/$tdir
12955         do_facet $SINGLEMDS lctl set_param \
12956                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12957 }
12958 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12959
12960 test_117() # bug 10891
12961 {
12962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12963
12964         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12965         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12966         lctl set_param fail_loc=0x21e
12967         > $DIR/$tfile || error "truncate failed"
12968         lctl set_param fail_loc=0
12969         echo "Truncate succeeded."
12970         rm -f $DIR/$tfile
12971 }
12972 run_test 117 "verify osd extend =========="
12973
12974 NO_SLOW_RESENDCOUNT=4
12975 export OLD_RESENDCOUNT=""
12976 set_resend_count () {
12977         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12978         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12979         lctl set_param -n $PROC_RESENDCOUNT $1
12980         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12981 }
12982
12983 # for reduce test_118* time (b=14842)
12984 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12985
12986 # Reset async IO behavior after error case
12987 reset_async() {
12988         FILE=$DIR/reset_async
12989
12990         # Ensure all OSCs are cleared
12991         $LFS setstripe -c -1 $FILE
12992         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12993         sync
12994         rm $FILE
12995 }
12996
12997 test_118a() #bug 11710
12998 {
12999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13000
13001         reset_async
13002
13003         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13004         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13005         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13006
13007         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13008                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13009                 return 1;
13010         fi
13011         rm -f $DIR/$tfile
13012 }
13013 run_test 118a "verify O_SYNC works =========="
13014
13015 test_118b()
13016 {
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018         remote_ost_nodsh && skip "remote OST with nodsh"
13019
13020         reset_async
13021
13022         #define OBD_FAIL_SRV_ENOENT 0x217
13023         set_nodes_failloc "$(osts_nodes)" 0x217
13024         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13025         RC=$?
13026         set_nodes_failloc "$(osts_nodes)" 0
13027         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13028         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13029                     grep -c writeback)
13030
13031         if [[ $RC -eq 0 ]]; then
13032                 error "Must return error due to dropped pages, rc=$RC"
13033                 return 1;
13034         fi
13035
13036         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13037                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13038                 return 1;
13039         fi
13040
13041         echo "Dirty pages not leaked on ENOENT"
13042
13043         # Due to the above error the OSC will issue all RPCs syncronously
13044         # until a subsequent RPC completes successfully without error.
13045         $MULTIOP $DIR/$tfile Ow4096yc
13046         rm -f $DIR/$tfile
13047
13048         return 0
13049 }
13050 run_test 118b "Reclaim dirty pages on fatal error =========="
13051
13052 test_118c()
13053 {
13054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13055
13056         # for 118c, restore the original resend count, LU-1940
13057         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13058                                 set_resend_count $OLD_RESENDCOUNT
13059         remote_ost_nodsh && skip "remote OST with nodsh"
13060
13061         reset_async
13062
13063         #define OBD_FAIL_OST_EROFS               0x216
13064         set_nodes_failloc "$(osts_nodes)" 0x216
13065
13066         # multiop should block due to fsync until pages are written
13067         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13068         MULTIPID=$!
13069         sleep 1
13070
13071         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13072                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13073         fi
13074
13075         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13076                     grep -c writeback)
13077         if [[ $WRITEBACK -eq 0 ]]; then
13078                 error "No page in writeback, writeback=$WRITEBACK"
13079         fi
13080
13081         set_nodes_failloc "$(osts_nodes)" 0
13082         wait $MULTIPID
13083         RC=$?
13084         if [[ $RC -ne 0 ]]; then
13085                 error "Multiop fsync failed, rc=$RC"
13086         fi
13087
13088         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13089         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13090                     grep -c writeback)
13091         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13092                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13093         fi
13094
13095         rm -f $DIR/$tfile
13096         echo "Dirty pages flushed via fsync on EROFS"
13097         return 0
13098 }
13099 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13100
13101 # continue to use small resend count to reduce test_118* time (b=14842)
13102 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13103
13104 test_118d()
13105 {
13106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13107         remote_ost_nodsh && skip "remote OST with nodsh"
13108
13109         reset_async
13110
13111         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13112         set_nodes_failloc "$(osts_nodes)" 0x214
13113         # multiop should block due to fsync until pages are written
13114         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13115         MULTIPID=$!
13116         sleep 1
13117
13118         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13119                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13120         fi
13121
13122         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13123                     grep -c writeback)
13124         if [[ $WRITEBACK -eq 0 ]]; then
13125                 error "No page in writeback, writeback=$WRITEBACK"
13126         fi
13127
13128         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13129         set_nodes_failloc "$(osts_nodes)" 0
13130
13131         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13132         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13133                     grep -c writeback)
13134         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13135                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13136         fi
13137
13138         rm -f $DIR/$tfile
13139         echo "Dirty pages gaurenteed flushed via fsync"
13140         return 0
13141 }
13142 run_test 118d "Fsync validation inject a delay of the bulk =========="
13143
13144 test_118f() {
13145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13146
13147         reset_async
13148
13149         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13150         lctl set_param fail_loc=0x8000040a
13151
13152         # Should simulate EINVAL error which is fatal
13153         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13154         RC=$?
13155         if [[ $RC -eq 0 ]]; then
13156                 error "Must return error due to dropped pages, rc=$RC"
13157         fi
13158
13159         lctl set_param fail_loc=0x0
13160
13161         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13162         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13163         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13164                     grep -c writeback)
13165         if [[ $LOCKED -ne 0 ]]; then
13166                 error "Locked pages remain in cache, locked=$LOCKED"
13167         fi
13168
13169         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13170                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13171         fi
13172
13173         rm -f $DIR/$tfile
13174         echo "No pages locked after fsync"
13175
13176         reset_async
13177         return 0
13178 }
13179 run_test 118f "Simulate unrecoverable OSC side error =========="
13180
13181 test_118g() {
13182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13183
13184         reset_async
13185
13186         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13187         lctl set_param fail_loc=0x406
13188
13189         # simulate local -ENOMEM
13190         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13191         RC=$?
13192
13193         lctl set_param fail_loc=0
13194         if [[ $RC -eq 0 ]]; then
13195                 error "Must return error due to dropped pages, rc=$RC"
13196         fi
13197
13198         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13199         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13200         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13201                         grep -c writeback)
13202         if [[ $LOCKED -ne 0 ]]; then
13203                 error "Locked pages remain in cache, locked=$LOCKED"
13204         fi
13205
13206         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13207                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13208         fi
13209
13210         rm -f $DIR/$tfile
13211         echo "No pages locked after fsync"
13212
13213         reset_async
13214         return 0
13215 }
13216 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13217
13218 test_118h() {
13219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13220         remote_ost_nodsh && skip "remote OST with nodsh"
13221
13222         reset_async
13223
13224         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13225         set_nodes_failloc "$(osts_nodes)" 0x20e
13226         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13227         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13228         RC=$?
13229
13230         set_nodes_failloc "$(osts_nodes)" 0
13231         if [[ $RC -eq 0 ]]; then
13232                 error "Must return error due to dropped pages, rc=$RC"
13233         fi
13234
13235         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13236         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13237         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13238                     grep -c writeback)
13239         if [[ $LOCKED -ne 0 ]]; then
13240                 error "Locked pages remain in cache, locked=$LOCKED"
13241         fi
13242
13243         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13244                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13245         fi
13246
13247         rm -f $DIR/$tfile
13248         echo "No pages locked after fsync"
13249
13250         return 0
13251 }
13252 run_test 118h "Verify timeout in handling recoverables errors  =========="
13253
13254 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13255
13256 test_118i() {
13257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13258         remote_ost_nodsh && skip "remote OST with nodsh"
13259
13260         reset_async
13261
13262         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13263         set_nodes_failloc "$(osts_nodes)" 0x20e
13264
13265         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13266         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13267         PID=$!
13268         sleep 5
13269         set_nodes_failloc "$(osts_nodes)" 0
13270
13271         wait $PID
13272         RC=$?
13273         if [[ $RC -ne 0 ]]; then
13274                 error "got error, but should be not, rc=$RC"
13275         fi
13276
13277         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13278         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13279         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13280         if [[ $LOCKED -ne 0 ]]; then
13281                 error "Locked pages remain in cache, locked=$LOCKED"
13282         fi
13283
13284         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13285                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13286         fi
13287
13288         rm -f $DIR/$tfile
13289         echo "No pages locked after fsync"
13290
13291         return 0
13292 }
13293 run_test 118i "Fix error before timeout in recoverable error  =========="
13294
13295 [ "$SLOW" = "no" ] && set_resend_count 4
13296
13297 test_118j() {
13298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13299         remote_ost_nodsh && skip "remote OST with nodsh"
13300
13301         reset_async
13302
13303         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13304         set_nodes_failloc "$(osts_nodes)" 0x220
13305
13306         # return -EIO from OST
13307         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13308         RC=$?
13309         set_nodes_failloc "$(osts_nodes)" 0x0
13310         if [[ $RC -eq 0 ]]; then
13311                 error "Must return error due to dropped pages, rc=$RC"
13312         fi
13313
13314         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13315         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13316         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13317         if [[ $LOCKED -ne 0 ]]; then
13318                 error "Locked pages remain in cache, locked=$LOCKED"
13319         fi
13320
13321         # in recoverable error on OST we want resend and stay until it finished
13322         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13323                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13324         fi
13325
13326         rm -f $DIR/$tfile
13327         echo "No pages locked after fsync"
13328
13329         return 0
13330 }
13331 run_test 118j "Simulate unrecoverable OST side error =========="
13332
13333 test_118k()
13334 {
13335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13336         remote_ost_nodsh && skip "remote OSTs with nodsh"
13337
13338         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13339         set_nodes_failloc "$(osts_nodes)" 0x20e
13340         test_mkdir $DIR/$tdir
13341
13342         for ((i=0;i<10;i++)); do
13343                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13344                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13345                 SLEEPPID=$!
13346                 sleep 0.500s
13347                 kill $SLEEPPID
13348                 wait $SLEEPPID
13349         done
13350
13351         set_nodes_failloc "$(osts_nodes)" 0
13352         rm -rf $DIR/$tdir
13353 }
13354 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13355
13356 test_118l() # LU-646
13357 {
13358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13359
13360         test_mkdir $DIR/$tdir
13361         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13362         rm -rf $DIR/$tdir
13363 }
13364 run_test 118l "fsync dir"
13365
13366 test_118m() # LU-3066
13367 {
13368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13369
13370         test_mkdir $DIR/$tdir
13371         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13372         rm -rf $DIR/$tdir
13373 }
13374 run_test 118m "fdatasync dir ========="
13375
13376 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13377
13378 test_118n()
13379 {
13380         local begin
13381         local end
13382
13383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13384         remote_ost_nodsh && skip "remote OSTs with nodsh"
13385
13386         # Sleep to avoid a cached response.
13387         #define OBD_STATFS_CACHE_SECONDS 1
13388         sleep 2
13389
13390         # Inject a 10 second delay in the OST_STATFS handler.
13391         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13392         set_nodes_failloc "$(osts_nodes)" 0x242
13393
13394         begin=$SECONDS
13395         stat --file-system $MOUNT > /dev/null
13396         end=$SECONDS
13397
13398         set_nodes_failloc "$(osts_nodes)" 0
13399
13400         if ((end - begin > 20)); then
13401             error "statfs took $((end - begin)) seconds, expected 10"
13402         fi
13403 }
13404 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13405
13406 test_119a() # bug 11737
13407 {
13408         BSIZE=$((512 * 1024))
13409         directio write $DIR/$tfile 0 1 $BSIZE
13410         # We ask to read two blocks, which is more than a file size.
13411         # directio will indicate an error when requested and actual
13412         # sizes aren't equeal (a normal situation in this case) and
13413         # print actual read amount.
13414         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13415         if [ "$NOB" != "$BSIZE" ]; then
13416                 error "read $NOB bytes instead of $BSIZE"
13417         fi
13418         rm -f $DIR/$tfile
13419 }
13420 run_test 119a "Short directIO read must return actual read amount"
13421
13422 test_119b() # bug 11737
13423 {
13424         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13425
13426         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13427         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13428         sync
13429         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13430                 error "direct read failed"
13431         rm -f $DIR/$tfile
13432 }
13433 run_test 119b "Sparse directIO read must return actual read amount"
13434
13435 test_119c() # bug 13099
13436 {
13437         BSIZE=1048576
13438         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13439         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13440         rm -f $DIR/$tfile
13441 }
13442 run_test 119c "Testing for direct read hitting hole"
13443
13444 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13445 # Maloo test history
13446
13447 test_119e()
13448 {
13449         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13450
13451         local stripe_size=$((1024 * 1024)) #1 MiB
13452         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13453         local file_size=$((25 * stripe_size))
13454         local bsizes
13455
13456         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13457         stack_trap "rm -f $DIR/$tfile*"
13458
13459         # Just a bit bigger than the largest size in the test set below
13460         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13461                 error "buffered i/o to create file failed"
13462
13463         if zfs_or_rotational; then
13464                 # DIO on ZFS can take up to 2 seconds per IO
13465                 # rotational is better, but still slow.
13466                 # Limit testing on those media to larger sizes
13467                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13468         else
13469                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13470                         $((stripe_size * 4))"
13471         fi
13472
13473         for bs in $bsizes; do
13474                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13475                 echo "Read/write with DIO at size $bs"
13476                 # Read and write with DIO from source to dest
13477                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13478                         iflag=direct oflag=direct ||
13479                         error "dio failed"
13480
13481                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13482                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13483                         error "size incorrect, file copy read/write bsize: $bs"
13484                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13485                         error "files differ, bsize $bs"
13486                 rm -f $DIR/$tfile.2
13487         done
13488 }
13489 run_test 119e "Basic tests of dio read and write at various sizes"
13490
13491 test_119f()
13492 {
13493         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13494
13495         local stripe_size=$((1024 * 1024)) #1 MiB
13496         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13497         local file_size=$((25 * stripe_size))
13498         local bsizes
13499
13500         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13501         stack_trap "rm -f $DIR/$tfile*"
13502
13503         # Just a bit bigger than the largest size in the test set below
13504         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13505                 error "buffered i/o to create file failed"
13506
13507         if zfs_or_rotational; then
13508                 # DIO on ZFS can take up to 2 seconds per IO
13509                 # rotational is better, but still slow.
13510                 # Limit testing on those media to larger sizes
13511                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13512         else
13513                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13514                         $((stripe_size * 4))"
13515         fi
13516
13517         for bs in $bsizes; do
13518                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13519                 # Read and write with DIO from source to dest in two
13520                 # threads - should give correct copy of file
13521
13522                 echo "bs: $bs"
13523                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13524                         oflag=direct conv=notrunc &
13525                 pid_dio1=$!
13526                 # Note block size is different here for a more interesting race
13527                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13528                         iflag=direct oflag=direct conv=notrunc &
13529                 pid_dio2=$!
13530                 wait $pid_dio1
13531                 rc1=$?
13532                 wait $pid_dio2
13533                 rc2=$?
13534                 if (( rc1 != 0 )); then
13535                         error "dio copy 1 w/bsize $bs failed: $rc1"
13536                 fi
13537                 if (( rc2 != 0 )); then
13538                         error "dio copy 2 w/bsize $bs failed: $rc2"
13539                 fi
13540
13541
13542                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13543                         error "size incorrect, file copy read/write bsize: $bs"
13544                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13545                         error "files differ, bsize $bs"
13546                 rm -f $DIR/$tfile.2
13547         done
13548 }
13549 run_test 119f "dio vs dio race"
13550
13551 test_119g()
13552 {
13553         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13554
13555         local stripe_size=$((1024 * 1024)) #1 MiB
13556         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13557         local file_size=$((25 * stripe_size))
13558         local bsizes
13559
13560         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13561         stack_trap "rm -f $DIR/$tfile*"
13562
13563         # Just a bit bigger than the largest size in the test set below
13564         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13565                 error "buffered i/o to create file failed"
13566
13567         if zfs_or_rotational; then
13568                 # DIO on ZFS can take up to 2 seconds per IO
13569                 # rotational is better, but still slow.
13570                 # Limit testing on those media to larger sizes
13571                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13572         else
13573                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13574                         $((stripe_size * 4))"
13575         fi
13576
13577         for bs in $bsizes; do
13578                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13579                 echo "bs: $bs"
13580                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13581                         oflag=direct conv=notrunc &
13582                 pid_dio1=$!
13583                 # Buffered I/O with similar but not the same block size
13584                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13585                 pid_bio2=$!
13586                 wait $pid_dio1
13587                 rc1=$?
13588                 wait $pid_bio2
13589                 rc2=$?
13590                 if (( rc1 != 0 )); then
13591                         error "dio copy 1 w/bsize $bs failed: $rc1"
13592                 fi
13593                 if (( rc2 != 0 )); then
13594                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13595                 fi
13596
13597                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13598                         error "size incorrect"
13599                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13600                         error "files differ, bsize $bs"
13601                 rm -f $DIR/$tfile.2
13602         done
13603 }
13604 run_test 119g "dio vs buffered I/O race"
13605
13606 test_120a() {
13607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13608         remote_mds_nodsh && skip "remote MDS with nodsh"
13609         test_mkdir -i0 -c1 $DIR/$tdir
13610         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13611                 skip_env "no early lock cancel on server"
13612
13613         lru_resize_disable mdc
13614         lru_resize_disable osc
13615         cancel_lru_locks mdc
13616         # asynchronous object destroy at MDT could cause bl ast to client
13617         cancel_lru_locks osc
13618
13619         stat $DIR/$tdir > /dev/null
13620         can1=$(do_facet mds1 \
13621                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13622                awk '/ldlm_cancel/ {print $2}')
13623         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13624                awk '/ldlm_bl_callback/ {print $2}')
13625         test_mkdir -i0 -c1 $DIR/$tdir/d1
13626         can2=$(do_facet mds1 \
13627                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13628                awk '/ldlm_cancel/ {print $2}')
13629         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13630                awk '/ldlm_bl_callback/ {print $2}')
13631         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13632         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13633         lru_resize_enable mdc
13634         lru_resize_enable osc
13635 }
13636 run_test 120a "Early Lock Cancel: mkdir test"
13637
13638 test_120b() {
13639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13640         remote_mds_nodsh && skip "remote MDS with nodsh"
13641         test_mkdir $DIR/$tdir
13642         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13643                 skip_env "no early lock cancel on server"
13644
13645         lru_resize_disable mdc
13646         lru_resize_disable osc
13647         cancel_lru_locks mdc
13648         stat $DIR/$tdir > /dev/null
13649         can1=$(do_facet $SINGLEMDS \
13650                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13651                awk '/ldlm_cancel/ {print $2}')
13652         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13653                awk '/ldlm_bl_callback/ {print $2}')
13654         touch $DIR/$tdir/f1
13655         can2=$(do_facet $SINGLEMDS \
13656                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13657                awk '/ldlm_cancel/ {print $2}')
13658         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13659                awk '/ldlm_bl_callback/ {print $2}')
13660         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13661         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13662         lru_resize_enable mdc
13663         lru_resize_enable osc
13664 }
13665 run_test 120b "Early Lock Cancel: create test"
13666
13667 test_120c() {
13668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13669         remote_mds_nodsh && skip "remote MDS with nodsh"
13670         test_mkdir -i0 -c1 $DIR/$tdir
13671         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13672                 skip "no early lock cancel on server"
13673
13674         lru_resize_disable mdc
13675         lru_resize_disable osc
13676         test_mkdir -i0 -c1 $DIR/$tdir/d1
13677         test_mkdir -i0 -c1 $DIR/$tdir/d2
13678         touch $DIR/$tdir/d1/f1
13679         cancel_lru_locks mdc
13680         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13681         can1=$(do_facet mds1 \
13682                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13683                awk '/ldlm_cancel/ {print $2}')
13684         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13685                awk '/ldlm_bl_callback/ {print $2}')
13686         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13687         can2=$(do_facet mds1 \
13688                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13689                awk '/ldlm_cancel/ {print $2}')
13690         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13691                awk '/ldlm_bl_callback/ {print $2}')
13692         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13693         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13694         lru_resize_enable mdc
13695         lru_resize_enable osc
13696 }
13697 run_test 120c "Early Lock Cancel: link test"
13698
13699 test_120d() {
13700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13701         remote_mds_nodsh && skip "remote MDS with nodsh"
13702         test_mkdir -i0 -c1 $DIR/$tdir
13703         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13704                 skip_env "no early lock cancel on server"
13705
13706         lru_resize_disable mdc
13707         lru_resize_disable osc
13708         touch $DIR/$tdir
13709         cancel_lru_locks mdc
13710         stat $DIR/$tdir > /dev/null
13711         can1=$(do_facet mds1 \
13712                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13713                awk '/ldlm_cancel/ {print $2}')
13714         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13715                awk '/ldlm_bl_callback/ {print $2}')
13716         chmod a+x $DIR/$tdir
13717         can2=$(do_facet mds1 \
13718                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13719                awk '/ldlm_cancel/ {print $2}')
13720         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13721                awk '/ldlm_bl_callback/ {print $2}')
13722         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13723         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13724         lru_resize_enable mdc
13725         lru_resize_enable osc
13726 }
13727 run_test 120d "Early Lock Cancel: setattr test"
13728
13729 test_120e() {
13730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13731         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13732                 skip_env "no early lock cancel on server"
13733         remote_mds_nodsh && skip "remote MDS with nodsh"
13734
13735         local dlmtrace_set=false
13736
13737         test_mkdir -i0 -c1 $DIR/$tdir
13738         lru_resize_disable mdc
13739         lru_resize_disable osc
13740         ! $LCTL get_param debug | grep -q dlmtrace &&
13741                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13742         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13743         cancel_lru_locks mdc
13744         cancel_lru_locks osc
13745         dd if=$DIR/$tdir/f1 of=/dev/null
13746         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13747         # XXX client can not do early lock cancel of OST lock
13748         # during unlink (LU-4206), so cancel osc lock now.
13749         sleep 2
13750         cancel_lru_locks osc
13751         can1=$(do_facet mds1 \
13752                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13753                awk '/ldlm_cancel/ {print $2}')
13754         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13755                awk '/ldlm_bl_callback/ {print $2}')
13756         unlink $DIR/$tdir/f1
13757         sleep 5
13758         can2=$(do_facet mds1 \
13759                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13760                awk '/ldlm_cancel/ {print $2}')
13761         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13762                awk '/ldlm_bl_callback/ {print $2}')
13763         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13764                 $LCTL dk $TMP/cancel.debug.txt
13765         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13766                 $LCTL dk $TMP/blocking.debug.txt
13767         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13768         lru_resize_enable mdc
13769         lru_resize_enable osc
13770 }
13771 run_test 120e "Early Lock Cancel: unlink test"
13772
13773 test_120f() {
13774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13775         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13776                 skip_env "no early lock cancel on server"
13777         remote_mds_nodsh && skip "remote MDS with nodsh"
13778
13779         test_mkdir -i0 -c1 $DIR/$tdir
13780         lru_resize_disable mdc
13781         lru_resize_disable osc
13782         test_mkdir -i0 -c1 $DIR/$tdir/d1
13783         test_mkdir -i0 -c1 $DIR/$tdir/d2
13784         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13785         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13786         cancel_lru_locks mdc
13787         cancel_lru_locks osc
13788         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13789         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13790         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13791         # XXX client can not do early lock cancel of OST lock
13792         # during rename (LU-4206), so cancel osc lock now.
13793         sleep 2
13794         cancel_lru_locks osc
13795         can1=$(do_facet mds1 \
13796                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13797                awk '/ldlm_cancel/ {print $2}')
13798         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13799                awk '/ldlm_bl_callback/ {print $2}')
13800         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13801         sleep 5
13802         can2=$(do_facet mds1 \
13803                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13804                awk '/ldlm_cancel/ {print $2}')
13805         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13806                awk '/ldlm_bl_callback/ {print $2}')
13807         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13808         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13809         lru_resize_enable mdc
13810         lru_resize_enable osc
13811 }
13812 run_test 120f "Early Lock Cancel: rename test"
13813
13814 test_120g() {
13815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13816         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13817                 skip_env "no early lock cancel on server"
13818         remote_mds_nodsh && skip "remote MDS with nodsh"
13819
13820         lru_resize_disable mdc
13821         lru_resize_disable osc
13822         count=10000
13823         echo create $count files
13824         test_mkdir $DIR/$tdir
13825         cancel_lru_locks mdc
13826         cancel_lru_locks osc
13827         t0=$(date +%s)
13828
13829         can0=$(do_facet $SINGLEMDS \
13830                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13831                awk '/ldlm_cancel/ {print $2}')
13832         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13833                awk '/ldlm_bl_callback/ {print $2}')
13834         createmany -o $DIR/$tdir/f $count
13835         sync
13836         can1=$(do_facet $SINGLEMDS \
13837                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13838                awk '/ldlm_cancel/ {print $2}')
13839         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13840                awk '/ldlm_bl_callback/ {print $2}')
13841         t1=$(date +%s)
13842         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13843         echo rm $count files
13844         rm -r $DIR/$tdir
13845         sync
13846         can2=$(do_facet $SINGLEMDS \
13847                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13848                awk '/ldlm_cancel/ {print $2}')
13849         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13850                awk '/ldlm_bl_callback/ {print $2}')
13851         t2=$(date +%s)
13852         echo total: $count removes in $((t2-t1))
13853         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13854         sleep 2
13855         # wait for commitment of removal
13856         lru_resize_enable mdc
13857         lru_resize_enable osc
13858 }
13859 run_test 120g "Early Lock Cancel: performance test"
13860
13861 test_121() { #bug #10589
13862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13863
13864         rm -rf $DIR/$tfile
13865         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13866 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13867         lctl set_param fail_loc=0x310
13868         cancel_lru_locks osc > /dev/null
13869         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13870         lctl set_param fail_loc=0
13871         [[ $reads -eq $writes ]] ||
13872                 error "read $reads blocks, must be $writes blocks"
13873 }
13874 run_test 121 "read cancel race ========="
13875
13876 test_123a_base() { # was test 123, statahead(bug 11401)
13877         local lsx="$1"
13878
13879         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13880
13881         SLOWOK=0
13882         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13883                 log "testing UP system. Performance may be lower than expected."
13884                 SLOWOK=1
13885         fi
13886         running_in_vm && SLOWOK=1
13887
13888         $LCTL set_param mdc.*.batch_stats=0
13889
13890         rm -rf $DIR/$tdir
13891         test_mkdir $DIR/$tdir
13892         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13893         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13894         MULT=10
13895         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13896                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13897
13898                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13899                 lctl set_param -n llite.*.statahead_max 0
13900                 lctl get_param llite.*.statahead_max
13901                 cancel_lru_locks mdc
13902                 cancel_lru_locks osc
13903                 stime=$(date +%s)
13904                 time $lsx $DIR/$tdir | wc -l
13905                 etime=$(date +%s)
13906                 delta=$((etime - stime))
13907                 log "$lsx $i files without statahead: $delta sec"
13908                 lctl set_param llite.*.statahead_max=$max
13909
13910                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13911                          awk '/statahead.wrong:/ { print $NF }')
13912                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13913                 cancel_lru_locks mdc
13914                 cancel_lru_locks osc
13915                 stime=$(date +%s)
13916                 time $lsx $DIR/$tdir | wc -l
13917                 etime=$(date +%s)
13918                 delta_sa=$((etime - stime))
13919                 log "$lsx $i files with statahead: $delta_sa sec"
13920                 lctl get_param -n llite.*.statahead_stats
13921                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13922                          awk '/statahead.wrong:/ { print $NF }')
13923
13924                 [[ $swrong -lt $ewrong ]] &&
13925                         log "statahead was stopped, maybe too many locks held!"
13926                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13927
13928                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13929                         max=$(lctl get_param -n llite.*.statahead_max |
13930                                 head -n 1)
13931                         lctl set_param -n llite.*.statahead_max 0
13932                         lctl get_param llite.*.statahead_max
13933                         cancel_lru_locks mdc
13934                         cancel_lru_locks osc
13935                         stime=$(date +%s)
13936                         time $lsx $DIR/$tdir | wc -l
13937                         etime=$(date +%s)
13938                         delta=$((etime - stime))
13939                         log "$lsx $i files again without statahead: $delta sec"
13940                         lctl set_param llite.*.statahead_max=$max
13941                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13942                                 if [ $SLOWOK -eq 0 ]; then
13943                                         error "$lsx $i files is slower with statahead!"
13944                                 else
13945                                         log "$lsx $i files is slower with statahead!"
13946                                 fi
13947                                 break
13948                         fi
13949                 fi
13950
13951                 [ $delta -gt 20 ] && break
13952                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13953                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13954         done
13955         log "$lsx done"
13956
13957         stime=$(date +%s)
13958         rm -r $DIR/$tdir
13959         sync
13960         etime=$(date +%s)
13961         delta=$((etime - stime))
13962         log "rm -r $DIR/$tdir/: $delta seconds"
13963         log "rm done"
13964         lctl get_param -n llite.*.statahead_stats
13965         $LCTL get_param mdc.*.batch_stats
13966 }
13967
13968 test_123aa() {
13969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13970
13971         test_123a_base "ls -l"
13972 }
13973 run_test 123aa "verify statahead work"
13974
13975 test_123ab() {
13976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13977
13978         statx_supported || skip_env "Test must be statx() syscall supported"
13979
13980         test_123a_base "$STATX -l"
13981 }
13982 run_test 123ab "verify statahead work by using statx"
13983
13984 test_123ac() {
13985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13986
13987         statx_supported || skip_env "Test must be statx() syscall supported"
13988
13989         local rpcs_before
13990         local rpcs_after
13991         local agl_before
13992         local agl_after
13993
13994         cancel_lru_locks $OSC
13995         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13996         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13997                      awk '/agl.total:/ { print $NF }')
13998         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13999         test_123a_base "$STATX --cached=always -D"
14000         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14001                     awk '/agl.total:/ { print $NF }')
14002         [ $agl_before -eq $agl_after ] ||
14003                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14004         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14005         [ $rpcs_after -eq $rpcs_before ] ||
14006                 error "$STATX should not send glimpse RPCs to $OSC"
14007 }
14008 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14009
14010 test_batch_statahead() {
14011         local max=$1
14012         local batch_max=$2
14013         local num=10000
14014         local batch_rpcs
14015         local unbatch_rpcs
14016         local hit_total
14017
14018         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14019         $LCTL set_param mdc.*.batch_stats=0
14020         $LCTL set_param llite.*.statahead_max=$max
14021         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14022         # Verify that batched statahead is faster than one without statahead
14023         test_123a_base "ls -l"
14024
14025         stack_trap "rm -rf $DIR/$tdir" EXIT
14026         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14027         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14028
14029         # unbatched statahead
14030         $LCTL set_param llite.*.statahead_batch_max=0
14031         $LCTL set_param llite.*.statahead_stats=clear
14032         $LCTL set_param mdc.*.stats=clear
14033         cancel_lru_locks mdc
14034         cancel_lru_locks osc
14035         time ls -l $DIR/$tdir | wc -l
14036         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14037         sleep 2
14038         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14039                     awk '/hit.total:/ { print $NF }')
14040         # hit ratio should be larger than 75% (7500).
14041         (( $hit_total > 7500 )) ||
14042                 error "unbatched statahead hit count ($hit_total) is too low"
14043
14044         # batched statahead
14045         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14046         $LCTL set_param llite.*.statahead_stats=clear
14047         $LCTL set_param mdc.*.batch_stats=clear
14048         $LCTL set_param mdc.*.stats=clear
14049         cancel_lru_locks mdc
14050         cancel_lru_locks osc
14051         time ls -l $DIR/$tdir | wc -l
14052         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14053         # wait for statahead thread to quit and update statahead stats
14054         sleep 2
14055         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14056                     awk '/hit.total:/ { print $NF }')
14057         # hit ratio should be larger than 75% (7500).
14058         (( $hit_total > 7500 )) ||
14059                 error "batched statahead hit count ($hit_total) is too low"
14060
14061         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14062         (( $unbatch_rpcs > $batch_rpcs )) ||
14063                 error "batched statahead does not reduce RPC count"
14064         $LCTL get_param mdc.*.batch_stats
14065 }
14066
14067 test_123ad() {
14068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14069
14070         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14071                 skip "Need server version at least 2.15.53"
14072
14073         local max
14074         local batch_max
14075
14076         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14077         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14078
14079         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14080         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14081
14082         test_batch_statahead 32 32
14083         test_batch_statahead 2048 256
14084 }
14085 run_test 123ad "Verify batching statahead works correctly"
14086
14087 test_123b () { # statahead(bug 15027)
14088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14089
14090         test_mkdir $DIR/$tdir
14091         createmany -o $DIR/$tdir/$tfile-%d 1000
14092
14093         cancel_lru_locks mdc
14094         cancel_lru_locks osc
14095
14096 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14097         lctl set_param fail_loc=0x80000803
14098         ls -lR $DIR/$tdir > /dev/null
14099         log "ls done"
14100         lctl set_param fail_loc=0x0
14101         lctl get_param -n llite.*.statahead_stats
14102         rm -r $DIR/$tdir
14103         sync
14104
14105 }
14106 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14107
14108 test_123c() {
14109         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14110
14111         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14112         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14113         touch $DIR/$tdir.1/{1..3}
14114         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14115
14116         remount_client $MOUNT
14117
14118         $MULTIOP $DIR/$tdir.0 Q
14119
14120         # let statahead to complete
14121         ls -l $DIR/$tdir.0 > /dev/null
14122
14123         testid=$(echo $TESTNAME | tr '_' ' ')
14124         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14125                 error "statahead warning" || true
14126 }
14127 run_test 123c "Can not initialize inode warning on DNE statahead"
14128
14129 test_123d() {
14130         local num=100
14131         local swrong
14132         local ewrong
14133
14134         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14135         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14136                 error "setdirstripe $DIR/$tdir failed"
14137         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14138         remount_client $MOUNT
14139         $LCTL get_param llite.*.statahead_max
14140         $LCTL set_param llite.*.statahead_stats=0 ||
14141                 error "clear statahead_stats failed"
14142         swrong=$(lctl get_param -n llite.*.statahead_stats |
14143                  awk '/statahead.wrong:/ { print $NF }')
14144         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14145         # wait for statahead thread finished to update hit/miss stats.
14146         sleep 1
14147         $LCTL get_param -n llite.*.statahead_stats
14148         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14149                  awk '/statahead.wrong:/ { print $NF }')
14150         (( $swrong == $ewrong )) ||
14151                 log "statahead was stopped, maybe too many locks held!"
14152 }
14153 run_test 123d "Statahead on striped directories works correctly"
14154
14155 test_123e() {
14156         local max
14157         local batch_max
14158         local dir=$DIR/$tdir
14159
14160         mkdir $dir || error "mkdir $dir failed"
14161         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14162         stack_trap "rm -rf $dir"
14163
14164         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14165
14166         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14167         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14168         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14169         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14170
14171         $LCTL set_param llite.*.statahead_max=2048
14172         $LCTL set_param llite.*.statahead_batch_max=1024
14173
14174         ls -l $dir
14175         $LCTL get_param mdc.*.batch_stats
14176         $LCTL get_param llite.*.statahead_*
14177 }
14178 run_test 123e "statahead with large wide striping"
14179
14180 test_123f() {
14181         local max
14182         local batch_max
14183         local dir=$DIR/$tdir
14184
14185         mkdir $dir || error "mkdir $dir failed"
14186         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14187         stack_trap "rm -rf $dir"
14188
14189         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14190
14191         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14192         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14193
14194         $LCTL set_param llite.*.statahead_max=64
14195         $LCTL set_param llite.*.statahead_batch_max=64
14196
14197         ls -l $dir
14198         lctl get_param mdc.*.batch_stats
14199         lctl get_param llite.*.statahead_*
14200
14201         $LCTL set_param llite.*.statahead_max=$max
14202         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14203 }
14204 run_test 123f "Retry mechanism with large wide striping files"
14205
14206 test_124a() {
14207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14208         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14209                 skip_env "no lru resize on server"
14210
14211         local NR=2000
14212
14213         test_mkdir $DIR/$tdir
14214
14215         log "create $NR files at $DIR/$tdir"
14216         createmany -o $DIR/$tdir/f $NR ||
14217                 error "failed to create $NR files in $DIR/$tdir"
14218
14219         cancel_lru_locks mdc
14220         ls -l $DIR/$tdir > /dev/null
14221
14222         local NSDIR=""
14223         local LRU_SIZE=0
14224         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14225                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14226                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14227                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14228                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14229                         log "NSDIR=$NSDIR"
14230                         log "NS=$(basename $NSDIR)"
14231                         break
14232                 fi
14233         done
14234
14235         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14236                 skip "Not enough cached locks created!"
14237         fi
14238         log "LRU=$LRU_SIZE"
14239
14240         local SLEEP=30
14241
14242         # We know that lru resize allows one client to hold $LIMIT locks
14243         # for 10h. After that locks begin to be killed by client.
14244         local MAX_HRS=10
14245         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14246         log "LIMIT=$LIMIT"
14247         if [ $LIMIT -lt $LRU_SIZE ]; then
14248                 skip "Limit is too small $LIMIT"
14249         fi
14250
14251         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14252         # killing locks. Some time was spent for creating locks. This means
14253         # that up to the moment of sleep finish we must have killed some of
14254         # them (10-100 locks). This depends on how fast ther were created.
14255         # Many of them were touched in almost the same moment and thus will
14256         # be killed in groups.
14257         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14258
14259         # Use $LRU_SIZE_B here to take into account real number of locks
14260         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14261         local LRU_SIZE_B=$LRU_SIZE
14262         log "LVF=$LVF"
14263         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14264         log "OLD_LVF=$OLD_LVF"
14265         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14266
14267         # Let's make sure that we really have some margin. Client checks
14268         # cached locks every 10 sec.
14269         SLEEP=$((SLEEP+20))
14270         log "Sleep ${SLEEP} sec"
14271         local SEC=0
14272         while ((SEC<$SLEEP)); do
14273                 echo -n "..."
14274                 sleep 5
14275                 SEC=$((SEC+5))
14276                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14277                 echo -n "$LRU_SIZE"
14278         done
14279         echo ""
14280         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14281         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14282
14283         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14284                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14285                 unlinkmany $DIR/$tdir/f $NR
14286                 return
14287         }
14288
14289         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14290         log "unlink $NR files at $DIR/$tdir"
14291         unlinkmany $DIR/$tdir/f $NR
14292 }
14293 run_test 124a "lru resize ======================================="
14294
14295 get_max_pool_limit()
14296 {
14297         local limit=$($LCTL get_param \
14298                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14299         local max=0
14300         for l in $limit; do
14301                 if [[ $l -gt $max ]]; then
14302                         max=$l
14303                 fi
14304         done
14305         echo $max
14306 }
14307
14308 test_124b() {
14309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14310         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14311                 skip_env "no lru resize on server"
14312
14313         LIMIT=$(get_max_pool_limit)
14314
14315         NR=$(($(default_lru_size)*20))
14316         if [[ $NR -gt $LIMIT ]]; then
14317                 log "Limit lock number by $LIMIT locks"
14318                 NR=$LIMIT
14319         fi
14320
14321         IFree=$(mdsrate_inodes_available)
14322         if [ $IFree -lt $NR ]; then
14323                 log "Limit lock number by $IFree inodes"
14324                 NR=$IFree
14325         fi
14326
14327         lru_resize_disable mdc
14328         test_mkdir -p $DIR/$tdir/disable_lru_resize
14329
14330         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14331         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14332         cancel_lru_locks mdc
14333         stime=`date +%s`
14334         PID=""
14335         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14336         PID="$PID $!"
14337         sleep 2
14338         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14339         PID="$PID $!"
14340         sleep 2
14341         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14342         PID="$PID $!"
14343         wait $PID
14344         etime=`date +%s`
14345         nolruresize_delta=$((etime-stime))
14346         log "ls -la time: $nolruresize_delta seconds"
14347         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14348         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14349
14350         lru_resize_enable mdc
14351         test_mkdir -p $DIR/$tdir/enable_lru_resize
14352
14353         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14354         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14355         cancel_lru_locks mdc
14356         stime=`date +%s`
14357         PID=""
14358         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14359         PID="$PID $!"
14360         sleep 2
14361         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14362         PID="$PID $!"
14363         sleep 2
14364         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14365         PID="$PID $!"
14366         wait $PID
14367         etime=`date +%s`
14368         lruresize_delta=$((etime-stime))
14369         log "ls -la time: $lruresize_delta seconds"
14370         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14371
14372         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14373                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14374         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14375                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14376         else
14377                 log "lru resize performs the same with no lru resize"
14378         fi
14379         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14380 }
14381 run_test 124b "lru resize (performance test) ======================="
14382
14383 test_124c() {
14384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14385         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14386                 skip_env "no lru resize on server"
14387
14388         # cache ununsed locks on client
14389         local nr=100
14390         cancel_lru_locks mdc
14391         test_mkdir $DIR/$tdir
14392         createmany -o $DIR/$tdir/f $nr ||
14393                 error "failed to create $nr files in $DIR/$tdir"
14394         ls -l $DIR/$tdir > /dev/null
14395
14396         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14397         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14398         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14399         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14400         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14401
14402         # set lru_max_age to 1 sec
14403         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14404         echo "sleep $((recalc_p * 2)) seconds..."
14405         sleep $((recalc_p * 2))
14406
14407         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14408         # restore lru_max_age
14409         $LCTL set_param -n $nsdir.lru_max_age $max_age
14410         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14411         unlinkmany $DIR/$tdir/f $nr
14412 }
14413 run_test 124c "LRUR cancel very aged locks"
14414
14415 test_124d() {
14416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14417         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14418                 skip_env "no lru resize on server"
14419
14420         # cache ununsed locks on client
14421         local nr=100
14422
14423         lru_resize_disable mdc
14424         stack_trap "lru_resize_enable mdc" EXIT
14425
14426         cancel_lru_locks mdc
14427
14428         # asynchronous object destroy at MDT could cause bl ast to client
14429         test_mkdir $DIR/$tdir
14430         createmany -o $DIR/$tdir/f $nr ||
14431                 error "failed to create $nr files in $DIR/$tdir"
14432         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14433
14434         ls -l $DIR/$tdir > /dev/null
14435
14436         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14437         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14438         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14439         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14440
14441         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14442
14443         # set lru_max_age to 1 sec
14444         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14445         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14446
14447         echo "sleep $((recalc_p * 2)) seconds..."
14448         sleep $((recalc_p * 2))
14449
14450         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14451
14452         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14453 }
14454 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14455
14456 test_125() { # 13358
14457         $LCTL get_param -n llite.*.client_type | grep -q local ||
14458                 skip "must run as local client"
14459         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14460                 skip_env "must have acl enabled"
14461         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14462         id $USER0 || skip_env "missing user $USER0"
14463
14464         test_mkdir $DIR/$tdir
14465         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14466         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14467                 error "setfacl $DIR/$tdir failed"
14468         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14469 }
14470 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14471
14472 test_126() { # bug 12829/13455
14473         $GSS && skip_env "must run as gss disabled"
14474         $LCTL get_param -n llite.*.client_type | grep -q local ||
14475                 skip "must run as local client"
14476         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14477
14478         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14479         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14480         rm -f $DIR/$tfile
14481         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14482 }
14483 run_test 126 "check that the fsgid provided by the client is taken into account"
14484
14485 test_127a() { # bug 15521
14486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14487         local name count samp unit min max sum sumsq
14488         local tmpfile=$TMP/$tfile.tmp
14489
14490         # enable stats header if it is disabled
14491         $LCTL set_param enable_stats_header=1
14492
14493         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14494         echo "stats before reset"
14495         stack_trap "rm -f $tmpfile"
14496         local now=$(date +%s)
14497
14498         $LCTL get_param osc.*.stats | tee $tmpfile
14499
14500         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14501         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14502         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14503         local uptime=$(awk '{ print $1 }' /proc/uptime)
14504
14505         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14506         (( ${snapshot_time%\.*} >= $now - 5 &&
14507            ${snapshot_time%\.*} <= $now + 5 )) ||
14508                 error "snapshot_time=$snapshot_time != now=$now"
14509         # elapsed _should_ be from mount, but at least less than uptime
14510         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14511                 error "elapsed=$elapsed > uptime=$uptime"
14512         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14513            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14514                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14515
14516         $LCTL set_param osc.*.stats=0
14517         local reset=$(date +%s)
14518         local fsize=$((2048 * 1024))
14519
14520         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14521         cancel_lru_locks osc
14522         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14523
14524         now=$(date +%s)
14525         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14526         while read name count samp unit min max sum sumsq; do
14527                 [[ "$samp" == "samples" ]] || continue
14528
14529                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14530                 [ ! $min ] && error "Missing min value for $name proc entry"
14531                 eval $name=$count || error "Wrong proc format"
14532
14533                 case $name in
14534                 read_bytes|write_bytes)
14535                         [[ "$unit" =~ "bytes" ]] ||
14536                                 error "unit is not 'bytes': $unit"
14537                         (( $min >= 4096 )) || error "min is too small: $min"
14538                         (( $min <= $fsize )) || error "min is too big: $min"
14539                         (( $max >= 4096 )) || error "max is too small: $max"
14540                         (( $max <= $fsize )) || error "max is too big: $max"
14541                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14542                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14543                                 error "sumsquare is too small: $sumsq"
14544                         (( $sumsq <= $fsize * $fsize )) ||
14545                                 error "sumsquare is too big: $sumsq"
14546                         ;;
14547                 ost_read|ost_write)
14548                         [[ "$unit" =~ "usec" ]] ||
14549                                 error "unit is not 'usec': $unit"
14550                         ;;
14551                 *)      ;;
14552                 esac
14553         done < $tmpfile
14554
14555         #check that we actually got some stats
14556         [ "$read_bytes" ] || error "Missing read_bytes stats"
14557         [ "$write_bytes" ] || error "Missing write_bytes stats"
14558         [ "$read_bytes" != 0 ] || error "no read done"
14559         [ "$write_bytes" != 0 ] || error "no write done"
14560
14561         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14562         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14563         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14564
14565         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14566         (( ${snapshot_time%\.*} >= $now - 5 &&
14567            ${snapshot_time%\.*} <= $now + 5 )) ||
14568                 error "reset snapshot_time=$snapshot_time != now=$now"
14569         # elapsed should be from time of stats reset
14570         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14571            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14572                 error "reset elapsed=$elapsed > $now - $reset"
14573         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14574            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14575                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14576 }
14577 run_test 127a "verify the client stats are sane"
14578
14579 test_127b() { # bug LU-333
14580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14581         local name count samp unit min max sum sumsq
14582
14583         echo "stats before reset"
14584         $LCTL get_param llite.*.stats
14585         $LCTL set_param llite.*.stats=0
14586
14587         # perform 2 reads and writes so MAX is different from SUM.
14588         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14589         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14590         cancel_lru_locks osc
14591         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14592         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14593
14594         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14595         stack_trap "rm -f $TMP/$tfile.tmp"
14596         while read name count samp unit min max sum sumsq; do
14597                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14598                 eval $name=$count || error "Wrong proc format"
14599
14600                 case $name in
14601                 read_bytes|write_bytes)
14602                         [[ "$unit" =~ "bytes" ]] ||
14603                                 error "unit is not 'bytes': $unit"
14604                         (( $count == 2 )) || error "count is not 2: $count"
14605                         (( $min == $PAGE_SIZE )) ||
14606                                 error "min is not $PAGE_SIZE: $min"
14607                         (( $max == $PAGE_SIZE )) ||
14608                                 error "max is not $PAGE_SIZE: $max"
14609                         (( $sum == $PAGE_SIZE * 2 )) ||
14610                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14611                         ;;
14612                 read|write)
14613                         [[ "$unit" =~ "usec" ]] ||
14614                                 error "unit is not 'usec': $unit"
14615                         ;;
14616                 *)      ;;
14617                 esac
14618         done < $TMP/$tfile.tmp
14619
14620         #check that we actually got some stats
14621         [ "$read_bytes" ] || error "Missing read_bytes stats"
14622         [ "$write_bytes" ] || error "Missing write_bytes stats"
14623         [ "$read_bytes" != 0 ] || error "no read done"
14624         [ "$write_bytes" != 0 ] || error "no write done"
14625 }
14626 run_test 127b "verify the llite client stats are sane"
14627
14628 test_127c() { # LU-12394
14629         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14630         local size
14631         local bsize
14632         local reads
14633         local writes
14634         local count
14635
14636         $LCTL set_param llite.*.extents_stats=1
14637         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14638
14639         # Use two stripes so there is enough space in default config
14640         $LFS setstripe -c 2 $DIR/$tfile
14641
14642         # Extent stats start at 0-4K and go in power of two buckets
14643         # LL_HIST_START = 12 --> 2^12 = 4K
14644         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14645         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14646         # small configs
14647         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14648                 do
14649                 # Write and read, 2x each, second time at a non-zero offset
14650                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14651                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14652                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14653                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14654                 rm -f $DIR/$tfile
14655         done
14656
14657         $LCTL get_param llite.*.extents_stats
14658
14659         count=2
14660         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14661                 do
14662                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14663                                 grep -m 1 $bsize)
14664                 reads=$(echo $bucket | awk '{print $5}')
14665                 writes=$(echo $bucket | awk '{print $9}')
14666                 [ "$reads" -eq $count ] ||
14667                         error "$reads reads in < $bsize bucket, expect $count"
14668                 [ "$writes" -eq $count ] ||
14669                         error "$writes writes in < $bsize bucket, expect $count"
14670         done
14671
14672         # Test mmap write and read
14673         $LCTL set_param llite.*.extents_stats=c
14674         size=512
14675         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14676         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14677         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14678
14679         $LCTL get_param llite.*.extents_stats
14680
14681         count=$(((size*1024) / PAGE_SIZE))
14682
14683         bsize=$((2 * PAGE_SIZE / 1024))K
14684
14685         bucket=$($LCTL get_param -n llite.*.extents_stats |
14686                         grep -m 1 $bsize)
14687         reads=$(echo $bucket | awk '{print $5}')
14688         writes=$(echo $bucket | awk '{print $9}')
14689         # mmap writes fault in the page first, creating an additonal read
14690         [ "$reads" -eq $((2 * count)) ] ||
14691                 error "$reads reads in < $bsize bucket, expect $count"
14692         [ "$writes" -eq $count ] ||
14693                 error "$writes writes in < $bsize bucket, expect $count"
14694 }
14695 run_test 127c "test llite extent stats with regular & mmap i/o"
14696
14697 test_128() { # bug 15212
14698         touch $DIR/$tfile
14699         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14700                 find $DIR/$tfile
14701                 find $DIR/$tfile
14702         EOF
14703
14704         result=$(grep error $TMP/$tfile.log)
14705         rm -f $DIR/$tfile $TMP/$tfile.log
14706         [ -z "$result" ] ||
14707                 error "consecutive find's under interactive lfs failed"
14708 }
14709 run_test 128 "interactive lfs for 2 consecutive find's"
14710
14711 set_dir_limits () {
14712         local mntdev
14713         local canondev
14714         local node
14715
14716         local ldproc=/proc/fs/ldiskfs
14717         local facets=$(get_facets MDS)
14718
14719         for facet in ${facets//,/ }; do
14720                 canondev=$(ldiskfs_canon \
14721                            *.$(convert_facet2label $facet).mntdev $facet)
14722                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14723                         ldproc=/sys/fs/ldiskfs
14724                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14725                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14726         done
14727 }
14728
14729 check_mds_dmesg() {
14730         local facets=$(get_facets MDS)
14731         for facet in ${facets//,/ }; do
14732                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14733         done
14734         return 1
14735 }
14736
14737 test_129() {
14738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14739         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14740                 skip "Need MDS version with at least 2.5.56"
14741         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14742                 skip_env "ldiskfs only test"
14743         fi
14744         remote_mds_nodsh && skip "remote MDS with nodsh"
14745
14746         local ENOSPC=28
14747         local has_warning=false
14748
14749         rm -rf $DIR/$tdir
14750         mkdir -p $DIR/$tdir
14751
14752         # block size of mds1
14753         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14754         set_dir_limits $maxsize $((maxsize * 6 / 8))
14755         stack_trap "set_dir_limits 0 0"
14756         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14757         local dirsize=$(stat -c%s "$DIR/$tdir")
14758         local nfiles=0
14759         while (( $dirsize <= $maxsize )); do
14760                 $MCREATE $DIR/$tdir/file_base_$nfiles
14761                 rc=$?
14762                 # check two errors:
14763                 # ENOSPC for ext4 max_dir_size, which has been used since
14764                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14765                 if (( rc == ENOSPC )); then
14766                         set_dir_limits 0 0
14767                         echo "rc=$rc returned as expected after $nfiles files"
14768
14769                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14770                                 error "create failed w/o dir size limit"
14771
14772                         # messages may be rate limited if test is run repeatedly
14773                         check_mds_dmesg '"is approaching max"' ||
14774                                 echo "warning message should be output"
14775                         check_mds_dmesg '"has reached max"' ||
14776                                 echo "reached message should be output"
14777
14778                         dirsize=$(stat -c%s "$DIR/$tdir")
14779
14780                         [[ $dirsize -ge $maxsize ]] && return 0
14781                         error "dirsize $dirsize < $maxsize after $nfiles files"
14782                 elif (( rc != 0 )); then
14783                         break
14784                 fi
14785                 nfiles=$((nfiles + 1))
14786                 dirsize=$(stat -c%s "$DIR/$tdir")
14787         done
14788
14789         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14790 }
14791 run_test 129 "test directory size limit ========================"
14792
14793 OLDIFS="$IFS"
14794 cleanup_130() {
14795         trap 0
14796         IFS="$OLDIFS"
14797         rm -f $DIR/$tfile
14798 }
14799
14800 test_130a() {
14801         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14802         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14803
14804         trap cleanup_130 EXIT RETURN
14805
14806         local fm_file=$DIR/$tfile
14807         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14808         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14809                 error "dd failed for $fm_file"
14810
14811         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14812         filefrag -ves $fm_file
14813         local rc=$?
14814         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14815                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14816         (( $rc == 0 )) || error "filefrag $fm_file failed"
14817
14818         filefrag_op=$(filefrag -ve -k $fm_file |
14819                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14820         local lun=$($LFS getstripe -i $fm_file)
14821
14822         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14823         IFS=$'\n'
14824         local tot_len=0
14825         for line in $filefrag_op; do
14826                 local frag_lun=$(echo $line | cut -d: -f5)
14827                 local ext_len=$(echo $line | cut -d: -f4)
14828
14829                 if (( $frag_lun != $lun )); then
14830                         error "FIEMAP on 1-stripe file($fm_file) failed"
14831                         return
14832                 fi
14833                 (( tot_len += ext_len ))
14834         done
14835
14836         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14837                 error "FIEMAP on 1-stripe file($fm_file) failed"
14838                 return
14839         fi
14840
14841         echo "FIEMAP on single striped file succeeded"
14842 }
14843 run_test 130a "FIEMAP (1-stripe file)"
14844
14845 test_130b() {
14846         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14847
14848         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14849         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14850         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14851                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14852
14853         trap cleanup_130 EXIT RETURN
14854
14855         local fm_file=$DIR/$tfile
14856         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14857                 error "setstripe on $fm_file"
14858
14859         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14860                 error "dd failed on $fm_file"
14861
14862         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14863         filefrag_op=$(filefrag -ve -k $fm_file |
14864                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14865
14866         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14867                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14868
14869         IFS=$'\n'
14870         local tot_len=0
14871         local num_luns=1
14872
14873         for line in $filefrag_op; do
14874                 local frag_lun=$(echo $line | cut -d: -f5 |
14875                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14876                 local ext_len=$(echo $line | cut -d: -f4)
14877                 if (( $frag_lun != $last_lun )); then
14878                         if (( tot_len != 1024 )); then
14879                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14880                                 return
14881                         else
14882                                 (( num_luns += 1 ))
14883                                 tot_len=0
14884                         fi
14885                 fi
14886                 (( tot_len += ext_len ))
14887                 last_lun=$frag_lun
14888         done
14889         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14890                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14891                 return
14892         fi
14893
14894         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14895 }
14896 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14897
14898 test_130c() {
14899         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14900
14901         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14902         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14903         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14904                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14905
14906         trap cleanup_130 EXIT RETURN
14907
14908         local fm_file=$DIR/$tfile
14909         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14910
14911         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14912                 error "dd failed on $fm_file"
14913
14914         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14915         filefrag_op=$(filefrag -ve -k $fm_file |
14916                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14917
14918         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14919                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14920
14921         IFS=$'\n'
14922         local tot_len=0
14923         local num_luns=1
14924         for line in $filefrag_op; do
14925                 local frag_lun=$(echo $line | cut -d: -f5 |
14926                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14927                 local ext_len=$(echo $line | cut -d: -f4)
14928                 if (( $frag_lun != $last_lun )); then
14929                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14930                         if (( logical != 512 )); then
14931                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14932                                 return
14933                         fi
14934                         if (( tot_len != 512 )); then
14935                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14936                                 return
14937                         else
14938                                 (( num_luns += 1 ))
14939                                 tot_len=0
14940                         fi
14941                 fi
14942                 (( tot_len += ext_len ))
14943                 last_lun=$frag_lun
14944         done
14945         if (( num_luns != 2 || tot_len != 512 )); then
14946                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14947                 return
14948         fi
14949
14950         echo "FIEMAP on 2-stripe file with hole succeeded"
14951 }
14952 run_test 130c "FIEMAP (2-stripe file with hole)"
14953
14954 test_130d() {
14955         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14956
14957         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14958         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14959         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14960                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14961
14962         trap cleanup_130 EXIT RETURN
14963
14964         local fm_file=$DIR/$tfile
14965         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14966                         error "setstripe on $fm_file"
14967
14968         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14969         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14970                 error "dd failed on $fm_file"
14971
14972         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14973         filefrag_op=$(filefrag -ve -k $fm_file |
14974                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14975
14976         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14977                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14978
14979         IFS=$'\n'
14980         local tot_len=0
14981         local num_luns=1
14982         for line in $filefrag_op; do
14983                 local frag_lun=$(echo $line | cut -d: -f5 |
14984                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14985                 local ext_len=$(echo $line | cut -d: -f4)
14986                 if (( $frag_lun != $last_lun )); then
14987                         if (( tot_len != 1024 )); then
14988                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14989                                 return
14990                         else
14991                                 (( num_luns += 1 ))
14992                                 local tot_len=0
14993                         fi
14994                 fi
14995                 (( tot_len += ext_len ))
14996                 last_lun=$frag_lun
14997         done
14998         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14999                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15000                 return
15001         fi
15002
15003         echo "FIEMAP on N-stripe file succeeded"
15004 }
15005 run_test 130d "FIEMAP (N-stripe file)"
15006
15007 test_130e() {
15008         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15009
15010         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15011         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15012         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15013                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15014
15015         trap cleanup_130 EXIT RETURN
15016
15017         local fm_file=$DIR/$tfile
15018         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15019         stack_trap "rm -f $fm_file"
15020
15021         local num_blks=512
15022         local expected_len=$(( (num_blks / 2) * 64 ))
15023         for ((i = 0; i < $num_blks; i++)); do
15024                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15025                         conv=notrunc > /dev/null 2>&1
15026         done
15027
15028         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15029         filefrag_op=$(filefrag -ve -k $fm_file |
15030                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15031
15032         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15033
15034         IFS=$'\n'
15035         local tot_len=0
15036         local num_luns=1
15037         for line in $filefrag_op; do
15038                 local frag_lun=$(echo $line | cut -d: -f5)
15039                 local ext_len=$(echo $line | cut -d: -f4)
15040                 if (( $frag_lun != $last_lun )); then
15041                         if (( tot_len != $expected_len )); then
15042                                 error "OST$last_lun $tot_len != $expected_len"
15043                         else
15044                                 (( num_luns += 1 ))
15045                                 tot_len=0
15046                         fi
15047                 fi
15048                 (( tot_len += ext_len ))
15049                 last_lun=$frag_lun
15050         done
15051         if (( num_luns != 2 || tot_len != $expected_len )); then
15052                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15053         fi
15054
15055         echo "FIEMAP with continuation calls succeeded"
15056 }
15057 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15058
15059 test_130f() {
15060         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15061         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15062         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15063                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15064
15065         local fm_file=$DIR/$tfile
15066         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15067                 error "multiop create with lov_delay_create on $fm_file"
15068
15069         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15070         filefrag_extents=$(filefrag -vek $fm_file |
15071                            awk '/extents? found/ { print $2 }')
15072         if (( $filefrag_extents != 0 )); then
15073                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15074         fi
15075
15076         rm -f $fm_file
15077 }
15078 run_test 130f "FIEMAP (unstriped file)"
15079
15080 test_130g() {
15081         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15082                 skip "Need MDS version with at least 2.12.53 for overstriping"
15083         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15084         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15085         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15086                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15087
15088         local file=$DIR/$tfile
15089         local nr=$((OSTCOUNT * 100))
15090
15091         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15092
15093         stack_trap "rm -f $file"
15094         dd if=/dev/zero of=$file count=$nr bs=1M
15095         sync
15096         nr=$($LFS getstripe -c $file)
15097
15098         local extents=$(filefrag -v $file |
15099                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15100
15101         echo "filefrag list $extents extents in file with stripecount $nr"
15102         if (( extents < nr )); then
15103                 $LFS getstripe $file
15104                 filefrag -v $file
15105                 error "filefrag printed $extents < $nr extents"
15106         fi
15107 }
15108 run_test 130g "FIEMAP (overstripe file)"
15109
15110 # Test for writev/readv
15111 test_131a() {
15112         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15113                 error "writev test failed"
15114         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15115                 error "readv failed"
15116         rm -f $DIR/$tfile
15117 }
15118 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15119
15120 test_131b() {
15121         local fsize=$((524288 + 1048576 + 1572864))
15122         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15123                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15124                         error "append writev test failed"
15125
15126         ((fsize += 1572864 + 1048576))
15127         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15128                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15129                         error "append writev test failed"
15130         rm -f $DIR/$tfile
15131 }
15132 run_test 131b "test append writev"
15133
15134 test_131c() {
15135         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15136         error "NOT PASS"
15137 }
15138 run_test 131c "test read/write on file w/o objects"
15139
15140 test_131d() {
15141         rwv -f $DIR/$tfile -w -n 1 1572864
15142         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15143         if [ "$NOB" != 1572864 ]; then
15144                 error "Short read filed: read $NOB bytes instead of 1572864"
15145         fi
15146         rm -f $DIR/$tfile
15147 }
15148 run_test 131d "test short read"
15149
15150 test_131e() {
15151         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15152         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15153         error "read hitting hole failed"
15154         rm -f $DIR/$tfile
15155 }
15156 run_test 131e "test read hitting hole"
15157
15158 check_stats() {
15159         local facet=$1
15160         local op=$2
15161         local want=${3:-0}
15162         local res
15163
15164         # open             11 samples [usecs] 468 4793 13658 35791898
15165         case $facet in
15166         mds*) res=($(do_facet $facet \
15167                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15168                  ;;
15169         ost*) res=($(do_facet $facet \
15170                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15171                  ;;
15172         *) error "Wrong facet '$facet'" ;;
15173         esac
15174         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15175         # if $want is zero, it means any stat increment is ok.
15176         if (( $want > 0 )); then
15177                 local count=${res[1]}
15178
15179                 if (( $count != $want )); then
15180                         if [[ $facet =~ "mds" ]]; then
15181                                 do_nodes $(comma_list $(mdts_nodes)) \
15182                                         $LCTL get_param mdt.*.md_stats
15183                         else
15184                                 do_nodes $(comma_list $(osts-nodes)) \
15185                                         $LCTL get_param obdfilter.*.stats
15186                         fi
15187                         error "The $op counter on $facet is $count, not $want"
15188                 fi
15189         fi
15190 }
15191
15192 test_133a() {
15193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15194         remote_ost_nodsh && skip "remote OST with nodsh"
15195         remote_mds_nodsh && skip "remote MDS with nodsh"
15196         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15197                 skip_env "MDS doesn't support rename stats"
15198
15199         local testdir=$DIR/${tdir}/stats_testdir
15200
15201         mkdir -p $DIR/${tdir}
15202
15203         # clear stats.
15204         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15205         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15206
15207         # verify mdt stats first.
15208         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15209         check_stats $SINGLEMDS "mkdir" 1
15210
15211         # clear "open" from "lfs mkdir" above
15212         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15213         touch ${testdir}/${tfile} || error "touch failed"
15214         check_stats $SINGLEMDS "open" 1
15215         check_stats $SINGLEMDS "close" 1
15216         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15217                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15218                 check_stats $SINGLEMDS "mknod" 2
15219         }
15220         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15221         check_stats $SINGLEMDS "unlink" 1
15222         rm -f ${testdir}/${tfile} || error "file remove failed"
15223         check_stats $SINGLEMDS "unlink" 2
15224
15225         # remove working dir and check mdt stats again.
15226         rmdir ${testdir} || error "rmdir failed"
15227         check_stats $SINGLEMDS "rmdir" 1
15228
15229         local testdir1=$DIR/${tdir}/stats_testdir1
15230         mkdir_on_mdt0 -p ${testdir}
15231         mkdir_on_mdt0 -p ${testdir1}
15232         touch ${testdir1}/test1
15233         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15234         check_stats $SINGLEMDS "crossdir_rename" 1
15235
15236         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15237         check_stats $SINGLEMDS "samedir_rename" 1
15238
15239         rm -rf $DIR/${tdir}
15240 }
15241 run_test 133a "Verifying MDT stats ========================================"
15242
15243 test_133b() {
15244         local res
15245
15246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15247         remote_ost_nodsh && skip "remote OST with nodsh"
15248         remote_mds_nodsh && skip "remote MDS with nodsh"
15249
15250         local testdir=$DIR/${tdir}/stats_testdir
15251
15252         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15253         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15254         touch ${testdir}/${tfile} || error "touch failed"
15255         cancel_lru_locks mdc
15256
15257         # clear stats.
15258         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15259         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15260
15261         # extra mdt stats verification.
15262         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15263         check_stats $SINGLEMDS "setattr" 1
15264         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15265         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15266         then            # LU-1740
15267                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15268                 check_stats $SINGLEMDS "getattr" 1
15269         fi
15270         rm -rf $DIR/${tdir}
15271
15272         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15273         # so the check below is not reliable
15274         [ $MDSCOUNT -eq 1 ] || return 0
15275
15276         # Sleep to avoid a cached response.
15277         #define OBD_STATFS_CACHE_SECONDS 1
15278         sleep 2
15279         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15280         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15281         $LFS df || error "lfs failed"
15282         check_stats $SINGLEMDS "statfs" 1
15283
15284         # check aggregated statfs (LU-10018)
15285         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15286                 return 0
15287         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15288                 return 0
15289         sleep 2
15290         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15291         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15292         df $DIR
15293         check_stats $SINGLEMDS "statfs" 1
15294
15295         # We want to check that the client didn't send OST_STATFS to
15296         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15297         # extra care is needed here.
15298         if remote_mds; then
15299                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15300                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15301
15302                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15303                 [ "$res" ] && error "OST got STATFS"
15304         fi
15305
15306         return 0
15307 }
15308 run_test 133b "Verifying extra MDT stats =================================="
15309
15310 test_133c() {
15311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15312         remote_ost_nodsh && skip "remote OST with nodsh"
15313         remote_mds_nodsh && skip "remote MDS with nodsh"
15314
15315         local testdir=$DIR/$tdir/stats_testdir
15316
15317         test_mkdir -p $testdir
15318
15319         # verify obdfilter stats.
15320         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15321         sync
15322         cancel_lru_locks osc
15323         wait_delete_completed
15324
15325         # clear stats.
15326         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15327         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15328
15329         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15330                 error "dd failed"
15331         sync
15332         cancel_lru_locks osc
15333         check_stats ost1 "write" 1
15334
15335         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15336         check_stats ost1 "read" 1
15337
15338         > $testdir/$tfile || error "truncate failed"
15339         check_stats ost1 "punch" 1
15340
15341         rm -f $testdir/$tfile || error "file remove failed"
15342         wait_delete_completed
15343         check_stats ost1 "destroy" 1
15344
15345         rm -rf $DIR/$tdir
15346 }
15347 run_test 133c "Verifying OST stats ========================================"
15348
15349 order_2() {
15350         local value=$1
15351         local orig=$value
15352         local order=1
15353
15354         while [ $value -ge 2 ]; do
15355                 order=$((order*2))
15356                 value=$((value/2))
15357         done
15358
15359         if [ $orig -gt $order ]; then
15360                 order=$((order*2))
15361         fi
15362         echo $order
15363 }
15364
15365 size_in_KMGT() {
15366     local value=$1
15367     local size=('K' 'M' 'G' 'T');
15368     local i=0
15369     local size_string=$value
15370
15371     while [ $value -ge 1024 ]; do
15372         if [ $i -gt 3 ]; then
15373             #T is the biggest unit we get here, if that is bigger,
15374             #just return XXXT
15375             size_string=${value}T
15376             break
15377         fi
15378         value=$((value >> 10))
15379         if [ $value -lt 1024 ]; then
15380             size_string=${value}${size[$i]}
15381             break
15382         fi
15383         i=$((i + 1))
15384     done
15385
15386     echo $size_string
15387 }
15388
15389 get_rename_size() {
15390         local size=$1
15391         local context=${2:-.}
15392         local sample=$(do_facet $SINGLEMDS $LCTL \
15393                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15394                 grep -A1 $context |
15395                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15396         echo $sample
15397 }
15398
15399 test_133d() {
15400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15401         remote_ost_nodsh && skip "remote OST with nodsh"
15402         remote_mds_nodsh && skip "remote MDS with nodsh"
15403         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15404                 skip_env "MDS doesn't support rename stats"
15405
15406         local testdir1=$DIR/${tdir}/stats_testdir1
15407         local testdir2=$DIR/${tdir}/stats_testdir2
15408         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15409
15410         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15411
15412         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15413         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15414
15415         createmany -o $testdir1/test 512 || error "createmany failed"
15416
15417         # check samedir rename size
15418         mv ${testdir1}/test0 ${testdir1}/test_0
15419
15420         local testdir1_size=$(ls -l $DIR/${tdir} |
15421                 awk '/stats_testdir1/ {print $5}')
15422         local testdir2_size=$(ls -l $DIR/${tdir} |
15423                 awk '/stats_testdir2/ {print $5}')
15424
15425         testdir1_size=$(order_2 $testdir1_size)
15426         testdir2_size=$(order_2 $testdir2_size)
15427
15428         testdir1_size=$(size_in_KMGT $testdir1_size)
15429         testdir2_size=$(size_in_KMGT $testdir2_size)
15430
15431         echo "source rename dir size: ${testdir1_size}"
15432         echo "target rename dir size: ${testdir2_size}"
15433
15434         local cmd="do_facet $SINGLEMDS $LCTL "
15435         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15436
15437         eval $cmd || error "$cmd failed"
15438         local samedir=$($cmd | grep 'same_dir')
15439         local same_sample=$(get_rename_size $testdir1_size)
15440         [ -z "$samedir" ] && error "samedir_rename_size count error"
15441         [[ $same_sample -eq 1 ]] ||
15442                 error "samedir_rename_size error $same_sample"
15443         echo "Check same dir rename stats success"
15444
15445         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15446
15447         # check crossdir rename size
15448         mv ${testdir1}/test_0 ${testdir2}/test_0
15449
15450         testdir1_size=$(ls -l $DIR/${tdir} |
15451                 awk '/stats_testdir1/ {print $5}')
15452         testdir2_size=$(ls -l $DIR/${tdir} |
15453                 awk '/stats_testdir2/ {print $5}')
15454
15455         testdir1_size=$(order_2 $testdir1_size)
15456         testdir2_size=$(order_2 $testdir2_size)
15457
15458         testdir1_size=$(size_in_KMGT $testdir1_size)
15459         testdir2_size=$(size_in_KMGT $testdir2_size)
15460
15461         echo "source rename dir size: ${testdir1_size}"
15462         echo "target rename dir size: ${testdir2_size}"
15463
15464         eval $cmd || error "$cmd failed"
15465         local crossdir=$($cmd | grep 'crossdir')
15466         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15467         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15468         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15469         [[ $src_sample -eq 1 ]] ||
15470                 error "crossdir_rename_size error $src_sample"
15471         [[ $tgt_sample -eq 1 ]] ||
15472                 error "crossdir_rename_size error $tgt_sample"
15473         echo "Check cross dir rename stats success"
15474         rm -rf $DIR/${tdir}
15475 }
15476 run_test 133d "Verifying rename_stats ========================================"
15477
15478 test_133e() {
15479         remote_mds_nodsh && skip "remote MDS with nodsh"
15480         remote_ost_nodsh && skip "remote OST with nodsh"
15481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15482
15483         local testdir=$DIR/${tdir}/stats_testdir
15484         local ctr f0 f1 bs=32768 count=42 sum
15485
15486         mkdir -p ${testdir} || error "mkdir failed"
15487
15488         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15489
15490         for ctr in {write,read}_bytes; do
15491                 sync
15492                 cancel_lru_locks osc
15493
15494                 do_facet ost1 $LCTL set_param -n \
15495                         "obdfilter.*.exports.clear=clear"
15496
15497                 if [ $ctr = write_bytes ]; then
15498                         f0=/dev/zero
15499                         f1=${testdir}/${tfile}
15500                 else
15501                         f0=${testdir}/${tfile}
15502                         f1=/dev/null
15503                 fi
15504
15505                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15506                         error "dd failed"
15507                 sync
15508                 cancel_lru_locks osc
15509
15510                 sum=$(do_facet ost1 $LCTL get_param \
15511                         "obdfilter.*.exports.*.stats" |
15512                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15513                                 $1 == ctr { sum += $7 }
15514                                 END { printf("%0.0f", sum) }')
15515
15516                 if ((sum != bs * count)); then
15517                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15518                 fi
15519         done
15520
15521         rm -rf $DIR/${tdir}
15522 }
15523 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15524
15525 test_133f() {
15526         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15527                 skip "too old lustre for get_param -R ($facet_ver)"
15528
15529         # verifying readability.
15530         $LCTL get_param -R '*' &> /dev/null
15531
15532         # Verifing writability with badarea_io.
15533         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15534         local skipped_params='force_lbug|changelog_mask|daemon_file'
15535         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15536                 egrep -v "$skipped_params" |
15537                 xargs -n 1 find $proc_dirs -name |
15538                 xargs -n 1 badarea_io ||
15539                 error "client badarea_io failed"
15540
15541         # remount the FS in case writes/reads /proc break the FS
15542         cleanup || error "failed to unmount"
15543         setup || error "failed to setup"
15544 }
15545 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15546
15547 test_133g() {
15548         remote_mds_nodsh && skip "remote MDS with nodsh"
15549         remote_ost_nodsh && skip "remote OST with nodsh"
15550
15551         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15552         local proc_dirs_str=$(eval echo $proc_dirs)
15553         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15554         local facet
15555         for facet in mds1 ost1; do
15556                 local facet_ver=$(lustre_version_code $facet)
15557                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15558                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15559                 else
15560                         log "$facet: too old lustre for get_param -R"
15561                 fi
15562                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15563                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15564                                 tr -d = | egrep -v $skipped_params |
15565                                 xargs -n 1 find $proc_dirs_str -name |
15566                                 xargs -n 1 badarea_io" ||
15567                                         error "$facet badarea_io failed"
15568                 else
15569                         skip_noexit "$facet: too old lustre for get_param -R"
15570                 fi
15571         done
15572
15573         # remount the FS in case writes/reads /proc break the FS
15574         cleanup || error "failed to unmount"
15575         setup || error "failed to setup"
15576 }
15577 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15578
15579 test_133h() {
15580         remote_mds_nodsh && skip "remote MDS with nodsh"
15581         remote_ost_nodsh && skip "remote OST with nodsh"
15582         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15583                 skip "Need MDS version at least 2.9.54"
15584
15585         local facet
15586         for facet in client mds1 ost1; do
15587                 # Get the list of files that are missing the terminating newline
15588                 local plist=$(do_facet $facet
15589                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15590                 local ent
15591                 for ent in $plist; do
15592                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15593                                 awk -v FS='\v' -v RS='\v\v' \
15594                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15595                                         print FILENAME}'" 2>/dev/null)
15596                         [ -z $missing ] || {
15597                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15598                                 error "file does not end with newline: $facet-$ent"
15599                         }
15600                 done
15601         done
15602 }
15603 run_test 133h "Proc files should end with newlines"
15604
15605 test_134a() {
15606         remote_mds_nodsh && skip "remote MDS with nodsh"
15607         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15608                 skip "Need MDS version at least 2.7.54"
15609
15610         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15611         cancel_lru_locks mdc
15612
15613         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15614         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15615         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15616
15617         local nr=1000
15618         createmany -o $DIR/$tdir/f $nr ||
15619                 error "failed to create $nr files in $DIR/$tdir"
15620         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15621
15622         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15623         do_facet mds1 $LCTL set_param fail_loc=0x327
15624         do_facet mds1 $LCTL set_param fail_val=500
15625         touch $DIR/$tdir/m
15626
15627         echo "sleep 10 seconds ..."
15628         sleep 10
15629         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15630
15631         do_facet mds1 $LCTL set_param fail_loc=0
15632         do_facet mds1 $LCTL set_param fail_val=0
15633         [ $lck_cnt -lt $unused ] ||
15634                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15635
15636         rm $DIR/$tdir/m
15637         unlinkmany $DIR/$tdir/f $nr
15638 }
15639 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15640
15641 test_134b() {
15642         remote_mds_nodsh && skip "remote MDS with nodsh"
15643         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15644                 skip "Need MDS version at least 2.7.54"
15645
15646         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15647         cancel_lru_locks mdc
15648
15649         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15650                         ldlm.lock_reclaim_threshold_mb)
15651         # disable reclaim temporarily
15652         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15653
15654         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15655         do_facet mds1 $LCTL set_param fail_loc=0x328
15656         do_facet mds1 $LCTL set_param fail_val=500
15657
15658         $LCTL set_param debug=+trace
15659
15660         local nr=600
15661         createmany -o $DIR/$tdir/f $nr &
15662         local create_pid=$!
15663
15664         echo "Sleep $TIMEOUT seconds ..."
15665         sleep $TIMEOUT
15666         if ! ps -p $create_pid  > /dev/null 2>&1; then
15667                 do_facet mds1 $LCTL set_param fail_loc=0
15668                 do_facet mds1 $LCTL set_param fail_val=0
15669                 do_facet mds1 $LCTL set_param \
15670                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15671                 error "createmany finished incorrectly!"
15672         fi
15673         do_facet mds1 $LCTL set_param fail_loc=0
15674         do_facet mds1 $LCTL set_param fail_val=0
15675         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15676         wait $create_pid || return 1
15677
15678         unlinkmany $DIR/$tdir/f $nr
15679 }
15680 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15681
15682 test_135() {
15683         remote_mds_nodsh && skip "remote MDS with nodsh"
15684         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15685                 skip "Need MDS version at least 2.13.50"
15686         local fname
15687
15688         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15689
15690 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15691         #set only one record at plain llog
15692         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15693
15694         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15695
15696         #fill already existed plain llog each 64767
15697         #wrapping whole catalog
15698         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15699
15700         createmany -o $DIR/$tdir/$tfile_ 64700
15701         for (( i = 0; i < 64700; i = i + 2 ))
15702         do
15703                 rm $DIR/$tdir/$tfile_$i &
15704                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15705                 local pid=$!
15706                 wait $pid
15707         done
15708
15709         #waiting osp synchronization
15710         wait_delete_completed
15711 }
15712 run_test 135 "Race catalog processing"
15713
15714 test_136() {
15715         remote_mds_nodsh && skip "remote MDS with nodsh"
15716         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15717                 skip "Need MDS version at least 2.13.50"
15718         local fname
15719
15720         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15721         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15722         #set only one record at plain llog
15723 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15724         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15725
15726         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15727
15728         #fill already existed 2 plain llogs each 64767
15729         #wrapping whole catalog
15730         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15731         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15732         wait_delete_completed
15733
15734         createmany -o $DIR/$tdir/$tfile_ 10
15735         sleep 25
15736
15737         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15738         for (( i = 0; i < 10; i = i + 3 ))
15739         do
15740                 rm $DIR/$tdir/$tfile_$i &
15741                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15742                 local pid=$!
15743                 wait $pid
15744                 sleep 7
15745                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15746         done
15747
15748         #waiting osp synchronization
15749         wait_delete_completed
15750 }
15751 run_test 136 "Race catalog processing 2"
15752
15753 test_140() { #bug-17379
15754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15755
15756         test_mkdir $DIR/$tdir
15757         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15758         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15759
15760         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15761         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15762         local i=0
15763         while i=$((i + 1)); do
15764                 test_mkdir $i
15765                 cd $i || error "Changing to $i"
15766                 ln -s ../stat stat || error "Creating stat symlink"
15767                 # Read the symlink until ELOOP present,
15768                 # not LBUGing the system is considered success,
15769                 # we didn't overrun the stack.
15770                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15771                 if [ $ret -ne 0 ]; then
15772                         if [ $ret -eq 40 ]; then
15773                                 break  # -ELOOP
15774                         else
15775                                 error "Open stat symlink"
15776                                         return
15777                         fi
15778                 fi
15779         done
15780         i=$((i - 1))
15781         echo "The symlink depth = $i"
15782         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15783                 error "Invalid symlink depth"
15784
15785         # Test recursive symlink
15786         ln -s symlink_self symlink_self
15787         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15788         echo "open symlink_self returns $ret"
15789         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15790 }
15791 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15792
15793 test_150a() {
15794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15795
15796         local TF="$TMP/$tfile"
15797
15798         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15799         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15800         cp $TF $DIR/$tfile
15801         cancel_lru_locks $OSC
15802         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15803         remount_client $MOUNT
15804         df -P $MOUNT
15805         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15806
15807         $TRUNCATE $TF 6000
15808         $TRUNCATE $DIR/$tfile 6000
15809         cancel_lru_locks $OSC
15810         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15811
15812         echo "12345" >>$TF
15813         echo "12345" >>$DIR/$tfile
15814         cancel_lru_locks $OSC
15815         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15816
15817         echo "12345" >>$TF
15818         echo "12345" >>$DIR/$tfile
15819         cancel_lru_locks $OSC
15820         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15821 }
15822 run_test 150a "truncate/append tests"
15823
15824 test_150b() {
15825         check_set_fallocate_or_skip
15826         local out
15827
15828         touch $DIR/$tfile
15829         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15830         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15831                 skip_eopnotsupp "$out|check_fallocate failed"
15832 }
15833 run_test 150b "Verify fallocate (prealloc) functionality"
15834
15835 test_150bb() {
15836         check_set_fallocate_or_skip
15837
15838         touch $DIR/$tfile
15839         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15840         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15841         > $DIR/$tfile
15842         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15843         # precomputed md5sum for 20MB of zeroes
15844         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15845         local sum=($(md5sum $DIR/$tfile))
15846
15847         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15848
15849         check_set_fallocate 1
15850
15851         > $DIR/$tfile
15852         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15853         sum=($(md5sum $DIR/$tfile))
15854
15855         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15856 }
15857 run_test 150bb "Verify fallocate modes both zero space"
15858
15859 test_150c() {
15860         check_set_fallocate_or_skip
15861         local striping="-c2"
15862
15863         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15864         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15865         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15866         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15867         local want=$((OSTCOUNT * 1048576))
15868
15869         # Must allocate all requested space, not more than 5% extra
15870         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15871                 error "bytes $bytes is not $want"
15872
15873         rm -f $DIR/$tfile
15874
15875         echo "verify fallocate on PFL file"
15876
15877         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15878
15879         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15880                 error "Create $DIR/$tfile failed"
15881         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15882         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15883         want=$((512 * 1048576))
15884
15885         # Must allocate all requested space, not more than 5% extra
15886         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15887                 error "bytes $bytes is not $want"
15888 }
15889 run_test 150c "Verify fallocate Size and Blocks"
15890
15891 test_150d() {
15892         check_set_fallocate_or_skip
15893         local striping="-c2"
15894
15895         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15896
15897         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15898         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15899                 error "setstripe failed"
15900         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15901         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15902         local want=$((OSTCOUNT * 1048576))
15903
15904         # Must allocate all requested space, not more than 5% extra
15905         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15906                 error "bytes $bytes is not $want"
15907 }
15908 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15909
15910 test_150e() {
15911         check_set_fallocate_or_skip
15912
15913         echo "df before:"
15914         $LFS df
15915         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15916         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15917                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15918
15919         # Find OST with Minimum Size
15920         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15921                        sort -un | head -1)
15922
15923         # Get 100MB per OST of the available space to reduce run time
15924         # else 60% of the available space if we are running SLOW tests
15925         if [ $SLOW == "no" ]; then
15926                 local space=$((1024 * 100 * OSTCOUNT))
15927         else
15928                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15929         fi
15930
15931         fallocate -l${space}k $DIR/$tfile ||
15932                 error "fallocate ${space}k $DIR/$tfile failed"
15933         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15934
15935         # get size immediately after fallocate. This should be correctly
15936         # updated
15937         local size=$(stat -c '%s' $DIR/$tfile)
15938         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15939
15940         # Sleep for a while for statfs to get updated. And not pull from cache.
15941         sleep 2
15942
15943         echo "df after fallocate:"
15944         $LFS df
15945
15946         (( size / 1024 == space )) || error "size $size != requested $space"
15947         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15948                 error "used $used < space $space"
15949
15950         rm $DIR/$tfile || error "rm failed"
15951         sync
15952         wait_delete_completed
15953
15954         echo "df after unlink:"
15955         $LFS df
15956 }
15957 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15958
15959 test_150f() {
15960         local size
15961         local blocks
15962         local want_size_before=20480 # in bytes
15963         local want_blocks_before=40 # 512 sized blocks
15964         local want_blocks_after=24  # 512 sized blocks
15965         local length=$(((want_blocks_before - want_blocks_after) * 512))
15966
15967         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15968                 skip "need at least 2.14.0 for fallocate punch"
15969
15970         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15971                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15972         fi
15973
15974         check_set_fallocate_or_skip
15975         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15976
15977         [[ "x$DOM" == "xyes" ]] &&
15978                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15979
15980         echo "Verify fallocate punch: Range within the file range"
15981         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15982                 error "dd failed for bs 4096 and count 5"
15983
15984         # Call fallocate with punch range which is within the file range
15985         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15986                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15987         # client must see changes immediately after fallocate
15988         size=$(stat -c '%s' $DIR/$tfile)
15989         blocks=$(stat -c '%b' $DIR/$tfile)
15990
15991         # Verify punch worked.
15992         (( blocks == want_blocks_after )) ||
15993                 error "punch failed: blocks $blocks != $want_blocks_after"
15994
15995         (( size == want_size_before )) ||
15996                 error "punch failed: size $size != $want_size_before"
15997
15998         # Verify there is hole in file
15999         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16000         # precomputed md5sum
16001         local expect="4a9a834a2db02452929c0a348273b4aa"
16002
16003         cksum=($(md5sum $DIR/$tfile))
16004         [[ "${cksum[0]}" == "$expect" ]] ||
16005                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16006
16007         # Start second sub-case for fallocate punch.
16008         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16009         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16010                 error "dd failed for bs 4096 and count 5"
16011
16012         # Punch range less than block size will have no change in block count
16013         want_blocks_after=40  # 512 sized blocks
16014
16015         # Punch overlaps two blocks and less than blocksize
16016         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16017                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16018         size=$(stat -c '%s' $DIR/$tfile)
16019         blocks=$(stat -c '%b' $DIR/$tfile)
16020
16021         # Verify punch worked.
16022         (( blocks == want_blocks_after )) ||
16023                 error "punch failed: blocks $blocks != $want_blocks_after"
16024
16025         (( size == want_size_before )) ||
16026                 error "punch failed: size $size != $want_size_before"
16027
16028         # Verify if range is really zero'ed out. We expect Zeros.
16029         # precomputed md5sum
16030         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16031         cksum=($(md5sum $DIR/$tfile))
16032         [[ "${cksum[0]}" == "$expect" ]] ||
16033                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16034 }
16035 run_test 150f "Verify fallocate punch functionality"
16036
16037 test_150g() {
16038         local space
16039         local size
16040         local blocks
16041         local blocks_after
16042         local size_after
16043         local BS=4096 # Block size in bytes
16044
16045         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16046                 skip "need at least 2.14.0 for fallocate punch"
16047
16048         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16049                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16050         fi
16051
16052         check_set_fallocate_or_skip
16053         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16054
16055         if [[ "x$DOM" == "xyes" ]]; then
16056                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16057                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16058         else
16059                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16060                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16061         fi
16062
16063         # Get 100MB per OST of the available space to reduce run time
16064         # else 60% of the available space if we are running SLOW tests
16065         if [ $SLOW == "no" ]; then
16066                 space=$((1024 * 100 * OSTCOUNT))
16067         else
16068                 # Find OST with Minimum Size
16069                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16070                         sort -un | head -1)
16071                 echo "min size OST: $space"
16072                 space=$(((space * 60)/100 * OSTCOUNT))
16073         fi
16074         # space in 1k units, round to 4k blocks
16075         local blkcount=$((space * 1024 / $BS))
16076
16077         echo "Verify fallocate punch: Very large Range"
16078         fallocate -l${space}k $DIR/$tfile ||
16079                 error "fallocate ${space}k $DIR/$tfile failed"
16080         # write 1M at the end, start and in the middle
16081         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16082                 error "dd failed: bs $BS count 256"
16083         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16084                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16085         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16086                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16087
16088         # Gather stats.
16089         size=$(stat -c '%s' $DIR/$tfile)
16090
16091         # gather punch length.
16092         local punch_size=$((size - (BS * 2)))
16093
16094         echo "punch_size = $punch_size"
16095         echo "size - punch_size: $((size - punch_size))"
16096         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16097
16098         # Call fallocate to punch all except 2 blocks. We leave the
16099         # first and the last block
16100         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16101         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16102                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16103
16104         size_after=$(stat -c '%s' $DIR/$tfile)
16105         blocks_after=$(stat -c '%b' $DIR/$tfile)
16106
16107         # Verify punch worked.
16108         # Size should be kept
16109         (( size == size_after )) ||
16110                 error "punch failed: size $size != $size_after"
16111
16112         # two 4k data blocks to remain plus possible 1 extra extent block
16113         (( blocks_after <= ((BS / 512) * 3) )) ||
16114                 error "too many blocks remains: $blocks_after"
16115
16116         # Verify that file has hole between the first and the last blocks
16117         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16118         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16119
16120         echo "Hole at [$hole_start, $hole_end)"
16121         (( hole_start == BS )) ||
16122                 error "no hole at offset $BS after punch"
16123
16124         (( hole_end == BS + punch_size )) ||
16125                 error "data at offset $hole_end < $((BS + punch_size))"
16126 }
16127 run_test 150g "Verify fallocate punch on large range"
16128
16129 test_150h() {
16130         local file=$DIR/$tfile
16131         local size
16132
16133         check_set_fallocate_or_skip
16134         statx_supported || skip_env "Test must be statx() syscall supported"
16135
16136         # fallocate() does not update the size information on the MDT
16137         fallocate -l 16K $file || error "failed to fallocate $file"
16138         cancel_lru_locks $OSC
16139         # STATX with cached-always mode will not send glimpse RPCs to OST,
16140         # it uses the caching attrs on the client side as much as possible.
16141         size=$($STATX --cached=always -c %s $file)
16142         [ $size == 16384 ] ||
16143                 error "size after fallocate() is $size, expected 16384"
16144 }
16145 run_test 150h "Verify extend fallocate updates the file size"
16146
16147 #LU-2902 roc_hit was not able to read all values from lproc
16148 function roc_hit_init() {
16149         local list=$(comma_list $(osts_nodes))
16150         local dir=$DIR/$tdir-check
16151         local file=$dir/$tfile
16152         local BEFORE
16153         local AFTER
16154         local idx
16155
16156         test_mkdir $dir
16157         #use setstripe to do a write to every ost
16158         for i in $(seq 0 $((OSTCOUNT-1))); do
16159                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16160                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16161                 idx=$(printf %04x $i)
16162                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16163                         awk '$1 == "cache_access" {sum += $7}
16164                                 END { printf("%0.0f", sum) }')
16165
16166                 cancel_lru_locks osc
16167                 cat $file >/dev/null
16168
16169                 AFTER=$(get_osd_param $list *OST*$idx stats |
16170                         awk '$1 == "cache_access" {sum += $7}
16171                                 END { printf("%0.0f", sum) }')
16172
16173                 echo BEFORE:$BEFORE AFTER:$AFTER
16174                 if ! let "AFTER - BEFORE == 4"; then
16175                         rm -rf $dir
16176                         error "roc_hit is not safe to use"
16177                 fi
16178                 rm $file
16179         done
16180
16181         rm -rf $dir
16182 }
16183
16184 function roc_hit() {
16185         local list=$(comma_list $(osts_nodes))
16186         echo $(get_osd_param $list '' stats |
16187                 awk '$1 == "cache_hit" {sum += $7}
16188                         END { printf("%0.0f", sum) }')
16189 }
16190
16191 function set_cache() {
16192         local on=1
16193
16194         if [ "$2" == "off" ]; then
16195                 on=0;
16196         fi
16197         local list=$(comma_list $(osts_nodes))
16198         set_osd_param $list '' $1_cache_enable $on
16199
16200         cancel_lru_locks osc
16201 }
16202
16203 test_151() {
16204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16205         remote_ost_nodsh && skip "remote OST with nodsh"
16206         (( CLIENT_VERSION == OST1_VERSION )) ||
16207                 skip "LU-13081: no interop testing for OSS cache"
16208
16209         local CPAGES=3
16210         local list=$(comma_list $(osts_nodes))
16211
16212         # check whether obdfilter is cache capable at all
16213         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16214                 skip "not cache-capable obdfilter"
16215         fi
16216
16217         # check cache is enabled on all obdfilters
16218         if get_osd_param $list '' read_cache_enable | grep 0; then
16219                 skip "oss cache is disabled"
16220         fi
16221
16222         set_osd_param $list '' writethrough_cache_enable 1
16223
16224         # check write cache is enabled on all obdfilters
16225         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16226                 skip "oss write cache is NOT enabled"
16227         fi
16228
16229         roc_hit_init
16230
16231         #define OBD_FAIL_OBD_NO_LRU  0x609
16232         do_nodes $list $LCTL set_param fail_loc=0x609
16233
16234         # pages should be in the case right after write
16235         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16236                 error "dd failed"
16237
16238         local BEFORE=$(roc_hit)
16239         cancel_lru_locks osc
16240         cat $DIR/$tfile >/dev/null
16241         local AFTER=$(roc_hit)
16242
16243         do_nodes $list $LCTL set_param fail_loc=0
16244
16245         if ! let "AFTER - BEFORE == CPAGES"; then
16246                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16247         fi
16248
16249         cancel_lru_locks osc
16250         # invalidates OST cache
16251         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16252         set_osd_param $list '' read_cache_enable 0
16253         cat $DIR/$tfile >/dev/null
16254
16255         # now data shouldn't be found in the cache
16256         BEFORE=$(roc_hit)
16257         cancel_lru_locks osc
16258         cat $DIR/$tfile >/dev/null
16259         AFTER=$(roc_hit)
16260         if let "AFTER - BEFORE != 0"; then
16261                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16262         fi
16263
16264         set_osd_param $list '' read_cache_enable 1
16265         rm -f $DIR/$tfile
16266 }
16267 run_test 151 "test cache on oss and controls ==============================="
16268
16269 test_152() {
16270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16271
16272         local TF="$TMP/$tfile"
16273
16274         # simulate ENOMEM during write
16275 #define OBD_FAIL_OST_NOMEM      0x226
16276         lctl set_param fail_loc=0x80000226
16277         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16278         cp $TF $DIR/$tfile
16279         sync || error "sync failed"
16280         lctl set_param fail_loc=0
16281
16282         # discard client's cache
16283         cancel_lru_locks osc
16284
16285         # simulate ENOMEM during read
16286         lctl set_param fail_loc=0x80000226
16287         cmp $TF $DIR/$tfile || error "cmp failed"
16288         lctl set_param fail_loc=0
16289
16290         rm -f $TF
16291 }
16292 run_test 152 "test read/write with enomem ============================"
16293
16294 test_153() {
16295         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16296 }
16297 run_test 153 "test if fdatasync does not crash ======================="
16298
16299 dot_lustre_fid_permission_check() {
16300         local fid=$1
16301         local ffid=$MOUNT/.lustre/fid/$fid
16302         local test_dir=$2
16303
16304         echo "stat fid $fid"
16305         stat $ffid || error "stat $ffid failed."
16306         echo "touch fid $fid"
16307         touch $ffid || error "touch $ffid failed."
16308         echo "write to fid $fid"
16309         cat /etc/hosts > $ffid || error "write $ffid failed."
16310         echo "read fid $fid"
16311         diff /etc/hosts $ffid || error "read $ffid failed."
16312         echo "append write to fid $fid"
16313         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16314         echo "rename fid $fid"
16315         mv $ffid $test_dir/$tfile.1 &&
16316                 error "rename $ffid to $tfile.1 should fail."
16317         touch $test_dir/$tfile.1
16318         mv $test_dir/$tfile.1 $ffid &&
16319                 error "rename $tfile.1 to $ffid should fail."
16320         rm -f $test_dir/$tfile.1
16321         echo "truncate fid $fid"
16322         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16323         echo "link fid $fid"
16324         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16325         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16326                 id $USER0 || skip_env "missing user $USER0"
16327                 echo "setfacl fid $fid"
16328                 setfacl -R -m u:$USER0:rwx $ffid ||
16329                         error "setfacl $ffid failed"
16330                 echo "getfacl fid $fid"
16331                 getfacl $ffid || error "getfacl $ffid failed."
16332         fi
16333         echo "unlink fid $fid"
16334         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16335         echo "mknod fid $fid"
16336         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16337
16338         fid=[0xf00000400:0x1:0x0]
16339         ffid=$MOUNT/.lustre/fid/$fid
16340
16341         echo "stat non-exist fid $fid"
16342         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16343         echo "write to non-exist fid $fid"
16344         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16345         echo "link new fid $fid"
16346         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16347
16348         mkdir -p $test_dir/$tdir
16349         touch $test_dir/$tdir/$tfile
16350         fid=$($LFS path2fid $test_dir/$tdir)
16351         rc=$?
16352         [ $rc -ne 0 ] &&
16353                 error "error: could not get fid for $test_dir/$dir/$tfile."
16354
16355         ffid=$MOUNT/.lustre/fid/$fid
16356
16357         echo "ls $fid"
16358         ls $ffid || error "ls $ffid failed."
16359         echo "touch $fid/$tfile.1"
16360         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16361
16362         echo "touch $MOUNT/.lustre/fid/$tfile"
16363         touch $MOUNT/.lustre/fid/$tfile && \
16364                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16365
16366         echo "setxattr to $MOUNT/.lustre/fid"
16367         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16368
16369         echo "listxattr for $MOUNT/.lustre/fid"
16370         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16371
16372         echo "delxattr from $MOUNT/.lustre/fid"
16373         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16374
16375         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16376         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16377                 error "touch invalid fid should fail."
16378
16379         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16380         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16381                 error "touch non-normal fid should fail."
16382
16383         echo "rename $tdir to $MOUNT/.lustre/fid"
16384         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16385                 error "rename to $MOUNT/.lustre/fid should fail."
16386
16387         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16388         then            # LU-3547
16389                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16390                 local new_obf_mode=777
16391
16392                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16393                 chmod $new_obf_mode $DIR/.lustre/fid ||
16394                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16395
16396                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16397                 [ $obf_mode -eq $new_obf_mode ] ||
16398                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16399
16400                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16401                 chmod $old_obf_mode $DIR/.lustre/fid ||
16402                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16403         fi
16404
16405         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16406         fid=$($LFS path2fid $test_dir/$tfile-2)
16407
16408         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16409         then # LU-5424
16410                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16411                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16412                         error "create lov data thru .lustre failed"
16413         fi
16414         echo "cp /etc/passwd $test_dir/$tfile-2"
16415         cp /etc/passwd $test_dir/$tfile-2 ||
16416                 error "copy to $test_dir/$tfile-2 failed."
16417         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16418         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16419                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16420
16421         rm -rf $test_dir/tfile.lnk
16422         rm -rf $test_dir/$tfile-2
16423 }
16424
16425 test_154A() {
16426         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16427                 skip "Need MDS version at least 2.4.1"
16428
16429         local tf=$DIR/$tfile
16430         touch $tf
16431
16432         local fid=$($LFS path2fid $tf)
16433         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16434
16435         # check that we get the same pathname back
16436         local rootpath
16437         local found
16438         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16439                 echo "$rootpath $fid"
16440                 found=$($LFS fid2path $rootpath "$fid")
16441                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16442                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16443         done
16444
16445         # check wrong root path format
16446         rootpath=$MOUNT"_wrong"
16447         found=$($LFS fid2path $rootpath "$fid")
16448         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16449 }
16450 run_test 154A "lfs path2fid and fid2path basic checks"
16451
16452 test_154B() {
16453         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16454                 skip "Need MDS version at least 2.4.1"
16455
16456         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16457         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16458         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16459         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16460
16461         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16462         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16463
16464         # check that we get the same pathname
16465         echo "PFID: $PFID, name: $name"
16466         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16467         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16468         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16469                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16470
16471         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16472 }
16473 run_test 154B "verify the ll_decode_linkea tool"
16474
16475 test_154a() {
16476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16477         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16478         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16479                 skip "Need MDS version at least 2.2.51"
16480         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16481
16482         cp /etc/hosts $DIR/$tfile
16483
16484         fid=$($LFS path2fid $DIR/$tfile)
16485         rc=$?
16486         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16487
16488         dot_lustre_fid_permission_check "$fid" $DIR ||
16489                 error "dot lustre permission check $fid failed"
16490
16491         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16492
16493         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16494
16495         touch $MOUNT/.lustre/file &&
16496                 error "creation is not allowed under .lustre"
16497
16498         mkdir $MOUNT/.lustre/dir &&
16499                 error "mkdir is not allowed under .lustre"
16500
16501         rm -rf $DIR/$tfile
16502 }
16503 run_test 154a "Open-by-FID"
16504
16505 test_154b() {
16506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16507         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16508         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16509         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16510                 skip "Need MDS version at least 2.2.51"
16511
16512         local remote_dir=$DIR/$tdir/remote_dir
16513         local MDTIDX=1
16514         local rc=0
16515
16516         mkdir -p $DIR/$tdir
16517         $LFS mkdir -i $MDTIDX $remote_dir ||
16518                 error "create remote directory failed"
16519
16520         cp /etc/hosts $remote_dir/$tfile
16521
16522         fid=$($LFS path2fid $remote_dir/$tfile)
16523         rc=$?
16524         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16525
16526         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16527                 error "dot lustre permission check $fid failed"
16528         rm -rf $DIR/$tdir
16529 }
16530 run_test 154b "Open-by-FID for remote directory"
16531
16532 test_154c() {
16533         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16534                 skip "Need MDS version at least 2.4.1"
16535
16536         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16537         local FID1=$($LFS path2fid $DIR/$tfile.1)
16538         local FID2=$($LFS path2fid $DIR/$tfile.2)
16539         local FID3=$($LFS path2fid $DIR/$tfile.3)
16540
16541         local N=1
16542         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16543                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16544                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16545                 local want=FID$N
16546                 [ "$FID" = "${!want}" ] ||
16547                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16548                 N=$((N + 1))
16549         done
16550
16551         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16552         do
16553                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16554                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16555                 N=$((N + 1))
16556         done
16557 }
16558 run_test 154c "lfs path2fid and fid2path multiple arguments"
16559
16560 test_154d() {
16561         remote_mds_nodsh && skip "remote MDS with nodsh"
16562         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16563                 skip "Need MDS version at least 2.5.53"
16564
16565         if remote_mds; then
16566                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16567         else
16568                 nid="0@lo"
16569         fi
16570         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16571         local fd
16572         local cmd
16573
16574         rm -f $DIR/$tfile
16575         touch $DIR/$tfile
16576
16577         local fid=$($LFS path2fid $DIR/$tfile)
16578         # Open the file
16579         fd=$(free_fd)
16580         cmd="exec $fd<$DIR/$tfile"
16581         eval $cmd
16582         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16583         echo "$fid_list" | grep "$fid"
16584         rc=$?
16585
16586         cmd="exec $fd>/dev/null"
16587         eval $cmd
16588         if [ $rc -ne 0 ]; then
16589                 error "FID $fid not found in open files list $fid_list"
16590         fi
16591 }
16592 run_test 154d "Verify open file fid"
16593
16594 test_154e()
16595 {
16596         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16597                 skip "Need MDS version at least 2.6.50"
16598
16599         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16600                 error ".lustre returned by readdir"
16601         fi
16602 }
16603 run_test 154e ".lustre is not returned by readdir"
16604
16605 test_154f() {
16606         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16607
16608         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16609         mkdir_on_mdt0 $DIR/$tdir
16610         # test dirs inherit from its stripe
16611         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16612         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16613         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16614         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16615         touch $DIR/f
16616
16617         # get fid of parents
16618         local FID0=$($LFS path2fid $DIR/$tdir)
16619         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16620         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16621         local FID3=$($LFS path2fid $DIR)
16622
16623         # check that path2fid --parents returns expected <parent_fid>/name
16624         # 1) test for a directory (single parent)
16625         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16626         [ "$parent" == "$FID0/foo1" ] ||
16627                 error "expected parent: $FID0/foo1, got: $parent"
16628
16629         # 2) test for a file with nlink > 1 (multiple parents)
16630         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16631         echo "$parent" | grep -F "$FID1/$tfile" ||
16632                 error "$FID1/$tfile not returned in parent list"
16633         echo "$parent" | grep -F "$FID2/link" ||
16634                 error "$FID2/link not returned in parent list"
16635
16636         # 3) get parent by fid
16637         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16638         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16639         echo "$parent" | grep -F "$FID1/$tfile" ||
16640                 error "$FID1/$tfile not returned in parent list (by fid)"
16641         echo "$parent" | grep -F "$FID2/link" ||
16642                 error "$FID2/link not returned in parent list (by fid)"
16643
16644         # 4) test for entry in root directory
16645         parent=$($LFS path2fid --parents $DIR/f)
16646         echo "$parent" | grep -F "$FID3/f" ||
16647                 error "$FID3/f not returned in parent list"
16648
16649         # 5) test it on root directory
16650         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16651                 error "$MOUNT should not have parents"
16652
16653         # enable xattr caching and check that linkea is correctly updated
16654         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16655         save_lustre_params client "llite.*.xattr_cache" > $save
16656         lctl set_param llite.*.xattr_cache 1
16657
16658         # 6.1) linkea update on rename
16659         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16660
16661         # get parents by fid
16662         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16663         # foo1 should no longer be returned in parent list
16664         echo "$parent" | grep -F "$FID1" &&
16665                 error "$FID1 should no longer be in parent list"
16666         # the new path should appear
16667         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16668                 error "$FID2/$tfile.moved is not in parent list"
16669
16670         # 6.2) linkea update on unlink
16671         rm -f $DIR/$tdir/foo2/link
16672         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16673         # foo2/link should no longer be returned in parent list
16674         echo "$parent" | grep -F "$FID2/link" &&
16675                 error "$FID2/link should no longer be in parent list"
16676         true
16677
16678         rm -f $DIR/f
16679         restore_lustre_params < $save
16680         rm -f $save
16681 }
16682 run_test 154f "get parent fids by reading link ea"
16683
16684 test_154g()
16685 {
16686         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16687            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16688                 skip "Need MDS version at least 2.6.92"
16689
16690         mkdir_on_mdt0 $DIR/$tdir
16691         llapi_fid_test -d $DIR/$tdir
16692 }
16693 run_test 154g "various llapi FID tests"
16694
16695 test_154h()
16696 {
16697         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16698                 skip "Need client at least version 2.15.55.1"
16699
16700         # Create an empty file
16701         touch $DIR/$tfile
16702
16703         # Get FID (interactive mode) and save under $TMP/$tfile.log
16704         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16705                 path2fid $DIR/$tfile
16706         EOF
16707
16708         fid=$(cat $TMP/$tfile.log)
16709         # $fid should not be empty
16710         [[ ! -z $fid ]] || error "FID is empty"
16711         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16712 }
16713 run_test 154h "Verify interactive path2fid"
16714
16715 test_155_small_load() {
16716     local temp=$TMP/$tfile
16717     local file=$DIR/$tfile
16718
16719     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16720         error "dd of=$temp bs=6096 count=1 failed"
16721     cp $temp $file
16722     cancel_lru_locks $OSC
16723     cmp $temp $file || error "$temp $file differ"
16724
16725     $TRUNCATE $temp 6000
16726     $TRUNCATE $file 6000
16727     cmp $temp $file || error "$temp $file differ (truncate1)"
16728
16729     echo "12345" >>$temp
16730     echo "12345" >>$file
16731     cmp $temp $file || error "$temp $file differ (append1)"
16732
16733     echo "12345" >>$temp
16734     echo "12345" >>$file
16735     cmp $temp $file || error "$temp $file differ (append2)"
16736
16737     rm -f $temp $file
16738     true
16739 }
16740
16741 test_155_big_load() {
16742         remote_ost_nodsh && skip "remote OST with nodsh"
16743
16744         local temp=$TMP/$tfile
16745         local file=$DIR/$tfile
16746
16747         free_min_max
16748         local cache_size=$(do_facet ost$((MAXI+1)) \
16749                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16750
16751         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16752         # pre-set value
16753         if [ -z "$cache_size" ]; then
16754                 cache_size=256
16755         fi
16756         local large_file_size=$((cache_size * 2))
16757
16758         echo "OSS cache size: $cache_size KB"
16759         echo "Large file size: $large_file_size KB"
16760
16761         [ $MAXV -le $large_file_size ] &&
16762                 skip_env "max available OST size needs > $large_file_size KB"
16763
16764         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16765
16766         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16767                 error "dd of=$temp bs=$large_file_size count=1k failed"
16768         cp $temp $file
16769         ls -lh $temp $file
16770         cancel_lru_locks osc
16771         cmp $temp $file || error "$temp $file differ"
16772
16773         rm -f $temp $file
16774         true
16775 }
16776
16777 save_writethrough() {
16778         local facets=$(get_facets OST)
16779
16780         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16781 }
16782
16783 test_155a() {
16784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16785
16786         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16787
16788         save_writethrough $p
16789
16790         set_cache read on
16791         set_cache writethrough on
16792         test_155_small_load
16793         restore_lustre_params < $p
16794         rm -f $p
16795 }
16796 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16797
16798 test_155b() {
16799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16800
16801         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16802
16803         save_writethrough $p
16804
16805         set_cache read on
16806         set_cache writethrough off
16807         test_155_small_load
16808         restore_lustre_params < $p
16809         rm -f $p
16810 }
16811 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16812
16813 test_155c() {
16814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16815
16816         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16817
16818         save_writethrough $p
16819
16820         set_cache read off
16821         set_cache writethrough on
16822         test_155_small_load
16823         restore_lustre_params < $p
16824         rm -f $p
16825 }
16826 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16827
16828 test_155d() {
16829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16830
16831         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16832
16833         save_writethrough $p
16834
16835         set_cache read off
16836         set_cache writethrough off
16837         test_155_small_load
16838         restore_lustre_params < $p
16839         rm -f $p
16840 }
16841 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16842
16843 test_155e() {
16844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16845
16846         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16847
16848         save_writethrough $p
16849
16850         set_cache read on
16851         set_cache writethrough on
16852         test_155_big_load
16853         restore_lustre_params < $p
16854         rm -f $p
16855 }
16856 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16857
16858 test_155f() {
16859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16860
16861         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16862
16863         save_writethrough $p
16864
16865         set_cache read on
16866         set_cache writethrough off
16867         test_155_big_load
16868         restore_lustre_params < $p
16869         rm -f $p
16870 }
16871 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16872
16873 test_155g() {
16874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16875
16876         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16877
16878         save_writethrough $p
16879
16880         set_cache read off
16881         set_cache writethrough on
16882         test_155_big_load
16883         restore_lustre_params < $p
16884         rm -f $p
16885 }
16886 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16887
16888 test_155h() {
16889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16890
16891         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16892
16893         save_writethrough $p
16894
16895         set_cache read off
16896         set_cache writethrough off
16897         test_155_big_load
16898         restore_lustre_params < $p
16899         rm -f $p
16900 }
16901 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16902
16903 test_156() {
16904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16905         remote_ost_nodsh && skip "remote OST with nodsh"
16906         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16907                 skip "stats not implemented on old servers"
16908         [ "$ost1_FSTYPE" = "zfs" ] &&
16909                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16910         (( CLIENT_VERSION == OST1_VERSION )) ||
16911                 skip "LU-13081: no interop testing for OSS cache"
16912
16913         local CPAGES=3
16914         local BEFORE
16915         local AFTER
16916         local file="$DIR/$tfile"
16917         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16918
16919         save_writethrough $p
16920         roc_hit_init
16921
16922         log "Turn on read and write cache"
16923         set_cache read on
16924         set_cache writethrough on
16925
16926         log "Write data and read it back."
16927         log "Read should be satisfied from the cache."
16928         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16929         BEFORE=$(roc_hit)
16930         cancel_lru_locks osc
16931         cat $file >/dev/null
16932         AFTER=$(roc_hit)
16933         if ! let "AFTER - BEFORE == CPAGES"; then
16934                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16935         else
16936                 log "cache hits: before: $BEFORE, after: $AFTER"
16937         fi
16938
16939         log "Read again; it should be satisfied from the cache."
16940         BEFORE=$AFTER
16941         cancel_lru_locks osc
16942         cat $file >/dev/null
16943         AFTER=$(roc_hit)
16944         if ! let "AFTER - BEFORE == CPAGES"; then
16945                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16946         else
16947                 log "cache hits:: before: $BEFORE, after: $AFTER"
16948         fi
16949
16950         log "Turn off the read cache and turn on the write cache"
16951         set_cache read off
16952         set_cache writethrough on
16953
16954         log "Read again; it should be satisfied from the cache."
16955         BEFORE=$(roc_hit)
16956         cancel_lru_locks osc
16957         cat $file >/dev/null
16958         AFTER=$(roc_hit)
16959         if ! let "AFTER - BEFORE == CPAGES"; then
16960                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16961         else
16962                 log "cache hits:: before: $BEFORE, after: $AFTER"
16963         fi
16964
16965         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16966                 # > 2.12.56 uses pagecache if cached
16967                 log "Read again; it should not be satisfied from the cache."
16968                 BEFORE=$AFTER
16969                 cancel_lru_locks osc
16970                 cat $file >/dev/null
16971                 AFTER=$(roc_hit)
16972                 if ! let "AFTER - BEFORE == 0"; then
16973                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16974                 else
16975                         log "cache hits:: before: $BEFORE, after: $AFTER"
16976                 fi
16977         fi
16978
16979         log "Write data and read it back."
16980         log "Read should be satisfied from the cache."
16981         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16982         BEFORE=$(roc_hit)
16983         cancel_lru_locks osc
16984         cat $file >/dev/null
16985         AFTER=$(roc_hit)
16986         if ! let "AFTER - BEFORE == CPAGES"; then
16987                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16988         else
16989                 log "cache hits:: before: $BEFORE, after: $AFTER"
16990         fi
16991
16992         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16993                 # > 2.12.56 uses pagecache if cached
16994                 log "Read again; it should not be satisfied from the cache."
16995                 BEFORE=$AFTER
16996                 cancel_lru_locks osc
16997                 cat $file >/dev/null
16998                 AFTER=$(roc_hit)
16999                 if ! let "AFTER - BEFORE == 0"; then
17000                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17001                 else
17002                         log "cache hits:: before: $BEFORE, after: $AFTER"
17003                 fi
17004         fi
17005
17006         log "Turn off read and write cache"
17007         set_cache read off
17008         set_cache writethrough off
17009
17010         log "Write data and read it back"
17011         log "It should not be satisfied from the cache."
17012         rm -f $file
17013         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17014         cancel_lru_locks osc
17015         BEFORE=$(roc_hit)
17016         cat $file >/dev/null
17017         AFTER=$(roc_hit)
17018         if ! let "AFTER - BEFORE == 0"; then
17019                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17020         else
17021                 log "cache hits:: before: $BEFORE, after: $AFTER"
17022         fi
17023
17024         log "Turn on the read cache and turn off the write cache"
17025         set_cache read on
17026         set_cache writethrough off
17027
17028         log "Write data and read it back"
17029         log "It should not be satisfied from the cache."
17030         rm -f $file
17031         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17032         BEFORE=$(roc_hit)
17033         cancel_lru_locks osc
17034         cat $file >/dev/null
17035         AFTER=$(roc_hit)
17036         if ! let "AFTER - BEFORE == 0"; then
17037                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17038         else
17039                 log "cache hits:: before: $BEFORE, after: $AFTER"
17040         fi
17041
17042         log "Read again; it should be satisfied from the cache."
17043         BEFORE=$(roc_hit)
17044         cancel_lru_locks osc
17045         cat $file >/dev/null
17046         AFTER=$(roc_hit)
17047         if ! let "AFTER - BEFORE == CPAGES"; then
17048                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17049         else
17050                 log "cache hits:: before: $BEFORE, after: $AFTER"
17051         fi
17052
17053         restore_lustre_params < $p
17054         rm -f $p $file
17055 }
17056 run_test 156 "Verification of tunables"
17057
17058 test_160a() {
17059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17060         remote_mds_nodsh && skip "remote MDS with nodsh"
17061         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17062                 skip "Need MDS version at least 2.2.0"
17063
17064         changelog_register || error "changelog_register failed"
17065         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17066         changelog_users $SINGLEMDS | grep -q $cl_user ||
17067                 error "User $cl_user not found in changelog_users"
17068
17069         mkdir_on_mdt0 $DIR/$tdir
17070
17071         # change something
17072         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17073         changelog_clear 0 || error "changelog_clear failed"
17074         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17075         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17076         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17077         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17078         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17079         rm $DIR/$tdir/pics/desktop.jpg
17080
17081         echo "verifying changelog mask"
17082         changelog_chmask "-MKDIR"
17083         changelog_chmask "-CLOSE"
17084
17085         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17086         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17087
17088         changelog_chmask "+MKDIR"
17089         changelog_chmask "+CLOSE"
17090
17091         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17092         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17093
17094         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17095         CLOSES=$(changelog_dump | grep -c "CLOSE")
17096         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17097         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17098
17099         # verify contents
17100         echo "verifying target fid"
17101         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17102         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17103         [ "$fidc" == "$fidf" ] ||
17104                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17105         echo "verifying parent fid"
17106         # The FID returned from the Changelog may be the directory shard on
17107         # a different MDT, and not the FID returned by path2fid on the parent.
17108         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17109         # since this is what will matter when recreating this file in the tree.
17110         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17111         local pathp=$($LFS fid2path $MOUNT "$fidp")
17112         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17113                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17114
17115         echo "getting records for $cl_user"
17116         changelog_users $SINGLEMDS
17117         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17118         local nclr=3
17119         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17120                 error "changelog_clear failed"
17121         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17122         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17123         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17124                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17125
17126         local min0_rec=$(changelog_users $SINGLEMDS |
17127                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17128         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17129                           awk '{ print $1; exit; }')
17130
17131         changelog_dump | tail -n 5
17132         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17133         [ $first_rec == $((min0_rec + 1)) ] ||
17134                 error "first index should be $min0_rec + 1 not $first_rec"
17135
17136         # LU-3446 changelog index reset on MDT restart
17137         local cur_rec1=$(changelog_users $SINGLEMDS |
17138                          awk '/^current.index:/ { print $NF }')
17139         changelog_clear 0 ||
17140                 error "clear all changelog records for $cl_user failed"
17141         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17142         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17143                 error "Fail to start $SINGLEMDS"
17144         local cur_rec2=$(changelog_users $SINGLEMDS |
17145                          awk '/^current.index:/ { print $NF }')
17146         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17147         [ $cur_rec1 == $cur_rec2 ] ||
17148                 error "current index should be $cur_rec1 not $cur_rec2"
17149
17150         echo "verifying users from this test are deregistered"
17151         changelog_deregister || error "changelog_deregister failed"
17152         changelog_users $SINGLEMDS | grep -q $cl_user &&
17153                 error "User '$cl_user' still in changelog_users"
17154
17155         # lctl get_param -n mdd.*.changelog_users
17156         # current_index: 144
17157         # ID    index (idle seconds)
17158         # cl3   144   (2) mask=<list>
17159         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17160                 # this is the normal case where all users were deregistered
17161                 # make sure no new records are added when no users are present
17162                 local last_rec1=$(changelog_users $SINGLEMDS |
17163                                   awk '/^current.index:/ { print $NF }')
17164                 touch $DIR/$tdir/chloe
17165                 local last_rec2=$(changelog_users $SINGLEMDS |
17166                                   awk '/^current.index:/ { print $NF }')
17167                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17168                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17169         else
17170                 # any changelog users must be leftovers from a previous test
17171                 changelog_users $SINGLEMDS
17172                 echo "other changelog users; can't verify off"
17173         fi
17174 }
17175 run_test 160a "changelog sanity"
17176
17177 test_160b() { # LU-3587
17178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17179         remote_mds_nodsh && skip "remote MDS with nodsh"
17180         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17181                 skip "Need MDS version at least 2.2.0"
17182
17183         changelog_register || error "changelog_register failed"
17184         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17185         changelog_users $SINGLEMDS | grep -q $cl_user ||
17186                 error "User '$cl_user' not found in changelog_users"
17187
17188         local longname1=$(str_repeat a 255)
17189         local longname2=$(str_repeat b 255)
17190
17191         cd $DIR
17192         echo "creating very long named file"
17193         touch $longname1 || error "create of '$longname1' failed"
17194         echo "renaming very long named file"
17195         mv $longname1 $longname2
17196
17197         changelog_dump | grep RENME | tail -n 5
17198         rm -f $longname2
17199 }
17200 run_test 160b "Verify that very long rename doesn't crash in changelog"
17201
17202 test_160c() {
17203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17204         remote_mds_nodsh && skip "remote MDS with nodsh"
17205
17206         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17207                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17208                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17209                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17210
17211         local rc=0
17212
17213         # Registration step
17214         changelog_register || error "changelog_register failed"
17215
17216         rm -rf $DIR/$tdir
17217         mkdir -p $DIR/$tdir
17218         $MCREATE $DIR/$tdir/foo_160c
17219         changelog_chmask "-TRUNC"
17220         $TRUNCATE $DIR/$tdir/foo_160c 200
17221         changelog_chmask "+TRUNC"
17222         $TRUNCATE $DIR/$tdir/foo_160c 199
17223         changelog_dump | tail -n 5
17224         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17225         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17226 }
17227 run_test 160c "verify that changelog log catch the truncate event"
17228
17229 test_160d() {
17230         remote_mds_nodsh && skip "remote MDS with nodsh"
17231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17233         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17234                 skip "Need MDS version at least 2.7.60"
17235
17236         # Registration step
17237         changelog_register || error "changelog_register failed"
17238
17239         mkdir -p $DIR/$tdir/migrate_dir
17240         changelog_clear 0 || error "changelog_clear failed"
17241
17242         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17243         changelog_dump | tail -n 5
17244         local migrates=$(changelog_dump | grep -c "MIGRT")
17245         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17246 }
17247 run_test 160d "verify that changelog log catch the migrate event"
17248
17249 test_160e() {
17250         remote_mds_nodsh && skip "remote MDS with nodsh"
17251
17252         # Create a user
17253         changelog_register || error "changelog_register failed"
17254
17255         local MDT0=$(facet_svc $SINGLEMDS)
17256         local rc
17257
17258         # No user (expect fail)
17259         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17260         rc=$?
17261         if [ $rc -eq 0 ]; then
17262                 error "Should fail without user"
17263         elif [ $rc -ne 4 ]; then
17264                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17265         fi
17266
17267         # Delete a future user (expect fail)
17268         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17269         rc=$?
17270         if [ $rc -eq 0 ]; then
17271                 error "Deleted non-existant user cl77"
17272         elif [ $rc -ne 2 ]; then
17273                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17274         fi
17275
17276         # Clear to a bad index (1 billion should be safe)
17277         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17278         rc=$?
17279
17280         if [ $rc -eq 0 ]; then
17281                 error "Successfully cleared to invalid CL index"
17282         elif [ $rc -ne 22 ]; then
17283                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17284         fi
17285 }
17286 run_test 160e "changelog negative testing (should return errors)"
17287
17288 test_160f() {
17289         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17290         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17291                 skip "Need MDS version at least 2.10.56"
17292
17293         local mdts=$(comma_list $(mdts_nodes))
17294
17295         # Create a user
17296         changelog_register || error "first changelog_register failed"
17297         changelog_register || error "second changelog_register failed"
17298         local cl_users
17299         declare -A cl_user1
17300         declare -A cl_user2
17301         local user_rec1
17302         local user_rec2
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         log "$(date +%s): creating first files"
17310         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17311                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17312                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17313         done
17314
17315         # check changelogs have been generated
17316         local start=$SECONDS
17317         local idle_time=$((MDSCOUNT * 5 + 5))
17318         local nbcl=$(changelog_dump | wc -l)
17319         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17320
17321         for param in "changelog_max_idle_time=$idle_time" \
17322                      "changelog_gc=1" \
17323                      "changelog_min_gc_interval=2" \
17324                      "changelog_min_free_cat_entries=3"; do
17325                 local MDT0=$(facet_svc $SINGLEMDS)
17326                 local var="${param%=*}"
17327                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17328
17329                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17330                 do_nodes $mdts $LCTL set_param mdd.*.$param
17331         done
17332
17333         # force cl_user2 to be idle (1st part), but also cancel the
17334         # cl_user1 records so that it is not evicted later in the test.
17335         local sleep1=$((idle_time / 2))
17336         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17337         sleep $sleep1
17338
17339         # simulate changelog catalog almost full
17340         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17341         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17342
17343         for i in $(seq $MDSCOUNT); do
17344                 cl_users=(${CL_USERS[mds$i]})
17345                 cl_user1[mds$i]="${cl_users[0]}"
17346                 cl_user2[mds$i]="${cl_users[1]}"
17347
17348                 [ -n "${cl_user1[mds$i]}" ] ||
17349                         error "mds$i: no user registered"
17350                 [ -n "${cl_user2[mds$i]}" ] ||
17351                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17352
17353                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17354                 [ -n "$user_rec1" ] ||
17355                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17356                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17357                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17358                 [ -n "$user_rec2" ] ||
17359                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17360                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17361                      "$user_rec1 + 2 == $user_rec2"
17362                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17363                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17364                               "$user_rec1 + 2, but is $user_rec2"
17365                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17366                 [ -n "$user_rec2" ] ||
17367                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17368                 [ $user_rec1 == $user_rec2 ] ||
17369                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17370                               "$user_rec1, but is $user_rec2"
17371         done
17372
17373         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17374         local sleep2=$((idle_time - (SECONDS - start) + 1))
17375         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17376         sleep $sleep2
17377
17378         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17379         # cl_user1 should be OK because it recently processed records.
17380         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17381         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17382                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17383                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17384         done
17385
17386         # ensure gc thread is done
17387         for i in $(mdts_nodes); do
17388                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17389                         error "$i: GC-thread not done"
17390         done
17391
17392         local first_rec
17393         for (( i = 1; i <= MDSCOUNT; i++ )); do
17394                 # check cl_user1 still registered
17395                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17396                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17397                 # check cl_user2 unregistered
17398                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17399                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17400
17401                 # check changelogs are present and starting at $user_rec1 + 1
17402                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17403                 [ -n "$user_rec1" ] ||
17404                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17405                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17406                             awk '{ print $1; exit; }')
17407
17408                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17409                 [ $((user_rec1 + 1)) == $first_rec ] ||
17410                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17411         done
17412 }
17413 run_test 160f "changelog garbage collect (timestamped users)"
17414
17415 test_160g() {
17416         remote_mds_nodsh && skip "remote MDS with nodsh"
17417         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17418                 skip "Need MDS version at least 2.14.55"
17419
17420         local mdts=$(comma_list $(mdts_nodes))
17421
17422         # Create a user
17423         changelog_register || error "first changelog_register failed"
17424         changelog_register || error "second changelog_register failed"
17425         local cl_users
17426         declare -A cl_user1
17427         declare -A cl_user2
17428         local user_rec1
17429         local user_rec2
17430         local i
17431
17432         # generate some changelog records to accumulate on each MDT
17433         # use all_char because created files should be evenly distributed
17434         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17435                 error "test_mkdir $tdir failed"
17436         for ((i = 0; i < MDSCOUNT; i++)); do
17437                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17438                         error "create $DIR/$tdir/d$i.1 failed"
17439         done
17440
17441         # check changelogs have been generated
17442         local nbcl=$(changelog_dump | wc -l)
17443         (( $nbcl > 0 )) || error "no changelogs found"
17444
17445         # reduce the max_idle_indexes value to make sure we exceed it
17446         for param in "changelog_max_idle_indexes=2" \
17447                      "changelog_gc=1" \
17448                      "changelog_min_gc_interval=2"; do
17449                 local MDT0=$(facet_svc $SINGLEMDS)
17450                 local var="${param%=*}"
17451                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17452
17453                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17454                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17455                         error "unable to set mdd.*.$param"
17456         done
17457
17458         local start=$SECONDS
17459         for i in $(seq $MDSCOUNT); do
17460                 cl_users=(${CL_USERS[mds$i]})
17461                 cl_user1[mds$i]="${cl_users[0]}"
17462                 cl_user2[mds$i]="${cl_users[1]}"
17463
17464                 [ -n "${cl_user1[mds$i]}" ] ||
17465                         error "mds$i: user1 is not registered"
17466                 [ -n "${cl_user2[mds$i]}" ] ||
17467                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17468
17469                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17470                 [ -n "$user_rec1" ] ||
17471                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17472                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17473                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17474                 [ -n "$user_rec2" ] ||
17475                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17476                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17477                      "$user_rec1 + 2 == $user_rec2"
17478                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17479                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17480                               "expected $user_rec1 + 2, but is $user_rec2"
17481                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17482                 [ -n "$user_rec2" ] ||
17483                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17484                 [ $user_rec1 == $user_rec2 ] ||
17485                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17486                               "expected $user_rec1, but is $user_rec2"
17487         done
17488
17489         # ensure we are past the previous changelog_min_gc_interval set above
17490         local sleep2=$((start + 2 - SECONDS))
17491         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17492         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17493         # cl_user1 should be OK because it recently processed records.
17494         for ((i = 0; i < MDSCOUNT; i++)); do
17495                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17496                         error "create $DIR/$tdir/d$i.3 failed"
17497         done
17498
17499         # ensure gc thread is done
17500         for i in $(mdts_nodes); do
17501                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17502                         error "$i: GC-thread not done"
17503         done
17504
17505         local first_rec
17506         for (( i = 1; i <= MDSCOUNT; i++ )); do
17507                 # check cl_user1 still registered
17508                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17509                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17510                 # check cl_user2 unregistered
17511                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17512                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17513
17514                 # check changelogs are present and starting at $user_rec1 + 1
17515                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17516                 [ -n "$user_rec1" ] ||
17517                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17518                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17519                             awk '{ print $1; exit; }')
17520
17521                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17522                 [ $((user_rec1 + 1)) == $first_rec ] ||
17523                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17524         done
17525 }
17526 run_test 160g "changelog garbage collect on idle records"
17527
17528 test_160h() {
17529         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17530         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17531                 skip "Need MDS version at least 2.10.56"
17532
17533         local mdts=$(comma_list $(mdts_nodes))
17534
17535         # Create a user
17536         changelog_register || error "first changelog_register failed"
17537         changelog_register || error "second changelog_register failed"
17538         local cl_users
17539         declare -A cl_user1
17540         declare -A cl_user2
17541         local user_rec1
17542         local user_rec2
17543         local i
17544
17545         # generate some changelog records to accumulate on each MDT
17546         # use all_char because created files should be evenly distributed
17547         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17548                 error "test_mkdir $tdir failed"
17549         for ((i = 0; i < MDSCOUNT; i++)); do
17550                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17551                         error "create $DIR/$tdir/d$i.1 failed"
17552         done
17553
17554         # check changelogs have been generated
17555         local nbcl=$(changelog_dump | wc -l)
17556         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17557
17558         for param in "changelog_max_idle_time=10" \
17559                      "changelog_gc=1" \
17560                      "changelog_min_gc_interval=2"; do
17561                 local MDT0=$(facet_svc $SINGLEMDS)
17562                 local var="${param%=*}"
17563                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17564
17565                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17566                 do_nodes $mdts $LCTL set_param mdd.*.$param
17567         done
17568
17569         # force cl_user2 to be idle (1st part)
17570         sleep 9
17571
17572         for i in $(seq $MDSCOUNT); do
17573                 cl_users=(${CL_USERS[mds$i]})
17574                 cl_user1[mds$i]="${cl_users[0]}"
17575                 cl_user2[mds$i]="${cl_users[1]}"
17576
17577                 [ -n "${cl_user1[mds$i]}" ] ||
17578                         error "mds$i: no user registered"
17579                 [ -n "${cl_user2[mds$i]}" ] ||
17580                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17581
17582                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17583                 [ -n "$user_rec1" ] ||
17584                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17585                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17586                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17587                 [ -n "$user_rec2" ] ||
17588                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17589                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17590                      "$user_rec1 + 2 == $user_rec2"
17591                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17592                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17593                               "$user_rec1 + 2, but is $user_rec2"
17594                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17595                 [ -n "$user_rec2" ] ||
17596                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17597                 [ $user_rec1 == $user_rec2 ] ||
17598                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17599                               "$user_rec1, but is $user_rec2"
17600         done
17601
17602         # force cl_user2 to be idle (2nd part) and to reach
17603         # changelog_max_idle_time
17604         sleep 2
17605
17606         # force each GC-thread start and block then
17607         # one per MDT/MDD, set fail_val accordingly
17608         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17609         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17610
17611         # generate more changelogs to trigger fail_loc
17612         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17613                 error "create $DIR/$tdir/${tfile}bis failed"
17614
17615         # stop MDT to stop GC-thread, should be done in back-ground as it will
17616         # block waiting for the thread to be released and exit
17617         declare -A stop_pids
17618         for i in $(seq $MDSCOUNT); do
17619                 stop mds$i &
17620                 stop_pids[mds$i]=$!
17621         done
17622
17623         for i in $(mdts_nodes); do
17624                 local facet
17625                 local nb=0
17626                 local facets=$(facets_up_on_host $i)
17627
17628                 for facet in ${facets//,/ }; do
17629                         if [[ $facet == mds* ]]; then
17630                                 nb=$((nb + 1))
17631                         fi
17632                 done
17633                 # ensure each MDS's gc threads are still present and all in "R"
17634                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17635                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17636                         error "$i: expected $nb GC-thread"
17637                 wait_update $i \
17638                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17639                         "R" 20 ||
17640                         error "$i: GC-thread not found in R-state"
17641                 # check umounts of each MDT on MDS have reached kthread_stop()
17642                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17643                         error "$i: expected $nb umount"
17644                 wait_update $i \
17645                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17646                         error "$i: umount not found in D-state"
17647         done
17648
17649         # release all GC-threads
17650         do_nodes $mdts $LCTL set_param fail_loc=0
17651
17652         # wait for MDT stop to complete
17653         for i in $(seq $MDSCOUNT); do
17654                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17655         done
17656
17657         # XXX
17658         # may try to check if any orphan changelog records are present
17659         # via ldiskfs/zfs and llog_reader...
17660
17661         # re-start/mount MDTs
17662         for i in $(seq $MDSCOUNT); do
17663                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17664                         error "Fail to start mds$i"
17665         done
17666
17667         local first_rec
17668         for i in $(seq $MDSCOUNT); do
17669                 # check cl_user1 still registered
17670                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17671                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17672                 # check cl_user2 unregistered
17673                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17674                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17675
17676                 # check changelogs are present and starting at $user_rec1 + 1
17677                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17678                 [ -n "$user_rec1" ] ||
17679                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17680                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17681                             awk '{ print $1; exit; }')
17682
17683                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17684                 [ $((user_rec1 + 1)) == $first_rec ] ||
17685                         error "mds$i: first index should be $user_rec1 + 1, " \
17686                               "but is $first_rec"
17687         done
17688 }
17689 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17690               "during mount"
17691
17692 test_160i() {
17693
17694         local mdts=$(comma_list $(mdts_nodes))
17695
17696         changelog_register || error "first changelog_register failed"
17697
17698         # generate some changelog records to accumulate on each MDT
17699         # use all_char because created files should be evenly distributed
17700         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17701                 error "test_mkdir $tdir failed"
17702         for ((i = 0; i < MDSCOUNT; i++)); do
17703                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17704                         error "create $DIR/$tdir/d$i.1 failed"
17705         done
17706
17707         # check changelogs have been generated
17708         local nbcl=$(changelog_dump | wc -l)
17709         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17710
17711         # simulate race between register and unregister
17712         # XXX as fail_loc is set per-MDS, with DNE configs the race
17713         # simulation will only occur for one MDT per MDS and for the
17714         # others the normal race scenario will take place
17715         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17716         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17717         do_nodes $mdts $LCTL set_param fail_val=1
17718
17719         # unregister 1st user
17720         changelog_deregister &
17721         local pid1=$!
17722         # wait some time for deregister work to reach race rdv
17723         sleep 2
17724         # register 2nd user
17725         changelog_register || error "2nd user register failed"
17726
17727         wait $pid1 || error "1st user deregister failed"
17728
17729         local i
17730         local last_rec
17731         declare -A LAST_REC
17732         for i in $(seq $MDSCOUNT); do
17733                 if changelog_users mds$i | grep "^cl"; then
17734                         # make sure new records are added with one user present
17735                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17736                                           awk '/^current.index:/ { print $NF }')
17737                 else
17738                         error "mds$i has no user registered"
17739                 fi
17740         done
17741
17742         # generate more changelog records to accumulate on each MDT
17743         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17744                 error "create $DIR/$tdir/${tfile}bis failed"
17745
17746         for i in $(seq $MDSCOUNT); do
17747                 last_rec=$(changelog_users $SINGLEMDS |
17748                            awk '/^current.index:/ { print $NF }')
17749                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17750                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17751                         error "changelogs are off on mds$i"
17752         done
17753 }
17754 run_test 160i "changelog user register/unregister race"
17755
17756 test_160j() {
17757         remote_mds_nodsh && skip "remote MDS with nodsh"
17758         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17759                 skip "Need MDS version at least 2.12.56"
17760
17761         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17762         stack_trap "umount $MOUNT2" EXIT
17763
17764         changelog_register || error "first changelog_register failed"
17765         stack_trap "changelog_deregister" EXIT
17766
17767         # generate some changelog
17768         # use all_char because created files should be evenly distributed
17769         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17770                 error "mkdir $tdir failed"
17771         for ((i = 0; i < MDSCOUNT; i++)); do
17772                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17773                         error "create $DIR/$tdir/d$i.1 failed"
17774         done
17775
17776         # open the changelog device
17777         exec 3>/dev/changelog-$FSNAME-MDT0000
17778         stack_trap "exec 3>&-" EXIT
17779         exec 4</dev/changelog-$FSNAME-MDT0000
17780         stack_trap "exec 4<&-" EXIT
17781
17782         # umount the first lustre mount
17783         umount $MOUNT
17784         stack_trap "mount_client $MOUNT" EXIT
17785
17786         # read changelog, which may or may not fail, but should not crash
17787         cat <&4 >/dev/null
17788
17789         # clear changelog
17790         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17791         changelog_users $SINGLEMDS | grep -q $cl_user ||
17792                 error "User $cl_user not found in changelog_users"
17793
17794         printf 'clear:'$cl_user':0' >&3
17795 }
17796 run_test 160j "client can be umounted while its chanangelog is being used"
17797
17798 test_160k() {
17799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17800         remote_mds_nodsh && skip "remote MDS with nodsh"
17801
17802         mkdir -p $DIR/$tdir/1/1
17803
17804         changelog_register || error "changelog_register failed"
17805         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17806
17807         changelog_users $SINGLEMDS | grep -q $cl_user ||
17808                 error "User '$cl_user' not found in changelog_users"
17809 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17810         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17811         rmdir $DIR/$tdir/1/1 & sleep 1
17812         mkdir $DIR/$tdir/2
17813         touch $DIR/$tdir/2/2
17814         rm -rf $DIR/$tdir/2
17815
17816         wait
17817         sleep 4
17818
17819         changelog_dump | grep rmdir || error "rmdir not recorded"
17820 }
17821 run_test 160k "Verify that changelog records are not lost"
17822
17823 # Verifies that a file passed as a parameter has recently had an operation
17824 # performed on it that has generated an MTIME changelog which contains the
17825 # correct parent FID. As files might reside on a different MDT from the
17826 # parent directory in DNE configurations, the FIDs are translated to paths
17827 # before being compared, which should be identical
17828 compare_mtime_changelog() {
17829         local file="${1}"
17830         local mdtidx
17831         local mtime
17832         local cl_fid
17833         local pdir
17834         local dir
17835
17836         mdtidx=$($LFS getstripe --mdt-index $file)
17837         mdtidx=$(printf "%04x" $mdtidx)
17838
17839         # Obtain the parent FID from the MTIME changelog
17840         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17841         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17842
17843         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17844         [ -z "$cl_fid" ] && error "parent FID not present"
17845
17846         # Verify that the path for the parent FID is the same as the path for
17847         # the test directory
17848         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17849
17850         dir=$(dirname $1)
17851
17852         [[ "${pdir%/}" == "$dir" ]] ||
17853                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17854 }
17855
17856 test_160l() {
17857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17858
17859         remote_mds_nodsh && skip "remote MDS with nodsh"
17860         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17861                 skip "Need MDS version at least 2.13.55"
17862
17863         local cl_user
17864
17865         changelog_register || error "changelog_register failed"
17866         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17867
17868         changelog_users $SINGLEMDS | grep -q $cl_user ||
17869                 error "User '$cl_user' not found in changelog_users"
17870
17871         # Clear some types so that MTIME changelogs are generated
17872         changelog_chmask "-CREAT"
17873         changelog_chmask "-CLOSE"
17874
17875         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17876
17877         # Test CL_MTIME during setattr
17878         touch $DIR/$tdir/$tfile
17879         compare_mtime_changelog $DIR/$tdir/$tfile
17880
17881         # Test CL_MTIME during close
17882         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17883         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17884 }
17885 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17886
17887 test_160m() {
17888         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17889         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17890                 skip "Need MDS version at least 2.14.51"
17891         local cl_users
17892         local cl_user1
17893         local cl_user2
17894         local pid1
17895
17896         # Create a user
17897         changelog_register || error "first changelog_register failed"
17898         changelog_register || error "second changelog_register failed"
17899
17900         cl_users=(${CL_USERS[mds1]})
17901         cl_user1="${cl_users[0]}"
17902         cl_user2="${cl_users[1]}"
17903         # generate some changelog records to accumulate on MDT0
17904         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17905         createmany -m $DIR/$tdir/$tfile 50 ||
17906                 error "create $DIR/$tdir/$tfile failed"
17907         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17908         rm -f $DIR/$tdir
17909
17910         # check changelogs have been generated
17911         local nbcl=$(changelog_dump | wc -l)
17912         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17913
17914 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17915         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17916
17917         __changelog_clear mds1 $cl_user1 +10
17918         __changelog_clear mds1 $cl_user2 0 &
17919         pid1=$!
17920         sleep 2
17921         __changelog_clear mds1 $cl_user1 0 ||
17922                 error "fail to cancel record for $cl_user1"
17923         wait $pid1
17924         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17925 }
17926 run_test 160m "Changelog clear race"
17927
17928 test_160n() {
17929         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17930         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17931                 skip "Need MDS version at least 2.14.51"
17932         local cl_users
17933         local cl_user1
17934         local cl_user2
17935         local pid1
17936         local first_rec
17937         local last_rec=0
17938
17939         # Create a user
17940         changelog_register || error "first changelog_register failed"
17941
17942         cl_users=(${CL_USERS[mds1]})
17943         cl_user1="${cl_users[0]}"
17944
17945         # generate some changelog records to accumulate on MDT0
17946         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17947         first_rec=$(changelog_users $SINGLEMDS |
17948                         awk '/^current.index:/ { print $NF }')
17949         while (( last_rec < (( first_rec + 65000)) )); do
17950                 createmany -m $DIR/$tdir/$tfile 10000 ||
17951                         error "create $DIR/$tdir/$tfile failed"
17952
17953                 for i in $(seq 0 10000); do
17954                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17955                                 > /dev/null
17956                 done
17957
17958                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17959                         error "unlinkmany failed unlink"
17960                 last_rec=$(changelog_users $SINGLEMDS |
17961                         awk '/^current.index:/ { print $NF }')
17962                 echo last record $last_rec
17963                 (( last_rec == 0 )) && error "no changelog found"
17964         done
17965
17966 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17967         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17968
17969         __changelog_clear mds1 $cl_user1 0 &
17970         pid1=$!
17971         sleep 2
17972         __changelog_clear mds1 $cl_user1 0 ||
17973                 error "fail to cancel record for $cl_user1"
17974         wait $pid1
17975         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17976 }
17977 run_test 160n "Changelog destroy race"
17978
17979 test_160o() {
17980         local mdt="$(facet_svc $SINGLEMDS)"
17981
17982         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17983         remote_mds_nodsh && skip "remote MDS with nodsh"
17984         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17985                 skip "Need MDS version at least 2.14.52"
17986
17987         changelog_register --user test_160o -m unlnk+close+open ||
17988                 error "changelog_register failed"
17989
17990         do_facet $SINGLEMDS $LCTL --device $mdt \
17991                                 changelog_register -u "Tt3_-#" &&
17992                 error "bad symbols in name should fail"
17993
17994         do_facet $SINGLEMDS $LCTL --device $mdt \
17995                                 changelog_register -u test_160o &&
17996                 error "the same name registration should fail"
17997
17998         do_facet $SINGLEMDS $LCTL --device $mdt \
17999                         changelog_register -u test_160toolongname &&
18000                 error "too long name registration should fail"
18001
18002         changelog_chmask "MARK+HSM"
18003         lctl get_param mdd.*.changelog*mask
18004         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18005         changelog_users $SINGLEMDS | grep -q $cl_user ||
18006                 error "User $cl_user not found in changelog_users"
18007         #verify username
18008         echo $cl_user | grep -q test_160o ||
18009                 error "User $cl_user has no specific name 'test160o'"
18010
18011         # change something
18012         changelog_clear 0 || error "changelog_clear failed"
18013         # generate some changelog records to accumulate on MDT0
18014         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18015         touch $DIR/$tdir/$tfile                 # open 1
18016
18017         OPENS=$(changelog_dump | grep -c "OPEN")
18018         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18019
18020         # must be no MKDIR it wasn't set as user mask
18021         MKDIR=$(changelog_dump | grep -c "MKDIR")
18022         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18023
18024         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18025                                 mdd.$mdt.changelog_current_mask -n)
18026         # register maskless user
18027         changelog_register || error "changelog_register failed"
18028         # effective mask should be not changed because it is not minimal
18029         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18030                                 mdd.$mdt.changelog_current_mask -n)
18031         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18032         # set server mask to minimal value
18033         changelog_chmask "MARK"
18034         # check effective mask again, should be treated as DEFMASK now
18035         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18036                                 mdd.$mdt.changelog_current_mask -n)
18037         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18038
18039         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18040                 # set server mask back to some value
18041                 changelog_chmask "CLOSE,UNLNK"
18042                 # check effective mask again, should not remain as DEFMASK
18043                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18044                                 mdd.$mdt.changelog_current_mask -n)
18045                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18046         fi
18047
18048         do_facet $SINGLEMDS $LCTL --device $mdt \
18049                                 changelog_deregister -u test_160o ||
18050                 error "cannot deregister by name"
18051 }
18052 run_test 160o "changelog user name and mask"
18053
18054 test_160p() {
18055         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18056         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18057                 skip "Need MDS version at least 2.14.51"
18058         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18059         local cl_users
18060         local cl_user1
18061         local entry_count
18062
18063         # Create a user
18064         changelog_register || error "first changelog_register failed"
18065
18066         cl_users=(${CL_USERS[mds1]})
18067         cl_user1="${cl_users[0]}"
18068
18069         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18070         createmany -m $DIR/$tdir/$tfile 50 ||
18071                 error "create $DIR/$tdir/$tfile failed"
18072         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18073         rm -rf $DIR/$tdir
18074
18075         # check changelogs have been generated
18076         entry_count=$(changelog_dump | wc -l)
18077         ((entry_count != 0)) || error "no changelog entries found"
18078
18079         # remove changelog_users and check that orphan entries are removed
18080         stop mds1
18081         local dev=$(mdsdevname 1)
18082         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18083         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18084         entry_count=$(changelog_dump | wc -l)
18085         ((entry_count == 0)) ||
18086                 error "found $entry_count changelog entries, expected none"
18087 }
18088 run_test 160p "Changelog orphan cleanup with no users"
18089
18090 test_160q() {
18091         local mdt="$(facet_svc $SINGLEMDS)"
18092         local clu
18093
18094         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18095         remote_mds_nodsh && skip "remote MDS with nodsh"
18096         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18097                 skip "Need MDS version at least 2.14.54"
18098
18099         # set server mask to minimal value like server init does
18100         changelog_chmask "MARK"
18101         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18102                 error "changelog_register failed"
18103         # check effective mask again, should be treated as DEFMASK now
18104         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18105                                 mdd.$mdt.changelog_current_mask -n)
18106         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18107                 error "changelog_deregister failed"
18108         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18109 }
18110 run_test 160q "changelog effective mask is DEFMASK if not set"
18111
18112 test_160s() {
18113         remote_mds_nodsh && skip "remote MDS with nodsh"
18114         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18115                 skip "Need MDS version at least 2.14.55"
18116
18117         local mdts=$(comma_list $(mdts_nodes))
18118
18119         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18120         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18121                                        fail_val=$((24 * 3600 * 10))
18122
18123         # Create a user which is 10 days old
18124         changelog_register || error "first changelog_register failed"
18125         local cl_users
18126         declare -A cl_user1
18127         local i
18128
18129         # generate some changelog records to accumulate on each MDT
18130         # use all_char because created files should be evenly distributed
18131         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18132                 error "test_mkdir $tdir failed"
18133         for ((i = 0; i < MDSCOUNT; i++)); do
18134                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18135                         error "create $DIR/$tdir/d$i.1 failed"
18136         done
18137
18138         # check changelogs have been generated
18139         local nbcl=$(changelog_dump | wc -l)
18140         (( nbcl > 0 )) || error "no changelogs found"
18141
18142         # reduce the max_idle_indexes value to make sure we exceed it
18143         for param in "changelog_max_idle_indexes=2097446912" \
18144                      "changelog_max_idle_time=2592000" \
18145                      "changelog_gc=1" \
18146                      "changelog_min_gc_interval=2"; do
18147                 local MDT0=$(facet_svc $SINGLEMDS)
18148                 local var="${param%=*}"
18149                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18150
18151                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18152                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18153                         error "unable to set mdd.*.$param"
18154         done
18155
18156         local start=$SECONDS
18157         for i in $(seq $MDSCOUNT); do
18158                 cl_users=(${CL_USERS[mds$i]})
18159                 cl_user1[mds$i]="${cl_users[0]}"
18160
18161                 [[ -n "${cl_user1[mds$i]}" ]] ||
18162                         error "mds$i: no user registered"
18163         done
18164
18165         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18166         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18167
18168         # ensure we are past the previous changelog_min_gc_interval set above
18169         local sleep2=$((start + 2 - SECONDS))
18170         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18171
18172         # Generate one more changelog to trigger GC
18173         for ((i = 0; i < MDSCOUNT; i++)); do
18174                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18175                         error "create $DIR/$tdir/d$i.3 failed"
18176         done
18177
18178         # ensure gc thread is done
18179         for node in $(mdts_nodes); do
18180                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18181                         error "$node: GC-thread not done"
18182         done
18183
18184         do_nodes $mdts $LCTL set_param fail_loc=0
18185
18186         for (( i = 1; i <= MDSCOUNT; i++ )); do
18187                 # check cl_user1 is purged
18188                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18189                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18190         done
18191         return 0
18192 }
18193 run_test 160s "changelog garbage collect on idle records * time"
18194
18195 test_160t() {
18196         remote_mds_nodsh && skip "remote MDS with nodsh"
18197         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18198                 skip "Need MDS version at least 2.15.50"
18199
18200         local MDT0=$(facet_svc $SINGLEMDS)
18201         local cl_users
18202         local cl_user1
18203         local cl_user2
18204         local start
18205
18206         changelog_register --user user1 -m all ||
18207                 error "user1 failed to register"
18208
18209         mkdir_on_mdt0 $DIR/$tdir
18210         # create default overstripe to maximize changelog size
18211         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18212         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18213         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18214
18215         # user2 consumes less records so less space
18216         changelog_register --user user2 || error "user2 failed to register"
18217         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18218         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18219
18220         # check changelogs have been generated
18221         local nbcl=$(changelog_dump | wc -l)
18222         (( nbcl > 0 )) || error "no changelogs found"
18223
18224         # reduce the changelog_min_gc_interval to force check
18225         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18226                 local var="${param%=*}"
18227                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18228
18229                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18230                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18231                         error "unable to set mdd.*.$param"
18232         done
18233
18234         start=$SECONDS
18235         cl_users=(${CL_USERS[mds1]})
18236         cl_user1="${cl_users[0]}"
18237         cl_user2="${cl_users[1]}"
18238
18239         [[ -n $cl_user1 ]] ||
18240                 error "mds1: user #1 isn't registered"
18241         [[ -n $cl_user2 ]] ||
18242                 error "mds1: user #2 isn't registered"
18243
18244         # ensure we are past the previous changelog_min_gc_interval set above
18245         local sleep2=$((start + 2 - SECONDS))
18246         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18247
18248         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18249         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18250                         fail_val=$(((llog_size1 + llog_size2) / 2))
18251
18252         # Generate more changelog to trigger GC
18253         createmany -o $DIR/$tdir/u3_ 4 ||
18254                 error "create failed for more files"
18255
18256         # ensure gc thread is done
18257         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18258                 error "mds1: GC-thread not done"
18259
18260         do_facet mds1 $LCTL set_param fail_loc=0
18261
18262         # check cl_user1 is purged
18263         changelog_users mds1 | grep -q "$cl_user1" &&
18264                 error "User $cl_user1 is registered"
18265         # check cl_user2 is not purged
18266         changelog_users mds1 | grep -q "$cl_user2" ||
18267                 error "User $cl_user2 is not registered"
18268 }
18269 run_test 160t "changelog garbage collect on lack of space"
18270
18271 test_161a() {
18272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18273
18274         test_mkdir -c1 $DIR/$tdir
18275         cp /etc/hosts $DIR/$tdir/$tfile
18276         test_mkdir -c1 $DIR/$tdir/foo1
18277         test_mkdir -c1 $DIR/$tdir/foo2
18278         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18279         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18280         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18281         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18282         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18283         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18284                 $LFS fid2path $DIR $FID
18285                 error "bad link ea"
18286         fi
18287         # middle
18288         rm $DIR/$tdir/foo2/zachary
18289         # last
18290         rm $DIR/$tdir/foo2/thor
18291         # first
18292         rm $DIR/$tdir/$tfile
18293         # rename
18294         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18295         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18296                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18297         rm $DIR/$tdir/foo2/maggie
18298
18299         # overflow the EA
18300         local longname=$tfile.avg_len_is_thirty_two_
18301         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18302                 error_noexit 'failed to unlink many hardlinks'" EXIT
18303         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18304                 error "failed to hardlink many files"
18305         links=$($LFS fid2path $DIR $FID | wc -l)
18306         echo -n "${links}/1000 links in link EA"
18307         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18308 }
18309 run_test 161a "link ea sanity"
18310
18311 test_161b() {
18312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18313         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18314
18315         local MDTIDX=1
18316         local remote_dir=$DIR/$tdir/remote_dir
18317
18318         mkdir -p $DIR/$tdir
18319         $LFS mkdir -i $MDTIDX $remote_dir ||
18320                 error "create remote directory failed"
18321
18322         cp /etc/hosts $remote_dir/$tfile
18323         mkdir -p $remote_dir/foo1
18324         mkdir -p $remote_dir/foo2
18325         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18326         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18327         ln $remote_dir/$tfile $remote_dir/foo1/luna
18328         ln $remote_dir/$tfile $remote_dir/foo2/thor
18329
18330         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18331                      tr -d ']')
18332         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18333                 $LFS fid2path $DIR $FID
18334                 error "bad link ea"
18335         fi
18336         # middle
18337         rm $remote_dir/foo2/zachary
18338         # last
18339         rm $remote_dir/foo2/thor
18340         # first
18341         rm $remote_dir/$tfile
18342         # rename
18343         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18344         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18345         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18346                 $LFS fid2path $DIR $FID
18347                 error "bad link rename"
18348         fi
18349         rm $remote_dir/foo2/maggie
18350
18351         # overflow the EA
18352         local longname=filename_avg_len_is_thirty_two_
18353         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18354                 error "failed to hardlink many files"
18355         links=$($LFS fid2path $DIR $FID | wc -l)
18356         echo -n "${links}/1000 links in link EA"
18357         [[ ${links} -gt 60 ]] ||
18358                 error "expected at least 60 links in link EA"
18359         unlinkmany $remote_dir/foo2/$longname 1000 ||
18360         error "failed to unlink many hardlinks"
18361 }
18362 run_test 161b "link ea sanity under remote directory"
18363
18364 test_161c() {
18365         remote_mds_nodsh && skip "remote MDS with nodsh"
18366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18367         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18368                 skip "Need MDS version at least 2.1.5"
18369
18370         # define CLF_RENAME_LAST 0x0001
18371         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18372         changelog_register || error "changelog_register failed"
18373
18374         rm -rf $DIR/$tdir
18375         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18376         touch $DIR/$tdir/foo_161c
18377         touch $DIR/$tdir/bar_161c
18378         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18379         changelog_dump | grep RENME | tail -n 5
18380         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18381         changelog_clear 0 || error "changelog_clear failed"
18382         if [ x$flags != "x0x1" ]; then
18383                 error "flag $flags is not 0x1"
18384         fi
18385
18386         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18387         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18388         touch $DIR/$tdir/foo_161c
18389         touch $DIR/$tdir/bar_161c
18390         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18391         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18392         changelog_dump | grep RENME | tail -n 5
18393         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18394         changelog_clear 0 || error "changelog_clear failed"
18395         if [ x$flags != "x0x0" ]; then
18396                 error "flag $flags is not 0x0"
18397         fi
18398         echo "rename overwrite a target having nlink > 1," \
18399                 "changelog record has flags of $flags"
18400
18401         # rename doesn't overwrite a target (changelog flag 0x0)
18402         touch $DIR/$tdir/foo_161c
18403         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18404         changelog_dump | grep RENME | tail -n 5
18405         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18406         changelog_clear 0 || error "changelog_clear failed"
18407         if [ x$flags != "x0x0" ]; then
18408                 error "flag $flags is not 0x0"
18409         fi
18410         echo "rename doesn't overwrite a target," \
18411                 "changelog record has flags of $flags"
18412
18413         # define CLF_UNLINK_LAST 0x0001
18414         # unlink a file having nlink = 1 (changelog flag 0x1)
18415         rm -f $DIR/$tdir/foo2_161c
18416         changelog_dump | grep UNLNK | tail -n 5
18417         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18418         changelog_clear 0 || error "changelog_clear failed"
18419         if [ x$flags != "x0x1" ]; then
18420                 error "flag $flags is not 0x1"
18421         fi
18422         echo "unlink a file having nlink = 1," \
18423                 "changelog record has flags of $flags"
18424
18425         # unlink a file having nlink > 1 (changelog flag 0x0)
18426         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18427         rm -f $DIR/$tdir/foobar_161c
18428         changelog_dump | grep UNLNK | tail -n 5
18429         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18430         changelog_clear 0 || error "changelog_clear failed"
18431         if [ x$flags != "x0x0" ]; then
18432                 error "flag $flags is not 0x0"
18433         fi
18434         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18435 }
18436 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18437
18438 test_161d() {
18439         remote_mds_nodsh && skip "remote MDS with nodsh"
18440         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18441
18442         local pid
18443         local fid
18444
18445         changelog_register || error "changelog_register failed"
18446
18447         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18448         # interfer with $MOUNT/.lustre/fid/ access
18449         mkdir $DIR/$tdir
18450         [[ $? -eq 0 ]] || error "mkdir failed"
18451
18452         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18453         $LCTL set_param fail_loc=0x8000140c
18454         # 5s pause
18455         $LCTL set_param fail_val=5
18456
18457         # create file
18458         echo foofoo > $DIR/$tdir/$tfile &
18459         pid=$!
18460
18461         # wait for create to be delayed
18462         sleep 2
18463
18464         ps -p $pid
18465         [[ $? -eq 0 ]] || error "create should be blocked"
18466
18467         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18468         stack_trap "rm -f $tempfile"
18469         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18470         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18471         # some delay may occur during ChangeLog publishing and file read just
18472         # above, that could allow file write to happen finally
18473         [[ -s $tempfile ]] && echo "file should be empty"
18474
18475         $LCTL set_param fail_loc=0
18476
18477         wait $pid
18478         [[ $? -eq 0 ]] || error "create failed"
18479 }
18480 run_test 161d "create with concurrent .lustre/fid access"
18481
18482 check_path() {
18483         local expected="$1"
18484         shift
18485         local fid="$2"
18486
18487         local path
18488         path=$($LFS fid2path "$@")
18489         local rc=$?
18490
18491         if [ $rc -ne 0 ]; then
18492                 error "path looked up of '$expected' failed: rc=$rc"
18493         elif [ "$path" != "$expected" ]; then
18494                 error "path looked up '$path' instead of '$expected'"
18495         else
18496                 echo "FID '$fid' resolves to path '$path' as expected"
18497         fi
18498 }
18499
18500 test_162a() { # was test_162
18501         test_mkdir -p -c1 $DIR/$tdir/d2
18502         touch $DIR/$tdir/d2/$tfile
18503         touch $DIR/$tdir/d2/x1
18504         touch $DIR/$tdir/d2/x2
18505         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18506         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18507         # regular file
18508         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18509         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18510
18511         # softlink
18512         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18513         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18514         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18515
18516         # softlink to wrong file
18517         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18518         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18519         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18520
18521         # hardlink
18522         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18523         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18524         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18525         # fid2path dir/fsname should both work
18526         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18527         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18528
18529         # hardlink count: check that there are 2 links
18530         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18531         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18532
18533         # hardlink indexing: remove the first link
18534         rm $DIR/$tdir/d2/p/q/r/hlink
18535         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18536 }
18537 run_test 162a "path lookup sanity"
18538
18539 test_162b() {
18540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18542
18543         mkdir $DIR/$tdir
18544         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18545                                 error "create striped dir failed"
18546
18547         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18548                                         tail -n 1 | awk '{print $2}')
18549         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18550
18551         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18552         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18553
18554         # regular file
18555         for ((i=0;i<5;i++)); do
18556                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18557                         error "get fid for f$i failed"
18558                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18559
18560                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18561                         error "get fid for d$i failed"
18562                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18563         done
18564
18565         return 0
18566 }
18567 run_test 162b "striped directory path lookup sanity"
18568
18569 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18570 test_162c() {
18571         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18572                 skip "Need MDS version at least 2.7.51"
18573
18574         local lpath=$tdir.local
18575         local rpath=$tdir.remote
18576
18577         test_mkdir $DIR/$lpath
18578         test_mkdir $DIR/$rpath
18579
18580         for ((i = 0; i <= 101; i++)); do
18581                 lpath="$lpath/$i"
18582                 mkdir $DIR/$lpath
18583                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18584                         error "get fid for local directory $DIR/$lpath failed"
18585                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18586
18587                 rpath="$rpath/$i"
18588                 test_mkdir $DIR/$rpath
18589                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18590                         error "get fid for remote directory $DIR/$rpath failed"
18591                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18592         done
18593
18594         return 0
18595 }
18596 run_test 162c "fid2path works with paths 100 or more directories deep"
18597
18598 oalr_event_count() {
18599         local event="${1}"
18600         local trace="${2}"
18601
18602         awk -v name="${FSNAME}-OST0000" \
18603             -v event="${event}" \
18604             '$1 == "TRACE" && $2 == event && $3 == name' \
18605             "${trace}" |
18606         wc -l
18607 }
18608
18609 oalr_expect_event_count() {
18610         local event="${1}"
18611         local trace="${2}"
18612         local expect="${3}"
18613         local count
18614
18615         count=$(oalr_event_count "${event}" "${trace}")
18616         if ((count == expect)); then
18617                 return 0
18618         fi
18619
18620         error_noexit "${event} event count was '${count}', expected ${expect}"
18621         cat "${trace}" >&2
18622         exit 1
18623 }
18624
18625 cleanup_165() {
18626         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18627         stop ost1
18628         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18629 }
18630
18631 setup_165() {
18632         sync # Flush previous IOs so we can count log entries.
18633         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18634         stack_trap cleanup_165 EXIT
18635 }
18636
18637 test_165a() {
18638         local trace="/tmp/${tfile}.trace"
18639         local rc
18640         local count
18641
18642         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18643                 skip "OFD access log unsupported"
18644
18645         setup_165
18646         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18647         sleep 5
18648
18649         do_facet ost1 ofd_access_log_reader --list
18650         stop ost1
18651
18652         do_facet ost1 killall -TERM ofd_access_log_reader
18653         wait
18654         rc=$?
18655
18656         if ((rc != 0)); then
18657                 error "ofd_access_log_reader exited with rc = '${rc}'"
18658         fi
18659
18660         # Parse trace file for discovery events:
18661         oalr_expect_event_count alr_log_add "${trace}" 1
18662         oalr_expect_event_count alr_log_eof "${trace}" 1
18663         oalr_expect_event_count alr_log_free "${trace}" 1
18664 }
18665 run_test 165a "ofd access log discovery"
18666
18667 test_165b() {
18668         local trace="/tmp/${tfile}.trace"
18669         local file="${DIR}/${tfile}"
18670         local pfid1
18671         local pfid2
18672         local -a entry
18673         local rc
18674         local count
18675         local size
18676         local flags
18677
18678         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18679                 skip "OFD access log unsupported"
18680
18681         setup_165
18682         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18683         sleep 5
18684
18685         do_facet ost1 ofd_access_log_reader --list
18686
18687         lfs setstripe -c 1 -i 0 "${file}"
18688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18689                 error "cannot create '${file}'"
18690
18691         sleep 5
18692         do_facet ost1 killall -TERM ofd_access_log_reader
18693         wait
18694         rc=$?
18695
18696         if ((rc != 0)); then
18697                 error "ofd_access_log_reader exited with rc = '${rc}'"
18698         fi
18699
18700         oalr_expect_event_count alr_log_entry "${trace}" 1
18701
18702         pfid1=$($LFS path2fid "${file}")
18703
18704         # 1     2             3   4    5     6   7    8    9     10
18705         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18706         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18707
18708         echo "entry = '${entry[*]}'" >&2
18709
18710         pfid2=${entry[4]}
18711         if [[ "${pfid1}" != "${pfid2}" ]]; then
18712                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18713         fi
18714
18715         size=${entry[8]}
18716         if ((size != 1048576)); then
18717                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18718         fi
18719
18720         flags=${entry[10]}
18721         if [[ "${flags}" != "w" ]]; then
18722                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18723         fi
18724
18725         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18726         sleep 5
18727
18728         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18729                 error "cannot read '${file}'"
18730         sleep 5
18731
18732         do_facet ost1 killall -TERM ofd_access_log_reader
18733         wait
18734         rc=$?
18735
18736         if ((rc != 0)); then
18737                 error "ofd_access_log_reader exited with rc = '${rc}'"
18738         fi
18739
18740         oalr_expect_event_count alr_log_entry "${trace}" 1
18741
18742         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18743         echo "entry = '${entry[*]}'" >&2
18744
18745         pfid2=${entry[4]}
18746         if [[ "${pfid1}" != "${pfid2}" ]]; then
18747                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18748         fi
18749
18750         size=${entry[8]}
18751         if ((size != 524288)); then
18752                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18753         fi
18754
18755         flags=${entry[10]}
18756         if [[ "${flags}" != "r" ]]; then
18757                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18758         fi
18759 }
18760 run_test 165b "ofd access log entries are produced and consumed"
18761
18762 test_165c() {
18763         local trace="/tmp/${tfile}.trace"
18764         local file="${DIR}/${tdir}/${tfile}"
18765
18766         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18767                 skip "OFD access log unsupported"
18768
18769         test_mkdir "${DIR}/${tdir}"
18770
18771         setup_165
18772         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18773         sleep 5
18774
18775         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18776
18777         # 4096 / 64 = 64. Create twice as many entries.
18778         for ((i = 0; i < 128; i++)); do
18779                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18780                         error "cannot create file"
18781         done
18782
18783         sync
18784
18785         do_facet ost1 killall -TERM ofd_access_log_reader
18786         wait
18787         rc=$?
18788         if ((rc != 0)); then
18789                 error "ofd_access_log_reader exited with rc = '${rc}'"
18790         fi
18791
18792         unlinkmany  "${file}-%d" 128
18793 }
18794 run_test 165c "full ofd access logs do not block IOs"
18795
18796 oal_get_read_count() {
18797         local stats="$1"
18798
18799         # STATS lustre-OST0001 alr_read_count 1
18800
18801         do_facet ost1 cat "${stats}" |
18802         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18803              END { print count; }'
18804 }
18805
18806 oal_expect_read_count() {
18807         local stats="$1"
18808         local count
18809         local expect="$2"
18810
18811         # Ask ofd_access_log_reader to write stats.
18812         do_facet ost1 killall -USR1 ofd_access_log_reader
18813
18814         # Allow some time for things to happen.
18815         sleep 1
18816
18817         count=$(oal_get_read_count "${stats}")
18818         if ((count == expect)); then
18819                 return 0
18820         fi
18821
18822         error_noexit "bad read count, got ${count}, expected ${expect}"
18823         do_facet ost1 cat "${stats}" >&2
18824         exit 1
18825 }
18826
18827 test_165d() {
18828         local stats="/tmp/${tfile}.stats"
18829         local file="${DIR}/${tdir}/${tfile}"
18830         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18831
18832         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18833                 skip "OFD access log unsupported"
18834
18835         test_mkdir "${DIR}/${tdir}"
18836
18837         setup_165
18838         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18839         sleep 5
18840
18841         lfs setstripe -c 1 -i 0 "${file}"
18842
18843         do_facet ost1 lctl set_param "${param}=rw"
18844         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18845                 error "cannot create '${file}'"
18846         oal_expect_read_count "${stats}" 1
18847
18848         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18849                 error "cannot read '${file}'"
18850         oal_expect_read_count "${stats}" 2
18851
18852         do_facet ost1 lctl set_param "${param}=r"
18853         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18854                 error "cannot create '${file}'"
18855         oal_expect_read_count "${stats}" 2
18856
18857         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18858                 error "cannot read '${file}'"
18859         oal_expect_read_count "${stats}" 3
18860
18861         do_facet ost1 lctl set_param "${param}=w"
18862         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18863                 error "cannot create '${file}'"
18864         oal_expect_read_count "${stats}" 4
18865
18866         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18867                 error "cannot read '${file}'"
18868         oal_expect_read_count "${stats}" 4
18869
18870         do_facet ost1 lctl set_param "${param}=0"
18871         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18872                 error "cannot create '${file}'"
18873         oal_expect_read_count "${stats}" 4
18874
18875         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18876                 error "cannot read '${file}'"
18877         oal_expect_read_count "${stats}" 4
18878
18879         do_facet ost1 killall -TERM ofd_access_log_reader
18880         wait
18881         rc=$?
18882         if ((rc != 0)); then
18883                 error "ofd_access_log_reader exited with rc = '${rc}'"
18884         fi
18885 }
18886 run_test 165d "ofd_access_log mask works"
18887
18888 test_165e() {
18889         local stats="/tmp/${tfile}.stats"
18890         local file0="${DIR}/${tdir}-0/${tfile}"
18891         local file1="${DIR}/${tdir}-1/${tfile}"
18892
18893         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18894                 skip "OFD access log unsupported"
18895
18896         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18897
18898         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18899         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18900
18901         lfs setstripe -c 1 -i 0 "${file0}"
18902         lfs setstripe -c 1 -i 0 "${file1}"
18903
18904         setup_165
18905         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18906         sleep 5
18907
18908         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18909                 error "cannot create '${file0}'"
18910         sync
18911         oal_expect_read_count "${stats}" 0
18912
18913         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18914                 error "cannot create '${file1}'"
18915         sync
18916         oal_expect_read_count "${stats}" 1
18917
18918         do_facet ost1 killall -TERM ofd_access_log_reader
18919         wait
18920         rc=$?
18921         if ((rc != 0)); then
18922                 error "ofd_access_log_reader exited with rc = '${rc}'"
18923         fi
18924 }
18925 run_test 165e "ofd_access_log MDT index filter works"
18926
18927 test_165f() {
18928         local trace="/tmp/${tfile}.trace"
18929         local rc
18930         local count
18931
18932         setup_165
18933         do_facet ost1 timeout 60 ofd_access_log_reader \
18934                 --exit-on-close --debug=- --trace=- > "${trace}" &
18935         sleep 5
18936         stop ost1
18937
18938         wait
18939         rc=$?
18940
18941         if ((rc != 0)); then
18942                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18943                 cat "${trace}"
18944                 exit 1
18945         fi
18946 }
18947 run_test 165f "ofd_access_log_reader --exit-on-close works"
18948
18949 test_169() {
18950         # do directio so as not to populate the page cache
18951         log "creating a 10 Mb file"
18952         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18953                 error "multiop failed while creating a file"
18954         log "starting reads"
18955         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18956         log "truncating the file"
18957         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18958                 error "multiop failed while truncating the file"
18959         log "killing dd"
18960         kill %+ || true # reads might have finished
18961         echo "wait until dd is finished"
18962         wait
18963         log "removing the temporary file"
18964         rm -rf $DIR/$tfile || error "tmp file removal failed"
18965 }
18966 run_test 169 "parallel read and truncate should not deadlock"
18967
18968 test_170() {
18969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18970
18971         $LCTL clear     # bug 18514
18972         $LCTL debug_daemon start $TMP/${tfile}_log_good
18973         touch $DIR/$tfile
18974         $LCTL debug_daemon stop
18975         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18976                 error "sed failed to read log_good"
18977
18978         $LCTL debug_daemon start $TMP/${tfile}_log_good
18979         rm -rf $DIR/$tfile
18980         $LCTL debug_daemon stop
18981
18982         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18983                error "lctl df log_bad failed"
18984
18985         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18986         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18987
18988         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18989         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18990
18991         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18992                 error "bad_line good_line1 good_line2 are empty"
18993
18994         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18995         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18996         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18997
18998         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18999         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19000         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19001
19002         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19003                 error "bad_line_new good_line_new are empty"
19004
19005         local expected_good=$((good_line1 + good_line2*2))
19006
19007         rm -f $TMP/${tfile}*
19008         # LU-231, short malformed line may not be counted into bad lines
19009         if [ $bad_line -ne $bad_line_new ] &&
19010                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19011                 error "expected $bad_line bad lines, but got $bad_line_new"
19012                 return 1
19013         fi
19014
19015         if [ $expected_good -ne $good_line_new ]; then
19016                 error "expected $expected_good good lines, but got $good_line_new"
19017                 return 2
19018         fi
19019         true
19020 }
19021 run_test 170 "test lctl df to handle corrupted log ====================="
19022
19023 test_171() { # bug20592
19024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19025
19026         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19027         $LCTL set_param fail_loc=0x50e
19028         $LCTL set_param fail_val=3000
19029         multiop_bg_pause $DIR/$tfile O_s || true
19030         local MULTIPID=$!
19031         kill -USR1 $MULTIPID
19032         # cause log dump
19033         sleep 3
19034         wait $MULTIPID
19035         if dmesg | grep "recursive fault"; then
19036                 error "caught a recursive fault"
19037         fi
19038         $LCTL set_param fail_loc=0
19039         true
19040 }
19041 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19042
19043 test_172() {
19044
19045         #define OBD_FAIL_OBD_CLEANUP  0x60e
19046         $LCTL set_param fail_loc=0x60e
19047         umount $MOUNT || error "umount $MOUNT failed"
19048         stack_trap "mount_client $MOUNT"
19049
19050         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19051                 error "no client OBDs are remained"
19052
19053         $LCTL dl | while read devno state type name foo; do
19054                 case $type in
19055                 lov|osc|lmv|mdc)
19056                         $LCTL --device $name cleanup
19057                         $LCTL --device $name detach
19058                         ;;
19059                 *)
19060                         # skip server devices
19061                         ;;
19062                 esac
19063         done
19064
19065         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19066                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19067                 error "some client OBDs are still remained"
19068         fi
19069
19070 }
19071 run_test 172 "manual device removal with lctl cleanup/detach ======"
19072
19073 # it would be good to share it with obdfilter-survey/iokit-libecho code
19074 setup_obdecho_osc () {
19075         local rc=0
19076         local ost_nid=$1
19077         local obdfilter_name=$2
19078         echo "Creating new osc for $obdfilter_name on $ost_nid"
19079         # make sure we can find loopback nid
19080         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19081
19082         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19083                            ${obdfilter_name}_osc_UUID || rc=2; }
19084         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19085                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19086         return $rc
19087 }
19088
19089 cleanup_obdecho_osc () {
19090         local obdfilter_name=$1
19091         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19092         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19093         return 0
19094 }
19095
19096 obdecho_test() {
19097         local OBD=$1
19098         local node=$2
19099         local pages=${3:-64}
19100         local rc=0
19101         local id
19102
19103         local count=10
19104         local obd_size=$(get_obd_size $node $OBD)
19105         local page_size=$(get_page_size $node)
19106         if [[ -n "$obd_size" ]]; then
19107                 local new_count=$((obd_size / (pages * page_size / 1024)))
19108                 [[ $new_count -ge $count ]] || count=$new_count
19109         fi
19110
19111         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19112         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19113                            rc=2; }
19114         if [ $rc -eq 0 ]; then
19115             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19116             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19117         fi
19118         echo "New object id is $id"
19119         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19120                            rc=4; }
19121         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19122                            "test_brw $count w v $pages $id" || rc=4; }
19123         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19124                            rc=4; }
19125         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19126                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19127         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19128                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19129         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19130         return $rc
19131 }
19132
19133 test_180a() {
19134         skip "obdecho on osc is no longer supported"
19135 }
19136 run_test 180a "test obdecho on osc"
19137
19138 test_180b() {
19139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19140         remote_ost_nodsh && skip "remote OST with nodsh"
19141
19142         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19143                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19144                 error "failed to load module obdecho"
19145
19146         local target=$(do_facet ost1 $LCTL dl |
19147                        awk '/obdfilter/ { print $4; exit; }')
19148
19149         if [ -n "$target" ]; then
19150                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19151         else
19152                 do_facet ost1 $LCTL dl
19153                 error "there is no obdfilter target on ost1"
19154         fi
19155 }
19156 run_test 180b "test obdecho directly on obdfilter"
19157
19158 test_180c() { # LU-2598
19159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19160         remote_ost_nodsh && skip "remote OST with nodsh"
19161         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19162                 skip "Need MDS version at least 2.4.0"
19163
19164         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19165                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19166                 error "failed to load module obdecho"
19167
19168         local target=$(do_facet ost1 $LCTL dl |
19169                        awk '/obdfilter/ { print $4; exit; }')
19170
19171         if [ -n "$target" ]; then
19172                 local pages=16384 # 64MB bulk I/O RPC size
19173
19174                 obdecho_test "$target" ost1 "$pages" ||
19175                         error "obdecho_test with pages=$pages failed with $?"
19176         else
19177                 do_facet ost1 $LCTL dl
19178                 error "there is no obdfilter target on ost1"
19179         fi
19180 }
19181 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19182
19183 test_181() { # bug 22177
19184         test_mkdir $DIR/$tdir
19185         # create enough files to index the directory
19186         createmany -o $DIR/$tdir/foobar 4000
19187         # print attributes for debug purpose
19188         lsattr -d .
19189         # open dir
19190         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19191         MULTIPID=$!
19192         # remove the files & current working dir
19193         unlinkmany $DIR/$tdir/foobar 4000
19194         rmdir $DIR/$tdir
19195         kill -USR1 $MULTIPID
19196         wait $MULTIPID
19197         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19198         return 0
19199 }
19200 run_test 181 "Test open-unlinked dir ========================"
19201
19202 test_182a() {
19203         local fcount=1000
19204         local tcount=10
19205
19206         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19207
19208         $LCTL set_param mdc.*.rpc_stats=clear
19209
19210         for (( i = 0; i < $tcount; i++ )) ; do
19211                 mkdir $DIR/$tdir/$i
19212         done
19213
19214         for (( i = 0; i < $tcount; i++ )) ; do
19215                 createmany -o $DIR/$tdir/$i/f- $fcount &
19216         done
19217         wait
19218
19219         for (( i = 0; i < $tcount; i++ )) ; do
19220                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19221         done
19222         wait
19223
19224         $LCTL get_param mdc.*.rpc_stats
19225
19226         rm -rf $DIR/$tdir
19227 }
19228 run_test 182a "Test parallel modify metadata operations from mdc"
19229
19230 test_182b() {
19231         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19232         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19233         local dcount=1000
19234         local tcount=10
19235         local stime
19236         local etime
19237         local delta
19238
19239         do_facet mds1 $LCTL list_param \
19240                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19241                 skip "MDS lacks parallel RPC handling"
19242
19243         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19244
19245         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19246                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19247
19248         stime=$(date +%s)
19249         createmany -i 0 -d $DIR/$tdir/t- $tcount
19250
19251         for (( i = 0; i < $tcount; i++ )) ; do
19252                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19253         done
19254         wait
19255         etime=$(date +%s)
19256         delta=$((etime - stime))
19257         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19258
19259         stime=$(date +%s)
19260         for (( i = 0; i < $tcount; i++ )) ; do
19261                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19262         done
19263         wait
19264         etime=$(date +%s)
19265         delta=$((etime - stime))
19266         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19267
19268         rm -rf $DIR/$tdir
19269
19270         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19271
19272         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19273
19274         stime=$(date +%s)
19275         createmany -i 0 -d $DIR/$tdir/t- $tcount
19276
19277         for (( i = 0; i < $tcount; i++ )) ; do
19278                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19279         done
19280         wait
19281         etime=$(date +%s)
19282         delta=$((etime - stime))
19283         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19284
19285         stime=$(date +%s)
19286         for (( i = 0; i < $tcount; i++ )) ; do
19287                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19288         done
19289         wait
19290         etime=$(date +%s)
19291         delta=$((etime - stime))
19292         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19293
19294         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19295 }
19296 run_test 182b "Test parallel modify metadata operations from osp"
19297
19298 test_183() { # LU-2275
19299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19300         remote_mds_nodsh && skip "remote MDS with nodsh"
19301         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19302                 skip "Need MDS version at least 2.3.56"
19303
19304         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19305         echo aaa > $DIR/$tdir/$tfile
19306
19307 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19308         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19309
19310         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19311         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19312
19313         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19314
19315         # Flush negative dentry cache
19316         touch $DIR/$tdir/$tfile
19317
19318         # We are not checking for any leaked references here, they'll
19319         # become evident next time we do cleanup with module unload.
19320         rm -rf $DIR/$tdir
19321 }
19322 run_test 183 "No crash or request leak in case of strange dispositions ========"
19323
19324 # test suite 184 is for LU-2016, LU-2017
19325 test_184a() {
19326         check_swap_layouts_support
19327
19328         dir0=$DIR/$tdir/$testnum
19329         test_mkdir -p -c1 $dir0
19330         ref1=/etc/passwd
19331         ref2=/etc/group
19332         file1=$dir0/f1
19333         file2=$dir0/f2
19334         $LFS setstripe -c1 $file1
19335         cp $ref1 $file1
19336         $LFS setstripe -c2 $file2
19337         cp $ref2 $file2
19338         gen1=$($LFS getstripe -g $file1)
19339         gen2=$($LFS getstripe -g $file2)
19340
19341         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19342         gen=$($LFS getstripe -g $file1)
19343         [[ $gen1 != $gen ]] ||
19344                 error "Layout generation on $file1 does not change"
19345         gen=$($LFS getstripe -g $file2)
19346         [[ $gen2 != $gen ]] ||
19347                 error "Layout generation on $file2 does not change"
19348
19349         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19350         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19351
19352         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19353 }
19354 run_test 184a "Basic layout swap"
19355
19356 test_184b() {
19357         check_swap_layouts_support
19358
19359         dir0=$DIR/$tdir/$testnum
19360         mkdir -p $dir0 || error "creating dir $dir0"
19361         file1=$dir0/f1
19362         file2=$dir0/f2
19363         file3=$dir0/f3
19364         dir1=$dir0/d1
19365         dir2=$dir0/d2
19366         mkdir $dir1 $dir2
19367         $LFS setstripe -c1 $file1
19368         $LFS setstripe -c2 $file2
19369         $LFS setstripe -c1 $file3
19370         chown $RUNAS_ID $file3
19371         gen1=$($LFS getstripe -g $file1)
19372         gen2=$($LFS getstripe -g $file2)
19373
19374         $LFS swap_layouts $dir1 $dir2 &&
19375                 error "swap of directories layouts should fail"
19376         $LFS swap_layouts $dir1 $file1 &&
19377                 error "swap of directory and file layouts should fail"
19378         $RUNAS $LFS swap_layouts $file1 $file2 &&
19379                 error "swap of file we cannot write should fail"
19380         $LFS swap_layouts $file1 $file3 &&
19381                 error "swap of file with different owner should fail"
19382         /bin/true # to clear error code
19383 }
19384 run_test 184b "Forbidden layout swap (will generate errors)"
19385
19386 test_184c() {
19387         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19388         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19389         check_swap_layouts_support
19390         check_swap_layout_no_dom $DIR
19391
19392         local dir0=$DIR/$tdir/$testnum
19393         mkdir -p $dir0 || error "creating dir $dir0"
19394
19395         local ref1=$dir0/ref1
19396         local ref2=$dir0/ref2
19397         local file1=$dir0/file1
19398         local file2=$dir0/file2
19399         # create a file large enough for the concurrent test
19400         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19401         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19402         echo "ref file size: ref1($(stat -c %s $ref1))," \
19403              "ref2($(stat -c %s $ref2))"
19404
19405         cp $ref2 $file2
19406         dd if=$ref1 of=$file1 bs=16k &
19407         local DD_PID=$!
19408
19409         # Make sure dd starts to copy file, but wait at most 5 seconds
19410         local loops=0
19411         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19412
19413         $LFS swap_layouts $file1 $file2
19414         local rc=$?
19415         wait $DD_PID
19416         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19417         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19418
19419         # how many bytes copied before swapping layout
19420         local copied=$(stat -c %s $file2)
19421         local remaining=$(stat -c %s $ref1)
19422         remaining=$((remaining - copied))
19423         echo "Copied $copied bytes before swapping layout..."
19424
19425         cmp -n $copied $file1 $ref2 | grep differ &&
19426                 error "Content mismatch [0, $copied) of ref2 and file1"
19427         cmp -n $copied $file2 $ref1 ||
19428                 error "Content mismatch [0, $copied) of ref1 and file2"
19429         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19430                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19431
19432         # clean up
19433         rm -f $ref1 $ref2 $file1 $file2
19434 }
19435 run_test 184c "Concurrent write and layout swap"
19436
19437 test_184d() {
19438         check_swap_layouts_support
19439         check_swap_layout_no_dom $DIR
19440         [ -z "$(which getfattr 2>/dev/null)" ] &&
19441                 skip_env "no getfattr command"
19442
19443         local file1=$DIR/$tdir/$tfile-1
19444         local file2=$DIR/$tdir/$tfile-2
19445         local file3=$DIR/$tdir/$tfile-3
19446         local lovea1
19447         local lovea2
19448
19449         mkdir -p $DIR/$tdir
19450         touch $file1 || error "create $file1 failed"
19451         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19452                 error "create $file2 failed"
19453         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19454                 error "create $file3 failed"
19455         lovea1=$(get_layout_param $file1)
19456
19457         $LFS swap_layouts $file2 $file3 ||
19458                 error "swap $file2 $file3 layouts failed"
19459         $LFS swap_layouts $file1 $file2 ||
19460                 error "swap $file1 $file2 layouts failed"
19461
19462         lovea2=$(get_layout_param $file2)
19463         echo "$lovea1"
19464         echo "$lovea2"
19465         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19466
19467         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19468         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19469 }
19470 run_test 184d "allow stripeless layouts swap"
19471
19472 test_184e() {
19473         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19474                 skip "Need MDS version at least 2.6.94"
19475         check_swap_layouts_support
19476         check_swap_layout_no_dom $DIR
19477         [ -z "$(which getfattr 2>/dev/null)" ] &&
19478                 skip_env "no getfattr command"
19479
19480         local file1=$DIR/$tdir/$tfile-1
19481         local file2=$DIR/$tdir/$tfile-2
19482         local file3=$DIR/$tdir/$tfile-3
19483         local lovea
19484
19485         mkdir -p $DIR/$tdir
19486         touch $file1 || error "create $file1 failed"
19487         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19488                 error "create $file2 failed"
19489         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19490                 error "create $file3 failed"
19491
19492         $LFS swap_layouts $file1 $file2 ||
19493                 error "swap $file1 $file2 layouts failed"
19494
19495         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19496         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19497
19498         echo 123 > $file1 || error "Should be able to write into $file1"
19499
19500         $LFS swap_layouts $file1 $file3 ||
19501                 error "swap $file1 $file3 layouts failed"
19502
19503         echo 123 > $file1 || error "Should be able to write into $file1"
19504
19505         rm -rf $file1 $file2 $file3
19506 }
19507 run_test 184e "Recreate layout after stripeless layout swaps"
19508
19509 test_184f() {
19510         # Create a file with name longer than sizeof(struct stat) ==
19511         # 144 to see if we can get chars from the file name to appear
19512         # in the returned striping. Note that 'f' == 0x66.
19513         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19514
19515         mkdir -p $DIR/$tdir
19516         mcreate $DIR/$tdir/$file
19517         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19518                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19519         fi
19520 }
19521 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19522
19523 test_185() { # LU-2441
19524         # LU-3553 - no volatile file support in old servers
19525         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19526                 skip "Need MDS version at least 2.3.60"
19527
19528         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19529         touch $DIR/$tdir/spoo
19530         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19531         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19532                 error "cannot create/write a volatile file"
19533         [ "$FILESET" == "" ] &&
19534         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19535                 error "FID is still valid after close"
19536
19537         multiop_bg_pause $DIR/$tdir Vw4096_c
19538         local multi_pid=$!
19539
19540         local OLD_IFS=$IFS
19541         IFS=":"
19542         local fidv=($fid)
19543         IFS=$OLD_IFS
19544         # assume that the next FID for this client is sequential, since stdout
19545         # is unfortunately eaten by multiop_bg_pause
19546         local n=$((${fidv[1]} + 1))
19547         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19548         if [ "$FILESET" == "" ]; then
19549                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19550                         error "FID is missing before close"
19551         fi
19552         kill -USR1 $multi_pid
19553         # 1 second delay, so if mtime change we will see it
19554         sleep 1
19555         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19556         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19557 }
19558 run_test 185 "Volatile file support"
19559
19560 function create_check_volatile() {
19561         local idx=$1
19562         local tgt
19563
19564         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19565         local PID=$!
19566         sleep 1
19567         local FID=$(cat /tmp/${tfile}.fid)
19568         [ "$FID" == "" ] && error "can't get FID for volatile"
19569         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19570         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19571         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19572         kill -USR1 $PID
19573         wait
19574         sleep 1
19575         cancel_lru_locks mdc # flush opencache
19576         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19577         return 0
19578 }
19579
19580 test_185a(){
19581         # LU-12516 - volatile creation via .lustre
19582         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19583                 skip "Need MDS version at least 2.3.55"
19584
19585         create_check_volatile 0
19586         [ $MDSCOUNT -lt 2 ] && return 0
19587
19588         # DNE case
19589         create_check_volatile 1
19590
19591         return 0
19592 }
19593 run_test 185a "Volatile file creation in .lustre/fid/"
19594
19595 test_187a() {
19596         remote_mds_nodsh && skip "remote MDS with nodsh"
19597         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19598                 skip "Need MDS version at least 2.3.0"
19599
19600         local dir0=$DIR/$tdir/$testnum
19601         mkdir -p $dir0 || error "creating dir $dir0"
19602
19603         local file=$dir0/file1
19604         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19605         stack_trap "rm -f $file"
19606         local dv1=$($LFS data_version $file)
19607         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19608         local dv2=$($LFS data_version $file)
19609         [[ $dv1 != $dv2 ]] ||
19610                 error "data version did not change on write $dv1 == $dv2"
19611 }
19612 run_test 187a "Test data version change"
19613
19614 test_187b() {
19615         remote_mds_nodsh && skip "remote MDS with nodsh"
19616         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19617                 skip "Need MDS version at least 2.3.0"
19618
19619         local dir0=$DIR/$tdir/$testnum
19620         mkdir -p $dir0 || error "creating dir $dir0"
19621
19622         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19623         [[ ${DV[0]} != ${DV[1]} ]] ||
19624                 error "data version did not change on write"\
19625                       " ${DV[0]} == ${DV[1]}"
19626
19627         # clean up
19628         rm -f $file1
19629 }
19630 run_test 187b "Test data version change on volatile file"
19631
19632 test_200() {
19633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19634         remote_mgs_nodsh && skip "remote MGS with nodsh"
19635         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19636
19637         local POOL=${POOL:-cea1}
19638         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19639         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19640         # Pool OST targets
19641         local first_ost=0
19642         local last_ost=$(($OSTCOUNT - 1))
19643         local ost_step=2
19644         local ost_list=$(seq $first_ost $ost_step $last_ost)
19645         local ost_range="$first_ost $last_ost $ost_step"
19646         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19647         local file_dir=$POOL_ROOT/file_tst
19648         local subdir=$test_path/subdir
19649         local rc=0
19650
19651         while : ; do
19652                 # former test_200a test_200b
19653                 pool_add $POOL                          || { rc=$? ; break; }
19654                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19655                 # former test_200c test_200d
19656                 mkdir -p $test_path
19657                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19658                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19659                 mkdir -p $subdir
19660                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19661                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19662                                                         || { rc=$? ; break; }
19663                 # former test_200e test_200f
19664                 local files=$((OSTCOUNT*3))
19665                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19666                                                         || { rc=$? ; break; }
19667                 pool_create_files $POOL $file_dir $files "$ost_list" \
19668                                                         || { rc=$? ; break; }
19669                 # former test_200g test_200h
19670                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19671                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19672
19673                 # former test_201a test_201b test_201c
19674                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19675
19676                 local f=$test_path/$tfile
19677                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19678                 pool_remove $POOL $f                    || { rc=$? ; break; }
19679                 break
19680         done
19681
19682         destroy_test_pools
19683
19684         return $rc
19685 }
19686 run_test 200 "OST pools"
19687
19688 # usage: default_attr <count | size | offset>
19689 default_attr() {
19690         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19691 }
19692
19693 # usage: check_default_stripe_attr
19694 check_default_stripe_attr() {
19695         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19696         case $1 in
19697         --stripe-count|-c)
19698                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19699         --stripe-size|-S)
19700                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19701         --stripe-index|-i)
19702                 EXPECTED=-1;;
19703         *)
19704                 error "unknown getstripe attr '$1'"
19705         esac
19706
19707         [ $ACTUAL == $EXPECTED ] ||
19708                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19709 }
19710
19711 test_204a() {
19712         test_mkdir $DIR/$tdir
19713         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19714
19715         check_default_stripe_attr --stripe-count
19716         check_default_stripe_attr --stripe-size
19717         check_default_stripe_attr --stripe-index
19718 }
19719 run_test 204a "Print default stripe attributes"
19720
19721 test_204b() {
19722         test_mkdir $DIR/$tdir
19723         $LFS setstripe --stripe-count 1 $DIR/$tdir
19724
19725         check_default_stripe_attr --stripe-size
19726         check_default_stripe_attr --stripe-index
19727 }
19728 run_test 204b "Print default stripe size and offset"
19729
19730 test_204c() {
19731         test_mkdir $DIR/$tdir
19732         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19733
19734         check_default_stripe_attr --stripe-count
19735         check_default_stripe_attr --stripe-index
19736 }
19737 run_test 204c "Print default stripe count and offset"
19738
19739 test_204d() {
19740         test_mkdir $DIR/$tdir
19741         $LFS setstripe --stripe-index 0 $DIR/$tdir
19742
19743         check_default_stripe_attr --stripe-count
19744         check_default_stripe_attr --stripe-size
19745 }
19746 run_test 204d "Print default stripe count and size"
19747
19748 test_204e() {
19749         test_mkdir $DIR/$tdir
19750         $LFS setstripe -d $DIR/$tdir
19751
19752         # LU-16904 check if root is set as PFL layout
19753         local numcomp=$($LFS getstripe --component-count $MOUNT)
19754
19755         if [[ $numcomp -gt 0 ]]; then
19756                 check_default_stripe_attr --stripe-count
19757         else
19758                 check_default_stripe_attr --stripe-count --raw
19759         fi
19760         check_default_stripe_attr --stripe-size --raw
19761         check_default_stripe_attr --stripe-index --raw
19762 }
19763 run_test 204e "Print raw stripe attributes"
19764
19765 test_204f() {
19766         test_mkdir $DIR/$tdir
19767         $LFS setstripe --stripe-count 1 $DIR/$tdir
19768
19769         check_default_stripe_attr --stripe-size --raw
19770         check_default_stripe_attr --stripe-index --raw
19771 }
19772 run_test 204f "Print raw stripe size and offset"
19773
19774 test_204g() {
19775         test_mkdir $DIR/$tdir
19776         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19777
19778         check_default_stripe_attr --stripe-count --raw
19779         check_default_stripe_attr --stripe-index --raw
19780 }
19781 run_test 204g "Print raw stripe count and offset"
19782
19783 test_204h() {
19784         test_mkdir $DIR/$tdir
19785         $LFS setstripe --stripe-index 0 $DIR/$tdir
19786
19787         check_default_stripe_attr --stripe-count --raw
19788         check_default_stripe_attr --stripe-size --raw
19789 }
19790 run_test 204h "Print raw stripe count and size"
19791
19792 # Figure out which job scheduler is being used, if any,
19793 # or use a fake one
19794 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19795         JOBENV=SLURM_JOB_ID
19796 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19797         JOBENV=LSB_JOBID
19798 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19799         JOBENV=PBS_JOBID
19800 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19801         JOBENV=LOADL_STEP_ID
19802 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19803         JOBENV=JOB_ID
19804 else
19805         $LCTL list_param jobid_name > /dev/null 2>&1
19806         if [ $? -eq 0 ]; then
19807                 JOBENV=nodelocal
19808         else
19809                 JOBENV=FAKE_JOBID
19810         fi
19811 fi
19812 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19813
19814 verify_jobstats() {
19815         local cmd=($1)
19816         shift
19817         local facets="$@"
19818
19819 # we don't really need to clear the stats for this test to work, since each
19820 # command has a unique jobid, but it makes debugging easier if needed.
19821 #       for facet in $facets; do
19822 #               local dev=$(convert_facet2label $facet)
19823 #               # clear old jobstats
19824 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19825 #       done
19826
19827         # use a new JobID for each test, or we might see an old one
19828         [ "$JOBENV" = "FAKE_JOBID" ] &&
19829                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19830
19831         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19832
19833         [ "$JOBENV" = "nodelocal" ] && {
19834                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19835                 $LCTL set_param jobid_name=$FAKE_JOBID
19836                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19837         }
19838
19839         log "Test: ${cmd[*]}"
19840         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19841
19842         if [ $JOBENV = "FAKE_JOBID" ]; then
19843                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19844         else
19845                 ${cmd[*]}
19846         fi
19847
19848         # all files are created on OST0000
19849         for facet in $facets; do
19850                 local stats="*.$(convert_facet2label $facet).job_stats"
19851
19852                 # strip out libtool wrappers for in-tree executables
19853                 if (( $(do_facet $facet lctl get_param $stats |
19854                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19855                         do_facet $facet lctl get_param $stats
19856                         error "No jobstats for $JOBVAL found on $facet::$stats"
19857                 fi
19858         done
19859 }
19860
19861 jobstats_set() {
19862         local new_jobenv=$1
19863
19864         set_persistent_param_and_check client "jobid_var" \
19865                 "$FSNAME.sys.jobid_var" $new_jobenv
19866 }
19867
19868 test_205a() { # Job stats
19869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19870         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19871                 skip "Need MDS version with at least 2.7.1"
19872         remote_mgs_nodsh && skip "remote MGS with nodsh"
19873         remote_mds_nodsh && skip "remote MDS with nodsh"
19874         remote_ost_nodsh && skip "remote OST with nodsh"
19875         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19876                 skip "Server doesn't support jobstats"
19877         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19878
19879         local old_jobenv=$($LCTL get_param -n jobid_var)
19880         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19881         stack_trap "jobstats_set $old_jobenv" EXIT
19882
19883         changelog_register
19884
19885         local old_jobid_name=$($LCTL get_param jobid_name)
19886         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19887
19888         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19889                                 mdt.*.job_cleanup_interval | head -n 1)
19890         local new_interval=5
19891         do_facet $SINGLEMDS \
19892                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19893         stack_trap "do_facet $SINGLEMDS \
19894                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19895         local start=$SECONDS
19896
19897         local cmd
19898         # mkdir
19899         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19900         verify_jobstats "$cmd" "$SINGLEMDS"
19901         # rmdir
19902         cmd="rmdir $DIR/$tdir"
19903         verify_jobstats "$cmd" "$SINGLEMDS"
19904         # mkdir on secondary MDT
19905         if [ $MDSCOUNT -gt 1 ]; then
19906                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19907                 verify_jobstats "$cmd" "mds2"
19908         fi
19909         # mknod
19910         cmd="mknod $DIR/$tfile c 1 3"
19911         verify_jobstats "$cmd" "$SINGLEMDS"
19912         # unlink
19913         cmd="rm -f $DIR/$tfile"
19914         verify_jobstats "$cmd" "$SINGLEMDS"
19915         # create all files on OST0000 so verify_jobstats can find OST stats
19916         # open & close
19917         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19918         verify_jobstats "$cmd" "$SINGLEMDS"
19919         # setattr
19920         cmd="touch $DIR/$tfile"
19921         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19922         # write
19923         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19924         verify_jobstats "$cmd" "ost1"
19925         # read
19926         cancel_lru_locks osc
19927         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19928         verify_jobstats "$cmd" "ost1"
19929         # truncate
19930         cmd="$TRUNCATE $DIR/$tfile 0"
19931         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19932         # rename
19933         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19934         verify_jobstats "$cmd" "$SINGLEMDS"
19935         # jobstats expiry - sleep until old stats should be expired
19936         local left=$((new_interval + 5 - (SECONDS - start)))
19937         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19938                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19939                         "0" $left
19940         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19941         verify_jobstats "$cmd" "$SINGLEMDS"
19942         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19943             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19944
19945         # Ensure that jobid are present in changelog (if supported by MDS)
19946         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19947                 changelog_dump | tail -10
19948                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19949                 [ $jobids -eq 9 ] ||
19950                         error "Wrong changelog jobid count $jobids != 9"
19951
19952                 # LU-5862
19953                 JOBENV="disable"
19954                 jobstats_set $JOBENV
19955                 touch $DIR/$tfile
19956                 changelog_dump | grep $tfile
19957                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19958                 [ $jobids -eq 0 ] ||
19959                         error "Unexpected jobids when jobid_var=$JOBENV"
19960         fi
19961
19962         # test '%j' access to environment variable - if supported
19963         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19964                 JOBENV="JOBCOMPLEX"
19965                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19966
19967                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19968         fi
19969
19970         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19971                 JOBENV="JOBCOMPLEX"
19972                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19973
19974                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19975         fi
19976
19977         # test '%j' access to per-session jobid - if supported
19978         if lctl list_param jobid_this_session > /dev/null 2>&1
19979         then
19980                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19981                 lctl set_param jobid_this_session=$USER
19982
19983                 JOBENV="JOBCOMPLEX"
19984                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19985
19986                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19987         fi
19988 }
19989 run_test 205a "Verify job stats"
19990
19991 # LU-13117, LU-13597, LU-16599
19992 test_205b() {
19993         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19994                 skip "Need MDS version at least 2.13.54.91"
19995
19996         local job_stats="mdt.*.job_stats"
19997         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19998
19999         do_facet mds1 $LCTL set_param $job_stats=clear
20000
20001         # Setting jobid_var to USER might not be supported
20002         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20003         $LCTL set_param jobid_var=USER || true
20004         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20005         $LCTL set_param jobid_name="%j.%e.%u"
20006
20007         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20008         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20009                 { do_facet mds1 $LCTL get_param $job_stats;
20010                   error "Unexpected jobid found"; }
20011         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20012                 { do_facet mds1 $LCTL get_param $job_stats;
20013                   error "wrong job_stats format found"; }
20014
20015         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20016                 echo "MDS does not yet escape jobid" && return 0
20017
20018         mkdir_on_mdt0 $DIR/$tdir
20019         $LCTL set_param jobid_var=TEST205b
20020         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20021         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20022                       awk '/has\\x20sp/ {print $3}')
20023         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20024                   error "jobid not escaped"; }
20025
20026         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20027                 # need to run such a command on mds1:
20028                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20029                 #
20030                 # there might be multiple MDTs on single mds server, so need to
20031                 # specifiy MDT0000. Or the command will fail due to other MDTs
20032                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20033                         error "cannot clear escaped jobid in job_stats";
20034         else
20035                 echo "MDS does not support clearing escaped jobid"
20036         fi
20037 }
20038 run_test 205b "Verify job stats jobid and output format"
20039
20040 # LU-13733
20041 test_205c() {
20042         $LCTL set_param llite.*.stats=0
20043         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20044         $LCTL get_param llite.*.stats
20045         $LCTL get_param llite.*.stats | grep \
20046                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20047                         error "wrong client stats format found"
20048 }
20049 run_test 205c "Verify client stats format"
20050
20051 test_205d() {
20052         local file=$DIR/$tdir/$tfile
20053
20054         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20055                 skip "need lustre >= 2.15.53 for lljobstat"
20056         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20057                 skip "need lustre >= 2.15.53 for lljobstat"
20058         verify_yaml_available || skip_env "YAML verification not installed"
20059
20060         test_mkdir -i 0 $DIR/$tdir
20061         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20062         stack_trap "rm -rf $DIR/$tdir"
20063
20064         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20065                 error "failed to write data to $file"
20066         mv $file $file.2
20067
20068         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20069         echo -n 'verify rename_stats...'
20070         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20071                 verify_yaml || error "rename_stats is not valid YAML"
20072         echo " OK"
20073
20074         echo -n 'verify mdt job_stats...'
20075         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20076                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20077         echo " OK"
20078
20079         echo -n 'verify ost job_stats...'
20080         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20081                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20082         echo " OK"
20083 }
20084 run_test 205d "verify the format of some stats files"
20085
20086 test_205e() {
20087         local ops_comma
20088         local file=$DIR/$tdir/$tfile
20089         local -a cli_params
20090
20091         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20092                 skip "need lustre >= 2.15.53 for lljobstat"
20093         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20094                 skip "need lustre >= 2.15.53 for lljobstat"
20095         verify_yaml_available || skip_env "YAML verification not installed"
20096
20097         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20098         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20099         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20100
20101         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20102         stack_trap "rm -rf $DIR/$tdir"
20103
20104         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20105                 error "failed to create $file on ost1"
20106         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20107                 error "failed to write data to $file"
20108
20109         do_facet mds1 "$LCTL get_param *.*.job_stats"
20110         do_facet ost1 "$LCTL get_param *.*.job_stats"
20111
20112         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20113         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20114                 error "The output of lljobstat is not an valid YAML"
20115
20116         # verify that job dd.0 does exist and has some ops on ost1
20117         # typically this line is like:
20118         # - 205e.dd.0:            {ops: 20, ...}
20119         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20120                     awk '$2=="205e.dd.0:" {print $4}')
20121
20122         (( ${ops_comma%,} >= 10 )) ||
20123                 error "cannot find job 205e.dd.0 with ops >= 10"
20124 }
20125 run_test 205e "verify the output of lljobstat"
20126
20127 test_205f() {
20128         verify_yaml_available || skip_env "YAML verification not installed"
20129
20130         # check both qos_ost_weights and qos_mdt_weights
20131         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20132         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20133                 error "qos_ost_weights is not valid YAML"
20134 }
20135 run_test 205f "verify qos_ost_weights YAML format "
20136
20137 __test_205_jobstats_dump() {
20138         local -a pids
20139         local nbr_instance=$1
20140
20141         while true; do
20142                 if (( ${#pids[@]} >= nbr_instance )); then
20143                         wait ${pids[@]}
20144                         pids=()
20145                 fi
20146
20147                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20148                 pids+=( $! )
20149         done
20150 }
20151
20152 __test_205_cleanup() {
20153         kill $@
20154         # Clear all job entries
20155         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20156 }
20157
20158 test_205g() {
20159         local -a mds1_params
20160         local -a cli_params
20161         local pids
20162         local interval=5
20163
20164         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20165         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20166         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20167
20168         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20169         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20170         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20171
20172         # start jobs loop
20173         export TEST205G_ID=205g
20174         stack_trap "unset TEST205G_ID" EXIT
20175         while true; do
20176                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20177         done & pids="$! "
20178
20179         __test_205_jobstats_dump 4 & pids+="$! "
20180         stack_trap "__test_205_cleanup $pids" EXIT INT
20181
20182         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20183 }
20184 run_test 205g "stress test for job_stats procfile"
20185
20186 test_205h() {
20187         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20188
20189         local dir=$DIR/$tdir
20190         local f=$dir/$tfile
20191         local f2=$dir/$tfile-2
20192         local f3=$dir/$tfile-3
20193         local subdir=$DIR/dir
20194         local val
20195
20196         local mdts=$(comma_list $(mdts_nodes))
20197         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20198         local client_saved=$($LCTL get_param -n jobid_var)
20199
20200         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20201         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20202
20203         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20204                 error "failed to set job_xattr parameter to user.job"
20205         $LCTL set_param jobid_var=procname.uid ||
20206                 error "failed to set jobid_var parameter"
20207
20208         test_mkdir $dir
20209
20210         touch $f
20211         val=$(getfattr -n user.job $f | grep user.job)
20212         [[ $val = user.job=\"touch.0\" ]] ||
20213                 error "expected user.job=\"touch.0\", got '$val'"
20214
20215         mkdir $subdir
20216         val=$(getfattr -n user.job $subdir | grep user.job)
20217         [[ $val = user.job=\"mkdir.0\" ]] ||
20218                 error "expected user.job=\"mkdir.0\", got '$val'"
20219
20220         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20221                 error "failed to set job_xattr parameter to NONE"
20222
20223         touch $f2
20224         val=$(getfattr -d $f2)
20225         [[ -z $val ]] ||
20226                 error "expected no user xattr, got '$val'"
20227
20228         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20229                 error "failed to set job_xattr parameter to trusted.job"
20230
20231         touch $f3
20232         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20233         [[ $val = trusted.job=\"touch.0\" ]] ||
20234                 error "expected trusted.job=\"touch.0\", got '$val'"
20235 }
20236 run_test 205h "check jobid xattr is stored correctly"
20237
20238 test_205i() {
20239         local mdts=$(comma_list $(mdts_nodes))
20240         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20241
20242         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20243
20244         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20245                 error "failed to set mdt.*.job_xattr to user.1234567"
20246
20247         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20248                 error "failed to reject too long job_xattr name"
20249
20250         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20251                 error "failed to reject job_xattr name in bad format"
20252
20253         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20254                 error "failed to reject job_xattr name with invalid character"
20255
20256         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20257                         xargs $LCTL set_param" &&
20258                 error "failed to reject job_xattr name with non-ascii character"
20259
20260         return 0
20261 }
20262 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20263
20264 # LU-1480, LU-1773 and LU-1657
20265 test_206() {
20266         mkdir -p $DIR/$tdir
20267         $LFS setstripe -c -1 $DIR/$tdir
20268 #define OBD_FAIL_LOV_INIT 0x1403
20269         $LCTL set_param fail_loc=0xa0001403
20270         $LCTL set_param fail_val=1
20271         touch $DIR/$tdir/$tfile || true
20272 }
20273 run_test 206 "fail lov_init_raid0() doesn't lbug"
20274
20275 test_207a() {
20276         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20277         local fsz=`stat -c %s $DIR/$tfile`
20278         cancel_lru_locks mdc
20279
20280         # do not return layout in getattr intent
20281 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20282         $LCTL set_param fail_loc=0x170
20283         local sz=`stat -c %s $DIR/$tfile`
20284
20285         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20286
20287         rm -rf $DIR/$tfile
20288 }
20289 run_test 207a "can refresh layout at glimpse"
20290
20291 test_207b() {
20292         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20293         local cksum=`md5sum $DIR/$tfile`
20294         local fsz=`stat -c %s $DIR/$tfile`
20295         cancel_lru_locks mdc
20296         cancel_lru_locks osc
20297
20298         # do not return layout in getattr intent
20299 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20300         $LCTL set_param fail_loc=0x171
20301
20302         # it will refresh layout after the file is opened but before read issues
20303         echo checksum is "$cksum"
20304         echo "$cksum" |md5sum -c --quiet || error "file differs"
20305
20306         rm -rf $DIR/$tfile
20307 }
20308 run_test 207b "can refresh layout at open"
20309
20310 test_208() {
20311         # FIXME: in this test suite, only RD lease is used. This is okay
20312         # for now as only exclusive open is supported. After generic lease
20313         # is done, this test suite should be revised. - Jinshan
20314
20315         remote_mds_nodsh && skip "remote MDS with nodsh"
20316         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20317                 skip "Need MDS version at least 2.4.52"
20318
20319         echo "==== test 1: verify get lease work"
20320         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20321
20322         echo "==== test 2: verify lease can be broken by upcoming open"
20323         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20324         local PID=$!
20325         sleep 2
20326
20327         $MULTIOP $DIR/$tfile oO_RDWR:c
20328         kill -USR1 $PID && wait $PID || error "break lease error"
20329
20330         echo "==== test 3: verify lease can't be granted if an open already exists"
20331         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20332         local PID=$!
20333         sleep 2
20334
20335         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20336         kill -USR1 $PID && wait $PID || error "open file error"
20337
20338         echo "==== test 4: lease can sustain over recovery"
20339         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20340         PID=$!
20341         sleep 2
20342
20343         fail mds1
20344
20345         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20346
20347         echo "==== test 5: lease broken can't be regained by replay"
20348         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20349         PID=$!
20350         sleep 2
20351
20352         # open file to break lease and then recovery
20353         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20354         fail mds1
20355
20356         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20357
20358         rm -f $DIR/$tfile
20359 }
20360 run_test 208 "Exclusive open"
20361
20362 test_209() {
20363         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20364                 skip_env "must have disp_stripe"
20365
20366         touch $DIR/$tfile
20367         sync; sleep 5; sync;
20368
20369         echo 3 > /proc/sys/vm/drop_caches
20370         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20371                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20372         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20373
20374         # open/close 500 times
20375         for i in $(seq 500); do
20376                 cat $DIR/$tfile
20377         done
20378
20379         echo 3 > /proc/sys/vm/drop_caches
20380         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20381                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20382         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20383
20384         echo "before: $req_before, after: $req_after"
20385         [ $((req_after - req_before)) -ge 300 ] &&
20386                 error "open/close requests are not freed"
20387         return 0
20388 }
20389 run_test 209 "read-only open/close requests should be freed promptly"
20390
20391 test_210() {
20392         local pid
20393
20394         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20395         pid=$!
20396         sleep 1
20397
20398         $LFS getstripe $DIR/$tfile
20399         kill -USR1 $pid
20400         wait $pid || error "multiop failed"
20401
20402         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20403         pid=$!
20404         sleep 1
20405
20406         $LFS getstripe $DIR/$tfile
20407         kill -USR1 $pid
20408         wait $pid || error "multiop failed"
20409 }
20410 run_test 210 "lfs getstripe does not break leases"
20411
20412 test_212() {
20413         size=`date +%s`
20414         size=$((size % 8192 + 1))
20415         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20416         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20417         rm -f $DIR/f212 $DIR/f212.xyz
20418 }
20419 run_test 212 "Sendfile test ============================================"
20420
20421 test_213() {
20422         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20423         cancel_lru_locks osc
20424         lctl set_param fail_loc=0x8000040f
20425         # generate a read lock
20426         cat $DIR/$tfile > /dev/null
20427         # write to the file, it will try to cancel the above read lock.
20428         cat /etc/hosts >> $DIR/$tfile
20429 }
20430 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20431
20432 test_214() { # for bug 20133
20433         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20434         for (( i=0; i < 340; i++ )) ; do
20435                 touch $DIR/$tdir/d214c/a$i
20436         done
20437
20438         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20439         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20440         ls $DIR/d214c || error "ls $DIR/d214c failed"
20441         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20442         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20443 }
20444 run_test 214 "hash-indexed directory test - bug 20133"
20445
20446 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20447 create_lnet_proc_files() {
20448         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20449 }
20450
20451 # counterpart of create_lnet_proc_files
20452 remove_lnet_proc_files() {
20453         rm -f $TMP/lnet_$1.sys
20454 }
20455
20456 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20457 # 3rd arg as regexp for body
20458 check_lnet_proc_stats() {
20459         local l=$(cat "$TMP/lnet_$1" |wc -l)
20460         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20461
20462         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20463 }
20464
20465 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20466 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20467 # optional and can be regexp for 2nd line (lnet.routes case)
20468 check_lnet_proc_entry() {
20469         local blp=2          # blp stands for 'position of 1st line of body'
20470         [ -z "$5" ] || blp=3 # lnet.routes case
20471
20472         local l=$(cat "$TMP/lnet_$1" |wc -l)
20473         # subtracting one from $blp because the body can be empty
20474         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20475
20476         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20477                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20478
20479         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20480                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20481
20482         # bail out if any unexpected line happened
20483         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20484         [ "$?" != 0 ] || error "$2 misformatted"
20485 }
20486
20487 test_215() { # for bugs 18102, 21079, 21517
20488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20489
20490         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20491         local P='[1-9][0-9]*'           # positive numeric
20492         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20493         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20494         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20495         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20496
20497         local L1 # regexp for 1st line
20498         local L2 # regexp for 2nd line (optional)
20499         local BR # regexp for the rest (body)
20500
20501         # lnet.stats should look as 11 space-separated non-negative numerics
20502         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20503         create_lnet_proc_files "stats"
20504         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20505         remove_lnet_proc_files "stats"
20506
20507         # lnet.routes should look like this:
20508         # Routing disabled/enabled
20509         # net hops priority state router
20510         # where net is a string like tcp0, hops > 0, priority >= 0,
20511         # state is up/down,
20512         # router is a string like 192.168.1.1@tcp2
20513         L1="^Routing (disabled|enabled)$"
20514         L2="^net +hops +priority +state +router$"
20515         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20516         create_lnet_proc_files "routes"
20517         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20518         remove_lnet_proc_files "routes"
20519
20520         # lnet.routers should look like this:
20521         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20522         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20523         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20524         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20525         L1="^ref +rtr_ref +alive +router$"
20526         BR="^$P +$P +(up|down) +$NID$"
20527         create_lnet_proc_files "routers"
20528         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20529         remove_lnet_proc_files "routers"
20530
20531         # lnet.peers should look like this:
20532         # nid refs state last max rtr min tx min queue
20533         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20534         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20535         # numeric (0 or >0 or <0), queue >= 0.
20536         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20537         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20538         create_lnet_proc_files "peers"
20539         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20540         remove_lnet_proc_files "peers"
20541
20542         # lnet.buffers  should look like this:
20543         # pages count credits min
20544         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20545         L1="^pages +count +credits +min$"
20546         BR="^ +$N +$N +$I +$I$"
20547         create_lnet_proc_files "buffers"
20548         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20549         remove_lnet_proc_files "buffers"
20550
20551         # lnet.nis should look like this:
20552         # nid status alive refs peer rtr max tx min
20553         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20554         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20555         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20556         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20557         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20558         create_lnet_proc_files "nis"
20559         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20560         remove_lnet_proc_files "nis"
20561
20562         # can we successfully write to lnet.stats?
20563         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20564 }
20565 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20566
20567 test_216() { # bug 20317
20568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20569         remote_ost_nodsh && skip "remote OST with nodsh"
20570
20571         local node
20572         local facets=$(get_facets OST)
20573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20574
20575         save_lustre_params client "osc.*.contention_seconds" > $p
20576         save_lustre_params $facets \
20577                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20578         save_lustre_params $facets \
20579                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20580         save_lustre_params $facets \
20581                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20582         clear_stats osc.*.osc_stats
20583
20584         # agressive lockless i/o settings
20585         do_nodes $(comma_list $(osts_nodes)) \
20586                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20587                         ldlm.namespaces.filter-*.contended_locks=0 \
20588                         ldlm.namespaces.filter-*.contention_seconds=60"
20589         lctl set_param -n osc.*.contention_seconds=60
20590
20591         $DIRECTIO write $DIR/$tfile 0 10 4096
20592         $CHECKSTAT -s 40960 $DIR/$tfile
20593
20594         # disable lockless i/o
20595         do_nodes $(comma_list $(osts_nodes)) \
20596                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20597                         ldlm.namespaces.filter-*.contended_locks=32 \
20598                         ldlm.namespaces.filter-*.contention_seconds=0"
20599         lctl set_param -n osc.*.contention_seconds=0
20600         clear_stats osc.*.osc_stats
20601
20602         dd if=/dev/zero of=$DIR/$tfile count=0
20603         $CHECKSTAT -s 0 $DIR/$tfile
20604
20605         restore_lustre_params <$p
20606         rm -f $p
20607         rm $DIR/$tfile
20608 }
20609 run_test 216 "check lockless direct write updates file size and kms correctly"
20610
20611 test_217() { # bug 22430
20612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20613
20614         local node
20615
20616         for node in $(nodes_list); do
20617                 local nid=$(host_nids_address $node $NETTYPE)
20618                 local node_ip=$(do_node $node getent ahostsv4 $node |
20619                                 awk '{ print $1; exit; }')
20620
20621                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20622                 # if hostname matches any NID, use hostname for better testing
20623                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20624                         echo "lctl ping node $node@$NETTYPE"
20625                         lctl ping $node@$NETTYPE
20626                 else # otherwise, at least test 'lctl ping' is working
20627                         echo "lctl ping nid $(h2nettype $nid)"
20628                         lctl ping $(h2nettype $nid)
20629                         echo "skipping $node (no hyphen detected)"
20630                 fi
20631         done
20632 }
20633 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20634
20635 test_218() {
20636         # do directio so as not to populate the page cache
20637         log "creating a 10 Mb file"
20638         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20639                 error "multiop failed while creating a file"
20640         log "starting reads"
20641         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20642         log "truncating the file"
20643         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20644                 error "multiop failed while truncating the file"
20645         log "killing dd"
20646         kill %+ || true # reads might have finished
20647         echo "wait until dd is finished"
20648         wait
20649         log "removing the temporary file"
20650         rm -rf $DIR/$tfile || error "tmp file removal failed"
20651 }
20652 run_test 218 "parallel read and truncate should not deadlock"
20653
20654 test_219() {
20655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20656
20657         # write one partial page
20658         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20659         # set no grant so vvp_io_commit_write will do sync write
20660         $LCTL set_param fail_loc=0x411
20661         # write a full page at the end of file
20662         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20663
20664         $LCTL set_param fail_loc=0
20665         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20666         $LCTL set_param fail_loc=0x411
20667         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20668
20669         # LU-4201
20670         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20671         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20672 }
20673 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20674
20675 test_220() { #LU-325
20676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20677         remote_ost_nodsh && skip "remote OST with nodsh"
20678         remote_mds_nodsh && skip "remote MDS with nodsh"
20679         remote_mgs_nodsh && skip "remote MGS with nodsh"
20680
20681         local OSTIDX=0
20682
20683         # create on MDT0000 so the last_id and next_id are correct
20684         mkdir_on_mdt0 $DIR/$tdir
20685         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20686         OST=${OST%_UUID}
20687
20688         # on the mdt's osc
20689         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20690         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20691                         osp.$mdtosc_proc1.prealloc_last_id)
20692         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20693                         osp.$mdtosc_proc1.prealloc_next_id)
20694
20695         $LFS df -i
20696
20697         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20698         #define OBD_FAIL_OST_ENOINO              0x229
20699         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20700         create_pool $FSNAME.$TESTNAME || return 1
20701         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20702
20703         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20704
20705         MDSOBJS=$((last_id - next_id))
20706         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20707
20708         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20709         echo "OST still has $count kbytes free"
20710
20711         echo "create $MDSOBJS files @next_id..."
20712         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20713
20714         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20715                         osp.$mdtosc_proc1.prealloc_last_id)
20716         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20717                         osp.$mdtosc_proc1.prealloc_next_id)
20718
20719         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20720         $LFS df -i
20721
20722         echo "cleanup..."
20723
20724         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20725         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20726
20727         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20728                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20729         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20730                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20731         echo "unlink $MDSOBJS files @$next_id..."
20732         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20733 }
20734 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20735
20736 test_221() {
20737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20738
20739         dd if=`which date` of=$MOUNT/date oflag=sync
20740         chmod +x $MOUNT/date
20741
20742         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20743         $LCTL set_param fail_loc=0x80001401
20744
20745         $MOUNT/date > /dev/null
20746         rm -f $MOUNT/date
20747 }
20748 run_test 221 "make sure fault and truncate race to not cause OOM"
20749
20750 test_222a () {
20751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20752
20753         rm -rf $DIR/$tdir
20754         test_mkdir $DIR/$tdir
20755         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20756         createmany -o $DIR/$tdir/$tfile 10
20757         cancel_lru_locks mdc
20758         cancel_lru_locks osc
20759         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20760         $LCTL set_param fail_loc=0x31a
20761         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20762         $LCTL set_param fail_loc=0
20763         rm -r $DIR/$tdir
20764 }
20765 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20766
20767 test_222b () {
20768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20769
20770         rm -rf $DIR/$tdir
20771         test_mkdir $DIR/$tdir
20772         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20773         createmany -o $DIR/$tdir/$tfile 10
20774         cancel_lru_locks mdc
20775         cancel_lru_locks osc
20776         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20777         $LCTL set_param fail_loc=0x31a
20778         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20779         $LCTL set_param fail_loc=0
20780 }
20781 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20782
20783 test_223 () {
20784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20785
20786         rm -rf $DIR/$tdir
20787         test_mkdir $DIR/$tdir
20788         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20789         createmany -o $DIR/$tdir/$tfile 10
20790         cancel_lru_locks mdc
20791         cancel_lru_locks osc
20792         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20793         $LCTL set_param fail_loc=0x31b
20794         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20795         $LCTL set_param fail_loc=0
20796         rm -r $DIR/$tdir
20797 }
20798 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20799
20800 test_224a() { # LU-1039, MRP-303
20801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20802         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20803         $LCTL set_param fail_loc=0x508
20804         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20805         $LCTL set_param fail_loc=0
20806         df $DIR
20807 }
20808 run_test 224a "Don't panic on bulk IO failure"
20809
20810 test_224bd_sub() { # LU-1039, MRP-303
20811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20812         local timeout=$1
20813
20814         shift
20815         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20816
20817         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20818
20819         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20820         cancel_lru_locks osc
20821         set_checksums 0
20822         stack_trap "set_checksums $ORIG_CSUM" EXIT
20823         local at_max_saved=0
20824
20825         # adaptive timeouts may prevent seeing the issue
20826         if at_is_enabled; then
20827                 at_max_saved=$(at_max_get mds)
20828                 at_max_set 0 mds client
20829                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20830         fi
20831
20832         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20833         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20834         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20835
20836         do_facet ost1 $LCTL set_param fail_loc=0
20837         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20838         df $DIR
20839 }
20840
20841 test_224b() {
20842         test_224bd_sub 3 error "dd failed"
20843 }
20844 run_test 224b "Don't panic on bulk IO failure"
20845
20846 test_224c() { # LU-6441
20847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20848         remote_mds_nodsh && skip "remote MDS with nodsh"
20849
20850         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20851         save_writethrough $p
20852         set_cache writethrough on
20853
20854         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20855         local at_max=$($LCTL get_param -n at_max)
20856         local timeout=$($LCTL get_param -n timeout)
20857         local test_at="at_max"
20858         local param_at="$FSNAME.sys.at_max"
20859         local test_timeout="timeout"
20860         local param_timeout="$FSNAME.sys.timeout"
20861
20862         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20863
20864         set_persistent_param_and_check client "$test_at" "$param_at" 0
20865         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20866
20867         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20868         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20869         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20870         stack_trap "rm -f $DIR/$tfile"
20871         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20872         sync
20873         do_facet ost1 "$LCTL set_param fail_loc=0"
20874
20875         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20876         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20877                 $timeout
20878
20879         $LCTL set_param -n $pages_per_rpc
20880         restore_lustre_params < $p
20881         rm -f $p
20882 }
20883 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20884
20885 test_224d() { # LU-11169
20886         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20887 }
20888 run_test 224d "Don't corrupt data on bulk IO timeout"
20889
20890 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20891 test_225a () {
20892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20893         if [ -z ${MDSSURVEY} ]; then
20894                 skip_env "mds-survey not found"
20895         fi
20896         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20897                 skip "Need MDS version at least 2.2.51"
20898
20899         local mds=$(facet_host $SINGLEMDS)
20900         local target=$(do_nodes $mds 'lctl dl' |
20901                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20902
20903         local cmd1="file_count=1000 thrhi=4"
20904         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20905         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20906         local cmd="$cmd1 $cmd2 $cmd3"
20907
20908         rm -f ${TMP}/mds_survey*
20909         echo + $cmd
20910         eval $cmd || error "mds-survey with zero-stripe failed"
20911         cat ${TMP}/mds_survey*
20912         rm -f ${TMP}/mds_survey*
20913 }
20914 run_test 225a "Metadata survey sanity with zero-stripe"
20915
20916 test_225b () {
20917         if [ -z ${MDSSURVEY} ]; then
20918                 skip_env "mds-survey not found"
20919         fi
20920         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20921                 skip "Need MDS version at least 2.2.51"
20922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20923         remote_mds_nodsh && skip "remote MDS with nodsh"
20924         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20925                 skip_env "Need to mount OST to test"
20926         fi
20927
20928         local mds=$(facet_host $SINGLEMDS)
20929         local target=$(do_nodes $mds 'lctl dl' |
20930                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20931
20932         local cmd1="file_count=1000 thrhi=4"
20933         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20934         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20935         local cmd="$cmd1 $cmd2 $cmd3"
20936
20937         rm -f ${TMP}/mds_survey*
20938         echo + $cmd
20939         eval $cmd || error "mds-survey with stripe_count failed"
20940         cat ${TMP}/mds_survey*
20941         rm -f ${TMP}/mds_survey*
20942 }
20943 run_test 225b "Metadata survey sanity with stripe_count = 1"
20944
20945 mcreate_path2fid () {
20946         local mode=$1
20947         local major=$2
20948         local minor=$3
20949         local name=$4
20950         local desc=$5
20951         local path=$DIR/$tdir/$name
20952         local fid
20953         local rc
20954         local fid_path
20955
20956         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20957                 error "cannot create $desc"
20958
20959         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20960         rc=$?
20961         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20962
20963         fid_path=$($LFS fid2path $MOUNT $fid)
20964         rc=$?
20965         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20966
20967         [ "$path" == "$fid_path" ] ||
20968                 error "fid2path returned $fid_path, expected $path"
20969
20970         echo "pass with $path and $fid"
20971 }
20972
20973 test_226a () {
20974         rm -rf $DIR/$tdir
20975         mkdir -p $DIR/$tdir
20976
20977         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20978         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20979         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20980         mcreate_path2fid 0040666 0 0 dir "directory"
20981         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20982         mcreate_path2fid 0100666 0 0 file "regular file"
20983         mcreate_path2fid 0120666 0 0 link "symbolic link"
20984         mcreate_path2fid 0140666 0 0 sock "socket"
20985 }
20986 run_test 226a "call path2fid and fid2path on files of all type"
20987
20988 test_226b () {
20989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20990
20991         local MDTIDX=1
20992
20993         rm -rf $DIR/$tdir
20994         mkdir -p $DIR/$tdir
20995         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20996                 error "create remote directory failed"
20997         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20998         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20999                                 "character special file (null)"
21000         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21001                                 "character special file (no device)"
21002         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21003         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21004                                 "block special file (loop)"
21005         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21006         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21007         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21008 }
21009 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21010
21011 test_226c () {
21012         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21013         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21014                 skip "Need MDS version at least 2.13.55"
21015
21016         local submnt=/mnt/submnt
21017         local srcfile=/etc/passwd
21018         local dstfile=$submnt/passwd
21019         local path
21020         local fid
21021
21022         rm -rf $DIR/$tdir
21023         rm -rf $submnt
21024         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21025                 error "create remote directory failed"
21026         mkdir -p $submnt || error "create $submnt failed"
21027         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21028                 error "mount $submnt failed"
21029         stack_trap "umount $submnt" EXIT
21030
21031         cp $srcfile $dstfile
21032         fid=$($LFS path2fid $dstfile)
21033         path=$($LFS fid2path $submnt "$fid")
21034         [ "$path" = "$dstfile" ] ||
21035                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21036 }
21037 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21038
21039 test_226e () {
21040         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21041                 skip "Need client at least version 2.15.56"
21042
21043         # Define filename with 'newline' and a space
21044         local testfile="Test"$'\n'"file 01"
21045         # Define link name with multiple 'newline' and a space
21046         local linkfile="Link"$'\n'"file "$'\n'"01"
21047         # Remove prior hard link
21048         rm -f $DIR/"$linkfile"
21049
21050         # Create file
21051         touch $DIR/"$testfile"
21052         # Create link
21053         ln $DIR/"$testfile" $DIR/"$linkfile"
21054
21055         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21056                 error "getstripe failed on $DIR/$testfile"
21057
21058         # Call with -0 option
21059         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21060                 echo "FILE:" | grep -c "FILE:")
21061
21062         # With -0 option the output should be exactly 2 lines.
21063         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21064 }
21065 run_test 226e "Verify path2fid -0 option with newline and space"
21066
21067 # LU-1299 Executing or running ldd on a truncated executable does not
21068 # cause an out-of-memory condition.
21069 test_227() {
21070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21071         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21072
21073         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21074         chmod +x $MOUNT/date
21075
21076         $MOUNT/date > /dev/null
21077         ldd $MOUNT/date > /dev/null
21078         rm -f $MOUNT/date
21079 }
21080 run_test 227 "running truncated executable does not cause OOM"
21081
21082 # LU-1512 try to reuse idle OI blocks
21083 test_228a() {
21084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21085         remote_mds_nodsh && skip "remote MDS with nodsh"
21086         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21087
21088         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21089         local myDIR=$DIR/$tdir
21090
21091         mkdir -p $myDIR
21092         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21093         $LCTL set_param fail_loc=0x80001002
21094         createmany -o $myDIR/t- 10000
21095         $LCTL set_param fail_loc=0
21096         # The guard is current the largest FID holder
21097         touch $myDIR/guard
21098         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21099                     tr -d '[')
21100         local IDX=$(($SEQ % 64))
21101
21102         do_facet $SINGLEMDS sync
21103         # Make sure journal flushed.
21104         sleep 6
21105         local blk1=$(do_facet $SINGLEMDS \
21106                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21107                      grep Blockcount | awk '{print $4}')
21108
21109         # Remove old files, some OI blocks will become idle.
21110         unlinkmany $myDIR/t- 10000
21111         # Create new files, idle OI blocks should be reused.
21112         createmany -o $myDIR/t- 2000
21113         do_facet $SINGLEMDS sync
21114         # Make sure journal flushed.
21115         sleep 6
21116         local blk2=$(do_facet $SINGLEMDS \
21117                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21118                      grep Blockcount | awk '{print $4}')
21119
21120         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21121 }
21122 run_test 228a "try to reuse idle OI blocks"
21123
21124 test_228b() {
21125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21126         remote_mds_nodsh && skip "remote MDS with nodsh"
21127         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21128
21129         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21130         local myDIR=$DIR/$tdir
21131
21132         mkdir -p $myDIR
21133         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21134         $LCTL set_param fail_loc=0x80001002
21135         createmany -o $myDIR/t- 10000
21136         $LCTL set_param fail_loc=0
21137         # The guard is current the largest FID holder
21138         touch $myDIR/guard
21139         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21140                     tr -d '[')
21141         local IDX=$(($SEQ % 64))
21142
21143         do_facet $SINGLEMDS sync
21144         # Make sure journal flushed.
21145         sleep 6
21146         local blk1=$(do_facet $SINGLEMDS \
21147                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21148                      grep Blockcount | awk '{print $4}')
21149
21150         # Remove old files, some OI blocks will become idle.
21151         unlinkmany $myDIR/t- 10000
21152
21153         # stop the MDT
21154         stop $SINGLEMDS || error "Fail to stop MDT."
21155         # remount the MDT
21156         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21157                 error "Fail to start MDT."
21158
21159         client_up || error "Fail to df."
21160         # Create new files, idle OI blocks should be reused.
21161         createmany -o $myDIR/t- 2000
21162         do_facet $SINGLEMDS sync
21163         # Make sure journal flushed.
21164         sleep 6
21165         local blk2=$(do_facet $SINGLEMDS \
21166                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21167                      grep Blockcount | awk '{print $4}')
21168
21169         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21170 }
21171 run_test 228b "idle OI blocks can be reused after MDT restart"
21172
21173 #LU-1881
21174 test_228c() {
21175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21176         remote_mds_nodsh && skip "remote MDS with nodsh"
21177         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21178
21179         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21180         local myDIR=$DIR/$tdir
21181
21182         mkdir -p $myDIR
21183         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21184         $LCTL set_param fail_loc=0x80001002
21185         # 20000 files can guarantee there are index nodes in the OI file
21186         createmany -o $myDIR/t- 20000
21187         $LCTL set_param fail_loc=0
21188         # The guard is current the largest FID holder
21189         touch $myDIR/guard
21190         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21191                     tr -d '[')
21192         local IDX=$(($SEQ % 64))
21193
21194         do_facet $SINGLEMDS sync
21195         # Make sure journal flushed.
21196         sleep 6
21197         local blk1=$(do_facet $SINGLEMDS \
21198                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21199                      grep Blockcount | awk '{print $4}')
21200
21201         # Remove old files, some OI blocks will become idle.
21202         unlinkmany $myDIR/t- 20000
21203         rm -f $myDIR/guard
21204         # The OI file should become empty now
21205
21206         # Create new files, idle OI blocks should be reused.
21207         createmany -o $myDIR/t- 2000
21208         do_facet $SINGLEMDS sync
21209         # Make sure journal flushed.
21210         sleep 6
21211         local blk2=$(do_facet $SINGLEMDS \
21212                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21213                      grep Blockcount | awk '{print $4}')
21214
21215         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21216 }
21217 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21218
21219 test_229() { # LU-2482, LU-3448
21220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21221         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21222         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21223                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21224
21225         rm -f $DIR/$tfile
21226
21227         # Create a file with a released layout and stripe count 2.
21228         $MULTIOP $DIR/$tfile H2c ||
21229                 error "failed to create file with released layout"
21230
21231         $LFS getstripe -v $DIR/$tfile
21232
21233         local pattern=$($LFS getstripe -L $DIR/$tfile)
21234         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21235
21236         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21237                 error "getstripe"
21238         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21239         stat $DIR/$tfile || error "failed to stat released file"
21240
21241         chown $RUNAS_ID $DIR/$tfile ||
21242                 error "chown $RUNAS_ID $DIR/$tfile failed"
21243
21244         chgrp $RUNAS_ID $DIR/$tfile ||
21245                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21246
21247         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21248         rm $DIR/$tfile || error "failed to remove released file"
21249 }
21250 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21251
21252 test_230a() {
21253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21255         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21256                 skip "Need MDS version at least 2.11.52"
21257
21258         local MDTIDX=1
21259
21260         test_mkdir $DIR/$tdir
21261         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21262         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21263         [ $mdt_idx -ne 0 ] &&
21264                 error "create local directory on wrong MDT $mdt_idx"
21265
21266         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21267                         error "create remote directory failed"
21268         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21269         [ $mdt_idx -ne $MDTIDX ] &&
21270                 error "create remote directory on wrong MDT $mdt_idx"
21271
21272         createmany -o $DIR/$tdir/test_230/t- 10 ||
21273                 error "create files on remote directory failed"
21274         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21275         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21276         rm -r $DIR/$tdir || error "unlink remote directory failed"
21277 }
21278 run_test 230a "Create remote directory and files under the remote directory"
21279
21280 test_230b() {
21281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21283         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21284                 skip "Need MDS version at least 2.11.52"
21285
21286         local MDTIDX=1
21287         local mdt_index
21288         local i
21289         local file
21290         local pid
21291         local stripe_count
21292         local migrate_dir=$DIR/$tdir/migrate_dir
21293         local other_dir=$DIR/$tdir/other_dir
21294
21295         test_mkdir $DIR/$tdir
21296         test_mkdir -i0 -c1 $migrate_dir
21297         test_mkdir -i0 -c1 $other_dir
21298         for ((i=0; i<10; i++)); do
21299                 mkdir -p $migrate_dir/dir_${i}
21300                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21301                         error "create files under remote dir failed $i"
21302         done
21303
21304         cp /etc/passwd $migrate_dir/$tfile
21305         cp /etc/passwd $other_dir/$tfile
21306         chattr +SAD $migrate_dir
21307         chattr +SAD $migrate_dir/$tfile
21308
21309         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21310         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21311         local old_dir_mode=$(stat -c%f $migrate_dir)
21312         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21313
21314         mkdir -p $migrate_dir/dir_default_stripe2
21315         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21316         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21317
21318         mkdir -p $other_dir
21319         ln $migrate_dir/$tfile $other_dir/luna
21320         ln $migrate_dir/$tfile $migrate_dir/sofia
21321         ln $other_dir/$tfile $migrate_dir/david
21322         ln -s $migrate_dir/$tfile $other_dir/zachary
21323         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21324         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21325
21326         local len
21327         local lnktgt
21328
21329         # inline symlink
21330         for len in 58 59 60; do
21331                 lnktgt=$(str_repeat 'l' $len)
21332                 touch $migrate_dir/$lnktgt
21333                 ln -s $lnktgt $migrate_dir/${len}char_ln
21334         done
21335
21336         # PATH_MAX
21337         for len in 4094 4095; do
21338                 lnktgt=$(str_repeat 'l' $len)
21339                 ln -s $lnktgt $migrate_dir/${len}char_ln
21340         done
21341
21342         # NAME_MAX
21343         for len in 254 255; do
21344                 touch $migrate_dir/$(str_repeat 'l' $len)
21345         done
21346
21347         $LFS migrate -m $MDTIDX $migrate_dir ||
21348                 error "fails on migrating remote dir to MDT1"
21349
21350         echo "migratate to MDT1, then checking.."
21351         for ((i = 0; i < 10; i++)); do
21352                 for file in $(find $migrate_dir/dir_${i}); do
21353                         mdt_index=$($LFS getstripe -m $file)
21354                         # broken symlink getstripe will fail
21355                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21356                                 error "$file is not on MDT${MDTIDX}"
21357                 done
21358         done
21359
21360         # the multiple link file should still in MDT0
21361         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21362         [ $mdt_index == 0 ] ||
21363                 error "$file is not on MDT${MDTIDX}"
21364
21365         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21366         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21367                 error " expect $old_dir_flag get $new_dir_flag"
21368
21369         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21370         [ "$old_file_flag" = "$new_file_flag" ] ||
21371                 error " expect $old_file_flag get $new_file_flag"
21372
21373         local new_dir_mode=$(stat -c%f $migrate_dir)
21374         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21375                 error "expect mode $old_dir_mode get $new_dir_mode"
21376
21377         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21378         [ "$old_file_mode" = "$new_file_mode" ] ||
21379                 error "expect mode $old_file_mode get $new_file_mode"
21380
21381         diff /etc/passwd $migrate_dir/$tfile ||
21382                 error "$tfile different after migration"
21383
21384         diff /etc/passwd $other_dir/luna ||
21385                 error "luna different after migration"
21386
21387         diff /etc/passwd $migrate_dir/sofia ||
21388                 error "sofia different after migration"
21389
21390         diff /etc/passwd $migrate_dir/david ||
21391                 error "david different after migration"
21392
21393         diff /etc/passwd $other_dir/zachary ||
21394                 error "zachary different after migration"
21395
21396         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21397                 error "${tfile}_ln different after migration"
21398
21399         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21400                 error "${tfile}_ln_other different after migration"
21401
21402         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21403         [ $stripe_count = 2 ] ||
21404                 error "dir strpe_count $d != 2 after migration."
21405
21406         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21407         [ $stripe_count = 2 ] ||
21408                 error "file strpe_count $d != 2 after migration."
21409
21410         #migrate back to MDT0
21411         MDTIDX=0
21412
21413         $LFS migrate -m $MDTIDX $migrate_dir ||
21414                 error "fails on migrating remote dir to MDT0"
21415
21416         echo "migrate back to MDT0, checking.."
21417         for file in $(find $migrate_dir); do
21418                 mdt_index=$($LFS getstripe -m $file)
21419                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21420                         error "$file is not on MDT${MDTIDX}"
21421         done
21422
21423         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21424         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21425                 error " expect $old_dir_flag get $new_dir_flag"
21426
21427         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21428         [ "$old_file_flag" = "$new_file_flag" ] ||
21429                 error " expect $old_file_flag get $new_file_flag"
21430
21431         local new_dir_mode=$(stat -c%f $migrate_dir)
21432         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21433                 error "expect mode $old_dir_mode get $new_dir_mode"
21434
21435         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21436         [ "$old_file_mode" = "$new_file_mode" ] ||
21437                 error "expect mode $old_file_mode get $new_file_mode"
21438
21439         diff /etc/passwd ${migrate_dir}/$tfile ||
21440                 error "$tfile different after migration"
21441
21442         diff /etc/passwd ${other_dir}/luna ||
21443                 error "luna different after migration"
21444
21445         diff /etc/passwd ${migrate_dir}/sofia ||
21446                 error "sofia different after migration"
21447
21448         diff /etc/passwd ${other_dir}/zachary ||
21449                 error "zachary different after migration"
21450
21451         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21452                 error "${tfile}_ln different after migration"
21453
21454         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21455                 error "${tfile}_ln_other different after migration"
21456
21457         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21458         [ $stripe_count = 2 ] ||
21459                 error "dir strpe_count $d != 2 after migration."
21460
21461         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21462         [ $stripe_count = 2 ] ||
21463                 error "file strpe_count $d != 2 after migration."
21464
21465         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21466 }
21467 run_test 230b "migrate directory"
21468
21469 test_230c() {
21470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21472         remote_mds_nodsh && skip "remote MDS with nodsh"
21473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21474                 skip "Need MDS version at least 2.11.52"
21475
21476         local MDTIDX=1
21477         local total=3
21478         local mdt_index
21479         local file
21480         local migrate_dir=$DIR/$tdir/migrate_dir
21481
21482         #If migrating directory fails in the middle, all entries of
21483         #the directory is still accessiable.
21484         test_mkdir $DIR/$tdir
21485         test_mkdir -i0 -c1 $migrate_dir
21486         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21487         stat $migrate_dir
21488         createmany -o $migrate_dir/f $total ||
21489                 error "create files under ${migrate_dir} failed"
21490
21491         # fail after migrating top dir, and this will fail only once, so the
21492         # first sub file migration will fail (currently f3), others succeed.
21493         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21494         do_facet mds1 lctl set_param fail_loc=0x1801
21495         local t=$(ls $migrate_dir | wc -l)
21496         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21497                 error "migrate should fail"
21498         local u=$(ls $migrate_dir | wc -l)
21499         [ "$u" == "$t" ] || error "$u != $t during migration"
21500
21501         # add new dir/file should succeed
21502         mkdir $migrate_dir/dir ||
21503                 error "mkdir failed under migrating directory"
21504         touch $migrate_dir/file ||
21505                 error "create file failed under migrating directory"
21506
21507         # add file with existing name should fail
21508         for file in $migrate_dir/f*; do
21509                 stat $file > /dev/null || error "stat $file failed"
21510                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21511                         error "open(O_CREAT|O_EXCL) $file should fail"
21512                 $MULTIOP $file m && error "create $file should fail"
21513                 touch $DIR/$tdir/remote_dir/$tfile ||
21514                         error "touch $tfile failed"
21515                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21516                         error "link $file should fail"
21517                 mdt_index=$($LFS getstripe -m $file)
21518                 if [ $mdt_index == 0 ]; then
21519                         # file failed to migrate is not allowed to rename to
21520                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21521                                 error "rename to $file should fail"
21522                 else
21523                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21524                                 error "rename to $file failed"
21525                 fi
21526                 echo hello >> $file || error "write $file failed"
21527         done
21528
21529         # resume migration with different options should fail
21530         $LFS migrate -m 0 $migrate_dir &&
21531                 error "migrate -m 0 $migrate_dir should fail"
21532
21533         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21534                 error "migrate -c 2 $migrate_dir should fail"
21535
21536         # resume migration should succeed
21537         $LFS migrate -m $MDTIDX $migrate_dir ||
21538                 error "migrate $migrate_dir failed"
21539
21540         echo "Finish migration, then checking.."
21541         for file in $(find $migrate_dir); do
21542                 mdt_index=$($LFS getstripe -m $file)
21543                 [ $mdt_index == $MDTIDX ] ||
21544                         error "$file is not on MDT${MDTIDX}"
21545         done
21546
21547         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21548 }
21549 run_test 230c "check directory accessiblity if migration failed"
21550
21551 test_230d() {
21552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21555                 skip "Need MDS version at least 2.11.52"
21556         # LU-11235
21557         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21558
21559         local migrate_dir=$DIR/$tdir/migrate_dir
21560         local old_index
21561         local new_index
21562         local old_count
21563         local new_count
21564         local new_hash
21565         local mdt_index
21566         local i
21567         local j
21568
21569         old_index=$((RANDOM % MDSCOUNT))
21570         old_count=$((MDSCOUNT - old_index))
21571         new_index=$((RANDOM % MDSCOUNT))
21572         new_count=$((MDSCOUNT - new_index))
21573         new_hash=1 # for all_char
21574
21575         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21576         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21577
21578         test_mkdir $DIR/$tdir
21579         test_mkdir -i $old_index -c $old_count $migrate_dir
21580
21581         for ((i=0; i<100; i++)); do
21582                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21583                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21584                         error "create files under remote dir failed $i"
21585         done
21586
21587         echo -n "Migrate from MDT$old_index "
21588         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21589         echo -n "to MDT$new_index"
21590         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21591         echo
21592
21593         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21594         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21595                 error "migrate remote dir error"
21596
21597         echo "Finish migration, then checking.."
21598         for file in $(find $migrate_dir -maxdepth 1); do
21599                 mdt_index=$($LFS getstripe -m $file)
21600                 if [ $mdt_index -lt $new_index ] ||
21601                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21602                         error "$file is on MDT$mdt_index"
21603                 fi
21604         done
21605
21606         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21607 }
21608 run_test 230d "check migrate big directory"
21609
21610 test_230e() {
21611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21613         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21614                 skip "Need MDS version at least 2.11.52"
21615
21616         local i
21617         local j
21618         local a_fid
21619         local b_fid
21620
21621         mkdir_on_mdt0 $DIR/$tdir
21622         mkdir $DIR/$tdir/migrate_dir
21623         mkdir $DIR/$tdir/other_dir
21624         touch $DIR/$tdir/migrate_dir/a
21625         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21626         ls $DIR/$tdir/other_dir
21627
21628         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21629                 error "migrate dir fails"
21630
21631         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21632         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21633
21634         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21635         [ $mdt_index == 0 ] || error "a is not on MDT0"
21636
21637         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21638                 error "migrate dir fails"
21639
21640         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21641         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21642
21643         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21644         [ $mdt_index == 1 ] || error "a is not on MDT1"
21645
21646         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21647         [ $mdt_index == 1 ] || error "b is not on MDT1"
21648
21649         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21650         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21651
21652         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21653
21654         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21655 }
21656 run_test 230e "migrate mulitple local link files"
21657
21658 test_230f() {
21659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21662                 skip "Need MDS version at least 2.11.52"
21663
21664         local a_fid
21665         local ln_fid
21666
21667         mkdir -p $DIR/$tdir
21668         mkdir $DIR/$tdir/migrate_dir
21669         $LFS mkdir -i1 $DIR/$tdir/other_dir
21670         touch $DIR/$tdir/migrate_dir/a
21671         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21672         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21673         ls $DIR/$tdir/other_dir
21674
21675         # a should be migrated to MDT1, since no other links on MDT0
21676         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21677                 error "#1 migrate dir fails"
21678         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21679         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21680         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21681         [ $mdt_index == 1 ] || error "a is not on MDT1"
21682
21683         # a should stay on MDT1, because it is a mulitple link file
21684         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21685                 error "#2 migrate dir fails"
21686         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21687         [ $mdt_index == 1 ] || error "a is not on MDT1"
21688
21689         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21690                 error "#3 migrate dir fails"
21691
21692         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21693         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21694         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21695
21696         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21697         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21698
21699         # a should be migrated to MDT0, since no other links on MDT1
21700         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21701                 error "#4 migrate dir fails"
21702         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21703         [ $mdt_index == 0 ] || error "a is not on MDT0"
21704
21705         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21706 }
21707 run_test 230f "migrate mulitple remote link files"
21708
21709 test_230g() {
21710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21711         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21712         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21713                 skip "Need MDS version at least 2.11.52"
21714
21715         mkdir -p $DIR/$tdir/migrate_dir
21716
21717         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21718                 error "migrating dir to non-exist MDT succeeds"
21719         true
21720 }
21721 run_test 230g "migrate dir to non-exist MDT"
21722
21723 test_230h() {
21724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21726         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21727                 skip "Need MDS version at least 2.11.52"
21728
21729         local mdt_index
21730
21731         mkdir -p $DIR/$tdir/migrate_dir
21732
21733         $LFS migrate -m1 $DIR &&
21734                 error "migrating mountpoint1 should fail"
21735
21736         $LFS migrate -m1 $DIR/$tdir/.. &&
21737                 error "migrating mountpoint2 should fail"
21738
21739         # same as mv
21740         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21741                 error "migrating $tdir/migrate_dir/.. should fail"
21742
21743         true
21744 }
21745 run_test 230h "migrate .. and root"
21746
21747 test_230i() {
21748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21750         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21751                 skip "Need MDS version at least 2.11.52"
21752
21753         mkdir -p $DIR/$tdir/migrate_dir
21754
21755         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21756                 error "migration fails with a tailing slash"
21757
21758         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21759                 error "migration fails with two tailing slashes"
21760 }
21761 run_test 230i "lfs migrate -m tolerates trailing slashes"
21762
21763 test_230j() {
21764         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21765         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21766                 skip "Need MDS version at least 2.11.52"
21767
21768         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21769         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21770                 error "create $tfile failed"
21771         cat /etc/passwd > $DIR/$tdir/$tfile
21772
21773         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21774
21775         cmp /etc/passwd $DIR/$tdir/$tfile ||
21776                 error "DoM file mismatch after migration"
21777 }
21778 run_test 230j "DoM file data not changed after dir migration"
21779
21780 test_230k() {
21781         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21782         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21783                 skip "Need MDS version at least 2.11.56"
21784
21785         local total=20
21786         local files_on_starting_mdt=0
21787
21788         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21789         $LFS getdirstripe $DIR/$tdir
21790         for i in $(seq $total); do
21791                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21792                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21793                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21794         done
21795
21796         echo "$files_on_starting_mdt files on MDT0"
21797
21798         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21799         $LFS getdirstripe $DIR/$tdir
21800
21801         files_on_starting_mdt=0
21802         for i in $(seq $total); do
21803                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21804                         error "file $tfile.$i mismatch after migration"
21805                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21806                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21807         done
21808
21809         echo "$files_on_starting_mdt files on MDT1 after migration"
21810         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21811
21812         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21813         $LFS getdirstripe $DIR/$tdir
21814
21815         files_on_starting_mdt=0
21816         for i in $(seq $total); do
21817                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21818                         error "file $tfile.$i mismatch after 2nd migration"
21819                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21820                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21821         done
21822
21823         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21824         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21825
21826         true
21827 }
21828 run_test 230k "file data not changed after dir migration"
21829
21830 test_230l() {
21831         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21832         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21833                 skip "Need MDS version at least 2.11.56"
21834
21835         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21836         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21837                 error "create files under remote dir failed $i"
21838         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21839 }
21840 run_test 230l "readdir between MDTs won't crash"
21841
21842 test_230m() {
21843         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21844         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21845                 skip "Need MDS version at least 2.11.56"
21846
21847         local MDTIDX=1
21848         local mig_dir=$DIR/$tdir/migrate_dir
21849         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21850         local shortstr="b"
21851         local val
21852
21853         echo "Creating files and dirs with xattrs"
21854         test_mkdir $DIR/$tdir
21855         test_mkdir -i0 -c1 $mig_dir
21856         mkdir $mig_dir/dir
21857         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21858                 error "cannot set xattr attr1 on dir"
21859         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21860                 error "cannot set xattr attr2 on dir"
21861         touch $mig_dir/dir/f0
21862         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21863                 error "cannot set xattr attr1 on file"
21864         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21865                 error "cannot set xattr attr2 on file"
21866         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21867         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21868         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21869         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21870         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21871         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21872         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21873         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21874         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21875
21876         echo "Migrating to MDT1"
21877         $LFS migrate -m $MDTIDX $mig_dir ||
21878                 error "fails on migrating dir to MDT1"
21879
21880         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21881         echo "Checking xattrs"
21882         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21883         [ "$val" = $longstr ] ||
21884                 error "expecting xattr1 $longstr on dir, found $val"
21885         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21886         [ "$val" = $shortstr ] ||
21887                 error "expecting xattr2 $shortstr on dir, found $val"
21888         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21889         [ "$val" = $longstr ] ||
21890                 error "expecting xattr1 $longstr on file, found $val"
21891         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21892         [ "$val" = $shortstr ] ||
21893                 error "expecting xattr2 $shortstr on file, found $val"
21894 }
21895 run_test 230m "xattrs not changed after dir migration"
21896
21897 test_230n() {
21898         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21899         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21900                 skip "Need MDS version at least 2.13.53"
21901
21902         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21903         cat /etc/hosts > $DIR/$tdir/$tfile
21904         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21905         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21906
21907         cmp /etc/hosts $DIR/$tdir/$tfile ||
21908                 error "File data mismatch after migration"
21909 }
21910 run_test 230n "Dir migration with mirrored file"
21911
21912 test_230o() {
21913         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21914         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21915                 skip "Need MDS version at least 2.13.52"
21916
21917         local mdts=$(comma_list $(mdts_nodes))
21918         local timeout=100
21919         local restripe_status
21920         local delta
21921         local i
21922
21923         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21924
21925         # in case "crush" hash type is not set
21926         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21927
21928         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21929                            mdt.*MDT0000.enable_dir_restripe)
21930         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21931         stack_trap "do_nodes $mdts $LCTL set_param \
21932                     mdt.*.enable_dir_restripe=$restripe_status"
21933
21934         mkdir $DIR/$tdir
21935         createmany -m $DIR/$tdir/f 100 ||
21936                 error "create files under remote dir failed $i"
21937         createmany -d $DIR/$tdir/d 100 ||
21938                 error "create dirs under remote dir failed $i"
21939
21940         for i in $(seq 2 $MDSCOUNT); do
21941                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21942                 $LFS setdirstripe -c $i $DIR/$tdir ||
21943                         error "split -c $i $tdir failed"
21944                 wait_update $HOSTNAME \
21945                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21946                         error "dir split not finished"
21947                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21948                         awk '/migrate/ {sum += $2} END { print sum }')
21949                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21950                 # delta is around total_files/stripe_count
21951                 (( $delta < 200 / (i - 1) + 4 )) ||
21952                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21953         done
21954 }
21955 run_test 230o "dir split"
21956
21957 test_230p() {
21958         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21959         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21960                 skip "Need MDS version at least 2.13.52"
21961
21962         local mdts=$(comma_list $(mdts_nodes))
21963         local timeout=100
21964         local restripe_status
21965         local delta
21966         local c
21967
21968         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21969
21970         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21971
21972         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21973                            mdt.*MDT0000.enable_dir_restripe)
21974         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21975         stack_trap "do_nodes $mdts $LCTL set_param \
21976                     mdt.*.enable_dir_restripe=$restripe_status"
21977
21978         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21979         createmany -m $DIR/$tdir/f 100 ||
21980                 error "create files under remote dir failed"
21981         createmany -d $DIR/$tdir/d 100 ||
21982                 error "create dirs under remote dir failed"
21983
21984         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21985                 local mdt_hash="crush"
21986
21987                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21988                 $LFS setdirstripe -c $c $DIR/$tdir ||
21989                         error "split -c $c $tdir failed"
21990                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21991                         mdt_hash="$mdt_hash,fixed"
21992                 elif [ $c -eq 1 ]; then
21993                         mdt_hash="none"
21994                 fi
21995                 wait_update $HOSTNAME \
21996                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21997                         error "dir merge not finished"
21998                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21999                         awk '/migrate/ {sum += $2} END { print sum }')
22000                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22001                 # delta is around total_files/stripe_count
22002                 (( delta < 200 / c + 4 )) ||
22003                         error "$delta files migrated >= $((200 / c + 4))"
22004         done
22005 }
22006 run_test 230p "dir merge"
22007
22008 test_230q() {
22009         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22010         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22011                 skip "Need MDS version at least 2.13.52"
22012
22013         local mdts=$(comma_list $(mdts_nodes))
22014         local saved_threshold=$(do_facet mds1 \
22015                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22016         local saved_delta=$(do_facet mds1 \
22017                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22018         local threshold=100
22019         local delta=2
22020         local total=0
22021         local stripe_count=0
22022         local stripe_index
22023         local nr_files
22024         local create
22025
22026         # test with fewer files on ZFS
22027         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22028
22029         stack_trap "do_nodes $mdts $LCTL set_param \
22030                     mdt.*.dir_split_count=$saved_threshold"
22031         stack_trap "do_nodes $mdts $LCTL set_param \
22032                     mdt.*.dir_split_delta=$saved_delta"
22033         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22034         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22035         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22036         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22037         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22038         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22039
22040         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22041         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22042
22043         create=$((threshold * 3 / 2))
22044         while [ $stripe_count -lt $MDSCOUNT ]; do
22045                 createmany -m $DIR/$tdir/f $total $create ||
22046                         error "create sub files failed"
22047                 stat $DIR/$tdir > /dev/null
22048                 total=$((total + create))
22049                 stripe_count=$((stripe_count + delta))
22050                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22051
22052                 wait_update $HOSTNAME \
22053                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22054                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22055
22056                 wait_update $HOSTNAME \
22057                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22058                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22059
22060                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22061                 echo "$nr_files/$total files on MDT$stripe_index after split"
22062                 # allow 10% margin of imbalance with crush hash
22063                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22064                         error "$nr_files files on MDT$stripe_index after split"
22065
22066                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22067                 [ $nr_files -eq $total ] ||
22068                         error "total sub files $nr_files != $total"
22069         done
22070
22071         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22072
22073         echo "fixed layout directory won't auto split"
22074         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22075         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22076                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22077         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22078                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22079 }
22080 run_test 230q "dir auto split"
22081
22082 test_230r() {
22083         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22084         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22085         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22086                 skip "Need MDS version at least 2.13.54"
22087
22088         # maximum amount of local locks:
22089         # parent striped dir - 2 locks
22090         # new stripe in parent to migrate to - 1 lock
22091         # source and target - 2 locks
22092         # Total 5 locks for regular file
22093         mkdir -p $DIR/$tdir
22094         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22095         touch $DIR/$tdir/dir1/eee
22096
22097         # create 4 hardlink for 4 more locks
22098         # Total: 9 locks > RS_MAX_LOCKS (8)
22099         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22100         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22101         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22102         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22103         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22104         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22105         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22106         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22107
22108         cancel_lru_locks mdc
22109
22110         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22111                 error "migrate dir fails"
22112
22113         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22114 }
22115 run_test 230r "migrate with too many local locks"
22116
22117 test_230s() {
22118         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22119                 skip "Need MDS version at least 2.14.52"
22120
22121         local mdts=$(comma_list $(mdts_nodes))
22122         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22123                                 mdt.*MDT0000.enable_dir_restripe)
22124
22125         stack_trap "do_nodes $mdts $LCTL set_param \
22126                     mdt.*.enable_dir_restripe=$restripe_status"
22127
22128         local st
22129         for st in 0 1; do
22130                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22131                 test_mkdir $DIR/$tdir
22132                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22133                         error "$LFS mkdir should return EEXIST if target exists"
22134                 rmdir $DIR/$tdir
22135         done
22136 }
22137 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22138
22139 test_230t()
22140 {
22141         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22142         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22143                 skip "Need MDS version at least 2.14.50"
22144
22145         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22146         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22147         $LFS project -p 1 -s $DIR/$tdir ||
22148                 error "set $tdir project id failed"
22149         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22150                 error "set subdir project id failed"
22151         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22152 }
22153 run_test 230t "migrate directory with project ID set"
22154
22155 test_230u()
22156 {
22157         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22158         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22159                 skip "Need MDS version at least 2.14.53"
22160
22161         local count
22162
22163         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22164         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22165         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22166         for i in $(seq 0 $((MDSCOUNT - 1))); do
22167                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22168                 echo "$count dirs migrated to MDT$i"
22169         done
22170         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22171         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22172 }
22173 run_test 230u "migrate directory by QOS"
22174
22175 test_230v()
22176 {
22177         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22178         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22179                 skip "Need MDS version at least 2.14.53"
22180
22181         local count
22182
22183         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22184         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22185         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22186         for i in $(seq 0 $((MDSCOUNT - 1))); do
22187                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22188                 echo "$count subdirs migrated to MDT$i"
22189                 (( i == 3 )) && (( count > 0 )) &&
22190                         error "subdir shouldn't be migrated to MDT3"
22191         done
22192         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22193         (( count == 3 )) || error "dirs migrated to $count MDTs"
22194 }
22195 run_test 230v "subdir migrated to the MDT where its parent is located"
22196
22197 test_230w() {
22198         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22199         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22200                 skip "Need MDS version at least 2.15.0"
22201
22202         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22203         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22204         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22205
22206         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22207                 error "migrate failed"
22208
22209         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22210                 error "$tdir stripe count mismatch"
22211
22212         for i in $(seq 0 9); do
22213                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22214                         error "d$i is striped"
22215         done
22216 }
22217 run_test 230w "non-recursive mode dir migration"
22218
22219 test_230x() {
22220         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22221         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22222                 skip "Need MDS version at least 2.15.0"
22223
22224         mkdir -p $DIR/$tdir || error "mkdir failed"
22225         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22226
22227         local mdt_name=$(mdtname_from_index 0)
22228         local low=$(do_facet mds2 $LCTL get_param -n \
22229                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22230         local high=$(do_facet mds2 $LCTL get_param -n \
22231                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22232         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22233         local maxage=$(do_facet mds2 $LCTL get_param -n \
22234                 osp.*$mdt_name-osp-MDT0001.maxage)
22235
22236         stack_trap "do_facet mds2 $LCTL set_param -n \
22237                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22238                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22239         stack_trap "do_facet mds2 $LCTL set_param -n \
22240                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22241
22242         do_facet mds2 $LCTL set_param -n \
22243                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22244         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22245         sleep 4
22246         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22247                 error "migrate $tdir should fail"
22248
22249         do_facet mds2 $LCTL set_param -n \
22250                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22251         do_facet mds2 $LCTL set_param -n \
22252                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22253         sleep 4
22254         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22255                 error "migrate failed"
22256         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22257                 error "$tdir stripe count mismatch"
22258 }
22259 run_test 230x "dir migration check space"
22260
22261 test_230y() {
22262         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22263         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22264                 skip "Need MDS version at least 2.15.55.45"
22265
22266         local pid
22267
22268         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22269         $LFS getdirstripe $DIR/$tdir
22270         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22271         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22272         pid=$!
22273         sleep 1
22274
22275         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22276         do_facet mds2 lctl set_param fail_loc=0x1802
22277
22278         wait $pid
22279         do_facet mds2 lctl set_param fail_loc=0
22280         $LFS getdirstripe $DIR/$tdir
22281         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22282         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22283 }
22284 run_test 230y "unlink dir with bad hash type"
22285
22286 test_230z() {
22287         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22288         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22289                 skip "Need MDS version at least 2.15.55.45"
22290
22291         local pid
22292
22293         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22294         $LFS getdirstripe $DIR/$tdir
22295         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22296         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22297         pid=$!
22298         sleep 1
22299
22300         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22301         do_facet mds2 lctl set_param fail_loc=0x1802
22302
22303         wait $pid
22304         do_facet mds2 lctl set_param fail_loc=0
22305         $LFS getdirstripe $DIR/$tdir
22306
22307         # resume migration
22308         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22309                 error "resume migration failed"
22310         $LFS getdirstripe $DIR/$tdir
22311         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22312                 error "migration is not finished"
22313 }
22314 run_test 230z "resume dir migration with bad hash type"
22315
22316 test_231a()
22317 {
22318         # For simplicity this test assumes that max_pages_per_rpc
22319         # is the same across all OSCs
22320         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22321         local bulk_size=$((max_pages * PAGE_SIZE))
22322         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22323                                        head -n 1)
22324
22325         mkdir -p $DIR/$tdir
22326         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22327                 error "failed to set stripe with -S ${brw_size}M option"
22328         stack_trap "rm -rf $DIR/$tdir"
22329
22330         # clear the OSC stats
22331         $LCTL set_param osc.*.stats=0 &>/dev/null
22332         stop_writeback
22333
22334         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22335         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22336                 oflag=direct &>/dev/null || error "dd failed"
22337
22338         sync; sleep 1; sync # just to be safe
22339         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22340         if [ x$nrpcs != "x1" ]; then
22341                 $LCTL get_param osc.*.stats
22342                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22343         fi
22344
22345         start_writeback
22346         # Drop the OSC cache, otherwise we will read from it
22347         cancel_lru_locks osc
22348
22349         # clear the OSC stats
22350         $LCTL set_param osc.*.stats=0 &>/dev/null
22351
22352         # Client reads $bulk_size.
22353         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22354                 iflag=direct &>/dev/null || error "dd failed"
22355
22356         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22357         if [ x$nrpcs != "x1" ]; then
22358                 $LCTL get_param osc.*.stats
22359                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22360         fi
22361 }
22362 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22363
22364 test_231b() {
22365         mkdir -p $DIR/$tdir
22366         stack_trap "rm -rf $DIR/$tdir"
22367         local i
22368         for i in {0..1023}; do
22369                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22370                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22371                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22372         done
22373         sync
22374 }
22375 run_test 231b "must not assert on fully utilized OST request buffer"
22376
22377 test_232a() {
22378         mkdir -p $DIR/$tdir
22379         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22380
22381         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22382         do_facet ost1 $LCTL set_param fail_loc=0x31c
22383
22384         # ignore dd failure
22385         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22386         stack_trap "rm -f $DIR/$tdir/$tfile"
22387
22388         do_facet ost1 $LCTL set_param fail_loc=0
22389         umount_client $MOUNT || error "umount failed"
22390         mount_client $MOUNT || error "mount failed"
22391         stop ost1 || error "cannot stop ost1"
22392         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22393 }
22394 run_test 232a "failed lock should not block umount"
22395
22396 test_232b() {
22397         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22398                 skip "Need MDS version at least 2.10.58"
22399
22400         mkdir -p $DIR/$tdir
22401         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22402         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22403         stack_trap "rm -f $DIR/$tdir/$tfile"
22404         sync
22405         cancel_lru_locks osc
22406
22407         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22408         do_facet ost1 $LCTL set_param fail_loc=0x31c
22409
22410         # ignore failure
22411         $LFS data_version $DIR/$tdir/$tfile || true
22412
22413         do_facet ost1 $LCTL set_param fail_loc=0
22414         umount_client $MOUNT || error "umount failed"
22415         mount_client $MOUNT || error "mount failed"
22416         stop ost1 || error "cannot stop ost1"
22417         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22418 }
22419 run_test 232b "failed data version lock should not block umount"
22420
22421 test_233a() {
22422         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22423                 skip "Need MDS version at least 2.3.64"
22424         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22425
22426         local fid=$($LFS path2fid $MOUNT)
22427
22428         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22429                 error "cannot access $MOUNT using its FID '$fid'"
22430 }
22431 run_test 233a "checking that OBF of the FS root succeeds"
22432
22433 test_233b() {
22434         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22435                 skip "Need MDS version at least 2.5.90"
22436         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22437
22438         local fid=$($LFS path2fid $MOUNT/.lustre)
22439
22440         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22441                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22442
22443         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22444         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22445                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22446 }
22447 run_test 233b "checking that OBF of the FS .lustre succeeds"
22448
22449 test_234() {
22450         local p="$TMP/sanityN-$TESTNAME.parameters"
22451         save_lustre_params client "llite.*.xattr_cache" > $p
22452         lctl set_param llite.*.xattr_cache 1 ||
22453                 skip_env "xattr cache is not supported"
22454
22455         mkdir -p $DIR/$tdir || error "mkdir failed"
22456         touch $DIR/$tdir/$tfile || error "touch failed"
22457         # OBD_FAIL_LLITE_XATTR_ENOMEM
22458         $LCTL set_param fail_loc=0x1405
22459         getfattr -n user.attr $DIR/$tdir/$tfile &&
22460                 error "getfattr should have failed with ENOMEM"
22461         $LCTL set_param fail_loc=0x0
22462         rm -rf $DIR/$tdir
22463
22464         restore_lustre_params < $p
22465         rm -f $p
22466 }
22467 run_test 234 "xattr cache should not crash on ENOMEM"
22468
22469 test_235() {
22470         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22471                 skip "Need MDS version at least 2.4.52"
22472
22473         flock_deadlock $DIR/$tfile
22474         local RC=$?
22475         case $RC in
22476                 0)
22477                 ;;
22478                 124) error "process hangs on a deadlock"
22479                 ;;
22480                 *) error "error executing flock_deadlock $DIR/$tfile"
22481                 ;;
22482         esac
22483 }
22484 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22485
22486 #LU-2935
22487 test_236() {
22488         check_swap_layouts_support
22489
22490         local ref1=/etc/passwd
22491         local ref2=/etc/group
22492         local file1=$DIR/$tdir/f1
22493         local file2=$DIR/$tdir/f2
22494
22495         test_mkdir -c1 $DIR/$tdir
22496         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22497         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22498         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22499         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22500         local fd=$(free_fd)
22501         local cmd="exec $fd<>$file2"
22502         eval $cmd
22503         rm $file2
22504         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22505                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22506         cmd="exec $fd>&-"
22507         eval $cmd
22508         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22509
22510         #cleanup
22511         rm -rf $DIR/$tdir
22512 }
22513 run_test 236 "Layout swap on open unlinked file"
22514
22515 # LU-4659 linkea consistency
22516 test_238() {
22517         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22518                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22519                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22520                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22521
22522         touch $DIR/$tfile
22523         ln $DIR/$tfile $DIR/$tfile.lnk
22524         touch $DIR/$tfile.new
22525         mv $DIR/$tfile.new $DIR/$tfile
22526         local fid1=$($LFS path2fid $DIR/$tfile)
22527         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22528         local path1=$($LFS fid2path $FSNAME "$fid1")
22529         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22530         local path2=$($LFS fid2path $FSNAME "$fid2")
22531         [ $tfile.lnk == $path2 ] ||
22532                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22533         rm -f $DIR/$tfile*
22534 }
22535 run_test 238 "Verify linkea consistency"
22536
22537 test_239A() { # was test_239
22538         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22539                 skip "Need MDS version at least 2.5.60"
22540
22541         local list=$(comma_list $(mdts_nodes))
22542
22543         mkdir -p $DIR/$tdir
22544         createmany -o $DIR/$tdir/f- 5000
22545         unlinkmany $DIR/$tdir/f- 5000
22546         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22547                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22548         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22549                         osp.*MDT*.sync_in_flight" | calc_sum)
22550         [ "$changes" -eq 0 ] || error "$changes not synced"
22551 }
22552 run_test 239A "osp_sync test"
22553
22554 test_239a() { #LU-5297
22555         remote_mds_nodsh && skip "remote MDS with nodsh"
22556
22557         touch $DIR/$tfile
22558         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22559         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22560         chgrp $RUNAS_GID $DIR/$tfile
22561         wait_delete_completed
22562 }
22563 run_test 239a "process invalid osp sync record correctly"
22564
22565 test_239b() { #LU-5297
22566         remote_mds_nodsh && skip "remote MDS with nodsh"
22567
22568         touch $DIR/$tfile1
22569         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22570         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22571         chgrp $RUNAS_GID $DIR/$tfile1
22572         wait_delete_completed
22573         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22574         touch $DIR/$tfile2
22575         chgrp $RUNAS_GID $DIR/$tfile2
22576         wait_delete_completed
22577 }
22578 run_test 239b "process osp sync record with ENOMEM error correctly"
22579
22580 test_240() {
22581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22582         remote_mds_nodsh && skip "remote MDS with nodsh"
22583
22584         mkdir -p $DIR/$tdir
22585
22586         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22587                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22588         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22589                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22590
22591         umount_client $MOUNT || error "umount failed"
22592         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22593         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22594         mount_client $MOUNT || error "failed to mount client"
22595
22596         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22597         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22598 }
22599 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22600
22601 test_241_bio() {
22602         local count=$1
22603         local bsize=$2
22604
22605         for LOOP in $(seq $count); do
22606                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22607                 cancel_lru_locks $OSC || true
22608         done
22609 }
22610
22611 test_241_dio() {
22612         local count=$1
22613         local bsize=$2
22614
22615         for LOOP in $(seq $1); do
22616                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22617                         2>/dev/null
22618         done
22619 }
22620
22621 test_241a() { # was test_241
22622         local bsize=$PAGE_SIZE
22623
22624         (( bsize < 40960 )) && bsize=40960
22625         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22626         ls -la $DIR/$tfile
22627         cancel_lru_locks $OSC
22628         test_241_bio 1000 $bsize &
22629         PID=$!
22630         test_241_dio 1000 $bsize
22631         wait $PID
22632 }
22633 run_test 241a "bio vs dio"
22634
22635 test_241b() {
22636         local bsize=$PAGE_SIZE
22637
22638         (( bsize < 40960 )) && bsize=40960
22639         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22640         ls -la $DIR/$tfile
22641         test_241_dio 1000 $bsize &
22642         PID=$!
22643         test_241_dio 1000 $bsize
22644         wait $PID
22645 }
22646 run_test 241b "dio vs dio"
22647
22648 test_242() {
22649         remote_mds_nodsh && skip "remote MDS with nodsh"
22650
22651         mkdir_on_mdt0 $DIR/$tdir
22652         touch $DIR/$tdir/$tfile
22653
22654         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22655         do_facet mds1 lctl set_param fail_loc=0x105
22656         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22657
22658         do_facet mds1 lctl set_param fail_loc=0
22659         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22660 }
22661 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22662
22663 test_243()
22664 {
22665         test_mkdir $DIR/$tdir
22666         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22667 }
22668 run_test 243 "various group lock tests"
22669
22670 test_244a()
22671 {
22672         test_mkdir $DIR/$tdir
22673         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22674         sendfile_grouplock $DIR/$tdir/$tfile || \
22675                 error "sendfile+grouplock failed"
22676         rm -rf $DIR/$tdir
22677 }
22678 run_test 244a "sendfile with group lock tests"
22679
22680 test_244b()
22681 {
22682         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22683
22684         local threads=50
22685         local size=$((1024*1024))
22686
22687         test_mkdir $DIR/$tdir
22688         for i in $(seq 1 $threads); do
22689                 local file=$DIR/$tdir/file_$((i / 10))
22690                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22691                 local pids[$i]=$!
22692         done
22693         for i in $(seq 1 $threads); do
22694                 wait ${pids[$i]}
22695         done
22696 }
22697 run_test 244b "multi-threaded write with group lock"
22698
22699 test_245a() {
22700         local flagname="multi_mod_rpcs"
22701         local connect_data_name="max_mod_rpcs"
22702         local out
22703
22704         # check if multiple modify RPCs flag is set
22705         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22706                 grep "connect_flags:")
22707         echo "$out"
22708
22709         echo "$out" | grep -qw $flagname
22710         if [ $? -ne 0 ]; then
22711                 echo "connect flag $flagname is not set"
22712                 return
22713         fi
22714
22715         # check if multiple modify RPCs data is set
22716         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22717         echo "$out"
22718
22719         echo "$out" | grep -qw $connect_data_name ||
22720                 error "import should have connect data $connect_data_name"
22721 }
22722 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22723
22724 test_245b() {
22725         local flagname="multi_mod_rpcs"
22726         local connect_data_name="max_mod_rpcs"
22727         local out
22728
22729         remote_mds_nodsh && skip "remote MDS with nodsh"
22730         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22731
22732         # check if multiple modify RPCs flag is set
22733         out=$(do_facet mds1 \
22734               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22735               grep "connect_flags:")
22736         echo "$out"
22737
22738         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22739
22740         # check if multiple modify RPCs data is set
22741         out=$(do_facet mds1 \
22742               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22743
22744         [[ "$out" =~ $connect_data_name ]] ||
22745                 {
22746                         echo "$out"
22747                         error "missing connect data $connect_data_name"
22748                 }
22749 }
22750 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22751
22752 cleanup_247() {
22753         local submount=$1
22754
22755         trap 0
22756         umount_client $submount
22757         rmdir $submount
22758 }
22759
22760 test_247a() {
22761         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22762                 grep -q subtree ||
22763                 skip_env "Fileset feature is not supported"
22764
22765         local submount=${MOUNT}_$tdir
22766
22767         mkdir $MOUNT/$tdir
22768         mkdir -p $submount || error "mkdir $submount failed"
22769         FILESET="$FILESET/$tdir" mount_client $submount ||
22770                 error "mount $submount failed"
22771         trap "cleanup_247 $submount" EXIT
22772         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22773         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22774                 error "read $MOUNT/$tdir/$tfile failed"
22775         cleanup_247 $submount
22776 }
22777 run_test 247a "mount subdir as fileset"
22778
22779 test_247b() {
22780         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22781                 skip_env "Fileset feature is not supported"
22782
22783         local submount=${MOUNT}_$tdir
22784
22785         rm -rf $MOUNT/$tdir
22786         mkdir -p $submount || error "mkdir $submount failed"
22787         SKIP_FILESET=1
22788         FILESET="$FILESET/$tdir" mount_client $submount &&
22789                 error "mount $submount should fail"
22790         rmdir $submount
22791 }
22792 run_test 247b "mount subdir that dose not exist"
22793
22794 test_247c() {
22795         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22796                 skip_env "Fileset feature is not supported"
22797
22798         local submount=${MOUNT}_$tdir
22799
22800         mkdir -p $MOUNT/$tdir/dir1
22801         mkdir -p $submount || error "mkdir $submount failed"
22802         trap "cleanup_247 $submount" EXIT
22803         FILESET="$FILESET/$tdir" mount_client $submount ||
22804                 error "mount $submount failed"
22805         local fid=$($LFS path2fid $MOUNT/)
22806         $LFS fid2path $submount $fid && error "fid2path should fail"
22807         cleanup_247 $submount
22808 }
22809 run_test 247c "running fid2path outside subdirectory root"
22810
22811 test_247d() {
22812         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22813                 skip "Fileset feature is not supported"
22814
22815         local submount=${MOUNT}_$tdir
22816
22817         mkdir -p $MOUNT/$tdir/dir1
22818         mkdir -p $submount || error "mkdir $submount failed"
22819         FILESET="$FILESET/$tdir" mount_client $submount ||
22820                 error "mount $submount failed"
22821         trap "cleanup_247 $submount" EXIT
22822
22823         local td=$submount/dir1
22824         local fid=$($LFS path2fid $td)
22825         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22826
22827         # check that we get the same pathname back
22828         local rootpath
22829         local found
22830         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22831                 echo "$rootpath $fid"
22832                 found=$($LFS fid2path $rootpath "$fid")
22833                 [ -n "$found" ] || error "fid2path should succeed"
22834                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22835         done
22836         # check wrong root path format
22837         rootpath=$submount"_wrong"
22838         found=$($LFS fid2path $rootpath "$fid")
22839         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22840
22841         cleanup_247 $submount
22842 }
22843 run_test 247d "running fid2path inside subdirectory root"
22844
22845 # LU-8037
22846 test_247e() {
22847         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22848                 grep -q subtree ||
22849                 skip "Fileset feature is not supported"
22850
22851         local submount=${MOUNT}_$tdir
22852
22853         mkdir $MOUNT/$tdir
22854         mkdir -p $submount || error "mkdir $submount failed"
22855         FILESET="$FILESET/.." mount_client $submount &&
22856                 error "mount $submount should fail"
22857         rmdir $submount
22858 }
22859 run_test 247e "mount .. as fileset"
22860
22861 test_247f() {
22862         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22863         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22864                 skip "Need at least version 2.14.50.162"
22865         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22866                 skip "Fileset feature is not supported"
22867
22868         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22869         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22870                 error "mkdir remote failed"
22871         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22872                 error "mkdir remote/subdir failed"
22873         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22874                 error "mkdir striped failed"
22875         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22876
22877         local submount=${MOUNT}_$tdir
22878
22879         mkdir -p $submount || error "mkdir $submount failed"
22880         stack_trap "rmdir $submount"
22881
22882         local dir
22883         local fileset=$FILESET
22884         local mdts=$(comma_list $(mdts_nodes))
22885
22886         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22887         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22888                 $tdir/striped/subdir $tdir/striped/.; do
22889                 FILESET="$fileset/$dir" mount_client $submount ||
22890                         error "mount $dir failed"
22891                 umount_client $submount
22892         done
22893 }
22894 run_test 247f "mount striped or remote directory as fileset"
22895
22896 test_subdir_mount_lock()
22897 {
22898         local testdir=$1
22899         local submount=${MOUNT}_$(basename $testdir)
22900
22901         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22902
22903         mkdir -p $submount || error "mkdir $submount failed"
22904         stack_trap "rmdir $submount"
22905
22906         FILESET="$fileset/$testdir" mount_client $submount ||
22907                 error "mount $FILESET failed"
22908         stack_trap "umount $submount"
22909
22910         local mdts=$(comma_list $(mdts_nodes))
22911
22912         local nrpcs
22913
22914         stat $submount > /dev/null || error "stat $submount failed"
22915         cancel_lru_locks $MDC
22916         stat $submount > /dev/null || error "stat $submount failed"
22917         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22918         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22919         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22920         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22921                 awk '/getattr/ {sum += $2} END {print sum}')
22922
22923         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22924 }
22925
22926 test_247g() {
22927         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22928
22929         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22930                 error "mkdir $tdir failed"
22931         test_subdir_mount_lock $tdir
22932 }
22933 run_test 247g "striped directory submount revalidate ROOT from cache"
22934
22935 test_247h() {
22936         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22937         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22938                 skip "Need MDS version at least 2.15.51"
22939
22940         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22941         test_subdir_mount_lock $tdir
22942         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22943         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22944                 error "mkdir $tdir.1 failed"
22945         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22946 }
22947 run_test 247h "remote directory submount revalidate ROOT from cache"
22948
22949 test_248a() {
22950         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22951         [ -z "$fast_read_sav" ] && skip "no fast read support"
22952
22953         # create a large file for fast read verification
22954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22955
22956         # make sure the file is created correctly
22957         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22958                 { rm -f $DIR/$tfile; skip "file creation error"; }
22959
22960         echo "Test 1: verify that fast read is 4 times faster on cache read"
22961
22962         # small read with fast read enabled
22963         $LCTL set_param -n llite.*.fast_read=1
22964         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22965                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22966                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22967         # small read with fast read disabled
22968         $LCTL set_param -n llite.*.fast_read=0
22969         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22970                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22971                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22972
22973         # verify that fast read is 4 times faster for cache read
22974         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22975                 error_not_in_vm "fast read was not 4 times faster: " \
22976                            "$t_fast vs $t_slow"
22977
22978         echo "Test 2: verify the performance between big and small read"
22979         $LCTL set_param -n llite.*.fast_read=1
22980
22981         # 1k non-cache read
22982         cancel_lru_locks osc
22983         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22984                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22985                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22986
22987         # 1M non-cache read
22988         cancel_lru_locks osc
22989         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22990                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22991                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22992
22993         # verify that big IO is not 4 times faster than small IO
22994         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22995                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22996
22997         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22998         rm -f $DIR/$tfile
22999 }
23000 run_test 248a "fast read verification"
23001
23002 test_248b() {
23003         # Default short_io_bytes=16384, try both smaller and larger sizes.
23004         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23005         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23006         echo "bs=53248 count=113 normal buffered write"
23007         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23008                 error "dd of initial data file failed"
23009         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23010
23011         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23012         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23013                 error "dd with sync normal writes failed"
23014         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23015
23016         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23017         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23018                 error "dd with sync small writes failed"
23019         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23020
23021         cancel_lru_locks osc
23022
23023         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23024         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23025         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23026         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23027                 iflag=direct || error "dd with O_DIRECT small read failed"
23028         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23029         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23030                 error "compare $TMP/$tfile.1 failed"
23031
23032         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23033         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23034
23035         # just to see what the maximum tunable value is, and test parsing
23036         echo "test invalid parameter 2MB"
23037         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23038                 error "too-large short_io_bytes allowed"
23039         echo "test maximum parameter 512KB"
23040         # if we can set a larger short_io_bytes, run test regardless of version
23041         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23042                 # older clients may not allow setting it this large, that's OK
23043                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23044                         skip "Need at least client version 2.13.50"
23045                 error "medium short_io_bytes failed"
23046         fi
23047         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23048         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23049
23050         echo "test large parameter 64KB"
23051         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23052         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23053
23054         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23055         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23056                 error "dd with sync large writes failed"
23057         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23058
23059         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23060         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23061         num=$((113 * 4096 / PAGE_SIZE))
23062         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23063         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23064                 error "dd with O_DIRECT large writes failed"
23065         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23066                 error "compare $DIR/$tfile.3 failed"
23067
23068         cancel_lru_locks osc
23069
23070         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23071         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23072                 error "dd with O_DIRECT large read failed"
23073         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23074                 error "compare $TMP/$tfile.2 failed"
23075
23076         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23077         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23078                 error "dd with O_DIRECT large read failed"
23079         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23080                 error "compare $TMP/$tfile.3 failed"
23081 }
23082 run_test 248b "test short_io read and write for both small and large sizes"
23083
23084 test_249() { # LU-7890
23085         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23086                 skip "Need at least version 2.8.54"
23087
23088         rm -f $DIR/$tfile
23089         $LFS setstripe -c 1 $DIR/$tfile
23090         # Offset 2T == 4k * 512M
23091         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23092                 error "dd to 2T offset failed"
23093 }
23094 run_test 249 "Write above 2T file size"
23095
23096 test_250() {
23097         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23098          && skip "no 16TB file size limit on ZFS"
23099
23100         $LFS setstripe -c 1 $DIR/$tfile
23101         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23102         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23103         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23104         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23105                 conv=notrunc,fsync && error "append succeeded"
23106         return 0
23107 }
23108 run_test 250 "Write above 16T limit"
23109
23110 test_251() {
23111         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23112
23113         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23114         #Skip once - writing the first stripe will succeed
23115         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23116         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23117                 error "short write happened"
23118
23119         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23120         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23121                 error "short read happened"
23122
23123         rm -f $DIR/$tfile
23124 }
23125 run_test 251 "Handling short read and write correctly"
23126
23127 test_252() {
23128         remote_mds_nodsh && skip "remote MDS with nodsh"
23129         remote_ost_nodsh && skip "remote OST with nodsh"
23130         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23131                 skip_env "ldiskfs only test"
23132         fi
23133
23134         local tgt
23135         local dev
23136         local out
23137         local uuid
23138         local num
23139         local gen
23140
23141         # check lr_reader on OST0000
23142         tgt=ost1
23143         dev=$(facet_device $tgt)
23144         out=$(do_facet $tgt $LR_READER $dev)
23145         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23146         echo "$out"
23147         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23148         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23149                 error "Invalid uuid returned by $LR_READER on target $tgt"
23150         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23151
23152         # check lr_reader -c on MDT0000
23153         tgt=mds1
23154         dev=$(facet_device $tgt)
23155         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23156                 skip "$LR_READER does not support additional options"
23157         fi
23158         out=$(do_facet $tgt $LR_READER -c $dev)
23159         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23160         echo "$out"
23161         num=$(echo "$out" | grep -c "mdtlov")
23162         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23163                 error "Invalid number of mdtlov clients returned by $LR_READER"
23164         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23165
23166         # check lr_reader -cr on MDT0000
23167         out=$(do_facet $tgt $LR_READER -cr $dev)
23168         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23169         echo "$out"
23170         echo "$out" | grep -q "^reply_data:$" ||
23171                 error "$LR_READER should have returned 'reply_data' section"
23172         num=$(echo "$out" | grep -c "client_generation")
23173         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23174 }
23175 run_test 252 "check lr_reader tool"
23176
23177 test_253() {
23178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23179         remote_mds_nodsh && skip "remote MDS with nodsh"
23180         remote_mgs_nodsh && skip "remote MGS with nodsh"
23181
23182         local ostidx=0
23183         local rc=0
23184         local ost_name=$(ostname_from_index $ostidx)
23185
23186         # on the mdt's osc
23187         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23188         do_facet $SINGLEMDS $LCTL get_param -n \
23189                 osp.$mdtosc_proc1.reserved_mb_high ||
23190                 skip  "remote MDS does not support reserved_mb_high"
23191
23192         rm -rf $DIR/$tdir
23193         wait_mds_ost_sync
23194         wait_delete_completed
23195         mkdir $DIR/$tdir
23196         stack_trap "rm -rf $DIR/$tdir"
23197
23198         pool_add $TESTNAME || error "Pool creation failed"
23199         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23200
23201         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23202                 error "Setstripe failed"
23203
23204         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23205
23206         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23207                     grep "watermarks")
23208         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23209
23210         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23211                         osp.$mdtosc_proc1.prealloc_status)
23212         echo "prealloc_status $oa_status"
23213
23214         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23215                 error "File creation should fail"
23216
23217         #object allocation was stopped, but we still able to append files
23218         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23219                 oflag=append || error "Append failed"
23220
23221         rm -f $DIR/$tdir/$tfile.0
23222
23223         # For this test, we want to delete the files we created to go out of
23224         # space but leave the watermark, so we remain nearly out of space
23225         ost_watermarks_enospc_delete_files $tfile $ostidx
23226
23227         wait_delete_completed
23228
23229         sleep_maxage
23230
23231         for i in $(seq 10 12); do
23232                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23233                         2>/dev/null || error "File creation failed after rm"
23234         done
23235
23236         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23237                         osp.$mdtosc_proc1.prealloc_status)
23238         echo "prealloc_status $oa_status"
23239
23240         if (( oa_status != 0 )); then
23241                 error "Object allocation still disable after rm"
23242         fi
23243 }
23244 run_test 253 "Check object allocation limit"
23245
23246 test_254() {
23247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23248         remote_mds_nodsh && skip "remote MDS with nodsh"
23249
23250         local mdt=$(facet_svc $SINGLEMDS)
23251
23252         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23253                 skip "MDS does not support changelog_size"
23254
23255         local cl_user
23256
23257         changelog_register || error "changelog_register failed"
23258
23259         changelog_clear 0 || error "changelog_clear failed"
23260
23261         local size1=$(do_facet $SINGLEMDS \
23262                       $LCTL get_param -n mdd.$mdt.changelog_size)
23263         echo "Changelog size $size1"
23264
23265         rm -rf $DIR/$tdir
23266         $LFS mkdir -i 0 $DIR/$tdir
23267         # change something
23268         mkdir -p $DIR/$tdir/pics/2008/zachy
23269         touch $DIR/$tdir/pics/2008/zachy/timestamp
23270         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23271         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23272         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23273         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23274         rm $DIR/$tdir/pics/desktop.jpg
23275
23276         local size2=$(do_facet $SINGLEMDS \
23277                       $LCTL get_param -n mdd.$mdt.changelog_size)
23278         echo "Changelog size after work $size2"
23279
23280         (( $size2 > $size1 )) ||
23281                 error "new Changelog size=$size2 less than old size=$size1"
23282 }
23283 run_test 254 "Check changelog size"
23284
23285 ladvise_no_type()
23286 {
23287         local type=$1
23288         local file=$2
23289
23290         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23291                 awk -F: '{print $2}' | grep $type > /dev/null
23292         if [ $? -ne 0 ]; then
23293                 return 0
23294         fi
23295         return 1
23296 }
23297
23298 ladvise_no_ioctl()
23299 {
23300         local file=$1
23301
23302         lfs ladvise -a willread $file > /dev/null 2>&1
23303         if [ $? -eq 0 ]; then
23304                 return 1
23305         fi
23306
23307         lfs ladvise -a willread $file 2>&1 |
23308                 grep "Inappropriate ioctl for device" > /dev/null
23309         if [ $? -eq 0 ]; then
23310                 return 0
23311         fi
23312         return 1
23313 }
23314
23315 percent() {
23316         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23317 }
23318
23319 # run a random read IO workload
23320 # usage: random_read_iops <filename> <filesize> <iosize>
23321 random_read_iops() {
23322         local file=$1
23323         local fsize=$2
23324         local iosize=${3:-4096}
23325
23326         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23327                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23328 }
23329
23330 drop_file_oss_cache() {
23331         local file="$1"
23332         local nodes="$2"
23333
23334         $LFS ladvise -a dontneed $file 2>/dev/null ||
23335                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23336 }
23337
23338 ladvise_willread_performance()
23339 {
23340         local repeat=10
23341         local average_origin=0
23342         local average_cache=0
23343         local average_ladvise=0
23344
23345         for ((i = 1; i <= $repeat; i++)); do
23346                 echo "Iter $i/$repeat: reading without willread hint"
23347                 cancel_lru_locks osc
23348                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23349                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23350                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23351                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23352
23353                 cancel_lru_locks osc
23354                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23355                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23356                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23357
23358                 cancel_lru_locks osc
23359                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23360                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23361                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23362                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23363                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23364         done
23365         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23366         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23367         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23368
23369         speedup_cache=$(percent $average_cache $average_origin)
23370         speedup_ladvise=$(percent $average_ladvise $average_origin)
23371
23372         echo "Average uncached read: $average_origin"
23373         echo "Average speedup with OSS cached read: " \
23374                 "$average_cache = +$speedup_cache%"
23375         echo "Average speedup with ladvise willread: " \
23376                 "$average_ladvise = +$speedup_ladvise%"
23377
23378         local lowest_speedup=20
23379         if (( ${average_cache%.*} < $lowest_speedup )); then
23380                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23381                      " got $average_cache%. Skipping ladvise willread check."
23382                 return 0
23383         fi
23384
23385         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23386         # it is still good to run until then to exercise 'ladvise willread'
23387         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23388                 [ "$ost1_FSTYPE" = "zfs" ] &&
23389                 echo "osd-zfs does not support dontneed or drop_caches" &&
23390                 return 0
23391
23392         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23393         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23394                 error_not_in_vm "Speedup with willread is less than " \
23395                         "$lowest_speedup%, got $average_ladvise%"
23396 }
23397
23398 test_255a() {
23399         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23400                 skip "lustre < 2.8.54 does not support ladvise "
23401         remote_ost_nodsh && skip "remote OST with nodsh"
23402
23403         stack_trap "rm -f $DIR/$tfile"
23404         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23405
23406         ladvise_no_type willread $DIR/$tfile &&
23407                 skip "willread ladvise is not supported"
23408
23409         ladvise_no_ioctl $DIR/$tfile &&
23410                 skip "ladvise ioctl is not supported"
23411
23412         local size_mb=100
23413         local size=$((size_mb * 1048576))
23414         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23415                 error "dd to $DIR/$tfile failed"
23416
23417         lfs ladvise -a willread $DIR/$tfile ||
23418                 error "Ladvise failed with no range argument"
23419
23420         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23421                 error "Ladvise failed with no -l or -e argument"
23422
23423         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23424                 error "Ladvise failed with only -e argument"
23425
23426         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23427                 error "Ladvise failed with only -l argument"
23428
23429         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23430                 error "End offset should not be smaller than start offset"
23431
23432         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23433                 error "End offset should not be equal to start offset"
23434
23435         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23436                 error "Ladvise failed with overflowing -s argument"
23437
23438         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23439                 error "Ladvise failed with overflowing -e argument"
23440
23441         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23442                 error "Ladvise failed with overflowing -l argument"
23443
23444         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23445                 error "Ladvise succeeded with conflicting -l and -e arguments"
23446
23447         echo "Synchronous ladvise should wait"
23448         local delay=8
23449 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23450         do_nodes $(comma_list $(osts_nodes)) \
23451                 $LCTL set_param fail_val=$delay fail_loc=0x237
23452         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23453                 $LCTL set_param fail_loc=0"
23454
23455         local start_ts=$SECONDS
23456         lfs ladvise -a willread $DIR/$tfile ||
23457                 error "Ladvise failed with no range argument"
23458         local end_ts=$SECONDS
23459         local inteval_ts=$((end_ts - start_ts))
23460
23461         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23462                 error "Synchronous advice didn't wait reply"
23463         fi
23464
23465         echo "Asynchronous ladvise shouldn't wait"
23466         local start_ts=$SECONDS
23467         lfs ladvise -a willread -b $DIR/$tfile ||
23468                 error "Ladvise failed with no range argument"
23469         local end_ts=$SECONDS
23470         local inteval_ts=$((end_ts - start_ts))
23471
23472         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23473                 error "Asynchronous advice blocked"
23474         fi
23475
23476         ladvise_willread_performance
23477 }
23478 run_test 255a "check 'lfs ladvise -a willread'"
23479
23480 facet_meminfo() {
23481         local facet=$1
23482         local info=$2
23483
23484         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23485 }
23486
23487 test_255b() {
23488         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23489                 skip "lustre < 2.8.54 does not support ladvise "
23490         remote_ost_nodsh && skip "remote OST with nodsh"
23491
23492         stack_trap "rm -f $DIR/$tfile"
23493         lfs setstripe -c 1 -i 0 $DIR/$tfile
23494
23495         ladvise_no_type dontneed $DIR/$tfile &&
23496                 skip "dontneed ladvise is not supported"
23497
23498         ladvise_no_ioctl $DIR/$tfile &&
23499                 skip "ladvise ioctl is not supported"
23500
23501         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23502                 [ "$ost1_FSTYPE" = "zfs" ] &&
23503                 skip "zfs-osd does not support 'ladvise dontneed'"
23504
23505         local size_mb=100
23506         local size=$((size_mb * 1048576))
23507         # In order to prevent disturbance of other processes, only check 3/4
23508         # of the memory usage
23509         local kibibytes=$((size_mb * 1024 * 3 / 4))
23510
23511         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23512                 error "dd to $DIR/$tfile failed"
23513
23514         #force write to complete before dropping OST cache & checking memory
23515         sync
23516
23517         local total=$(facet_meminfo ost1 MemTotal)
23518         echo "Total memory: $total KiB"
23519
23520         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23521         local before_read=$(facet_meminfo ost1 Cached)
23522         echo "Cache used before read: $before_read KiB"
23523
23524         lfs ladvise -a willread $DIR/$tfile ||
23525                 error "Ladvise willread failed"
23526         local after_read=$(facet_meminfo ost1 Cached)
23527         echo "Cache used after read: $after_read KiB"
23528
23529         lfs ladvise -a dontneed $DIR/$tfile ||
23530                 error "Ladvise dontneed again failed"
23531         local no_read=$(facet_meminfo ost1 Cached)
23532         echo "Cache used after dontneed ladvise: $no_read KiB"
23533
23534         if [ $total -lt $((before_read + kibibytes)) ]; then
23535                 echo "Memory is too small, abort checking"
23536                 return 0
23537         fi
23538
23539         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23540                 error "Ladvise willread should use more memory" \
23541                         "than $kibibytes KiB"
23542         fi
23543
23544         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23545                 error "Ladvise dontneed should release more memory" \
23546                         "than $kibibytes KiB"
23547         fi
23548 }
23549 run_test 255b "check 'lfs ladvise -a dontneed'"
23550
23551 test_255c() {
23552         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23553                 skip "lustre < 2.10.50 does not support lockahead"
23554
23555         local ost1_imp=$(get_osc_import_name client ost1)
23556         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23557                          cut -d'.' -f2)
23558         local count
23559         local new_count
23560         local difference
23561         local i
23562         local rc
23563
23564         test_mkdir -p $DIR/$tdir
23565         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23566
23567         #test 10 returns only success/failure
23568         i=10
23569         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23570         rc=$?
23571         if [ $rc -eq 255 ]; then
23572                 error "Ladvise test${i} failed, ${rc}"
23573         fi
23574
23575         #test 11 counts lock enqueue requests, all others count new locks
23576         i=11
23577         count=$(do_facet ost1 \
23578                 $LCTL get_param -n ost.OSS.ost.stats)
23579         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23580
23581         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23582         rc=$?
23583         if [ $rc -eq 255 ]; then
23584                 error "Ladvise test${i} failed, ${rc}"
23585         fi
23586
23587         new_count=$(do_facet ost1 \
23588                 $LCTL get_param -n ost.OSS.ost.stats)
23589         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23590                    awk '{ print $2 }')
23591
23592         difference="$((new_count - count))"
23593         if [ $difference -ne $rc ]; then
23594                 error "Ladvise test${i}, bad enqueue count, returned " \
23595                       "${rc}, actual ${difference}"
23596         fi
23597
23598         for i in $(seq 12 21); do
23599                 # If we do not do this, we run the risk of having too many
23600                 # locks and starting lock cancellation while we are checking
23601                 # lock counts.
23602                 cancel_lru_locks osc
23603
23604                 count=$($LCTL get_param -n \
23605                        ldlm.namespaces.$imp_name.lock_unused_count)
23606
23607                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23608                 rc=$?
23609                 if [ $rc -eq 255 ]; then
23610                         error "Ladvise test ${i} failed, ${rc}"
23611                 fi
23612
23613                 new_count=$($LCTL get_param -n \
23614                        ldlm.namespaces.$imp_name.lock_unused_count)
23615                 difference="$((new_count - count))"
23616
23617                 # Test 15 output is divided by 100 to map down to valid return
23618                 if [ $i -eq 15 ]; then
23619                         rc="$((rc * 100))"
23620                 fi
23621
23622                 if [ $difference -ne $rc ]; then
23623                         error "Ladvise test ${i}, bad lock count, returned " \
23624                               "${rc}, actual ${difference}"
23625                 fi
23626         done
23627
23628         #test 22 returns only success/failure
23629         i=22
23630         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23631         rc=$?
23632         if [ $rc -eq 255 ]; then
23633                 error "Ladvise test${i} failed, ${rc}"
23634         fi
23635 }
23636 run_test 255c "suite of ladvise lockahead tests"
23637
23638 test_256() {
23639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23640         remote_mds_nodsh && skip "remote MDS with nodsh"
23641         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23642         changelog_users $SINGLEMDS | grep "^cl" &&
23643                 skip "active changelog user"
23644
23645         local cl_user
23646         local cat_sl
23647         local mdt_dev
23648
23649         mdt_dev=$(facet_device $SINGLEMDS)
23650         echo $mdt_dev
23651
23652         changelog_register || error "changelog_register failed"
23653
23654         rm -rf $DIR/$tdir
23655         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23656
23657         changelog_clear 0 || error "changelog_clear failed"
23658
23659         # change something
23660         touch $DIR/$tdir/{1..10}
23661
23662         # stop the MDT
23663         stop $SINGLEMDS || error "Fail to stop MDT"
23664
23665         # remount the MDT
23666         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23667                 error "Fail to start MDT"
23668
23669         #after mount new plainllog is used
23670         touch $DIR/$tdir/{11..19}
23671         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23672         stack_trap "rm -f $tmpfile"
23673         cat_sl=$(do_facet $SINGLEMDS "sync; \
23674                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23675                  llog_reader $tmpfile | grep -c type=1064553b")
23676         do_facet $SINGLEMDS llog_reader $tmpfile
23677
23678         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23679
23680         changelog_clear 0 || error "changelog_clear failed"
23681
23682         cat_sl=$(do_facet $SINGLEMDS "sync; \
23683                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23684                  llog_reader $tmpfile | grep -c type=1064553b")
23685
23686         if (( cat_sl == 2 )); then
23687                 error "Empty plain llog was not deleted from changelog catalog"
23688         elif (( cat_sl != 1 )); then
23689                 error "Active plain llog shouldn't be deleted from catalog"
23690         fi
23691 }
23692 run_test 256 "Check llog delete for empty and not full state"
23693
23694 test_257() {
23695         remote_mds_nodsh && skip "remote MDS with nodsh"
23696         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23697                 skip "Need MDS version at least 2.8.55"
23698
23699         test_mkdir $DIR/$tdir
23700
23701         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23702                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23703         stat $DIR/$tdir
23704
23705 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23706         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23707         local facet=mds$((mdtidx + 1))
23708         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23709         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23710
23711         stop $facet || error "stop MDS failed"
23712         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23713                 error "start MDS fail"
23714         wait_recovery_complete $facet
23715 }
23716 run_test 257 "xattr locks are not lost"
23717
23718 # Verify we take the i_mutex when security requires it
23719 test_258a() {
23720 #define OBD_FAIL_IMUTEX_SEC 0x141c
23721         $LCTL set_param fail_loc=0x141c
23722         touch $DIR/$tfile
23723         chmod u+s $DIR/$tfile
23724         chmod a+rwx $DIR/$tfile
23725         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23726         RC=$?
23727         if [ $RC -ne 0 ]; then
23728                 error "error, failed to take i_mutex, rc=$?"
23729         fi
23730         rm -f $DIR/$tfile
23731 }
23732 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23733
23734 # Verify we do NOT take the i_mutex in the normal case
23735 test_258b() {
23736 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23737         $LCTL set_param fail_loc=0x141d
23738         touch $DIR/$tfile
23739         chmod a+rwx $DIR
23740         chmod a+rw $DIR/$tfile
23741         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23742         RC=$?
23743         if [ $RC -ne 0 ]; then
23744                 error "error, took i_mutex unnecessarily, rc=$?"
23745         fi
23746         rm -f $DIR/$tfile
23747
23748 }
23749 run_test 258b "verify i_mutex security behavior"
23750
23751 test_259() {
23752         local file=$DIR/$tfile
23753         local before
23754         local after
23755
23756         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23757
23758         stack_trap "rm -f $file" EXIT
23759
23760         wait_delete_completed
23761         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23762         echo "before: $before"
23763
23764         $LFS setstripe -i 0 -c 1 $file
23765         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23766         sync_all_data
23767         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23768         echo "after write: $after"
23769
23770 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23771         do_facet ost1 $LCTL set_param fail_loc=0x2301
23772         $TRUNCATE $file 0
23773         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23774         echo "after truncate: $after"
23775
23776         stop ost1
23777         do_facet ost1 $LCTL set_param fail_loc=0
23778         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23779         sleep 2
23780         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23781         echo "after restart: $after"
23782         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23783                 error "missing truncate?"
23784
23785         return 0
23786 }
23787 run_test 259 "crash at delayed truncate"
23788
23789 test_260() {
23790 #define OBD_FAIL_MDC_CLOSE               0x806
23791         $LCTL set_param fail_loc=0x80000806
23792         touch $DIR/$tfile
23793
23794 }
23795 run_test 260 "Check mdc_close fail"
23796
23797 ### Data-on-MDT sanity tests ###
23798 test_270a() {
23799         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23800                 skip "Need MDS version at least 2.10.55 for DoM"
23801
23802         # create DoM file
23803         local dom=$DIR/$tdir/dom_file
23804         local tmp=$DIR/$tdir/tmp_file
23805
23806         mkdir_on_mdt0 $DIR/$tdir
23807
23808         # basic checks for DoM component creation
23809         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23810                 error "Can set MDT layout to non-first entry"
23811
23812         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23813                 error "Can define multiple entries as MDT layout"
23814
23815         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23816
23817         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23818         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23819         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23820
23821         local mdtidx=$($LFS getstripe -m $dom)
23822         local mdtname=MDT$(printf %04x $mdtidx)
23823         local facet=mds$((mdtidx + 1))
23824         local space_check=1
23825
23826         # Skip free space checks with ZFS
23827         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23828
23829         # write
23830         sync
23831         local size_tmp=$((65536 * 3))
23832         local mdtfree1=$(do_facet $facet \
23833                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23834
23835         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23836         # check also direct IO along write
23837         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23838         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23839         sync
23840         cmp $tmp $dom || error "file data is different"
23841         [ $(stat -c%s $dom) == $size_tmp ] ||
23842                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23843         if [ $space_check == 1 ]; then
23844                 local mdtfree2=$(do_facet $facet \
23845                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23846
23847                 # increase in usage from by $size_tmp
23848                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23849                         error "MDT free space wrong after write: " \
23850                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23851         fi
23852
23853         # truncate
23854         local size_dom=10000
23855
23856         $TRUNCATE $dom $size_dom
23857         [ $(stat -c%s $dom) == $size_dom ] ||
23858                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23859         if [ $space_check == 1 ]; then
23860                 mdtfree1=$(do_facet $facet \
23861                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23862                 # decrease in usage from $size_tmp to new $size_dom
23863                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23864                   $(((size_tmp - size_dom) / 1024)) ] ||
23865                         error "MDT free space is wrong after truncate: " \
23866                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23867         fi
23868
23869         # append
23870         cat $tmp >> $dom
23871         sync
23872         size_dom=$((size_dom + size_tmp))
23873         [ $(stat -c%s $dom) == $size_dom ] ||
23874                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23875         if [ $space_check == 1 ]; then
23876                 mdtfree2=$(do_facet $facet \
23877                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23878                 # increase in usage by $size_tmp from previous
23879                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23880                         error "MDT free space is wrong after append: " \
23881                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23882         fi
23883
23884         # delete
23885         rm $dom
23886         if [ $space_check == 1 ]; then
23887                 mdtfree1=$(do_facet $facet \
23888                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23889                 # decrease in usage by $size_dom from previous
23890                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23891                         error "MDT free space is wrong after removal: " \
23892                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23893         fi
23894
23895         # combined striping
23896         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23897                 error "Can't create DoM + OST striping"
23898
23899         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23900         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23901         # check also direct IO along write
23902         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23903         sync
23904         cmp $tmp $dom || error "file data is different"
23905         [ $(stat -c%s $dom) == $size_tmp ] ||
23906                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23907         rm $dom $tmp
23908
23909         return 0
23910 }
23911 run_test 270a "DoM: basic functionality tests"
23912
23913 test_270b() {
23914         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23915                 skip "Need MDS version at least 2.10.55"
23916
23917         local dom=$DIR/$tdir/dom_file
23918         local max_size=1048576
23919
23920         mkdir -p $DIR/$tdir
23921         $LFS setstripe -E $max_size -L mdt $dom
23922
23923         # truncate over the limit
23924         $TRUNCATE $dom $(($max_size + 1)) &&
23925                 error "successful truncate over the maximum size"
23926         # write over the limit
23927         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23928                 error "successful write over the maximum size"
23929         # append over the limit
23930         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23931         echo "12345" >> $dom && error "successful append over the maximum size"
23932         rm $dom
23933
23934         return 0
23935 }
23936 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23937
23938 test_270c() {
23939         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23940                 skip "Need MDS version at least 2.10.55"
23941
23942         mkdir -p $DIR/$tdir
23943         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23944
23945         # check files inherit DoM EA
23946         touch $DIR/$tdir/first
23947         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23948                 error "bad pattern"
23949         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23950                 error "bad stripe count"
23951         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23952                 error "bad stripe size"
23953
23954         # check directory inherits DoM EA and uses it as default
23955         mkdir $DIR/$tdir/subdir
23956         touch $DIR/$tdir/subdir/second
23957         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23958                 error "bad pattern in sub-directory"
23959         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23960                 error "bad stripe count in sub-directory"
23961         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23962                 error "bad stripe size in sub-directory"
23963         return 0
23964 }
23965 run_test 270c "DoM: DoM EA inheritance tests"
23966
23967 test_270d() {
23968         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23969                 skip "Need MDS version at least 2.10.55"
23970
23971         mkdir -p $DIR/$tdir
23972         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23973
23974         # inherit default DoM striping
23975         mkdir $DIR/$tdir/subdir
23976         touch $DIR/$tdir/subdir/f1
23977
23978         # change default directory striping
23979         $LFS setstripe -c 1 $DIR/$tdir/subdir
23980         touch $DIR/$tdir/subdir/f2
23981         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23982                 error "wrong default striping in file 2"
23983         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23984                 error "bad pattern in file 2"
23985         return 0
23986 }
23987 run_test 270d "DoM: change striping from DoM to RAID0"
23988
23989 test_270e() {
23990         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23991                 skip "Need MDS version at least 2.10.55"
23992
23993         mkdir -p $DIR/$tdir/dom
23994         mkdir -p $DIR/$tdir/norm
23995         DOMFILES=20
23996         NORMFILES=10
23997         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23998         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23999
24000         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24001         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24002
24003         # find DoM files by layout
24004         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24005         [ $NUM -eq  $DOMFILES ] ||
24006                 error "lfs find -L: found $NUM, expected $DOMFILES"
24007         echo "Test 1: lfs find 20 DOM files by layout: OK"
24008
24009         # there should be 1 dir with default DOM striping
24010         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24011         [ $NUM -eq  1 ] ||
24012                 error "lfs find -L: found $NUM, expected 1 dir"
24013         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24014
24015         # find DoM files by stripe size
24016         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24017         [ $NUM -eq  $DOMFILES ] ||
24018                 error "lfs find -S: found $NUM, expected $DOMFILES"
24019         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24020
24021         # find files by stripe offset except DoM files
24022         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24023         [ $NUM -eq  $NORMFILES ] ||
24024                 error "lfs find -i: found $NUM, expected $NORMFILES"
24025         echo "Test 5: lfs find no DOM files by stripe index: OK"
24026         return 0
24027 }
24028 run_test 270e "DoM: lfs find with DoM files test"
24029
24030 test_270f() {
24031         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24032                 skip "Need MDS version at least 2.10.55"
24033
24034         local mdtname=${FSNAME}-MDT0000-mdtlov
24035         local dom=$DIR/$tdir/dom_file
24036         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24037                                                 lod.$mdtname.dom_stripesize)
24038         local dom_limit=131072
24039
24040         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24041         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24042                                                 lod.$mdtname.dom_stripesize)
24043         [ ${dom_limit} -eq ${dom_current} ] ||
24044                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24045
24046         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24047         $LFS setstripe -d $DIR/$tdir
24048         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24049                 error "Can't set directory default striping"
24050
24051         # exceed maximum stripe size
24052         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24053                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24054         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24055                 error "Able to create DoM component size more than LOD limit"
24056
24057         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24058         dom_current=$(do_facet mds1 $LCTL get_param -n \
24059                                                 lod.$mdtname.dom_stripesize)
24060         [ 0 -eq ${dom_current} ] ||
24061                 error "Can't set zero DoM stripe limit"
24062         rm $dom
24063
24064         # attempt to create DoM file on server with disabled DoM should
24065         # remove DoM entry from layout and be succeed
24066         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24067                 error "Can't create DoM file (DoM is disabled)"
24068         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24069                 error "File has DoM component while DoM is disabled"
24070         rm $dom
24071
24072         # attempt to create DoM file with only DoM stripe should return error
24073         $LFS setstripe -E $dom_limit -L mdt $dom &&
24074                 error "Able to create DoM-only file while DoM is disabled"
24075
24076         # too low values to be aligned with smallest stripe size 64K
24077         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24078         dom_current=$(do_facet mds1 $LCTL get_param -n \
24079                                                 lod.$mdtname.dom_stripesize)
24080         [ 30000 -eq ${dom_current} ] &&
24081                 error "Can set too small DoM stripe limit"
24082
24083         # 64K is a minimal stripe size in Lustre, expect limit of that size
24084         [ 65536 -eq ${dom_current} ] ||
24085                 error "Limit is not set to 64K but ${dom_current}"
24086
24087         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24088         dom_current=$(do_facet mds1 $LCTL get_param -n \
24089                                                 lod.$mdtname.dom_stripesize)
24090         echo $dom_current
24091         [ 2147483648 -eq ${dom_current} ] &&
24092                 error "Can set too large DoM stripe limit"
24093
24094         do_facet mds1 $LCTL set_param -n \
24095                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24096         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24097                 error "Can't create DoM component size after limit change"
24098         do_facet mds1 $LCTL set_param -n \
24099                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24100         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24101                 error "Can't create DoM file after limit decrease"
24102         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24103                 error "Can create big DoM component after limit decrease"
24104         touch ${dom}_def ||
24105                 error "Can't create file with old default layout"
24106
24107         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24108         return 0
24109 }
24110 run_test 270f "DoM: maximum DoM stripe size checks"
24111
24112 test_270g() {
24113         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24114                 skip "Need MDS version at least 2.13.52"
24115         local dom=$DIR/$tdir/$tfile
24116
24117         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24118         local lodname=${FSNAME}-MDT0000-mdtlov
24119
24120         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24121         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24122         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24123         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24124
24125         local dom_limit=1024
24126         local dom_threshold="50%"
24127
24128         $LFS setstripe -d $DIR/$tdir
24129         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24130                 error "Can't set directory default striping"
24131
24132         do_facet mds1 $LCTL set_param -n \
24133                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24134         # set 0 threshold and create DOM file to change tunable stripesize
24135         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24136         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24137                 error "Failed to create $dom file"
24138         # now tunable dom_cur_stripesize should reach maximum
24139         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24140                                         lod.${lodname}.dom_stripesize_cur_kb)
24141         [[ $dom_current == $dom_limit ]] ||
24142                 error "Current DOM stripesize is not maximum"
24143         rm $dom
24144
24145         # set threshold for further tests
24146         do_facet mds1 $LCTL set_param -n \
24147                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24148         echo "DOM threshold is $dom_threshold free space"
24149         local dom_def
24150         local dom_set
24151         # Spoof bfree to exceed threshold
24152         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24153         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24154         for spfree in 40 20 0 15 30 55; do
24155                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24156                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24157                         error "Failed to create $dom file"
24158                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24159                                         lod.${lodname}.dom_stripesize_cur_kb)
24160                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24161                 [[ $dom_def != $dom_current ]] ||
24162                         error "Default stripe size was not changed"
24163                 if (( spfree > 0 )) ; then
24164                         dom_set=$($LFS getstripe -S $dom)
24165                         (( dom_set == dom_def * 1024 )) ||
24166                                 error "DOM component size is still old"
24167                 else
24168                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24169                                 error "DoM component is set with no free space"
24170                 fi
24171                 rm $dom
24172                 dom_current=$dom_def
24173         done
24174 }
24175 run_test 270g "DoM: default DoM stripe size depends on free space"
24176
24177 test_270h() {
24178         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24179                 skip "Need MDS version at least 2.13.53"
24180
24181         local mdtname=${FSNAME}-MDT0000-mdtlov
24182         local dom=$DIR/$tdir/$tfile
24183         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24184
24185         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24186         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24187
24188         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24189         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24190                 error "can't create OST file"
24191         # mirrored file with DOM entry in the second mirror
24192         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24193                 error "can't create mirror with DoM component"
24194
24195         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24196
24197         # DOM component in the middle and has other enries in the same mirror,
24198         # should succeed but lost DoM component
24199         $LFS setstripe --copy=${dom}_1 $dom ||
24200                 error "Can't create file from OST|DOM mirror layout"
24201         # check new file has no DoM layout after all
24202         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24203                 error "File has DoM component while DoM is disabled"
24204 }
24205 run_test 270h "DoM: DoM stripe removal when disabled on server"
24206
24207 test_270i() {
24208         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24209                 skip "Need MDS version at least 2.14.54"
24210
24211         mkdir $DIR/$tdir
24212         # DoM with plain layout
24213         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24214                 error "default plain layout with DoM must fail"
24215         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24216                 error "setstripe plain file layout with DoM must fail"
24217         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24218                 error "default DoM layout with bad striping must fail"
24219         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24220                 error "setstripe to DoM layout with bad striping must fail"
24221         return 0
24222 }
24223 run_test 270i "DoM: setting invalid DoM striping should fail"
24224
24225 test_270j() {
24226         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24227                 skip "Need MDS version at least 2.15.55.203"
24228
24229         local dom=$DIR/$tdir/$tfile
24230         local odv
24231         local ndv
24232
24233         mkdir -p $DIR/$tdir
24234
24235         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24236
24237         odv=$($LFS data_version $dom)
24238         chmod 666 $dom
24239         mv $dom ${dom}_moved
24240         link ${dom}_moved $dom
24241         setfattr -n user.attrx -v "some_attr" $dom
24242         ndv=$($LFS data_version $dom)
24243         (( $ndv == $odv )) ||
24244                 error "data version was changed by metadata operations"
24245
24246         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24247                 error "failed to write data into $dom"
24248         cancel_lru_locks mdc
24249         ndv=$($LFS data_version $dom)
24250         (( $ndv != $odv )) ||
24251                 error "data version wasn't changed on write"
24252
24253         odv=$ndv
24254         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24255         ndv=$($LFS data_version $dom)
24256         (( $ndv != $odv )) ||
24257                 error "data version wasn't changed on truncate down"
24258
24259         odv=$ndv
24260         $TRUNCATE $dom 25000
24261         ndv=$($LFS data_version $dom)
24262         (( $ndv != $odv )) ||
24263                 error "data version wasn't changed on truncate up"
24264
24265         # check also fallocate for ldiskfs
24266         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24267                 odv=$ndv
24268                 fallocate -l 1048576 $dom
24269                 ndv=$($LFS data_version $dom)
24270                 (( $ndv != $odv )) ||
24271                         error "data version wasn't changed on fallocate"
24272
24273                 odv=$ndv
24274                 fallocate -p --offset 4096 -l 4096 $dom
24275                 ndv=$($LFS data_version $dom)
24276                 (( $ndv != $odv )) ||
24277                         error "data version wasn't changed on fallocate punch"
24278         fi
24279 }
24280 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24281
24282 test_271a() {
24283         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24284                 skip "Need MDS version at least 2.10.55"
24285
24286         local dom=$DIR/$tdir/dom
24287
24288         mkdir -p $DIR/$tdir
24289
24290         $LFS setstripe -E 1024K -L mdt $dom
24291
24292         lctl set_param -n mdc.*.stats=clear
24293         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24294         cat $dom > /dev/null
24295         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24296         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24297         ls $dom
24298         rm -f $dom
24299 }
24300 run_test 271a "DoM: data is cached for read after write"
24301
24302 test_271b() {
24303         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24304                 skip "Need MDS version at least 2.10.55"
24305
24306         local dom=$DIR/$tdir/dom
24307
24308         mkdir -p $DIR/$tdir
24309
24310         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24311
24312         lctl set_param -n mdc.*.stats=clear
24313         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24314         cancel_lru_locks mdc
24315         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24316         # second stat to check size is cached on client
24317         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24318         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24319         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24320         rm -f $dom
24321 }
24322 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24323
24324 test_271ba() {
24325         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24326                 skip "Need MDS version at least 2.10.55"
24327
24328         local dom=$DIR/$tdir/dom
24329
24330         mkdir -p $DIR/$tdir
24331
24332         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24333
24334         lctl set_param -n mdc.*.stats=clear
24335         lctl set_param -n osc.*.stats=clear
24336         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24337         cancel_lru_locks mdc
24338         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24339         # second stat to check size is cached on client
24340         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24341         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24342         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24343         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24344         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24345         rm -f $dom
24346 }
24347 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24348
24349
24350 get_mdc_stats() {
24351         local mdtidx=$1
24352         local param=$2
24353         local mdt=MDT$(printf %04x $mdtidx)
24354
24355         if [ -z $param ]; then
24356                 lctl get_param -n mdc.*$mdt*.stats
24357         else
24358                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24359         fi
24360 }
24361
24362 test_271c() {
24363         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24364                 skip "Need MDS version at least 2.10.55"
24365
24366         local dom=$DIR/$tdir/dom
24367
24368         mkdir -p $DIR/$tdir
24369
24370         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24371
24372         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24373         local facet=mds$((mdtidx + 1))
24374
24375         cancel_lru_locks mdc
24376         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24377         createmany -o $dom 1000
24378         lctl set_param -n mdc.*.stats=clear
24379         smalliomany -w $dom 1000 200
24380         get_mdc_stats $mdtidx
24381         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24382         # Each file has 1 open, 1 IO enqueues, total 2000
24383         # but now we have also +1 getxattr for security.capability, total 3000
24384         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24385         unlinkmany $dom 1000
24386
24387         cancel_lru_locks mdc
24388         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24389         createmany -o $dom 1000
24390         lctl set_param -n mdc.*.stats=clear
24391         smalliomany -w $dom 1000 200
24392         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24393         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24394         # for OPEN and IO lock.
24395         [ $((enq - enq_2)) -ge 1000 ] ||
24396                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24397         unlinkmany $dom 1000
24398         return 0
24399 }
24400 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24401
24402 cleanup_271def_tests() {
24403         trap 0
24404         rm -f $1
24405 }
24406
24407 test_271d() {
24408         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24409                 skip "Need MDS version at least 2.10.57"
24410
24411         local dom=$DIR/$tdir/dom
24412         local tmp=$TMP/$tfile
24413         trap "cleanup_271def_tests $tmp" EXIT
24414
24415         mkdir -p $DIR/$tdir
24416
24417         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24418
24419         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24420
24421         cancel_lru_locks mdc
24422         dd if=/dev/urandom of=$tmp bs=1000 count=1
24423         dd if=$tmp of=$dom bs=1000 count=1
24424         cancel_lru_locks mdc
24425
24426         cat /etc/hosts >> $tmp
24427         lctl set_param -n mdc.*.stats=clear
24428
24429         # append data to the same file it should update local page
24430         echo "Append to the same page"
24431         cat /etc/hosts >> $dom
24432         local num=$(get_mdc_stats $mdtidx ost_read)
24433         local ra=$(get_mdc_stats $mdtidx req_active)
24434         local rw=$(get_mdc_stats $mdtidx req_waittime)
24435
24436         [ -z $num ] || error "$num READ RPC occured"
24437         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24438         echo "... DONE"
24439
24440         # compare content
24441         cmp $tmp $dom || error "file miscompare"
24442
24443         cancel_lru_locks mdc
24444         lctl set_param -n mdc.*.stats=clear
24445
24446         echo "Open and read file"
24447         cat $dom > /dev/null
24448         local num=$(get_mdc_stats $mdtidx ost_read)
24449         local ra=$(get_mdc_stats $mdtidx req_active)
24450         local rw=$(get_mdc_stats $mdtidx req_waittime)
24451
24452         [ -z $num ] || error "$num READ RPC occured"
24453         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24454         echo "... DONE"
24455
24456         # compare content
24457         cmp $tmp $dom || error "file miscompare"
24458
24459         return 0
24460 }
24461 run_test 271d "DoM: read on open (1K file in reply buffer)"
24462
24463 test_271f() {
24464         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24465                 skip "Need MDS version at least 2.10.57"
24466
24467         local dom=$DIR/$tdir/dom
24468         local tmp=$TMP/$tfile
24469         trap "cleanup_271def_tests $tmp" EXIT
24470
24471         mkdir -p $DIR/$tdir
24472
24473         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24474
24475         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24476
24477         cancel_lru_locks mdc
24478         dd if=/dev/urandom of=$tmp bs=265000 count=1
24479         dd if=$tmp of=$dom bs=265000 count=1
24480         cancel_lru_locks mdc
24481         cat /etc/hosts >> $tmp
24482         lctl set_param -n mdc.*.stats=clear
24483
24484         echo "Append to the same page"
24485         cat /etc/hosts >> $dom
24486         local num=$(get_mdc_stats $mdtidx ost_read)
24487         local ra=$(get_mdc_stats $mdtidx req_active)
24488         local rw=$(get_mdc_stats $mdtidx req_waittime)
24489
24490         [ -z $num ] || error "$num READ RPC occured"
24491         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24492         echo "... DONE"
24493
24494         # compare content
24495         cmp $tmp $dom || error "file miscompare"
24496
24497         cancel_lru_locks mdc
24498         lctl set_param -n mdc.*.stats=clear
24499
24500         echo "Open and read file"
24501         cat $dom > /dev/null
24502         local num=$(get_mdc_stats $mdtidx ost_read)
24503         local ra=$(get_mdc_stats $mdtidx req_active)
24504         local rw=$(get_mdc_stats $mdtidx req_waittime)
24505
24506         [ -z $num ] && num=0
24507         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24508         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24509         echo "... DONE"
24510
24511         # compare content
24512         cmp $tmp $dom || error "file miscompare"
24513
24514         return 0
24515 }
24516 run_test 271f "DoM: read on open (200K file and read tail)"
24517
24518 test_271g() {
24519         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24520                 skip "Skipping due to old client or server version"
24521
24522         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24523         # to get layout
24524         $CHECKSTAT -t file $DIR1/$tfile
24525
24526         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24527         MULTIOP_PID=$!
24528         sleep 1
24529         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24530         $LCTL set_param fail_loc=0x80000314
24531         rm $DIR1/$tfile || error "Unlink fails"
24532         RC=$?
24533         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24534         [ $RC -eq 0 ] || error "Failed write to stale object"
24535 }
24536 run_test 271g "Discard DoM data vs client flush race"
24537
24538 test_272a() {
24539         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24540                 skip "Need MDS version at least 2.11.50"
24541
24542         local dom=$DIR/$tdir/dom
24543         mkdir -p $DIR/$tdir
24544
24545         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24546         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24547                 error "failed to write data into $dom"
24548         local old_md5=$(md5sum $dom)
24549
24550         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24551                 error "failed to migrate to the same DoM component"
24552
24553         local new_md5=$(md5sum $dom)
24554
24555         [ "$old_md5" == "$new_md5" ] ||
24556                 error "md5sum differ: $old_md5, $new_md5"
24557
24558         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24559                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24560 }
24561 run_test 272a "DoM migration: new layout with the same DOM component"
24562
24563 test_272b() {
24564         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24565                 skip "Need MDS version at least 2.11.50"
24566
24567         local dom=$DIR/$tdir/dom
24568         mkdir -p $DIR/$tdir
24569         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24570         stack_trap "rm -rf $DIR/$tdir"
24571
24572         local mdtidx=$($LFS getstripe -m $dom)
24573         local mdtname=MDT$(printf %04x $mdtidx)
24574         local facet=mds$((mdtidx + 1))
24575
24576         local mdtfree1=$(do_facet $facet \
24577                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24578         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24579                 error "failed to write data into $dom"
24580         local old_md5=$(md5sum $dom)
24581         cancel_lru_locks mdc
24582         local mdtfree1=$(do_facet $facet \
24583                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24584
24585         $LFS migrate -c2 $dom ||
24586                 error "failed to migrate to the new composite layout"
24587         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24588                 error "MDT stripe was not removed"
24589         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24590                 error "$dir1 shouldn't have DATAVER EA"
24591
24592         cancel_lru_locks mdc
24593         local new_md5=$(md5sum $dom)
24594         [ "$old_md5" == "$new_md5" ] ||
24595                 error "$old_md5 != $new_md5"
24596
24597         # Skip free space checks with ZFS
24598         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24599                 local mdtfree2=$(do_facet $facet \
24600                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24601                 [ $mdtfree2 -gt $mdtfree1 ] ||
24602                         error "MDT space is not freed after migration"
24603         fi
24604         return 0
24605 }
24606 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24607
24608 test_272c() {
24609         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24610                 skip "Need MDS version at least 2.11.50"
24611
24612         local dom=$DIR/$tdir/$tfile
24613         mkdir -p $DIR/$tdir
24614         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24615         stack_trap "rm -rf $DIR/$tdir"
24616
24617         local mdtidx=$($LFS getstripe -m $dom)
24618         local mdtname=MDT$(printf %04x $mdtidx)
24619         local facet=mds$((mdtidx + 1))
24620
24621         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24622                 error "failed to write data into $dom"
24623         local old_md5=$(md5sum $dom)
24624         cancel_lru_locks mdc
24625         local mdtfree1=$(do_facet $facet \
24626                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24627
24628         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24629                 error "failed to migrate to the new composite layout"
24630         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24631                 error "MDT stripe was not removed"
24632
24633         cancel_lru_locks mdc
24634         local new_md5=$(md5sum $dom)
24635         [ "$old_md5" == "$new_md5" ] ||
24636                 error "$old_md5 != $new_md5"
24637
24638         # Skip free space checks with ZFS
24639         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24640                 local mdtfree2=$(do_facet $facet \
24641                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24642                 [ $mdtfree2 -gt $mdtfree1 ] ||
24643                         error "MDS space is not freed after migration"
24644         fi
24645         return 0
24646 }
24647 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24648
24649 test_272d() {
24650         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24651                 skip "Need MDS version at least 2.12.55"
24652
24653         local dom=$DIR/$tdir/$tfile
24654         mkdir -p $DIR/$tdir
24655         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24656
24657         local mdtidx=$($LFS getstripe -m $dom)
24658         local mdtname=MDT$(printf %04x $mdtidx)
24659         local facet=mds$((mdtidx + 1))
24660
24661         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24662                 error "failed to write data into $dom"
24663         local old_md5=$(md5sum $dom)
24664         cancel_lru_locks mdc
24665         local mdtfree1=$(do_facet $facet \
24666                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24667
24668         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24669                 error "failed mirroring to the new composite layout"
24670         $LFS mirror resync $dom ||
24671                 error "failed mirror resync"
24672         $LFS mirror split --mirror-id 1 -d $dom ||
24673                 error "failed mirror split"
24674
24675         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24676                 error "MDT stripe was not removed"
24677
24678         cancel_lru_locks mdc
24679         local new_md5=$(md5sum $dom)
24680         [ "$old_md5" == "$new_md5" ] ||
24681                 error "$old_md5 != $new_md5"
24682
24683         # Skip free space checks with ZFS
24684         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24685                 local mdtfree2=$(do_facet $facet \
24686                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24687                 [ $mdtfree2 -gt $mdtfree1 ] ||
24688                         error "MDS space is not freed after DOM mirror deletion"
24689         fi
24690         return 0
24691 }
24692 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24693
24694 test_272e() {
24695         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24696                 skip "Need MDS version at least 2.12.55"
24697
24698         local dom=$DIR/$tdir/$tfile
24699         mkdir -p $DIR/$tdir
24700         $LFS setstripe -c 2 $dom
24701
24702         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24703                 error "failed to write data into $dom"
24704         local old_md5=$(md5sum $dom)
24705         cancel_lru_locks
24706
24707         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24708                 error "failed mirroring to the DOM layout"
24709         $LFS mirror resync $dom ||
24710                 error "failed mirror resync"
24711         $LFS mirror split --mirror-id 1 -d $dom ||
24712                 error "failed mirror split"
24713
24714         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24715                 error "MDT stripe wasn't set"
24716
24717         cancel_lru_locks
24718         local new_md5=$(md5sum $dom)
24719         [ "$old_md5" == "$new_md5" ] ||
24720                 error "$old_md5 != $new_md5"
24721
24722         return 0
24723 }
24724 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24725
24726 test_272f() {
24727         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24728                 skip "Need MDS version at least 2.12.55"
24729
24730         local dom=$DIR/$tdir/$tfile
24731         mkdir -p $DIR/$tdir
24732         $LFS setstripe -c 2 $dom
24733
24734         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24735                 error "failed to write data into $dom"
24736         local old_md5=$(md5sum $dom)
24737         cancel_lru_locks
24738
24739         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24740                 error "failed migrating to the DOM file"
24741
24742         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24743                 error "MDT stripe wasn't set"
24744
24745         cancel_lru_locks
24746         local new_md5=$(md5sum $dom)
24747         [ "$old_md5" != "$new_md5" ] &&
24748                 error "$old_md5 != $new_md5"
24749
24750         return 0
24751 }
24752 run_test 272f "DoM migration: OST-striped file to DOM file"
24753
24754 test_273a() {
24755         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24756                 skip "Need MDS version at least 2.11.50"
24757
24758         # Layout swap cannot be done if either file has DOM component,
24759         # this will never be supported, migration should be used instead
24760
24761         local dom=$DIR/$tdir/$tfile
24762         mkdir -p $DIR/$tdir
24763
24764         $LFS setstripe -c2 ${dom}_plain
24765         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24766         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24767                 error "can swap layout with DoM component"
24768         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24769                 error "can swap layout with DoM component"
24770
24771         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24772         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24773                 error "can swap layout with DoM component"
24774         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24775                 error "can swap layout with DoM component"
24776         return 0
24777 }
24778 run_test 273a "DoM: layout swapping should fail with DOM"
24779
24780 test_273b() {
24781         mkdir -p $DIR/$tdir
24782         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24783
24784 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24785         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24786
24787         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24788 }
24789 run_test 273b "DoM: race writeback and object destroy"
24790
24791 test_273c() {
24792         mkdir -p $DIR/$tdir
24793         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24794
24795         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24796         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24797
24798         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24799 }
24800 run_test 273c "race writeback and object destroy"
24801
24802 test_275() {
24803         remote_ost_nodsh && skip "remote OST with nodsh"
24804         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24805                 skip "Need OST version >= 2.10.57"
24806
24807         local file=$DIR/$tfile
24808         local oss
24809
24810         oss=$(comma_list $(osts_nodes))
24811
24812         dd if=/dev/urandom of=$file bs=1M count=2 ||
24813                 error "failed to create a file"
24814         stack_trap "rm -f $file"
24815         cancel_lru_locks osc
24816
24817         #lock 1
24818         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24819                 error "failed to read a file"
24820
24821 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24822         $LCTL set_param fail_loc=0x8000031f
24823
24824         cancel_lru_locks osc &
24825         sleep 1
24826
24827 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24828         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24829         #IO takes another lock, but matches the PENDING one
24830         #and places it to the IO RPC
24831         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24832                 error "failed to read a file with PENDING lock"
24833 }
24834 run_test 275 "Read on a canceled duplicate lock"
24835
24836 test_276() {
24837         remote_ost_nodsh && skip "remote OST with nodsh"
24838         local pid
24839
24840         do_facet ost1 "(while true; do \
24841                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24842                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24843         pid=$!
24844
24845         for LOOP in $(seq 20); do
24846                 stop ost1
24847                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24848         done
24849         kill -9 $pid
24850         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24851                 rm $TMP/sanity_276_pid"
24852 }
24853 run_test 276 "Race between mount and obd_statfs"
24854
24855 test_277() {
24856         $LCTL set_param ldlm.namespaces.*.lru_size=0
24857         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24858         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24859                         grep ^used_mb | awk '{print $2}')
24860         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24861         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24862                 oflag=direct conv=notrunc
24863         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24864                         grep ^used_mb | awk '{print $2}')
24865         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24866 }
24867 run_test 277 "Direct IO shall drop page cache"
24868
24869 test_278() {
24870         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24871         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24872         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24873                 skip "needs the same host for mdt1 mdt2" && return
24874
24875         local pid1
24876         local pid2
24877
24878 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24879         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24880         stop mds2 &
24881         pid2=$!
24882
24883         stop mds1
24884
24885         echo "Starting MDTs"
24886         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24887         wait $pid2
24888 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24889 #will return NULL
24890         do_facet mds2 $LCTL set_param fail_loc=0
24891
24892         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24893         wait_recovery_complete mds2
24894 }
24895 run_test 278 "Race starting MDS between MDTs stop/start"
24896
24897 test_280() {
24898         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24899                 skip "Need MGS version at least 2.13.52"
24900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24901         combined_mgs_mds || skip "needs combined MGS/MDT"
24902
24903         umount_client $MOUNT
24904 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24905         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24906
24907         mount_client $MOUNT &
24908         sleep 1
24909         stop mgs || error "stop mgs failed"
24910         #for a race mgs would crash
24911         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24912         # make sure we unmount client before remounting
24913         wait
24914         umount_client $MOUNT
24915         mount_client $MOUNT || error "mount client failed"
24916 }
24917 run_test 280 "Race between MGS umount and client llog processing"
24918
24919 cleanup_test_300() {
24920         trap 0
24921         umask $SAVE_UMASK
24922 }
24923 test_striped_dir() {
24924         local mdt_index=$1
24925         local stripe_count
24926         local stripe_index
24927
24928         mkdir -p $DIR/$tdir
24929
24930         SAVE_UMASK=$(umask)
24931         trap cleanup_test_300 RETURN EXIT
24932
24933         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24934                                                 $DIR/$tdir/striped_dir ||
24935                 error "set striped dir error"
24936
24937         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24938         [ "$mode" = "755" ] || error "expect 755 got $mode"
24939
24940         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24941                 error "getdirstripe failed"
24942         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24943         if [ "$stripe_count" != "2" ]; then
24944                 error "1:stripe_count is $stripe_count, expect 2"
24945         fi
24946         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24947         if [ "$stripe_count" != "2" ]; then
24948                 error "2:stripe_count is $stripe_count, expect 2"
24949         fi
24950
24951         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24952         if [ "$stripe_index" != "$mdt_index" ]; then
24953                 error "stripe_index is $stripe_index, expect $mdt_index"
24954         fi
24955
24956         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24957                 error "nlink error after create striped dir"
24958
24959         mkdir $DIR/$tdir/striped_dir/a
24960         mkdir $DIR/$tdir/striped_dir/b
24961
24962         stat $DIR/$tdir/striped_dir/a ||
24963                 error "create dir under striped dir failed"
24964         stat $DIR/$tdir/striped_dir/b ||
24965                 error "create dir under striped dir failed"
24966
24967         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24968                 error "nlink error after mkdir"
24969
24970         rmdir $DIR/$tdir/striped_dir/a
24971         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24972                 error "nlink error after rmdir"
24973
24974         rmdir $DIR/$tdir/striped_dir/b
24975         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24976                 error "nlink error after rmdir"
24977
24978         chattr +i $DIR/$tdir/striped_dir
24979         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24980                 error "immutable flags not working under striped dir!"
24981         chattr -i $DIR/$tdir/striped_dir
24982
24983         rmdir $DIR/$tdir/striped_dir ||
24984                 error "rmdir striped dir error"
24985
24986         cleanup_test_300
24987
24988         true
24989 }
24990
24991 test_300a() {
24992         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24993                 skip "skipped for lustre < 2.7.0"
24994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24995         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24996
24997         test_striped_dir 0 || error "failed on striped dir on MDT0"
24998         test_striped_dir 1 || error "failed on striped dir on MDT0"
24999 }
25000 run_test 300a "basic striped dir sanity test"
25001
25002 test_300b() {
25003         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25004                 skip "skipped for lustre < 2.7.0"
25005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25007
25008         local i
25009         local mtime1
25010         local mtime2
25011         local mtime3
25012
25013         test_mkdir $DIR/$tdir || error "mkdir fail"
25014         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25015                 error "set striped dir error"
25016         for i in {0..9}; do
25017                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25018                 sleep 1
25019                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25020                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25021                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25022                 sleep 1
25023                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25024                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25025                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25026         done
25027         true
25028 }
25029 run_test 300b "check ctime/mtime for striped dir"
25030
25031 test_300c() {
25032         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25033                 skip "skipped for lustre < 2.7.0"
25034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25036
25037         local file_count
25038
25039         mkdir_on_mdt0 $DIR/$tdir
25040         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25041                 error "set striped dir error"
25042
25043         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25044                 error "chown striped dir failed"
25045
25046         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25047                 error "create 5k files failed"
25048
25049         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25050
25051         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25052
25053         rm -rf $DIR/$tdir
25054 }
25055 run_test 300c "chown && check ls under striped directory"
25056
25057 test_300d() {
25058         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25059                 skip "skipped for lustre < 2.7.0"
25060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25062
25063         local stripe_count
25064         local file
25065
25066         mkdir -p $DIR/$tdir
25067         $LFS setstripe -c 2 $DIR/$tdir
25068
25069         #local striped directory
25070         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25071                 error "set striped dir error"
25072         #look at the directories for debug purposes
25073         ls -l $DIR/$tdir
25074         $LFS getdirstripe $DIR/$tdir
25075         ls -l $DIR/$tdir/striped_dir
25076         $LFS getdirstripe $DIR/$tdir/striped_dir
25077         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25078                 error "create 10 files failed"
25079
25080         #remote striped directory
25081         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25082                 error "set striped dir error"
25083         #look at the directories for debug purposes
25084         ls -l $DIR/$tdir
25085         $LFS getdirstripe $DIR/$tdir
25086         ls -l $DIR/$tdir/remote_striped_dir
25087         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25088         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25089                 error "create 10 files failed"
25090
25091         for file in $(find $DIR/$tdir); do
25092                 stripe_count=$($LFS getstripe -c $file)
25093                 [ $stripe_count -eq 2 ] ||
25094                         error "wrong stripe $stripe_count for $file"
25095         done
25096
25097         rm -rf $DIR/$tdir
25098 }
25099 run_test 300d "check default stripe under striped directory"
25100
25101 test_300e() {
25102         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25103                 skip "Need MDS version at least 2.7.55"
25104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25106
25107         local stripe_count
25108         local file
25109
25110         mkdir -p $DIR/$tdir
25111
25112         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25113                 error "set striped dir error"
25114
25115         touch $DIR/$tdir/striped_dir/a
25116         touch $DIR/$tdir/striped_dir/b
25117         touch $DIR/$tdir/striped_dir/c
25118
25119         mkdir $DIR/$tdir/striped_dir/dir_a
25120         mkdir $DIR/$tdir/striped_dir/dir_b
25121         mkdir $DIR/$tdir/striped_dir/dir_c
25122
25123         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25124                 error "set striped adir under striped dir error"
25125
25126         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25127                 error "set striped bdir under striped dir error"
25128
25129         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25130                 error "set striped cdir under striped dir error"
25131
25132         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25133                 error "rename dir under striped dir fails"
25134
25135         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25136                 error "rename dir under different stripes fails"
25137
25138         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25139                 error "rename file under striped dir should succeed"
25140
25141         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25142                 error "rename dir under striped dir should succeed"
25143
25144         rm -rf $DIR/$tdir
25145 }
25146 run_test 300e "check rename under striped directory"
25147
25148 test_300f() {
25149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25151         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25152                 skip "Need MDS version at least 2.7.55"
25153
25154         local stripe_count
25155         local file
25156
25157         rm -rf $DIR/$tdir
25158         mkdir -p $DIR/$tdir
25159
25160         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25161                 error "set striped dir error"
25162
25163         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25164                 error "set striped dir error"
25165
25166         touch $DIR/$tdir/striped_dir/a
25167         mkdir $DIR/$tdir/striped_dir/dir_a
25168         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25169                 error "create striped dir under striped dir fails"
25170
25171         touch $DIR/$tdir/striped_dir1/b
25172         mkdir $DIR/$tdir/striped_dir1/dir_b
25173         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25174                 error "create striped dir under striped dir fails"
25175
25176         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25177                 error "rename dir under different striped dir should fail"
25178
25179         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25180                 error "rename striped dir under diff striped dir should fail"
25181
25182         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25183                 error "rename file under diff striped dirs fails"
25184
25185         rm -rf $DIR/$tdir
25186 }
25187 run_test 300f "check rename cross striped directory"
25188
25189 test_300_check_default_striped_dir()
25190 {
25191         local dirname=$1
25192         local default_count=$2
25193         local default_index=$3
25194         local stripe_count
25195         local stripe_index
25196         local dir_stripe_index
25197         local dir
25198
25199         echo "checking $dirname $default_count $default_index"
25200         $LFS setdirstripe -D -c $default_count -i $default_index \
25201                                 -H all_char $DIR/$tdir/$dirname ||
25202                 error "set default stripe on striped dir error"
25203         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25204         [ $stripe_count -eq $default_count ] ||
25205                 error "expect $default_count get $stripe_count for $dirname"
25206
25207         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25208         [ $stripe_index -eq $default_index ] ||
25209                 error "expect $default_index get $stripe_index for $dirname"
25210
25211         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25212                                                 error "create dirs failed"
25213
25214         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25215         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25216         for dir in $(find $DIR/$tdir/$dirname/*); do
25217                 stripe_count=$($LFS getdirstripe -c $dir)
25218                 (( $stripe_count == $default_count )) ||
25219                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25220                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25221                 error "stripe count $default_count != $stripe_count for $dir"
25222
25223                 stripe_index=$($LFS getdirstripe -i $dir)
25224                 [ $default_index -eq -1 ] ||
25225                         [ $stripe_index -eq $default_index ] ||
25226                         error "$stripe_index != $default_index for $dir"
25227
25228                 #check default stripe
25229                 stripe_count=$($LFS getdirstripe -D -c $dir)
25230                 [ $stripe_count -eq $default_count ] ||
25231                 error "default count $default_count != $stripe_count for $dir"
25232
25233                 stripe_index=$($LFS getdirstripe -D -i $dir)
25234                 [ $stripe_index -eq $default_index ] ||
25235                 error "default index $default_index != $stripe_index for $dir"
25236         done
25237         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25238 }
25239
25240 test_300g() {
25241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25242         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25243                 skip "Need MDS version at least 2.7.55"
25244
25245         local dir
25246         local stripe_count
25247         local stripe_index
25248
25249         mkdir_on_mdt0 $DIR/$tdir
25250         mkdir $DIR/$tdir/normal_dir
25251
25252         #Checking when client cache stripe index
25253         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25254         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25255                 error "create striped_dir failed"
25256
25257         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25258                 error "create dir0 fails"
25259         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25260         [ $stripe_index -eq 0 ] ||
25261                 error "dir0 expect index 0 got $stripe_index"
25262
25263         mkdir $DIR/$tdir/striped_dir/dir1 ||
25264                 error "create dir1 fails"
25265         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25266         [ $stripe_index -eq 1 ] ||
25267                 error "dir1 expect index 1 got $stripe_index"
25268
25269         #check default stripe count/stripe index
25270         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25271         test_300_check_default_striped_dir normal_dir 1 0
25272         test_300_check_default_striped_dir normal_dir -1 1
25273         test_300_check_default_striped_dir normal_dir 2 -1
25274
25275         #delete default stripe information
25276         echo "delete default stripeEA"
25277         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25278                 error "set default stripe on striped dir error"
25279
25280         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25281         for dir in $(find $DIR/$tdir/normal_dir/*); do
25282                 stripe_count=$($LFS getdirstripe -c $dir)
25283                 [ $stripe_count -eq 0 ] ||
25284                         error "expect 1 get $stripe_count for $dir"
25285         done
25286 }
25287 run_test 300g "check default striped directory for normal directory"
25288
25289 test_300h() {
25290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25291         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25292                 skip "Need MDS version at least 2.7.55"
25293
25294         local dir
25295         local stripe_count
25296
25297         mkdir $DIR/$tdir
25298         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25299                 error "set striped dir error"
25300
25301         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25302         test_300_check_default_striped_dir striped_dir 1 0
25303         test_300_check_default_striped_dir striped_dir -1 1
25304         test_300_check_default_striped_dir striped_dir 2 -1
25305
25306         #delete default stripe information
25307         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25308                 error "set default stripe on striped dir error"
25309
25310         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25311         for dir in $(find $DIR/$tdir/striped_dir/*); do
25312                 stripe_count=$($LFS getdirstripe -c $dir)
25313                 [ $stripe_count -eq 0 ] ||
25314                         error "expect 1 get $stripe_count for $dir"
25315         done
25316 }
25317 run_test 300h "check default striped directory for striped directory"
25318
25319 test_300i() {
25320         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25321         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25322         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25323                 skip "Need MDS version at least 2.7.55"
25324
25325         local stripe_count
25326         local file
25327
25328         mkdir $DIR/$tdir
25329
25330         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25331                 error "set striped dir error"
25332
25333         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25334                 error "create files under striped dir failed"
25335
25336         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25337                 error "set striped hashdir error"
25338
25339         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25340                 error "create dir0 under hash dir failed"
25341         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25342                 error "create dir1 under hash dir failed"
25343         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25344                 error "create dir2 under hash dir failed"
25345
25346         # unfortunately, we need to umount to clear dir layout cache for now
25347         # once we fully implement dir layout, we can drop this
25348         umount_client $MOUNT || error "umount failed"
25349         mount_client $MOUNT || error "mount failed"
25350
25351         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25352         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25353         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25354
25355         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25356                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25357                         error "create crush2 dir $tdir/hashdir/d3 failed"
25358                 $LFS find -H crush2 $DIR/$tdir/hashdir
25359                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25360                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25361
25362                 # mkdir with an invalid hash type (hash=fail_val) from client
25363                 # should be replaced on MDS with a valid (default) hash type
25364                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25365                 $LCTL set_param fail_loc=0x1901 fail_val=99
25366                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25367
25368                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25369                 local expect=$(do_facet mds1 \
25370                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25371                 [[ $hash == $expect ]] ||
25372                         error "d99 hash '$hash' != expected hash '$expect'"
25373         fi
25374
25375         #set the stripe to be unknown hash type on read
25376         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25377         $LCTL set_param fail_loc=0x1901 fail_val=99
25378         for ((i = 0; i < 10; i++)); do
25379                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25380                         error "stat f-$i failed"
25381                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25382         done
25383
25384         touch $DIR/$tdir/striped_dir/f0 &&
25385                 error "create under striped dir with unknown hash should fail"
25386
25387         $LCTL set_param fail_loc=0
25388
25389         umount_client $MOUNT || error "umount failed"
25390         mount_client $MOUNT || error "mount failed"
25391
25392         return 0
25393 }
25394 run_test 300i "client handle unknown hash type striped directory"
25395
25396 test_300j() {
25397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25399         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25400                 skip "Need MDS version at least 2.7.55"
25401
25402         local stripe_count
25403         local file
25404
25405         mkdir $DIR/$tdir
25406
25407         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25408         $LCTL set_param fail_loc=0x1702
25409         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25410                 error "set striped dir error"
25411
25412         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25413                 error "create files under striped dir failed"
25414
25415         $LCTL set_param fail_loc=0
25416
25417         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25418
25419         return 0
25420 }
25421 run_test 300j "test large update record"
25422
25423 test_300k() {
25424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25425         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25426         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25427                 skip "Need MDS version at least 2.7.55"
25428
25429         # this test needs a huge transaction
25430         local kb
25431         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25432              osd*.$FSNAME-MDT0000.kbytestotal")
25433         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25434
25435         local stripe_count
25436         local file
25437
25438         mkdir $DIR/$tdir
25439
25440         #define OBD_FAIL_LARGE_STRIPE   0x1703
25441         $LCTL set_param fail_loc=0x1703
25442         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25443                 error "set striped dir error"
25444         $LCTL set_param fail_loc=0
25445
25446         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25447                 error "getstripeddir fails"
25448         rm -rf $DIR/$tdir/striped_dir ||
25449                 error "unlink striped dir fails"
25450
25451         return 0
25452 }
25453 run_test 300k "test large striped directory"
25454
25455 test_300l() {
25456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25457         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25458         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25459                 skip "Need MDS version at least 2.7.55"
25460
25461         local stripe_index
25462
25463         test_mkdir -p $DIR/$tdir/striped_dir
25464         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25465                         error "chown $RUNAS_ID failed"
25466         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25467                 error "set default striped dir failed"
25468
25469         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25470         $LCTL set_param fail_loc=0x80000158
25471         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25472
25473         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25474         [ $stripe_index -eq 1 ] ||
25475                 error "expect 1 get $stripe_index for $dir"
25476 }
25477 run_test 300l "non-root user to create dir under striped dir with stale layout"
25478
25479 test_300m() {
25480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25481         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25482         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25483                 skip "Need MDS version at least 2.7.55"
25484
25485         mkdir -p $DIR/$tdir/striped_dir
25486         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25487                 error "set default stripes dir error"
25488
25489         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25490
25491         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25492         [ $stripe_count -eq 0 ] ||
25493                         error "expect 0 get $stripe_count for a"
25494
25495         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25496                 error "set default stripes dir error"
25497
25498         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25499
25500         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25501         [ $stripe_count -eq 0 ] ||
25502                         error "expect 0 get $stripe_count for b"
25503
25504         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25505                 error "set default stripes dir error"
25506
25507         mkdir $DIR/$tdir/striped_dir/c &&
25508                 error "default stripe_index is invalid, mkdir c should fails"
25509
25510         rm -rf $DIR/$tdir || error "rmdir fails"
25511 }
25512 run_test 300m "setstriped directory on single MDT FS"
25513
25514 cleanup_300n() {
25515         local list=$(comma_list $(mdts_nodes))
25516
25517         trap 0
25518         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25519 }
25520
25521 test_300n() {
25522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25525                 skip "Need MDS version at least 2.7.55"
25526         remote_mds_nodsh && skip "remote MDS with nodsh"
25527
25528         local stripe_index
25529         local list=$(comma_list $(mdts_nodes))
25530
25531         trap cleanup_300n RETURN EXIT
25532         mkdir -p $DIR/$tdir
25533         chmod 777 $DIR/$tdir
25534         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25535                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25536                 error "create striped dir succeeds with gid=0"
25537
25538         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25539         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25540                 error "create striped dir fails with gid=-1"
25541
25542         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25543         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25544                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25545                 error "set default striped dir succeeds with gid=0"
25546
25547
25548         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25549         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25550                 error "set default striped dir fails with gid=-1"
25551
25552
25553         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25554         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25555                                         error "create test_dir fails"
25556         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25557                                         error "create test_dir1 fails"
25558         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25559                                         error "create test_dir2 fails"
25560         cleanup_300n
25561 }
25562 run_test 300n "non-root user to create dir under striped dir with default EA"
25563
25564 test_300o() {
25565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25567         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25568                 skip "Need MDS version at least 2.7.55"
25569
25570         local numfree1
25571         local numfree2
25572
25573         mkdir -p $DIR/$tdir
25574
25575         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25576         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25577         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25578                 skip "not enough free inodes $numfree1 $numfree2"
25579         fi
25580
25581         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25582         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25583         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25584                 skip "not enough free space $numfree1 $numfree2"
25585         fi
25586
25587         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25588                 error "setdirstripe fails"
25589
25590         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25591                 error "create dirs fails"
25592
25593         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25594         ls $DIR/$tdir/striped_dir > /dev/null ||
25595                 error "ls striped dir fails"
25596         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25597                 error "unlink big striped dir fails"
25598 }
25599 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25600
25601 test_300p() {
25602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25603         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25604         remote_mds_nodsh && skip "remote MDS with nodsh"
25605
25606         mkdir_on_mdt0 $DIR/$tdir
25607
25608         #define OBD_FAIL_OUT_ENOSPC     0x1704
25609         do_facet mds2 lctl set_param fail_loc=0x80001704
25610         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25611                  && error "create striped directory should fail"
25612
25613         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25614
25615         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25616         true
25617 }
25618 run_test 300p "create striped directory without space"
25619
25620 test_300q() {
25621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25623
25624         local fd=$(free_fd)
25625         local cmd="exec $fd<$tdir"
25626         cd $DIR
25627         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25628         eval $cmd
25629         cmd="exec $fd<&-"
25630         trap "eval $cmd" EXIT
25631         cd $tdir || error "cd $tdir fails"
25632         rmdir  ../$tdir || error "rmdir $tdir fails"
25633         mkdir local_dir && error "create dir succeeds"
25634         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25635         eval $cmd
25636         return 0
25637 }
25638 run_test 300q "create remote directory under orphan directory"
25639
25640 test_300r() {
25641         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25642                 skip "Need MDS version at least 2.7.55" && return
25643         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25644
25645         mkdir $DIR/$tdir
25646
25647         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25648                 error "set striped dir error"
25649
25650         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25651                 error "getstripeddir fails"
25652
25653         local stripe_count
25654         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25655                       awk '/lmv_stripe_count:/ { print $2 }')
25656
25657         [ $MDSCOUNT -ne $stripe_count ] &&
25658                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25659
25660         rm -rf $DIR/$tdir/striped_dir ||
25661                 error "unlink striped dir fails"
25662 }
25663 run_test 300r "test -1 striped directory"
25664
25665 test_300s_helper() {
25666         local count=$1
25667
25668         local stripe_dir=$DIR/$tdir/striped_dir.$count
25669
25670         $LFS mkdir -c $count $stripe_dir ||
25671                 error "lfs mkdir -c error"
25672
25673         $LFS getdirstripe $stripe_dir ||
25674                 error "lfs getdirstripe fails"
25675
25676         local stripe_count
25677         stripe_count=$($LFS getdirstripe $stripe_dir |
25678                       awk '/lmv_stripe_count:/ { print $2 }')
25679
25680         [ $count -ne $stripe_count ] &&
25681                 error_noexit "bad stripe count $stripe_count expected $count"
25682
25683         local dupe_stripes
25684         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25685                 awk '/0x/ {count[$1] += 1}; END {
25686                         for (idx in count) {
25687                                 if (count[idx]>1) {
25688                                         print "index " idx " count " count[idx]
25689                                 }
25690                         }
25691                 }')
25692
25693         if [[ -n "$dupe_stripes" ]] ; then
25694                 lfs getdirstripe $stripe_dir
25695                 error_noexit "Dupe MDT above: $dupe_stripes "
25696         fi
25697
25698         rm -rf $stripe_dir ||
25699                 error_noexit "unlink $stripe_dir fails"
25700 }
25701
25702 test_300s() {
25703         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25704                 skip "Need MDS version at least 2.7.55" && return
25705         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25706
25707         mkdir $DIR/$tdir
25708         for count in $(seq 2 $MDSCOUNT); do
25709                 test_300s_helper $count
25710         done
25711 }
25712 run_test 300s "test lfs mkdir -c without -i"
25713
25714 test_300t() {
25715         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25716                 skip "need MDS 2.14.55 or later"
25717         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25718
25719         local testdir="$DIR/$tdir/striped_dir"
25720         local dir1=$testdir/dir1
25721         local dir2=$testdir/dir2
25722
25723         mkdir -p $testdir
25724
25725         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25726                 error "failed to set default stripe count for $testdir"
25727
25728         mkdir $dir1
25729         local stripe_count=$($LFS getdirstripe -c $dir1)
25730
25731         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25732
25733         local max_count=$((MDSCOUNT - 1))
25734         local mdts=$(comma_list $(mdts_nodes))
25735
25736         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25737         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25738
25739         mkdir $dir2
25740         stripe_count=$($LFS getdirstripe -c $dir2)
25741
25742         (( $stripe_count == $max_count )) || error "wrong stripe count"
25743 }
25744 run_test 300t "test max_mdt_stripecount"
25745
25746 prepare_remote_file() {
25747         mkdir $DIR/$tdir/src_dir ||
25748                 error "create remote source failed"
25749
25750         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25751                  error "cp to remote source failed"
25752         touch $DIR/$tdir/src_dir/a
25753
25754         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25755                 error "create remote target dir failed"
25756
25757         touch $DIR/$tdir/tgt_dir/b
25758
25759         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25760                 error "rename dir cross MDT failed!"
25761
25762         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25763                 error "src_child still exists after rename"
25764
25765         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25766                 error "missing file(a) after rename"
25767
25768         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25769                 error "diff after rename"
25770 }
25771
25772 test_310a() {
25773         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25775
25776         local remote_file=$DIR/$tdir/tgt_dir/b
25777
25778         mkdir -p $DIR/$tdir
25779
25780         prepare_remote_file || error "prepare remote file failed"
25781
25782         #open-unlink file
25783         $OPENUNLINK $remote_file $remote_file ||
25784                 error "openunlink $remote_file failed"
25785         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25786 }
25787 run_test 310a "open unlink remote file"
25788
25789 test_310b() {
25790         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25792
25793         local remote_file=$DIR/$tdir/tgt_dir/b
25794
25795         mkdir -p $DIR/$tdir
25796
25797         prepare_remote_file || error "prepare remote file failed"
25798
25799         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25800         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25801         $CHECKSTAT -t file $remote_file || error "check file failed"
25802 }
25803 run_test 310b "unlink remote file with multiple links while open"
25804
25805 test_310c() {
25806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25807         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25808
25809         local remote_file=$DIR/$tdir/tgt_dir/b
25810
25811         mkdir -p $DIR/$tdir
25812
25813         prepare_remote_file || error "prepare remote file failed"
25814
25815         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25816         multiop_bg_pause $remote_file O_uc ||
25817                         error "mulitop failed for remote file"
25818         MULTIPID=$!
25819         $MULTIOP $DIR/$tfile Ouc
25820         kill -USR1 $MULTIPID
25821         wait $MULTIPID
25822 }
25823 run_test 310c "open-unlink remote file with multiple links"
25824
25825 #LU-4825
25826 test_311() {
25827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25828         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25829         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25830                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25831         remote_mds_nodsh && skip "remote MDS with nodsh"
25832
25833         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25834         local mdts=$(comma_list $(mdts_nodes))
25835
25836         mkdir -p $DIR/$tdir
25837         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25838         createmany -o $DIR/$tdir/$tfile. 1000
25839
25840         # statfs data is not real time, let's just calculate it
25841         old_iused=$((old_iused + 1000))
25842
25843         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25844                         osp.*OST0000*MDT0000.create_count")
25845         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25846                                 osp.*OST0000*MDT0000.max_create_count")
25847         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25848
25849         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25850         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25851         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25852
25853         unlinkmany $DIR/$tdir/$tfile. 1000
25854
25855         do_nodes $mdts "$LCTL set_param -n \
25856                         osp.*OST0000*.max_create_count=$max_count"
25857         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25858                 do_nodes $mdts "$LCTL set_param -n \
25859                                 osp.*OST0000*.create_count=$count"
25860         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25861                         grep "=0" && error "create_count is zero"
25862
25863         local new_iused
25864         for i in $(seq 120); do
25865                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25866                 # system may be too busy to destroy all objs in time, use
25867                 # a somewhat small value to not fail autotest
25868                 [ $((old_iused - new_iused)) -gt 400 ] && break
25869                 sleep 1
25870         done
25871
25872         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25873         [ $((old_iused - new_iused)) -gt 400 ] ||
25874                 error "objs not destroyed after unlink"
25875 }
25876 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25877
25878 zfs_get_objid()
25879 {
25880         local ost=$1
25881         local tf=$2
25882         local fid=($($LFS getstripe $tf | grep 0x))
25883         local seq=${fid[3]#0x}
25884         local objid=${fid[1]}
25885
25886         local vdevdir=$(dirname $(facet_vdevice $ost))
25887         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25888         local zfs_zapid=$(do_facet $ost $cmd |
25889                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25890                           awk '/Object/{getline; print $1}')
25891         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25892                           awk "/$objid = /"'{printf $3}')
25893
25894         echo $zfs_objid
25895 }
25896
25897 zfs_object_blksz() {
25898         local ost=$1
25899         local objid=$2
25900
25901         local vdevdir=$(dirname $(facet_vdevice $ost))
25902         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25903         local blksz=$(do_facet $ost $cmd $objid |
25904                       awk '/dblk/{getline; printf $4}')
25905
25906         case "${blksz: -1}" in
25907                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25908                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25909                 *) ;;
25910         esac
25911
25912         echo $blksz
25913 }
25914
25915 test_312() { # LU-4856
25916         remote_ost_nodsh && skip "remote OST with nodsh"
25917         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25918
25919         local max_blksz=$(do_facet ost1 \
25920                           $ZFS get -p recordsize $(facet_device ost1) |
25921                           awk '!/VALUE/{print $3}')
25922         local tf=$DIR/$tfile
25923
25924         $LFS setstripe -c1 $tf
25925         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25926
25927         # Get ZFS object id
25928         local zfs_objid=$(zfs_get_objid $facet $tf)
25929         # block size change by sequential overwrite
25930         local bs
25931
25932         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25933                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25934
25935                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25936                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25937         done
25938         rm -f $tf
25939
25940         $LFS setstripe -c1 $tf
25941         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25942
25943         # block size change by sequential append write
25944         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25945         zfs_objid=$(zfs_get_objid $facet $tf)
25946         local count
25947
25948         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25949                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25950                         oflag=sync conv=notrunc
25951
25952                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25953                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25954                         error "blksz error, actual $blksz, " \
25955                                 "expected: 2 * $count * $PAGE_SIZE"
25956         done
25957         rm -f $tf
25958
25959         # random write
25960         $LFS setstripe -c1 $tf
25961         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25962         zfs_objid=$(zfs_get_objid $facet $tf)
25963
25964         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25965         blksz=$(zfs_object_blksz $facet $zfs_objid)
25966         (( blksz == PAGE_SIZE )) ||
25967                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25968
25969         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25970         blksz=$(zfs_object_blksz $facet $zfs_objid)
25971         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25972
25973         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25974         blksz=$(zfs_object_blksz $facet $zfs_objid)
25975         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25976 }
25977 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25978
25979 test_313() {
25980         remote_ost_nodsh && skip "remote OST with nodsh"
25981
25982         local file=$DIR/$tfile
25983
25984         rm -f $file
25985         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25986
25987         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25988         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25989         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25990                 error "write should failed"
25991         do_facet ost1 "$LCTL set_param fail_loc=0"
25992         rm -f $file
25993 }
25994 run_test 313 "io should fail after last_rcvd update fail"
25995
25996 test_314() {
25997         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25998
25999         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26000         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26001         rm -f $DIR/$tfile
26002         wait_delete_completed
26003         do_facet ost1 "$LCTL set_param fail_loc=0"
26004 }
26005 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26006
26007 test_315() { # LU-618
26008         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26009
26010         local file=$DIR/$tfile
26011         rm -f $file
26012
26013         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26014                 error "multiop file write failed"
26015         $MULTIOP $file oO_RDONLY:r4063232_c &
26016         PID=$!
26017
26018         sleep 2
26019
26020         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26021         kill -USR1 $PID
26022
26023         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26024         rm -f $file
26025 }
26026 run_test 315 "read should be accounted"
26027
26028 test_316() {
26029         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26030         large_xattr_enabled || skip "ea_inode feature disabled"
26031
26032         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26033         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26034         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26035         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26036
26037         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26038 }
26039 run_test 316 "lfs migrate of file with large_xattr enabled"
26040
26041 test_317() {
26042         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26043                 skip "Need MDS version at least 2.11.53"
26044         if [ "$ost1_FSTYPE" == "zfs" ]; then
26045                 skip "LU-10370: no implementation for ZFS"
26046         fi
26047
26048         local trunc_sz
26049         local grant_blk_size
26050
26051         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26052                         awk '/grant_block_size:/ { print $2; exit; }')
26053         #
26054         # Create File of size 5M. Truncate it to below size's and verify
26055         # blocks count.
26056         #
26057         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26058                 error "Create file $DIR/$tfile failed"
26059         stack_trap "rm -f $DIR/$tfile" EXIT
26060
26061         for trunc_sz in 2097152 4097 4000 509 0; do
26062                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26063                         error "truncate $tfile to $trunc_sz failed"
26064                 local sz=$(stat --format=%s $DIR/$tfile)
26065                 local blk=$(stat --format=%b $DIR/$tfile)
26066                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26067                                      grant_blk_size) * 8))
26068
26069                 if [[ $blk -ne $trunc_blk ]]; then
26070                         $(which stat) $DIR/$tfile
26071                         error "Expected Block $trunc_blk got $blk for $tfile"
26072                 fi
26073
26074                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26075                         error "Expected Size $trunc_sz got $sz for $tfile"
26076         done
26077
26078         #
26079         # sparse file test
26080         # Create file with a hole and write actual 65536 bytes which aligned
26081         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26082         #
26083         local bs=65536
26084         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26085                 error "Create file : $DIR/$tfile"
26086
26087         #
26088         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26089         # blocks. The block count must drop to 8.
26090         #
26091         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26092                 ((bs - grant_blk_size) + 1)))
26093         $TRUNCATE $DIR/$tfile $trunc_sz ||
26094                 error "truncate $tfile to $trunc_sz failed"
26095
26096         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26097         sz=$(stat --format=%s $DIR/$tfile)
26098         blk=$(stat --format=%b $DIR/$tfile)
26099
26100         if [[ $blk -ne $trunc_bsz ]]; then
26101                 $(which stat) $DIR/$tfile
26102                 error "Expected Block $trunc_bsz got $blk for $tfile"
26103         fi
26104
26105         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26106                 error "Expected Size $trunc_sz got $sz for $tfile"
26107 }
26108 run_test 317 "Verify blocks get correctly update after truncate"
26109
26110 test_318() {
26111         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26112         local old_max_active=$($LCTL get_param -n \
26113                             ${llite_name}.max_read_ahead_async_active \
26114                             2>/dev/null)
26115
26116         $LCTL set_param llite.*.max_read_ahead_async_active=256
26117         local max_active=$($LCTL get_param -n \
26118                            ${llite_name}.max_read_ahead_async_active \
26119                            2>/dev/null)
26120         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26121
26122         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26123                 error "set max_read_ahead_async_active should succeed"
26124
26125         $LCTL set_param llite.*.max_read_ahead_async_active=512
26126         max_active=$($LCTL get_param -n \
26127                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26128         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26129
26130         # restore @max_active
26131         [ $old_max_active -ne 0 ] && $LCTL set_param \
26132                 llite.*.max_read_ahead_async_active=$old_max_active
26133
26134         local old_threshold=$($LCTL get_param -n \
26135                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26136         local max_per_file_mb=$($LCTL get_param -n \
26137                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26138
26139         local invalid=$(($max_per_file_mb + 1))
26140         $LCTL set_param \
26141                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26142                         && error "set $invalid should fail"
26143
26144         local valid=$(($invalid - 1))
26145         $LCTL set_param \
26146                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26147                         error "set $valid should succeed"
26148         local threshold=$($LCTL get_param -n \
26149                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26150         [ $threshold -eq $valid ] || error \
26151                 "expect threshold $valid got $threshold"
26152         $LCTL set_param \
26153                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26154 }
26155 run_test 318 "Verify async readahead tunables"
26156
26157 test_319() {
26158         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26159
26160         local before=$(date +%s)
26161         local evict
26162         local mdir=$DIR/$tdir
26163         local file=$mdir/xxx
26164
26165         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26166         touch $file
26167
26168 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26169         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26170         $LFS migrate -m1 $mdir &
26171
26172         sleep 1
26173         dd if=$file of=/dev/null
26174         wait
26175         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26176           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26177
26178         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26179 }
26180 run_test 319 "lost lease lock on migrate error"
26181
26182 test_398a() { # LU-4198
26183         local ost1_imp=$(get_osc_import_name client ost1)
26184         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26185                          cut -d'.' -f2)
26186
26187         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26188         stack_trap "rm -f $DIR/$tfile"
26189         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26190
26191         # request a new lock on client
26192         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26193
26194         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26195         local lock_count=$($LCTL get_param -n \
26196                            ldlm.namespaces.$imp_name.lru_size)
26197         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26198
26199         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26200
26201         # no lock cached, should use lockless DIO and not enqueue new lock
26202         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26203         lock_count=$($LCTL get_param -n \
26204                      ldlm.namespaces.$imp_name.lru_size)
26205         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26206
26207         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26208
26209         # no lock cached, should use locked DIO append
26210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26211                 conv=notrunc || error "DIO append failed"
26212         lock_count=$($LCTL get_param -n \
26213                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26214         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26215 }
26216 run_test 398a "direct IO should cancel lock otherwise lockless"
26217
26218 test_398b() { # LU-4198
26219         local before=$(date +%s)
26220         local njobs=4
26221         local size=48
26222
26223         which fio || skip_env "no fio installed"
26224         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26225         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26226
26227         # Single page, multiple pages, stripe size, 4*stripe size
26228         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26229                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26230                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26231                         --numjobs=$njobs --fallocate=none \
26232                         --iodepth=16 --allow_file_create=0 \
26233                         --size=$((size/njobs))M \
26234                         --filename=$DIR/$tfile &
26235                 bg_pid=$!
26236
26237                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26238                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26239                         --numjobs=$njobs --fallocate=none \
26240                         --iodepth=16 --allow_file_create=0 \
26241                         --size=$((size/njobs))M \
26242                         --filename=$DIR/$tfile || true
26243                 wait $bg_pid
26244         done
26245
26246         evict=$(do_facet client $LCTL get_param \
26247                 osc.$FSNAME-OST*-osc-*/state |
26248             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26249
26250         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26251                 (do_facet client $LCTL get_param \
26252                         osc.$FSNAME-OST*-osc-*/state;
26253                     error "eviction happened: $evict before:$before")
26254
26255         rm -f $DIR/$tfile
26256 }
26257 run_test 398b "DIO and buffer IO race"
26258
26259 test_398c() { # LU-4198
26260         local ost1_imp=$(get_osc_import_name client ost1)
26261         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26262                          cut -d'.' -f2)
26263
26264         which fio || skip_env "no fio installed"
26265
26266         saved_debug=$($LCTL get_param -n debug)
26267         $LCTL set_param debug=0
26268
26269         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26270         ((size /= 1024)) # by megabytes
26271         ((size /= 2)) # write half of the OST at most
26272         [ $size -gt 40 ] && size=40 #reduce test time anyway
26273
26274         $LFS setstripe -c 1 $DIR/$tfile
26275
26276         # it seems like ldiskfs reserves more space than necessary if the
26277         # writing blocks are not mapped, so it extends the file firstly
26278         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26279         cancel_lru_locks osc
26280
26281         # clear and verify rpc_stats later
26282         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26283
26284         local njobs=4
26285         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26286         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26287                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26288                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26289                 --filename=$DIR/$tfile
26290         [ $? -eq 0 ] || error "fio write error"
26291
26292         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26293                 error "Locks were requested while doing AIO"
26294
26295         # get the percentage of 1-page I/O
26296         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26297                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26298                 awk '{print $7}')
26299         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26300
26301         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26302         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26303                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26304                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26305                 --filename=$DIR/$tfile
26306         [ $? -eq 0 ] || error "fio mixed read write error"
26307
26308         echo "AIO with large block size ${size}M"
26309         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26310                 --numjobs=1 --fallocate=none --ioengine=libaio \
26311                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26312                 --filename=$DIR/$tfile
26313         [ $? -eq 0 ] || error "fio large block size failed"
26314
26315         rm -f $DIR/$tfile
26316         $LCTL set_param debug="$saved_debug"
26317 }
26318 run_test 398c "run fio to test AIO"
26319
26320 test_398d() { #  LU-13846
26321         which aiocp || skip_env "no aiocp installed"
26322         local aio_file=$DIR/$tfile.aio
26323
26324         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26325
26326         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26327         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26328         stack_trap "rm -f $DIR/$tfile $aio_file"
26329
26330         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26331
26332         # make sure we don't crash and fail properly
26333         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26334                 error "aio not aligned with PAGE SIZE should fail"
26335
26336         rm -f $DIR/$tfile $aio_file
26337 }
26338 run_test 398d "run aiocp to verify block size > stripe size"
26339
26340 test_398e() {
26341         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26342         touch $DIR/$tfile.new
26343         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26344 }
26345 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26346
26347 test_398f() { #  LU-14687
26348         which aiocp || skip_env "no aiocp installed"
26349         local aio_file=$DIR/$tfile.aio
26350
26351         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26352
26353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26354         stack_trap "rm -f $DIR/$tfile $aio_file"
26355
26356         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26357         $LCTL set_param fail_loc=0x1418
26358         # make sure we don't crash and fail properly
26359         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26360                 error "aio with page allocation failure succeeded"
26361         $LCTL set_param fail_loc=0
26362         diff $DIR/$tfile $aio_file
26363         [[ $? != 0 ]] || error "no diff after failed aiocp"
26364 }
26365 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26366
26367 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26368 # stripe and i/o size must be > stripe size
26369 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26370 # single RPC in flight.  This test shows async DIO submission is working by
26371 # showing multiple RPCs in flight.
26372 test_398g() { #  LU-13798
26373         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26374
26375         # We need to do some i/o first to acquire enough grant to put our RPCs
26376         # in flight; otherwise a new connection may not have enough grant
26377         # available
26378         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26379                 error "parallel dio failed"
26380         stack_trap "rm -f $DIR/$tfile"
26381
26382         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26383         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26384         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26385         stack_trap "$LCTL set_param -n $pages_per_rpc"
26386
26387         # Recreate file so it's empty
26388         rm -f $DIR/$tfile
26389         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26390         #Pause rpc completion to guarantee we see multiple rpcs in flight
26391         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26392         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26393         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26394
26395         # Clear rpc stats
26396         $LCTL set_param osc.*.rpc_stats=c
26397
26398         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26399                 error "parallel dio failed"
26400         stack_trap "rm -f $DIR/$tfile"
26401
26402         $LCTL get_param osc.*-OST0000-*.rpc_stats
26403         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26404                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26405                 grep "8:" | awk '{print $8}')
26406         # We look at the "8 rpcs in flight" field, and verify A) it is present
26407         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26408         # as expected for an 8M DIO to a file with 1M stripes.
26409         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26410
26411         # Verify turning off parallel dio works as expected
26412         # Clear rpc stats
26413         $LCTL set_param osc.*.rpc_stats=c
26414         $LCTL set_param llite.*.parallel_dio=0
26415         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26416
26417         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26418                 error "dio with parallel dio disabled failed"
26419
26420         # Ideally, we would see only one RPC in flight here, but there is an
26421         # unavoidable race between i/o completion and RPC in flight counting,
26422         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26423         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26424         # So instead we just verify it's always < 8.
26425         $LCTL get_param osc.*-OST0000-*.rpc_stats
26426         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26427                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26428                 grep '^$' -B1 | grep . | awk '{print $1}')
26429         [ $ret != "8:" ] ||
26430                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26431 }
26432 run_test 398g "verify parallel dio async RPC submission"
26433
26434 test_398h() { #  LU-13798
26435         local dio_file=$DIR/$tfile.dio
26436
26437         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26438
26439         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26440         stack_trap "rm -f $DIR/$tfile $dio_file"
26441
26442         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26443                 error "parallel dio failed"
26444         diff $DIR/$tfile $dio_file
26445         [[ $? == 0 ]] || error "file diff after aiocp"
26446 }
26447 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26448
26449 test_398i() { #  LU-13798
26450         local dio_file=$DIR/$tfile.dio
26451
26452         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26453
26454         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26455         stack_trap "rm -f $DIR/$tfile $dio_file"
26456
26457         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26458         $LCTL set_param fail_loc=0x1418
26459         # make sure we don't crash and fail properly
26460         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26461                 error "parallel dio page allocation failure succeeded"
26462         diff $DIR/$tfile $dio_file
26463         [[ $? != 0 ]] || error "no diff after failed aiocp"
26464 }
26465 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26466
26467 test_398j() { #  LU-13798
26468         # Stripe size > RPC size but less than i/o size tests split across
26469         # stripes and RPCs for individual i/o op
26470         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26471
26472         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26473         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26474         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26475         stack_trap "$LCTL set_param -n $pages_per_rpc"
26476
26477         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26478                 error "parallel dio write failed"
26479         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26480
26481         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26482                 error "parallel dio read failed"
26483         diff $DIR/$tfile $DIR/$tfile.2
26484         [[ $? == 0 ]] || error "file diff after parallel dio read"
26485 }
26486 run_test 398j "test parallel dio where stripe size > rpc_size"
26487
26488 test_398k() { #  LU-13798
26489         wait_delete_completed
26490         wait_mds_ost_sync
26491
26492         # 4 stripe file; we will cause out of space on OST0
26493         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26494
26495         # Fill OST0 (if it's not too large)
26496         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26497                    head -n1)
26498         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26499                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26500         fi
26501         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26502         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26503                 error "dd should fill OST0"
26504         stack_trap "rm -f $DIR/$tfile.1"
26505
26506         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26507         err=$?
26508
26509         ls -la $DIR/$tfile
26510         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26511                 error "file is not 0 bytes in size"
26512
26513         # dd above should not succeed, but don't error until here so we can
26514         # get debug info above
26515         [[ $err != 0 ]] ||
26516                 error "parallel dio write with enospc succeeded"
26517         stack_trap "rm -f $DIR/$tfile"
26518 }
26519 run_test 398k "test enospc on first stripe"
26520
26521 test_398l() { #  LU-13798
26522         wait_delete_completed
26523         wait_mds_ost_sync
26524
26525         # 4 stripe file; we will cause out of space on OST0
26526         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26527         # happens on the second i/o chunk we issue
26528         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26529
26530         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26531         stack_trap "rm -f $DIR/$tfile"
26532
26533         # Fill OST0 (if it's not too large)
26534         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26535                    head -n1)
26536         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26537                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26538         fi
26539         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26540         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26541                 error "dd should fill OST0"
26542         stack_trap "rm -f $DIR/$tfile.1"
26543
26544         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26545         err=$?
26546         stack_trap "rm -f $DIR/$tfile.2"
26547
26548         # Check that short write completed as expected
26549         ls -la $DIR/$tfile.2
26550         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26551                 error "file is not 1M in size"
26552
26553         # dd above should not succeed, but don't error until here so we can
26554         # get debug info above
26555         [[ $err != 0 ]] ||
26556                 error "parallel dio write with enospc succeeded"
26557
26558         # Truncate source file to same length as output file and diff them
26559         $TRUNCATE $DIR/$tfile 1048576
26560         diff $DIR/$tfile $DIR/$tfile.2
26561         [[ $? == 0 ]] || error "data incorrect after short write"
26562 }
26563 run_test 398l "test enospc on intermediate stripe/RPC"
26564
26565 test_398m() { #  LU-13798
26566         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26567
26568         # Set up failure on OST0, the first stripe:
26569         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26570         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26571         # OST0 is on ost1, OST1 is on ost2.
26572         # So this fail_val specifies OST0
26573         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26574         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26575
26576         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26577                 error "parallel dio write with failure on first stripe succeeded"
26578         stack_trap "rm -f $DIR/$tfile"
26579         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26580
26581         # Place data in file for read
26582         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26583                 error "parallel dio write failed"
26584
26585         # Fail read on OST0, first stripe
26586         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26587         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26588         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26589                 error "parallel dio read with error on first stripe succeeded"
26590         rm -f $DIR/$tfile.2
26591         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26592
26593         # Switch to testing on OST1, second stripe
26594         # Clear file contents, maintain striping
26595         echo > $DIR/$tfile
26596         # Set up failure on OST1, second stripe:
26597         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26598         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26599
26600         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26601                 error "parallel dio write with failure on second stripe succeeded"
26602         stack_trap "rm -f $DIR/$tfile"
26603         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26604
26605         # Place data in file for read
26606         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26607                 error "parallel dio write failed"
26608
26609         # Fail read on OST1, second stripe
26610         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26611         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26612         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26613                 error "parallel dio read with error on second stripe succeeded"
26614         rm -f $DIR/$tfile.2
26615         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26616 }
26617 run_test 398m "test RPC failures with parallel dio"
26618
26619 # Parallel submission of DIO should not cause problems for append, but it's
26620 # important to verify.
26621 test_398n() { #  LU-13798
26622         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26623
26624         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26625                 error "dd to create source file failed"
26626         stack_trap "rm -f $DIR/$tfile"
26627
26628         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26629                 error "parallel dio write with failure on second stripe succeeded"
26630         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26631         diff $DIR/$tfile $DIR/$tfile.1
26632         [[ $? == 0 ]] || error "data incorrect after append"
26633
26634 }
26635 run_test 398n "test append with parallel DIO"
26636
26637 test_398o() {
26638         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26639 }
26640 run_test 398o "right kms with DIO"
26641
26642 test_398p()
26643 {
26644         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26645         which aiocp || skip_env "no aiocp installed"
26646
26647         local stripe_size=$((1024 * 1024)) #1 MiB
26648         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26649         local file_size=$((25 * stripe_size))
26650
26651         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26652         stack_trap "rm -f $DIR/$tfile*"
26653         # Just a bit bigger than the largest size in the test set below
26654         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26655                 error "buffered i/o to create file failed"
26656
26657         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26658                 $((stripe_size * 4)); do
26659
26660                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26661
26662                 echo "bs: $bs, file_size $file_size"
26663                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26664                         $DIR/$tfile.1 $DIR/$tfile.2 &
26665                 pid_dio1=$!
26666                 # Buffered I/O with similar but not the same block size
26667                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26668                         conv=notrunc &
26669                 pid_bio2=$!
26670                 wait $pid_dio1
26671                 rc1=$?
26672                 wait $pid_bio2
26673                 rc2=$?
26674                 if (( rc1 != 0 )); then
26675                         error "aio copy 1 w/bsize $bs failed: $rc1"
26676                 fi
26677                 if (( rc2 != 0 )); then
26678                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26679                 fi
26680
26681                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26682                         error "size incorrect"
26683                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26684                         error "files differ, bsize $bs"
26685                 rm -f $DIR/$tfile.2
26686         done
26687 }
26688 run_test 398p "race aio with buffered i/o"
26689
26690 test_398q()
26691 {
26692         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26693
26694         local stripe_size=$((1024 * 1024)) #1 MiB
26695         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26696         local file_size=$((25 * stripe_size))
26697
26698         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26699         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26700
26701         # Just a bit bigger than the largest size in the test set below
26702         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26703                 error "buffered i/o to create file failed"
26704
26705         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26706                 $((stripe_size * 4)); do
26707
26708                 echo "bs: $bs, file_size $file_size"
26709                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26710                         conv=notrunc oflag=direct iflag=direct &
26711                 pid_dio1=$!
26712                 # Buffered I/O with similar but not the same block size
26713                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26714                         conv=notrunc &
26715                 pid_bio2=$!
26716                 wait $pid_dio1
26717                 rc1=$?
26718                 wait $pid_bio2
26719                 rc2=$?
26720                 if (( rc1 != 0 )); then
26721                         error "dio copy 1 w/bsize $bs failed: $rc1"
26722                 fi
26723                 if (( rc2 != 0 )); then
26724                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26725                 fi
26726
26727                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26728                         error "size incorrect"
26729                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26730                         error "files differ, bsize $bs"
26731         done
26732
26733         rm -f $DIR/$tfile*
26734 }
26735 run_test 398q "race dio with buffered i/o"
26736
26737 test_fake_rw() {
26738         local read_write=$1
26739         if [ "$read_write" = "write" ]; then
26740                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26741         elif [ "$read_write" = "read" ]; then
26742                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26743         else
26744                 error "argument error"
26745         fi
26746
26747         # turn off debug for performance testing
26748         local saved_debug=$($LCTL get_param -n debug)
26749         $LCTL set_param debug=0
26750
26751         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26752
26753         # get ost1 size - $FSNAME-OST0000
26754         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26755         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26756         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26757
26758         if [ "$read_write" = "read" ]; then
26759                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26760         fi
26761
26762         local start_time=$(date +%s.%N)
26763         $dd_cmd bs=1M count=$blocks oflag=sync ||
26764                 error "real dd $read_write error"
26765         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26766
26767         if [ "$read_write" = "write" ]; then
26768                 rm -f $DIR/$tfile
26769         fi
26770
26771         # define OBD_FAIL_OST_FAKE_RW           0x238
26772         do_facet ost1 $LCTL set_param fail_loc=0x238
26773
26774         local start_time=$(date +%s.%N)
26775         $dd_cmd bs=1M count=$blocks oflag=sync ||
26776                 error "fake dd $read_write error"
26777         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26778
26779         if [ "$read_write" = "write" ]; then
26780                 # verify file size
26781                 cancel_lru_locks osc
26782                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26783                         error "$tfile size not $blocks MB"
26784         fi
26785         do_facet ost1 $LCTL set_param fail_loc=0
26786
26787         echo "fake $read_write $duration_fake vs. normal $read_write" \
26788                 "$duration in seconds"
26789         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26790                 error_not_in_vm "fake write is slower"
26791
26792         $LCTL set_param -n debug="$saved_debug"
26793         rm -f $DIR/$tfile
26794 }
26795 test_399a() { # LU-7655 for OST fake write
26796         remote_ost_nodsh && skip "remote OST with nodsh"
26797
26798         test_fake_rw write
26799 }
26800 run_test 399a "fake write should not be slower than normal write"
26801
26802 test_399b() { # LU-8726 for OST fake read
26803         remote_ost_nodsh && skip "remote OST with nodsh"
26804         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26805                 skip_env "ldiskfs only test"
26806         fi
26807
26808         test_fake_rw read
26809 }
26810 run_test 399b "fake read should not be slower than normal read"
26811
26812 test_400a() { # LU-1606, was conf-sanity test_74
26813         if ! which $CC > /dev/null 2>&1; then
26814                 skip_env "$CC is not installed"
26815         fi
26816
26817         local extra_flags=''
26818         local out=$TMP/$tfile
26819         local prefix=/usr/include/lustre
26820         local prog
26821
26822         # Oleg removes .c files in his test rig so test if any c files exist
26823         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26824                 skip_env "Needed .c test files are missing"
26825
26826         if ! [[ -d $prefix ]]; then
26827                 # Assume we're running in tree and fixup the include path.
26828                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26829                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26830                 extra_flags+=" -L$LUSTRE/utils/.libs"
26831         fi
26832
26833         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26834                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26835                         error "client api broken"
26836         done
26837         rm -f $out
26838 }
26839 run_test 400a "Lustre client api program can compile and link"
26840
26841 test_400b() { # LU-1606, LU-5011
26842         local header
26843         local out=$TMP/$tfile
26844         local prefix=/usr/include/linux/lustre
26845
26846         # We use a hard coded prefix so that this test will not fail
26847         # when run in tree. There are headers in lustre/include/lustre/
26848         # that are not packaged (like lustre_idl.h) and have more
26849         # complicated include dependencies (like config.h and lnet/types.h).
26850         # Since this test about correct packaging we just skip them when
26851         # they don't exist (see below) rather than try to fixup cppflags.
26852
26853         if ! which $CC > /dev/null 2>&1; then
26854                 skip_env "$CC is not installed"
26855         fi
26856
26857         for header in $prefix/*.h; do
26858                 if ! [[ -f "$header" ]]; then
26859                         continue
26860                 fi
26861
26862                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26863                         continue # lustre_ioctl.h is internal header
26864                 fi
26865
26866                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26867                         error "cannot compile '$header'"
26868         done
26869         rm -f $out
26870 }
26871 run_test 400b "packaged headers can be compiled"
26872
26873 test_401a() { #LU-7437
26874         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26875         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26876
26877         #count the number of parameters by "list_param -R"
26878         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26879         #count the number of parameters by listing proc files
26880         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26881         echo "proc_dirs='$proc_dirs'"
26882         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26883         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26884                       sort -u | wc -l)
26885
26886         [ $params -eq $procs ] ||
26887                 error "found $params parameters vs. $procs proc files"
26888
26889         # test the list_param -D option only returns directories
26890         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26891         #count the number of parameters by listing proc directories
26892         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26893                 sort -u | wc -l)
26894
26895         [ $params -eq $procs ] ||
26896                 error "found $params parameters vs. $procs proc files"
26897 }
26898 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26899
26900 test_401b() {
26901         # jobid_var may not allow arbitrary values, so use jobid_name
26902         # if available
26903         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26904                 local testname=jobid_name tmp='testing%p'
26905         else
26906                 local testname=jobid_var tmp=testing
26907         fi
26908
26909         local save=$($LCTL get_param -n $testname)
26910
26911         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26912                 error "no error returned when setting bad parameters"
26913
26914         local jobid_new=$($LCTL get_param -n foe $testname baz)
26915         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26916
26917         $LCTL set_param -n fog=bam $testname=$save bat=fog
26918         local jobid_old=$($LCTL get_param -n foe $testname bag)
26919         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26920 }
26921 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26922
26923 test_401c() {
26924         # jobid_var may not allow arbitrary values, so use jobid_name
26925         # if available
26926         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26927                 local testname=jobid_name
26928         else
26929                 local testname=jobid_var
26930         fi
26931
26932         local jobid_var_old=$($LCTL get_param -n $testname)
26933         local jobid_var_new
26934
26935         $LCTL set_param $testname= &&
26936                 error "no error returned for 'set_param a='"
26937
26938         jobid_var_new=$($LCTL get_param -n $testname)
26939         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26940                 error "$testname was changed by setting without value"
26941
26942         $LCTL set_param $testname &&
26943                 error "no error returned for 'set_param a'"
26944
26945         jobid_var_new=$($LCTL get_param -n $testname)
26946         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26947                 error "$testname was changed by setting without value"
26948 }
26949 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26950
26951 test_401d() {
26952         # jobid_var may not allow arbitrary values, so use jobid_name
26953         # if available
26954         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26955                 local testname=jobid_name new_value='foo=bar%p'
26956         else
26957                 local testname=jobid_var new_valuie=foo=bar
26958         fi
26959
26960         local jobid_var_old=$($LCTL get_param -n $testname)
26961         local jobid_var_new
26962
26963         $LCTL set_param $testname=$new_value ||
26964                 error "'set_param a=b' did not accept a value containing '='"
26965
26966         jobid_var_new=$($LCTL get_param -n $testname)
26967         [[ "$jobid_var_new" == "$new_value" ]] ||
26968                 error "'set_param a=b' failed on a value containing '='"
26969
26970         # Reset the $testname to test the other format
26971         $LCTL set_param $testname=$jobid_var_old
26972         jobid_var_new=$($LCTL get_param -n $testname)
26973         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26974                 error "failed to reset $testname"
26975
26976         $LCTL set_param $testname $new_value ||
26977                 error "'set_param a b' did not accept a value containing '='"
26978
26979         jobid_var_new=$($LCTL get_param -n $testname)
26980         [[ "$jobid_var_new" == "$new_value" ]] ||
26981                 error "'set_param a b' failed on a value containing '='"
26982
26983         $LCTL set_param $testname $jobid_var_old
26984         jobid_var_new=$($LCTL get_param -n $testname)
26985         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26986                 error "failed to reset $testname"
26987 }
26988 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26989
26990 test_401e() { # LU-14779
26991         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26992                 error "lctl list_param MGC* failed"
26993         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26994         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26995                 error "lctl get_param lru_size failed"
26996 }
26997 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26998
26999 test_402() {
27000         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27001         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27002                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27003         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27004                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27005                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27006         remote_mds_nodsh && skip "remote MDS with nodsh"
27007
27008         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27009 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27010         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27011         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27012                 echo "Touch failed - OK"
27013 }
27014 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27015
27016 test_403() {
27017         local file1=$DIR/$tfile.1
27018         local file2=$DIR/$tfile.2
27019         local tfile=$TMP/$tfile
27020
27021         rm -f $file1 $file2 $tfile
27022
27023         touch $file1
27024         ln $file1 $file2
27025
27026         # 30 sec OBD_TIMEOUT in ll_getattr()
27027         # right before populating st_nlink
27028         $LCTL set_param fail_loc=0x80001409
27029         stat -c %h $file1 > $tfile &
27030
27031         # create an alias, drop all locks and reclaim the dentry
27032         < $file2
27033         cancel_lru_locks mdc
27034         cancel_lru_locks osc
27035         sysctl -w vm.drop_caches=2
27036
27037         wait
27038
27039         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27040
27041         rm -f $tfile $file1 $file2
27042 }
27043 run_test 403 "i_nlink should not drop to zero due to aliasing"
27044
27045 test_404() { # LU-6601
27046         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27047                 skip "Need server version newer than 2.8.52"
27048         remote_mds_nodsh && skip "remote MDS with nodsh"
27049
27050         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27051                 awk '/osp .*-osc-MDT/ { print $4}')
27052
27053         local osp
27054         for osp in $mosps; do
27055                 echo "Deactivate: " $osp
27056                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27057                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27058                         awk -vp=$osp '$4 == p { print $2 }')
27059                 [ $stat = IN ] || {
27060                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27061                         error "deactivate error"
27062                 }
27063                 echo "Activate: " $osp
27064                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27065                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27066                         awk -vp=$osp '$4 == p { print $2 }')
27067                 [ $stat = UP ] || {
27068                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27069                         error "activate error"
27070                 }
27071         done
27072 }
27073 run_test 404 "validate manual {de}activated works properly for OSPs"
27074
27075 test_405() {
27076         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27077         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27078                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27079                         skip "Layout swap lock is not supported"
27080
27081         check_swap_layouts_support
27082         check_swap_layout_no_dom $DIR
27083
27084         test_mkdir $DIR/$tdir
27085         swap_lock_test -d $DIR/$tdir ||
27086                 error "One layout swap locked test failed"
27087 }
27088 run_test 405 "Various layout swap lock tests"
27089
27090 test_406() {
27091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27092         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27093         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27095         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27096                 skip "Need MDS version at least 2.8.50"
27097
27098         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27099         local test_pool=$TESTNAME
27100
27101         pool_add $test_pool || error "pool_add failed"
27102         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27103                 error "pool_add_targets failed"
27104
27105         save_layout_restore_at_exit $MOUNT
27106
27107         # parent set default stripe count only, child will stripe from both
27108         # parent and fs default
27109         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27110                 error "setstripe $MOUNT failed"
27111         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27112         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27113         for i in $(seq 10); do
27114                 local f=$DIR/$tdir/$tfile.$i
27115                 touch $f || error "touch failed"
27116                 local count=$($LFS getstripe -c $f)
27117                 [ $count -eq $OSTCOUNT ] ||
27118                         error "$f stripe count $count != $OSTCOUNT"
27119                 local offset=$($LFS getstripe -i $f)
27120                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27121                 local size=$($LFS getstripe -S $f)
27122                 [ $size -eq $((def_stripe_size * 2)) ] ||
27123                         error "$f stripe size $size != $((def_stripe_size * 2))"
27124                 local pool=$($LFS getstripe -p $f)
27125                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27126         done
27127
27128         # change fs default striping, delete parent default striping, now child
27129         # will stripe from new fs default striping only
27130         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27131                 error "change $MOUNT default stripe failed"
27132         $LFS setstripe -c 0 $DIR/$tdir ||
27133                 error "delete $tdir default stripe failed"
27134         for i in $(seq 11 20); do
27135                 local f=$DIR/$tdir/$tfile.$i
27136                 touch $f || error "touch $f failed"
27137                 local count=$($LFS getstripe -c $f)
27138                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27139                 local offset=$($LFS getstripe -i $f)
27140                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27141                 local size=$($LFS getstripe -S $f)
27142                 [ $size -eq $def_stripe_size ] ||
27143                         error "$f stripe size $size != $def_stripe_size"
27144                 local pool=$($LFS getstripe -p $f)
27145                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27146         done
27147
27148         unlinkmany $DIR/$tdir/$tfile. 1 20
27149
27150         local f=$DIR/$tdir/$tfile
27151         pool_remove_all_targets $test_pool $f
27152         pool_remove $test_pool $f
27153 }
27154 run_test 406 "DNE support fs default striping"
27155
27156 test_407() {
27157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27158         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27159                 skip "Need MDS version at least 2.8.55"
27160         remote_mds_nodsh && skip "remote MDS with nodsh"
27161
27162         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27163                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27164         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27165                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27166         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27167
27168         #define OBD_FAIL_DT_TXN_STOP    0x2019
27169         for idx in $(seq $MDSCOUNT); do
27170                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27171         done
27172         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27173         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27174                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27175         true
27176 }
27177 run_test 407 "transaction fail should cause operation fail"
27178
27179 test_408() {
27180         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27181
27182         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27183         lctl set_param fail_loc=0x8000040a
27184         # let ll_prepare_partial_page() fail
27185         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27186
27187         rm -f $DIR/$tfile
27188
27189         # create at least 100 unused inodes so that
27190         # shrink_icache_memory(0) should not return 0
27191         touch $DIR/$tfile-{0..100}
27192         rm -f $DIR/$tfile-{0..100}
27193         sync
27194
27195         echo 2 > /proc/sys/vm/drop_caches
27196 }
27197 run_test 408 "drop_caches should not hang due to page leaks"
27198
27199 test_409()
27200 {
27201         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27202
27203         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27204         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27205         touch $DIR/$tdir/guard || error "(2) Fail to create"
27206
27207         local PREFIX=$(str_repeat 'A' 128)
27208         echo "Create 1K hard links start at $(date)"
27209         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27210                 error "(3) Fail to hard link"
27211
27212         echo "Links count should be right although linkEA overflow"
27213         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27214         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27215         [ $linkcount -eq 1001 ] ||
27216                 error "(5) Unexpected hard links count: $linkcount"
27217
27218         echo "List all links start at $(date)"
27219         ls -l $DIR/$tdir/foo > /dev/null ||
27220                 error "(6) Fail to list $DIR/$tdir/foo"
27221
27222         echo "Unlink hard links start at $(date)"
27223         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27224                 error "(7) Fail to unlink"
27225         echo "Unlink hard links finished at $(date)"
27226 }
27227 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27228
27229 test_410()
27230 {
27231         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27232                 skip "Need client version at least 2.9.59"
27233         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27234                 skip "Need MODULES build"
27235
27236         # Create a file, and stat it from the kernel
27237         local testfile=$DIR/$tfile
27238         touch $testfile
27239
27240         local run_id=$RANDOM
27241         local my_ino=$(stat --format "%i" $testfile)
27242
27243         # Try to insert the module. This will always fail as the
27244         # module is designed to not be inserted.
27245         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27246             &> /dev/null
27247
27248         # Anything but success is a test failure
27249         dmesg | grep -q \
27250             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27251             error "no inode match"
27252 }
27253 run_test 410 "Test inode number returned from kernel thread"
27254
27255 cleanup_test411_cgroup() {
27256         trap 0
27257         rmdir "$1"
27258 }
27259
27260 test_411() {
27261         local cg_basedir=/sys/fs/cgroup/memory
27262         # LU-9966
27263         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27264                 skip "no setup for cgroup"
27265
27266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27267                 error "test file creation failed"
27268         cancel_lru_locks osc
27269
27270         # Create a very small memory cgroup to force a slab allocation error
27271         local cgdir=$cg_basedir/osc_slab_alloc
27272         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27273         trap "cleanup_test411_cgroup $cgdir" EXIT
27274         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27275         echo 1M > $cgdir/memory.limit_in_bytes
27276
27277         # Should not LBUG, just be killed by oom-killer
27278         # dd will return 0 even allocation failure in some environment.
27279         # So don't check return value
27280         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27281         cleanup_test411_cgroup $cgdir
27282
27283         return 0
27284 }
27285 run_test 411 "Slab allocation error with cgroup does not LBUG"
27286
27287 test_412() {
27288         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27289         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27290                 skip "Need server version at least 2.10.55"
27291
27292         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27293                 error "mkdir failed"
27294         $LFS getdirstripe $DIR/$tdir
27295         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27296         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27297                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27298         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27299         [ $stripe_count -eq 2 ] ||
27300                 error "expect 2 get $stripe_count"
27301
27302         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27303
27304         local index
27305         local index2
27306
27307         # subdirs should be on the same MDT as parent
27308         for i in $(seq 0 $((MDSCOUNT - 1))); do
27309                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27310                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27311                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27312                 (( index == i )) || error "mdt$i/sub on MDT$index"
27313         done
27314
27315         # stripe offset -1, ditto
27316         for i in {1..10}; do
27317                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27318                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27319                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27320                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27321                 (( index == index2 )) ||
27322                         error "qos$i on MDT$index, sub on MDT$index2"
27323         done
27324
27325         local testdir=$DIR/$tdir/inherit
27326
27327         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27328         # inherit 2 levels
27329         for i in 1 2; do
27330                 testdir=$testdir/s$i
27331                 mkdir $testdir || error "mkdir $testdir failed"
27332                 index=$($LFS getstripe -m $testdir)
27333                 (( index == 1 )) ||
27334                         error "$testdir on MDT$index"
27335         done
27336
27337         # not inherit any more
27338         testdir=$testdir/s3
27339         mkdir $testdir || error "mkdir $testdir failed"
27340         getfattr -d -m dmv $testdir | grep dmv &&
27341                 error "default LMV set on $testdir" || true
27342 }
27343 run_test 412 "mkdir on specific MDTs"
27344
27345 TEST413_COUNT=${TEST413_COUNT:-200}
27346
27347 #
27348 # set_maxage() is used by test_413 only.
27349 # This is a helper function to set maxage. Does not return any value.
27350 # Input: maxage to set
27351 #
27352 set_maxage() {
27353         local lmv_qos_maxage
27354         local lod_qos_maxage
27355         local new_maxage=$1
27356
27357         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27358         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27359         stack_trap "$LCTL set_param \
27360                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27361         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27362                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27363         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27364                 lod.*.mdt_qos_maxage=$new_maxage
27365         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27366                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27367 }
27368
27369 generate_uneven_mdts() {
27370         local threshold=$1
27371         local ffree
27372         local bavail
27373         local max
27374         local min
27375         local max_index
27376         local min_index
27377         local tmp
27378         local i
27379
27380         echo
27381         echo "Check for uneven MDTs: "
27382
27383         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27384         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27385         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27386
27387         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27388         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27389         max_index=0
27390         min_index=0
27391         for ((i = 1; i < ${#ffree[@]}; i++)); do
27392                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27393                 if [ $tmp -gt $max ]; then
27394                         max=$tmp
27395                         max_index=$i
27396                 fi
27397                 if [ $tmp -lt $min ]; then
27398                         min=$tmp
27399                         min_index=$i
27400                 fi
27401         done
27402
27403         (( min > 0 )) || skip "low space on MDT$min_index"
27404         (( ${ffree[min_index]} > 0 )) ||
27405                 skip "no free files on MDT$min_index"
27406         (( ${ffree[min_index]} < 10000000 )) ||
27407                 skip "too many free files on MDT$min_index"
27408
27409         # Check if we need to generate uneven MDTs
27410         local diff=$(((max - min) * 100 / min))
27411         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27412         local testdir # individual folder within $testdirp
27413         local start
27414         local cmd
27415
27416         # fallocate is faster to consume space on MDT, if available
27417         if check_fallocate_supported mds$((min_index + 1)); then
27418                 cmd="fallocate -l 128K "
27419         else
27420                 cmd="dd if=/dev/zero bs=128K count=1 of="
27421         fi
27422
27423         echo "using cmd $cmd"
27424         for (( i = 0; diff < threshold; i++ )); do
27425                 testdir=${testdirp}/$i
27426                 [ -d $testdir ] && continue
27427
27428                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27429
27430                 mkdir -p $testdirp
27431                 # generate uneven MDTs, create till $threshold% diff
27432                 echo -n "weight diff=$diff% must be > $threshold% ..."
27433                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27434                 $LFS mkdir -i $min_index $testdir ||
27435                         error "mkdir $testdir failed"
27436                 $LFS setstripe -E 1M -L mdt $testdir ||
27437                         error "setstripe $testdir failed"
27438                 start=$SECONDS
27439                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27440                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27441                 done
27442                 sync; sleep 1; sync
27443
27444                 # wait for QOS to update
27445                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27446
27447                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27448                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27449                 max=$(((${ffree[max_index]} >> 8) *
27450                         (${bavail[max_index]} * bsize >> 16)))
27451                 min=$(((${ffree[min_index]} >> 8) *
27452                         (${bavail[min_index]} * bsize >> 16)))
27453                 (( min > 0 )) || skip "low space on MDT$min_index"
27454                 diff=$(((max - min) * 100 / min))
27455         done
27456
27457         echo "MDT filesfree available: ${ffree[*]}"
27458         echo "MDT blocks available: ${bavail[*]}"
27459         echo "weight diff=$diff%"
27460 }
27461
27462 test_qos_mkdir() {
27463         local mkdir_cmd=$1
27464         local stripe_count=$2
27465         local mdts=$(comma_list $(mdts_nodes))
27466
27467         local testdir
27468         local lmv_qos_prio_free
27469         local lmv_qos_threshold_rr
27470         local lod_qos_prio_free
27471         local lod_qos_threshold_rr
27472         local total
27473         local count
27474         local i
27475
27476         # @total is total directories created if it's testing plain
27477         # directories, otherwise it's total stripe object count for
27478         # striped directories test.
27479         # remote/striped directory unlinking is slow on zfs and may
27480         # timeout, test with fewer directories
27481         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27482
27483         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27484         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27485         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27486                 head -n1)
27487         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27488         stack_trap "$LCTL set_param \
27489                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27490         stack_trap "$LCTL set_param \
27491                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27492
27493         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27494                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27495         lod_qos_prio_free=${lod_qos_prio_free%%%}
27496         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27497                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27498         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27499         stack_trap "do_nodes $mdts $LCTL set_param \
27500                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27501         stack_trap "do_nodes $mdts $LCTL set_param \
27502                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27503
27504         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27505         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27506
27507         testdir=$DIR/$tdir-s$stripe_count/rr
27508
27509         local stripe_index=$($LFS getstripe -m $testdir)
27510         local test_mkdir_rr=true
27511
27512         getfattr -d -m dmv -e hex $testdir | grep dmv
27513         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27514                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27515                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27516                         test_mkdir_rr=false
27517         fi
27518
27519         echo
27520         $test_mkdir_rr &&
27521                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27522                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27523
27524         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27525         for (( i = 0; i < total / stripe_count; i++ )); do
27526                 eval $mkdir_cmd $testdir/subdir$i ||
27527                         error "$mkdir_cmd subdir$i failed"
27528         done
27529
27530         for (( i = 0; i < $MDSCOUNT; i++ )); do
27531                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27532                 echo "$count directories created on MDT$i"
27533                 if $test_mkdir_rr; then
27534                         (( count == total / stripe_count / MDSCOUNT )) ||
27535                                 error "subdirs are not evenly distributed"
27536                 elif (( i == stripe_index )); then
27537                         (( count == total / stripe_count )) ||
27538                                 error "$count subdirs created on MDT$i"
27539                 else
27540                         (( count == 0 )) ||
27541                                 error "$count subdirs created on MDT$i"
27542                 fi
27543
27544                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27545                         count=$($LFS getdirstripe $testdir/* |
27546                                 grep -c -P "^\s+$i\t")
27547                         echo "$count stripes created on MDT$i"
27548                         # deviation should < 5% of average
27549                         delta=$((count - total / MDSCOUNT))
27550                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27551                                 error "stripes are not evenly distributed"
27552                 fi
27553         done
27554
27555         echo
27556         echo "Check for uneven MDTs: "
27557
27558         local ffree
27559         local bavail
27560         local max
27561         local min
27562         local max_index
27563         local min_index
27564         local tmp
27565
27566         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27567         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27568         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27569
27570         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27571         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27572         max_index=0
27573         min_index=0
27574         for ((i = 1; i < ${#ffree[@]}; i++)); do
27575                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27576                 if [ $tmp -gt $max ]; then
27577                         max=$tmp
27578                         max_index=$i
27579                 fi
27580                 if [ $tmp -lt $min ]; then
27581                         min=$tmp
27582                         min_index=$i
27583                 fi
27584         done
27585         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27586
27587         (( min > 0 )) || skip "low space on MDT$min_index"
27588         (( ${ffree[min_index]} < 10000000 )) ||
27589                 skip "too many free files on MDT$min_index"
27590
27591         generate_uneven_mdts 120
27592
27593         echo "MDT filesfree available: ${ffree[*]}"
27594         echo "MDT blocks available: ${bavail[*]}"
27595         echo "weight diff=$(((max - min) * 100 / min))%"
27596         echo
27597         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27598
27599         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27600         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27601         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27602         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27603         # decrease statfs age, so that it can be updated in time
27604         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27605         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27606
27607         sleep 1
27608
27609         testdir=$DIR/$tdir-s$stripe_count/qos
27610
27611         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27612         for (( i = 0; i < total / stripe_count; i++ )); do
27613                 eval $mkdir_cmd $testdir/subdir$i ||
27614                         error "$mkdir_cmd subdir$i failed"
27615         done
27616
27617         max=0
27618         for (( i = 0; i < $MDSCOUNT; i++ )); do
27619                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27620                 (( count > max )) && max=$count
27621                 echo "$count directories created on MDT$i : curmax=$max"
27622         done
27623
27624         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27625
27626         # D-value should > 10% of average
27627         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27628                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27629
27630         # ditto for stripes
27631         if (( stripe_count > 1 )); then
27632                 max=0
27633                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27634                         count=$($LFS getdirstripe $testdir/* |
27635                                 grep -c -P "^\s+$i\t")
27636                         (( count > max )) && max=$count
27637                         echo "$count stripes created on MDT$i"
27638                 done
27639
27640                 min=$($LFS getdirstripe $testdir/* |
27641                         grep -c -P "^\s+$min_index\t")
27642                 (( max - min > total / MDSCOUNT / 10 )) ||
27643                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27644         fi
27645 }
27646
27647 most_full_mdt() {
27648         local ffree
27649         local bavail
27650         local bsize
27651         local min
27652         local min_index
27653         local tmp
27654
27655         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27656         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27657         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27658
27659         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27660         min_index=0
27661         for ((i = 1; i < ${#ffree[@]}; i++)); do
27662                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27663                 (( tmp < min )) && min=$tmp && min_index=$i
27664         done
27665
27666         echo -n $min_index
27667 }
27668
27669 test_413a() {
27670         [ $MDSCOUNT -lt 2 ] &&
27671                 skip "We need at least 2 MDTs for this test"
27672
27673         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27674                 skip "Need server version at least 2.12.52"
27675
27676         local stripe_max=$((MDSCOUNT - 1))
27677         local stripe_count
27678
27679         # let caller set maxage for latest result
27680         set_maxage 1
27681
27682         # fill MDT unevenly
27683         generate_uneven_mdts 120
27684
27685         # test 4-stripe directory at most, otherwise it's too slow
27686         # We are being very defensive. Although Autotest uses 4 MDTs.
27687         # We make sure stripe_max does not go over 4.
27688         (( stripe_max > 4 )) && stripe_max=4
27689         # unlinking striped directory is slow on zfs, and may timeout, only test
27690         # plain directory
27691         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27692         for stripe_count in $(seq 1 $stripe_max); do
27693                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27694                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27695                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27696                         error "mkdir failed"
27697                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27698         done
27699 }
27700 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27701
27702 test_413b() {
27703         [ $MDSCOUNT -lt 2 ] &&
27704                 skip "We need at least 2 MDTs for this test"
27705
27706         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27707                 skip "Need server version at least 2.12.52"
27708
27709         local stripe_max=$((MDSCOUNT - 1))
27710         local testdir
27711         local stripe_count
27712
27713         # let caller set maxage for latest result
27714         set_maxage 1
27715
27716         # fill MDT unevenly
27717         generate_uneven_mdts 120
27718
27719         # test 4-stripe directory at most, otherwise it's too slow
27720         # We are being very defensive. Although Autotest uses 4 MDTs.
27721         # We make sure stripe_max does not go over 4.
27722         (( stripe_max > 4 )) && stripe_max=4
27723         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27724         for stripe_count in $(seq 1 $stripe_max); do
27725                 testdir=$DIR/$tdir-s$stripe_count
27726                 mkdir $testdir || error "mkdir $testdir failed"
27727                 mkdir $testdir/rr || error "mkdir rr failed"
27728                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27729                         error "mkdir qos failed"
27730                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27731                         $testdir/rr || error "setdirstripe rr failed"
27732                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27733                         error "setdirstripe failed"
27734                 test_qos_mkdir "mkdir" $stripe_count
27735         done
27736 }
27737 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27738
27739 test_413c() {
27740         (( $MDSCOUNT >= 2 )) ||
27741                 skip "We need at least 2 MDTs for this test"
27742
27743         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27744                 skip "Need server version at least 2.14.51"
27745
27746         local testdir
27747         local inherit
27748         local inherit_rr
27749         local lmv_qos_maxage
27750         local lod_qos_maxage
27751
27752         # let caller set maxage for latest result
27753         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27754         $LCTL set_param lmv.*.qos_maxage=1
27755         stack_trap "$LCTL set_param \
27756                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27757         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27758                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27759         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27760                 lod.*.mdt_qos_maxage=1
27761         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27762                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27763
27764         # fill MDT unevenly
27765         generate_uneven_mdts 120
27766
27767         testdir=$DIR/${tdir}-s1
27768         mkdir $testdir || error "mkdir $testdir failed"
27769         mkdir $testdir/rr || error "mkdir rr failed"
27770         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27771         # default max_inherit is -1, default max_inherit_rr is 0
27772         $LFS setdirstripe -D -c 1 $testdir/rr ||
27773                 error "setdirstripe rr failed"
27774         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27775                 error "setdirstripe qos failed"
27776         test_qos_mkdir "mkdir" 1
27777
27778         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27779         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27780         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27781         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27782         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27783
27784         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27785         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27786         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27787         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27788         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27789         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27790         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27791                 error "level2 shouldn't have default LMV" || true
27792 }
27793 run_test 413c "mkdir with default LMV max inherit rr"
27794
27795 test_413d() {
27796         (( MDSCOUNT >= 2 )) ||
27797                 skip "We need at least 2 MDTs for this test"
27798
27799         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27800                 skip "Need server version at least 2.14.51"
27801
27802         local lmv_qos_threshold_rr
27803
27804         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27805                 head -n1)
27806         stack_trap "$LCTL set_param \
27807                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27808
27809         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27810         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27811         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27812                 error "$tdir shouldn't have default LMV"
27813         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27814                 error "mkdir sub failed"
27815
27816         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27817
27818         (( count == 100 )) || error "$count subdirs on MDT0"
27819 }
27820 run_test 413d "inherit ROOT default LMV"
27821
27822 test_413e() {
27823         (( MDSCOUNT >= 2 )) ||
27824                 skip "We need at least 2 MDTs for this test"
27825         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27826                 skip "Need server version at least 2.14.55"
27827
27828         local testdir=$DIR/$tdir
27829         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27830         local max_inherit
27831         local sub_max_inherit
27832
27833         mkdir -p $testdir || error "failed to create $testdir"
27834
27835         # set default max-inherit to -1 if stripe count is 0 or 1
27836         $LFS setdirstripe -D -c 1 $testdir ||
27837                 error "failed to set default LMV"
27838         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27839         (( max_inherit == -1 )) ||
27840                 error "wrong max_inherit value $max_inherit"
27841
27842         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27843         $LFS setdirstripe -D -c -1 $testdir ||
27844                 error "failed to set default LMV"
27845         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27846         (( max_inherit > 0 )) ||
27847                 error "wrong max_inherit value $max_inherit"
27848
27849         # and the subdir will decrease the max_inherit by 1
27850         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27851         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27852         (( sub_max_inherit == max_inherit - 1)) ||
27853                 error "wrong max-inherit of subdir $sub_max_inherit"
27854
27855         # check specified --max-inherit and warning message
27856         stack_trap "rm -f $tmpfile"
27857         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27858                 error "failed to set default LMV"
27859         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27860         (( max_inherit == -1 )) ||
27861                 error "wrong max_inherit value $max_inherit"
27862
27863         # check the warning messages
27864         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27865                 error "failed to detect warning string"
27866         fi
27867 }
27868 run_test 413e "check default max-inherit value"
27869
27870 test_fs_dmv_inherit()
27871 {
27872         local testdir=$DIR/$tdir
27873
27874         local count
27875         local inherit
27876         local inherit_rr
27877
27878         for i in 1 2; do
27879                 mkdir $testdir || error "mkdir $testdir failed"
27880                 count=$($LFS getdirstripe -D -c $testdir)
27881                 (( count == 1 )) ||
27882                         error "$testdir default LMV count mismatch $count != 1"
27883                 inherit=$($LFS getdirstripe -D -X $testdir)
27884                 (( inherit == 3 - i )) ||
27885                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27886                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27887                 (( inherit_rr == 3 - i )) ||
27888                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27889                 testdir=$testdir/sub
27890         done
27891
27892         mkdir $testdir || error "mkdir $testdir failed"
27893         count=$($LFS getdirstripe -D -c $testdir)
27894         (( count == 0 )) ||
27895                 error "$testdir default LMV count not zero: $count"
27896 }
27897
27898 test_413f() {
27899         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27900
27901         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27902                 skip "Need server version at least 2.14.55"
27903
27904         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27905                 error "dump $DIR default LMV failed"
27906         stack_trap "setfattr --restore=$TMP/dmv.ea"
27907
27908         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27909                 error "set $DIR default LMV failed"
27910
27911         test_fs_dmv_inherit
27912 }
27913 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27914
27915 test_413g() {
27916         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27917
27918         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27919         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27920                 error "dump $DIR default LMV failed"
27921         stack_trap "setfattr --restore=$TMP/dmv.ea"
27922
27923         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27924                 error "set $DIR default LMV failed"
27925
27926         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27927                 error "mount $MOUNT2 failed"
27928         stack_trap "umount_client $MOUNT2"
27929
27930         local saved_DIR=$DIR
27931
27932         export DIR=$MOUNT2
27933
27934         stack_trap "export DIR=$saved_DIR"
27935
27936         # first check filesystem-wide default LMV inheritance
27937         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27938
27939         # then check subdirs are spread to all MDTs
27940         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27941
27942         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27943
27944         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27945 }
27946 run_test 413g "enforce ROOT default LMV on subdir mount"
27947
27948 test_413h() {
27949         (( MDSCOUNT >= 2 )) ||
27950                 skip "We need at least 2 MDTs for this test"
27951
27952         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27953                 skip "Need server version at least 2.15.50.6"
27954
27955         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27956
27957         stack_trap "$LCTL set_param \
27958                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27959         $LCTL set_param lmv.*.qos_maxage=1
27960
27961         local depth=5
27962         local rr_depth=4
27963         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27964         local count=$((MDSCOUNT * 20))
27965
27966         generate_uneven_mdts 50
27967
27968         mkdir -p $dir || error "mkdir $dir failed"
27969         stack_trap "rm -rf $dir"
27970         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27971                 --max-inherit-rr=$rr_depth $dir
27972
27973         for ((d=0; d < depth + 2; d++)); do
27974                 log "dir=$dir:"
27975                 for ((sub=0; sub < count; sub++)); do
27976                         mkdir $dir/d$sub
27977                 done
27978                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27979                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27980                 # subdirs within $rr_depth should be created round-robin
27981                 if (( d < rr_depth )); then
27982                         (( ${num[0]} != count )) ||
27983                                 error "all objects created on MDT ${num[1]}"
27984                 fi
27985
27986                 dir=$dir/d0
27987         done
27988 }
27989 run_test 413h "don't stick to parent for round-robin dirs"
27990
27991 test_413i() {
27992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27993
27994         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27995                 skip "Need server version at least 2.14.55"
27996
27997         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27998                 error "dump $DIR default LMV failed"
27999         stack_trap "setfattr --restore=$TMP/dmv.ea"
28000
28001         local testdir=$DIR/$tdir
28002         local def_max_rr=1
28003         local def_max=3
28004         local count
28005
28006         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28007                 --max-inherit-rr=$def_max_rr $DIR ||
28008                 error "set $DIR default LMV failed"
28009
28010         for i in $(seq 2 3); do
28011                 def_max=$((def_max - 1))
28012                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28013
28014                 mkdir $testdir
28015                 # RR is decremented and keeps zeroed once exhausted
28016                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28017                 (( count == def_max_rr )) ||
28018                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28019
28020                 # max-inherit is decremented
28021                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28022                 (( count == def_max )) ||
28023                         error_noexit "$testdir: max-inherit $count != $def_max"
28024
28025                 testdir=$testdir/d$i
28026         done
28027
28028         # d3 is the last inherited from ROOT, no inheritance anymore
28029         # i.e. no the default layout anymore
28030         mkdir -p $testdir/d4/d5
28031         count=$($LFS getdirstripe -D --max-inherit $testdir)
28032         (( count == -1 )) ||
28033                 error_noexit "$testdir: max-inherit $count != -1"
28034
28035         local p_count=$($LFS getdirstripe -i $testdir)
28036
28037         for i in $(seq 4 5); do
28038                 testdir=$testdir/d$i
28039
28040                 # the root default layout is not applied once exhausted
28041                 count=$($LFS getdirstripe -i $testdir)
28042                 (( count == p_count )) ||
28043                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28044         done
28045
28046         $LFS setdirstripe -i 0 $DIR/d2
28047         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28048         (( count == -1 )) ||
28049                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28050 }
28051 run_test 413i "check default layout inheritance"
28052
28053 test_413z() {
28054         local pids=""
28055         local subdir
28056         local pid
28057
28058         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28059                 unlinkmany $subdir/f. $TEST413_COUNT &
28060                 pids="$pids $!"
28061         done
28062
28063         for pid in $pids; do
28064                 wait $pid
28065         done
28066
28067         true
28068 }
28069 run_test 413z "413 test cleanup"
28070
28071 test_414() {
28072 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28073         $LCTL set_param fail_loc=0x80000521
28074         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28075         rm -f $DIR/$tfile
28076 }
28077 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28078
28079 test_415() {
28080         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28081         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28082                 skip "Need server version at least 2.11.52"
28083
28084         # LU-11102
28085         local total=500
28086         local max=120
28087
28088         # this test may be slow on ZFS
28089         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28090
28091         # though this test is designed for striped directory, let's test normal
28092         # directory too since lock is always saved as CoS lock.
28093         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28094         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28095         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28096         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28097         wait_delete_completed_mds
28098
28099         # run a loop without concurrent touch to measure rename duration.
28100         # only for test debug/robustness, NOT part of COS functional test.
28101         local start_time=$SECONDS
28102         for ((i = 0; i < total; i++)); do
28103                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28104                         > /dev/null
28105         done
28106         local baseline=$((SECONDS - start_time))
28107         echo "rename $total files without 'touch' took $baseline sec"
28108
28109         (
28110                 while true; do
28111                         touch $DIR/$tdir
28112                 done
28113         ) &
28114         local setattr_pid=$!
28115
28116         # rename files back to original name so unlinkmany works
28117         start_time=$SECONDS
28118         for ((i = 0; i < total; i++)); do
28119                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28120                         > /dev/null
28121         done
28122         local duration=$((SECONDS - start_time))
28123
28124         kill -9 $setattr_pid
28125
28126         echo "rename $total files with 'touch' took $duration sec"
28127         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28128         (( duration <= max )) ||
28129                 error_not_in_vm "rename took $duration > $max sec"
28130 }
28131 run_test 415 "lock revoke is not missing"
28132
28133 test_416() {
28134         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28135                 skip "Need server version at least 2.11.55"
28136
28137         # define OBD_FAIL_OSD_TXN_START    0x19a
28138         do_facet mds1 lctl set_param fail_loc=0x19a
28139
28140         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28141
28142         true
28143 }
28144 run_test 416 "transaction start failure won't cause system hung"
28145
28146 cleanup_417() {
28147         trap 0
28148         do_nodes $(comma_list $(mdts_nodes)) \
28149                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28150         do_nodes $(comma_list $(mdts_nodes)) \
28151                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28152         do_nodes $(comma_list $(mdts_nodes)) \
28153                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28154 }
28155
28156 test_417() {
28157         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28158         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28159                 skip "Need MDS version at least 2.11.56"
28160
28161         trap cleanup_417 RETURN EXIT
28162
28163         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28164         do_nodes $(comma_list $(mdts_nodes)) \
28165                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28166         $LFS migrate -m 0 $DIR/$tdir.1 &&
28167                 error "migrate dir $tdir.1 should fail"
28168
28169         do_nodes $(comma_list $(mdts_nodes)) \
28170                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28171         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28172                 error "create remote dir $tdir.2 should fail"
28173
28174         do_nodes $(comma_list $(mdts_nodes)) \
28175                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28176         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28177                 error "create striped dir $tdir.3 should fail"
28178         true
28179 }
28180 run_test 417 "disable remote dir, striped dir and dir migration"
28181
28182 # Checks that the outputs of df [-i] and lfs df [-i] match
28183 #
28184 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28185 check_lfs_df() {
28186         local dir=$2
28187         local inodes
28188         local df_out
28189         local lfs_df_out
28190         local count
28191         local passed=false
28192
28193         # blocks or inodes
28194         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28195
28196         for count in {1..100}; do
28197                 do_nodes "$CLIENTS" \
28198                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28199                 sync; sleep 0.2
28200
28201                 # read the lines of interest
28202                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28203                         error "df $inodes $dir | tail -n +2 failed"
28204                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28205                         error "lfs df $inodes $dir | grep summary: failed"
28206
28207                 # skip first substrings of each output as they are different
28208                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28209                 # compare the two outputs
28210                 passed=true
28211                 #  skip "available" on MDT until LU-13997 is fixed.
28212                 #for i in {1..5}; do
28213                 for i in 1 2 4 5; do
28214                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28215                 done
28216                 $passed && break
28217         done
28218
28219         if ! $passed; then
28220                 df -P $inodes $dir
28221                 echo
28222                 lfs df $inodes $dir
28223                 error "df and lfs df $1 output mismatch: "      \
28224                       "df ${inodes}: ${df_out[*]}, "            \
28225                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28226         fi
28227 }
28228
28229 test_418() {
28230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28231
28232         local dir=$DIR/$tdir
28233         local numfiles=$((RANDOM % 4096 + 2))
28234         local numblocks=$((RANDOM % 256 + 1))
28235
28236         wait_delete_completed
28237         test_mkdir $dir
28238
28239         # check block output
28240         check_lfs_df blocks $dir
28241         # check inode output
28242         check_lfs_df inodes $dir
28243
28244         # create a single file and retest
28245         echo "Creating a single file and testing"
28246         createmany -o $dir/$tfile- 1 &>/dev/null ||
28247                 error "creating 1 file in $dir failed"
28248         check_lfs_df blocks $dir
28249         check_lfs_df inodes $dir
28250
28251         # create a random number of files
28252         echo "Creating $((numfiles - 1)) files and testing"
28253         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28254                 error "creating $((numfiles - 1)) files in $dir failed"
28255
28256         # write a random number of blocks to the first test file
28257         echo "Writing $numblocks 4K blocks and testing"
28258         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28259                 count=$numblocks &>/dev/null ||
28260                 error "dd to $dir/${tfile}-0 failed"
28261
28262         # retest
28263         check_lfs_df blocks $dir
28264         check_lfs_df inodes $dir
28265
28266         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28267                 error "unlinking $numfiles files in $dir failed"
28268 }
28269 run_test 418 "df and lfs df outputs match"
28270
28271 test_419()
28272 {
28273         local dir=$DIR/$tdir
28274
28275         mkdir -p $dir
28276         touch $dir/file
28277
28278         cancel_lru_locks mdc
28279
28280         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28281         $LCTL set_param fail_loc=0x1410
28282         cat $dir/file
28283         $LCTL set_param fail_loc=0
28284         rm -rf $dir
28285 }
28286 run_test 419 "Verify open file by name doesn't crash kernel"
28287
28288 test_420()
28289 {
28290         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28291                 skip "Need MDS version at least 2.12.53"
28292
28293         local SAVE_UMASK=$(umask)
28294         local dir=$DIR/$tdir
28295         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28296
28297         mkdir -p $dir
28298         umask 0000
28299         mkdir -m03777 $dir/testdir
28300         ls -dn $dir/testdir
28301         # Need to remove trailing '.' when SELinux is enabled
28302         local dirperms=$(ls -dn $dir/testdir |
28303                          awk '{ sub(/\.$/, "", $1); print $1}')
28304         [ $dirperms == "drwxrwsrwt" ] ||
28305                 error "incorrect perms on $dir/testdir"
28306
28307         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28308                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28309         ls -n $dir/testdir/testfile
28310         local fileperms=$(ls -n $dir/testdir/testfile |
28311                           awk '{ sub(/\.$/, "", $1); print $1}')
28312         [ $fileperms == "-rwxr-xr-x" ] ||
28313                 error "incorrect perms on $dir/testdir/testfile"
28314
28315         umask $SAVE_UMASK
28316 }
28317 run_test 420 "clear SGID bit on non-directories for non-members"
28318
28319 test_421a() {
28320         local cnt
28321         local fid1
28322         local fid2
28323
28324         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28325                 skip "Need MDS version at least 2.12.54"
28326
28327         test_mkdir $DIR/$tdir
28328         createmany -o $DIR/$tdir/f 3
28329         cnt=$(ls -1 $DIR/$tdir | wc -l)
28330         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28331
28332         fid1=$(lfs path2fid $DIR/$tdir/f1)
28333         fid2=$(lfs path2fid $DIR/$tdir/f2)
28334         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28335
28336         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28337         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28338
28339         cnt=$(ls -1 $DIR/$tdir | wc -l)
28340         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28341
28342         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28343         createmany -o $DIR/$tdir/f 3
28344         cnt=$(ls -1 $DIR/$tdir | wc -l)
28345         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28346
28347         fid1=$(lfs path2fid $DIR/$tdir/f1)
28348         fid2=$(lfs path2fid $DIR/$tdir/f2)
28349         echo "remove using fsname $FSNAME"
28350         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28351
28352         cnt=$(ls -1 $DIR/$tdir | wc -l)
28353         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28354 }
28355 run_test 421a "simple rm by fid"
28356
28357 test_421b() {
28358         local cnt
28359         local FID1
28360         local FID2
28361
28362         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28363                 skip "Need MDS version at least 2.12.54"
28364
28365         test_mkdir $DIR/$tdir
28366         createmany -o $DIR/$tdir/f 3
28367         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28368         MULTIPID=$!
28369
28370         FID1=$(lfs path2fid $DIR/$tdir/f1)
28371         FID2=$(lfs path2fid $DIR/$tdir/f2)
28372         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28373
28374         kill -USR1 $MULTIPID
28375         wait
28376
28377         cnt=$(ls $DIR/$tdir | wc -l)
28378         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28379 }
28380 run_test 421b "rm by fid on open file"
28381
28382 test_421c() {
28383         local cnt
28384         local FIDS
28385
28386         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28387                 skip "Need MDS version at least 2.12.54"
28388
28389         test_mkdir $DIR/$tdir
28390         createmany -o $DIR/$tdir/f 3
28391         touch $DIR/$tdir/$tfile
28392         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28393         cnt=$(ls -1 $DIR/$tdir | wc -l)
28394         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28395
28396         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28397         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28398
28399         cnt=$(ls $DIR/$tdir | wc -l)
28400         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28401 }
28402 run_test 421c "rm by fid against hardlinked files"
28403
28404 test_421d() {
28405         local cnt
28406         local FIDS
28407
28408         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28409                 skip "Need MDS version at least 2.12.54"
28410
28411         test_mkdir $DIR/$tdir
28412         createmany -o $DIR/$tdir/f 4097
28413         cnt=$(ls -1 $DIR/$tdir | wc -l)
28414         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28415
28416         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28417         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28418
28419         cnt=$(ls $DIR/$tdir | wc -l)
28420         rm -rf $DIR/$tdir
28421         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28422 }
28423 run_test 421d "rmfid en masse"
28424
28425 test_421e() {
28426         local cnt
28427         local FID
28428
28429         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28430         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28431                 skip "Need MDS version at least 2.12.54"
28432
28433         mkdir -p $DIR/$tdir
28434         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28435         createmany -o $DIR/$tdir/striped_dir/f 512
28436         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28437         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28438
28439         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28440                 sed "s/[/][^:]*://g")
28441         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28442
28443         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28444         rm -rf $DIR/$tdir
28445         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28446 }
28447 run_test 421e "rmfid in DNE"
28448
28449 test_421f() {
28450         local cnt
28451         local FID
28452
28453         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28454                 skip "Need MDS version at least 2.12.54"
28455
28456         test_mkdir $DIR/$tdir
28457         touch $DIR/$tdir/f
28458         cnt=$(ls -1 $DIR/$tdir | wc -l)
28459         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28460
28461         FID=$(lfs path2fid $DIR/$tdir/f)
28462         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28463         # rmfid should fail
28464         cnt=$(ls -1 $DIR/$tdir | wc -l)
28465         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28466
28467         chmod a+rw $DIR/$tdir
28468         ls -la $DIR/$tdir
28469         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28470         # rmfid should fail
28471         cnt=$(ls -1 $DIR/$tdir | wc -l)
28472         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28473
28474         rm -f $DIR/$tdir/f
28475         $RUNAS touch $DIR/$tdir/f
28476         FID=$(lfs path2fid $DIR/$tdir/f)
28477         echo "rmfid as root"
28478         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28479         cnt=$(ls -1 $DIR/$tdir | wc -l)
28480         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28481
28482         rm -f $DIR/$tdir/f
28483         $RUNAS touch $DIR/$tdir/f
28484         cnt=$(ls -1 $DIR/$tdir | wc -l)
28485         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28486         FID=$(lfs path2fid $DIR/$tdir/f)
28487         # rmfid w/o user_fid2path mount option should fail
28488         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28489         cnt=$(ls -1 $DIR/$tdir | wc -l)
28490         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28491
28492         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28493         stack_trap "rmdir $tmpdir"
28494         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28495                 error "failed to mount client'"
28496         stack_trap "umount_client $tmpdir"
28497
28498         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28499         # rmfid should succeed
28500         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28501         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28502
28503         # rmfid shouldn't allow to remove files due to dir's permission
28504         chmod a+rwx $tmpdir/$tdir
28505         touch $tmpdir/$tdir/f
28506         ls -la $tmpdir/$tdir
28507         FID=$(lfs path2fid $tmpdir/$tdir/f)
28508         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28509         return 0
28510 }
28511 run_test 421f "rmfid checks permissions"
28512
28513 test_421g() {
28514         local cnt
28515         local FIDS
28516
28517         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28518         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28519                 skip "Need MDS version at least 2.12.54"
28520
28521         mkdir -p $DIR/$tdir
28522         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28523         createmany -o $DIR/$tdir/striped_dir/f 512
28524         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28525         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28526
28527         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28528                 sed "s/[/][^:]*://g")
28529
28530         rm -f $DIR/$tdir/striped_dir/f1*
28531         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28532         removed=$((512 - cnt))
28533
28534         # few files have been just removed, so we expect
28535         # rmfid to fail on their fids
28536         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28537         [ $removed != $errors ] && error "$errors != $removed"
28538
28539         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28540         rm -rf $DIR/$tdir
28541         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28542 }
28543 run_test 421g "rmfid to return errors properly"
28544
28545 test_421h() {
28546         local mount_other
28547         local mount_ret
28548         local rmfid_ret
28549         local old_fid
28550         local fidA
28551         local fidB
28552         local fidC
28553         local fidD
28554
28555         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28556                 skip "Need MDS version at least 2.15.53"
28557
28558         test_mkdir $DIR/$tdir
28559         test_mkdir $DIR/$tdir/subdir
28560         touch $DIR/$tdir/subdir/file0
28561         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28562         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28563         rm -f $DIR/$tdir/subdir/file0
28564         touch $DIR/$tdir/subdir/fileA
28565         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28566         echo File $DIR/$tdir/subdir/fileA FID $fidA
28567         touch $DIR/$tdir/subdir/fileB
28568         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28569         echo File $DIR/$tdir/subdir/fileB FID $fidB
28570         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28571         touch $DIR/$tdir/subdir/fileC
28572         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28573         echo File $DIR/$tdir/subdir/fileC FID $fidC
28574         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28575         touch $DIR/$tdir/fileD
28576         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28577         echo File $DIR/$tdir/fileD FID $fidD
28578
28579         # mount another client mount point with subdirectory mount
28580         export FILESET=/$tdir/subdir
28581         mount_other=${MOUNT}_other
28582         mount_client $mount_other ${MOUNT_OPTS}
28583         mount_ret=$?
28584         export FILESET=""
28585         (( mount_ret == 0 )) || error "mount $mount_other failed"
28586
28587         echo Removing FIDs:
28588         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28589         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28590         rmfid_ret=$?
28591
28592         umount_client $mount_other || error "umount $mount_other failed"
28593
28594         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28595
28596         # fileA should have been deleted
28597         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28598
28599         # fileB should have been deleted
28600         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28601
28602         # fileC should not have been deleted, fid also exists outside of fileset
28603         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28604
28605         # fileD should not have been deleted, it exists outside of fileset
28606         stat $DIR/$tdir/fileD || error "fileD deleted"
28607 }
28608 run_test 421h "rmfid with fileset mount"
28609
28610 test_422() {
28611         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28612         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28613         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28614         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28615         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28616
28617         local amc=$(at_max_get client)
28618         local amo=$(at_max_get mds1)
28619         local timeout=`lctl get_param -n timeout`
28620
28621         at_max_set 0 client
28622         at_max_set 0 mds1
28623
28624 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28625         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28626                         fail_val=$(((2*timeout + 10)*1000))
28627         touch $DIR/$tdir/d3/file &
28628         sleep 2
28629 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28630         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28631                         fail_val=$((2*timeout + 5))
28632         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28633         local pid=$!
28634         sleep 1
28635         kill -9 $pid
28636         sleep $((2 * timeout))
28637         echo kill $pid
28638         kill -9 $pid
28639         lctl mark touch
28640         touch $DIR/$tdir/d2/file3
28641         touch $DIR/$tdir/d2/file4
28642         touch $DIR/$tdir/d2/file5
28643
28644         wait
28645         at_max_set $amc client
28646         at_max_set $amo mds1
28647
28648         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28649         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28650                 error "Watchdog is always throttled"
28651 }
28652 run_test 422 "kill a process with RPC in progress"
28653
28654 stat_test() {
28655     df -h $MOUNT &
28656     df -h $MOUNT &
28657     df -h $MOUNT &
28658     df -h $MOUNT &
28659     df -h $MOUNT &
28660     df -h $MOUNT &
28661 }
28662
28663 test_423() {
28664     local _stats
28665     # ensure statfs cache is expired
28666     sleep 2;
28667
28668     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28669     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28670
28671     return 0
28672 }
28673 run_test 423 "statfs should return a right data"
28674
28675 test_424() {
28676 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28677         $LCTL set_param fail_loc=0x80000522
28678         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28679         rm -f $DIR/$tfile
28680 }
28681 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28682
28683 test_425() {
28684         test_mkdir -c -1 $DIR/$tdir
28685         $LFS setstripe -c -1 $DIR/$tdir
28686
28687         lru_resize_disable "" 100
28688         stack_trap "lru_resize_enable" EXIT
28689
28690         sleep 5
28691
28692         for i in $(seq $((MDSCOUNT * 125))); do
28693                 local t=$DIR/$tdir/$tfile_$i
28694
28695                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28696                         error_noexit "Create file $t"
28697         done
28698         stack_trap "rm -rf $DIR/$tdir" EXIT
28699
28700         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28701                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28702                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28703
28704                 [ $lock_count -le $lru_size ] ||
28705                         error "osc lock count $lock_count > lru size $lru_size"
28706         done
28707
28708         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28709                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28710                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28711
28712                 [ $lock_count -le $lru_size ] ||
28713                         error "mdc lock count $lock_count > lru size $lru_size"
28714         done
28715 }
28716 run_test 425 "lock count should not exceed lru size"
28717
28718 test_426() {
28719         splice-test -r $DIR/$tfile
28720         splice-test -rd $DIR/$tfile
28721         splice-test $DIR/$tfile
28722         splice-test -d $DIR/$tfile
28723 }
28724 run_test 426 "splice test on Lustre"
28725
28726 test_427() {
28727         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28728         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28729                 skip "Need MDS version at least 2.12.4"
28730         local log
28731
28732         mkdir $DIR/$tdir
28733         mkdir $DIR/$tdir/1
28734         mkdir $DIR/$tdir/2
28735         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28736         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28737
28738         $LFS getdirstripe $DIR/$tdir/1/dir
28739
28740         #first setfattr for creating updatelog
28741         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28742
28743 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28744         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28745         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28746         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28747
28748         sleep 2
28749         fail mds2
28750         wait_recovery_complete mds2 $((2*TIMEOUT))
28751
28752         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28753         echo $log | grep "get update log failed" &&
28754                 error "update log corruption is detected" || true
28755 }
28756 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28757
28758 test_428() {
28759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28760         local cache_limit=$CACHE_MAX
28761
28762         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28763         $LCTL set_param -n llite.*.max_cached_mb=64
28764
28765         mkdir $DIR/$tdir
28766         $LFS setstripe -c 1 $DIR/$tdir
28767         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28768         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28769         #test write
28770         for f in $(seq 4); do
28771                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28772         done
28773         wait
28774
28775         cancel_lru_locks osc
28776         # Test read
28777         for f in $(seq 4); do
28778                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28779         done
28780         wait
28781 }
28782 run_test 428 "large block size IO should not hang"
28783
28784 test_429() { # LU-7915 / LU-10948
28785         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28786         local testfile=$DIR/$tfile
28787         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28788         local new_flag=1
28789         local first_rpc
28790         local second_rpc
28791         local third_rpc
28792
28793         $LCTL get_param $ll_opencache_threshold_count ||
28794                 skip "client does not have opencache parameter"
28795
28796         set_opencache $new_flag
28797         stack_trap "restore_opencache"
28798         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28799                 error "enable opencache failed"
28800         touch $testfile
28801         # drop MDC DLM locks
28802         cancel_lru_locks mdc
28803         # clear MDC RPC stats counters
28804         $LCTL set_param $mdc_rpcstats=clear
28805
28806         # According to the current implementation, we need to run 3 times
28807         # open & close file to verify if opencache is enabled correctly.
28808         # 1st, RPCs are sent for lookup/open and open handle is released on
28809         #      close finally.
28810         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28811         #      so open handle won't be released thereafter.
28812         # 3rd, No RPC is sent out.
28813         $MULTIOP $testfile oc || error "multiop failed"
28814         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28815         echo "1st: $first_rpc RPCs in flight"
28816
28817         $MULTIOP $testfile oc || error "multiop failed"
28818         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28819         echo "2nd: $second_rpc RPCs in flight"
28820
28821         $MULTIOP $testfile oc || error "multiop failed"
28822         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28823         echo "3rd: $third_rpc RPCs in flight"
28824
28825         #verify no MDC RPC is sent
28826         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28827 }
28828 run_test 429 "verify if opencache flag on client side does work"
28829
28830 lseek_test_430() {
28831         local offset
28832         local file=$1
28833
28834         # data at [200K, 400K)
28835         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28836                 error "256K->512K dd fails"
28837         # data at [2M, 3M)
28838         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28839                 error "2M->3M dd fails"
28840         # data at [4M, 5M)
28841         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28842                 error "4M->5M dd fails"
28843         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28844         # start at first component hole #1
28845         printf "Seeking hole from 1000 ... "
28846         offset=$(lseek_test -l 1000 $file)
28847         echo $offset
28848         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28849         printf "Seeking data from 1000 ... "
28850         offset=$(lseek_test -d 1000 $file)
28851         echo $offset
28852         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28853
28854         # start at first component data block
28855         printf "Seeking hole from 300000 ... "
28856         offset=$(lseek_test -l 300000 $file)
28857         echo $offset
28858         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28859         printf "Seeking data from 300000 ... "
28860         offset=$(lseek_test -d 300000 $file)
28861         echo $offset
28862         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28863
28864         # start at the first component but beyond end of object size
28865         printf "Seeking hole from 1000000 ... "
28866         offset=$(lseek_test -l 1000000 $file)
28867         echo $offset
28868         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28869         printf "Seeking data from 1000000 ... "
28870         offset=$(lseek_test -d 1000000 $file)
28871         echo $offset
28872         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28873
28874         # start at second component stripe 2 (empty file)
28875         printf "Seeking hole from 1500000 ... "
28876         offset=$(lseek_test -l 1500000 $file)
28877         echo $offset
28878         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28879         printf "Seeking data from 1500000 ... "
28880         offset=$(lseek_test -d 1500000 $file)
28881         echo $offset
28882         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28883
28884         # start at second component stripe 1 (all data)
28885         printf "Seeking hole from 3000000 ... "
28886         offset=$(lseek_test -l 3000000 $file)
28887         echo $offset
28888         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28889         printf "Seeking data from 3000000 ... "
28890         offset=$(lseek_test -d 3000000 $file)
28891         echo $offset
28892         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28893
28894         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28895                 error "2nd dd fails"
28896         echo "Add data block at 640K...1280K"
28897
28898         # start at before new data block, in hole
28899         printf "Seeking hole from 600000 ... "
28900         offset=$(lseek_test -l 600000 $file)
28901         echo $offset
28902         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28903         printf "Seeking data from 600000 ... "
28904         offset=$(lseek_test -d 600000 $file)
28905         echo $offset
28906         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28907
28908         # start at the first component new data block
28909         printf "Seeking hole from 1000000 ... "
28910         offset=$(lseek_test -l 1000000 $file)
28911         echo $offset
28912         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28913         printf "Seeking data from 1000000 ... "
28914         offset=$(lseek_test -d 1000000 $file)
28915         echo $offset
28916         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28917
28918         # start at second component stripe 2, new data
28919         printf "Seeking hole from 1200000 ... "
28920         offset=$(lseek_test -l 1200000 $file)
28921         echo $offset
28922         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28923         printf "Seeking data from 1200000 ... "
28924         offset=$(lseek_test -d 1200000 $file)
28925         echo $offset
28926         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28927
28928         # start beyond file end
28929         printf "Using offset > filesize ... "
28930         lseek_test -l 4000000 $file && error "lseek should fail"
28931         printf "Using offset > filesize ... "
28932         lseek_test -d 4000000 $file && error "lseek should fail"
28933
28934         printf "Done\n\n"
28935 }
28936
28937 test_430a() {
28938         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28939                 skip "MDT does not support SEEK_HOLE"
28940
28941         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28942                 skip "OST does not support SEEK_HOLE"
28943
28944         local file=$DIR/$tdir/$tfile
28945
28946         mkdir -p $DIR/$tdir
28947
28948         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28949         # OST stripe #1 will have continuous data at [1M, 3M)
28950         # OST stripe #2 is empty
28951         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28952         lseek_test_430 $file
28953         rm $file
28954         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28955         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28956         lseek_test_430 $file
28957         rm $file
28958         $LFS setstripe -c2 -S 512K $file
28959         echo "Two stripes, stripe size 512K"
28960         lseek_test_430 $file
28961         rm $file
28962         # FLR with stale mirror
28963         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28964                        -N -c2 -S 1M $file
28965         echo "Mirrored file:"
28966         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28967         echo "Plain 2 stripes 1M"
28968         lseek_test_430 $file
28969         rm $file
28970 }
28971 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28972
28973 test_430b() {
28974         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28975                 skip "OST does not support SEEK_HOLE"
28976
28977         local offset
28978         local file=$DIR/$tdir/$tfile
28979
28980         mkdir -p $DIR/$tdir
28981         # Empty layout lseek should fail
28982         $MCREATE $file
28983         # seek from 0
28984         printf "Seeking hole from 0 ... "
28985         lseek_test -l 0 $file && error "lseek should fail"
28986         printf "Seeking data from 0 ... "
28987         lseek_test -d 0 $file && error "lseek should fail"
28988         rm $file
28989
28990         # 1M-hole file
28991         $LFS setstripe -E 1M -c2 -E eof $file
28992         $TRUNCATE $file 1048576
28993         printf "Seeking hole from 1000000 ... "
28994         offset=$(lseek_test -l 1000000 $file)
28995         echo $offset
28996         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28997         printf "Seeking data from 1000000 ... "
28998         lseek_test -d 1000000 $file && error "lseek should fail"
28999         rm $file
29000
29001         # full component followed by non-inited one
29002         $LFS setstripe -E 1M -c2 -E eof $file
29003         dd if=/dev/urandom of=$file bs=1M count=1
29004         printf "Seeking hole from 1000000 ... "
29005         offset=$(lseek_test -l 1000000 $file)
29006         echo $offset
29007         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29008         printf "Seeking hole from 1048576 ... "
29009         lseek_test -l 1048576 $file && error "lseek should fail"
29010         # init second component and truncate back
29011         echo "123" >> $file
29012         $TRUNCATE $file 1048576
29013         printf "Seeking hole from 1000000 ... "
29014         offset=$(lseek_test -l 1000000 $file)
29015         echo $offset
29016         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29017         printf "Seeking hole from 1048576 ... "
29018         lseek_test -l 1048576 $file && error "lseek should fail"
29019         # boundary checks for big values
29020         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29021         offset=$(lseek_test -d 0 $file.10g)
29022         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29023         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29024         offset=$(lseek_test -d 0 $file.100g)
29025         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29026         return 0
29027 }
29028 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29029
29030 test_430c() {
29031         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29032                 skip "OST does not support SEEK_HOLE"
29033
29034         local file=$DIR/$tdir/$tfile
29035         local start
29036
29037         mkdir -p $DIR/$tdir
29038         stack_trap "rm -f $file $file.tmp"
29039         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29040
29041         # cp version 8.33+ prefers lseek over fiemap
29042         local ver=$(cp --version | awk '{ print $4; exit; }')
29043
29044         echo "cp $ver installed"
29045         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29046                 start=$SECONDS
29047                 time cp -v $file $file.tmp || error "cp $file failed"
29048                 (( SECONDS - start < 5 )) || {
29049                         strace cp $file $file.tmp |&
29050                                 grep -E "open|read|seek|FIEMAP" |
29051                                 grep -A 100 $file
29052                         error "cp: too long runtime $((SECONDS - start))"
29053                 }
29054         else
29055                 echo "cp test skipped due to $ver < 8.33"
29056         fi
29057
29058         # tar version 1.29+ supports SEEK_HOLE/DATA
29059         ver=$(tar --version | awk '{ print $4; exit; }')
29060         echo "tar $ver installed"
29061         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29062                 start=$SECONDS
29063                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29064                 (( SECONDS - start < 5 )) || {
29065                         strace tar cf $file.tmp --sparse $file |&
29066                                 grep -E "open|read|seek|FIEMAP" |
29067                                 grep -A 100 $file
29068                         error "tar: too long runtime $((SECONDS - start))"
29069                 }
29070         else
29071                 echo "tar test skipped due to $ver < 1.29"
29072         fi
29073 }
29074 run_test 430c "lseek: external tools check"
29075
29076 test_431() { # LU-14187
29077         local file=$DIR/$tdir/$tfile
29078
29079         mkdir -p $DIR/$tdir
29080         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29081         dd if=/dev/urandom of=$file bs=4k count=1
29082         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29083         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29084         #define OBD_FAIL_OST_RESTART_IO 0x251
29085         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29086         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29087         cp $file $file.0
29088         cancel_lru_locks
29089         sync_all_data
29090         echo 3 > /proc/sys/vm/drop_caches
29091         diff  $file $file.0 || error "data diff"
29092 }
29093 run_test 431 "Restart transaction for IO"
29094
29095 cleanup_test_432() {
29096         do_facet mgs $LCTL nodemap_activate 0
29097         wait_nm_sync active
29098 }
29099
29100 test_432() {
29101         local tmpdir=$TMP/dir432
29102
29103         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29104                 skip "Need MDS version at least 2.14.52"
29105
29106         stack_trap cleanup_test_432 EXIT
29107         mkdir $DIR/$tdir
29108         mkdir $tmpdir
29109
29110         do_facet mgs $LCTL nodemap_activate 1
29111         wait_nm_sync active
29112         do_facet mgs $LCTL nodemap_modify --name default \
29113                 --property admin --value 1
29114         do_facet mgs $LCTL nodemap_modify --name default \
29115                 --property trusted --value 1
29116         cancel_lru_locks mdc
29117         wait_nm_sync default admin_nodemap
29118         wait_nm_sync default trusted_nodemap
29119
29120         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29121                grep -ci "Operation not permitted") -ne 0 ]; then
29122                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29123         fi
29124 }
29125 run_test 432 "mv dir from outside Lustre"
29126
29127 test_433() {
29128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29129
29130         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29131                 skip "inode cache not supported"
29132
29133         $LCTL set_param llite.*.inode_cache=0
29134         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29135
29136         local count=256
29137         local before
29138         local after
29139
29140         cancel_lru_locks mdc
29141         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29142         createmany -m $DIR/$tdir/f $count
29143         createmany -d $DIR/$tdir/d $count
29144         ls -l $DIR/$tdir > /dev/null
29145         stack_trap "rm -rf $DIR/$tdir"
29146
29147         before=$(num_objects)
29148         cancel_lru_locks mdc
29149         after=$(num_objects)
29150
29151         # sometimes even @before is less than 2 * count
29152         while (( before - after < count )); do
29153                 sleep 1
29154                 after=$(num_objects)
29155                 wait=$((wait + 1))
29156                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29157                 if (( wait > 60 )); then
29158                         error "inode slab grew from $before to $after"
29159                 fi
29160         done
29161
29162         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29163 }
29164 run_test 433 "ldlm lock cancel releases dentries and inodes"
29165
29166 test_434() {
29167         local file
29168         local getxattr_count
29169         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29170         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29171
29172         [[ $(getenforce) == "Disabled" ]] ||
29173                 skip "lsm selinux module have to be disabled for this test"
29174
29175         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29176                 error "fail to create $DIR/$tdir/ on MDT0000"
29177
29178         touch $DIR/$tdir/$tfile-{001..100}
29179
29180         # disable the xattr cache
29181         save_lustre_params client "llite.*.xattr_cache" > $p
29182         lctl set_param llite.*.xattr_cache=0
29183         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29184
29185         # clear clients mdc stats
29186         clear_stats $mdc_stat_param ||
29187                 error "fail to clear stats on mdc MDT0000"
29188
29189         for file in $DIR/$tdir/$tfile-{001..100}; do
29190                 getfattr -n security.selinux $file |&
29191                         grep -q "Operation not supported" ||
29192                         error "getxattr on security.selinux should return EOPNOTSUPP"
29193         done
29194
29195         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29196         (( getxattr_count < 100 )) ||
29197                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29198 }
29199 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29200
29201 test_440() {
29202         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29203                 source $LUSTRE/scripts/bash-completion/lustre
29204         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29205                 source /usr/share/bash-completion/completions/lustre
29206         else
29207                 skip "bash completion scripts not found"
29208         fi
29209
29210         local lctl_completions
29211         local lfs_completions
29212
29213         lctl_completions=$(_lustre_cmds lctl)
29214         if [[ ! $lctl_completions =~ "get_param" ]]; then
29215                 error "lctl bash completion failed"
29216         fi
29217
29218         lfs_completions=$(_lustre_cmds lfs)
29219         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29220                 error "lfs bash completion failed"
29221         fi
29222 }
29223 run_test 440 "bash completion for lfs, lctl"
29224
29225 prep_801() {
29226         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29227         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29228                 skip "Need server version at least 2.9.55"
29229
29230         start_full_debug_logging
29231 }
29232
29233 post_801() {
29234         stop_full_debug_logging
29235 }
29236
29237 barrier_stat() {
29238         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29239                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29240                            awk '/The barrier for/ { print $7 }')
29241                 echo $st
29242         else
29243                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29244                 echo \'$st\'
29245         fi
29246 }
29247
29248 barrier_expired() {
29249         local expired
29250
29251         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29252                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29253                           awk '/will be expired/ { print $7 }')
29254         else
29255                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29256         fi
29257
29258         echo $expired
29259 }
29260
29261 test_801a() {
29262         prep_801
29263
29264         echo "Start barrier_freeze at: $(date)"
29265         #define OBD_FAIL_BARRIER_DELAY          0x2202
29266         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29267         # Do not reduce barrier time - See LU-11873
29268         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29269
29270         sleep 2
29271         local b_status=$(barrier_stat)
29272         echo "Got barrier status at: $(date)"
29273         [ "$b_status" = "'freezing_p1'" ] ||
29274                 error "(1) unexpected barrier status $b_status"
29275
29276         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29277         wait
29278         b_status=$(barrier_stat)
29279         [ "$b_status" = "'frozen'" ] ||
29280                 error "(2) unexpected barrier status $b_status"
29281
29282         local expired=$(barrier_expired)
29283         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29284         sleep $((expired + 3))
29285
29286         b_status=$(barrier_stat)
29287         [ "$b_status" = "'expired'" ] ||
29288                 error "(3) unexpected barrier status $b_status"
29289
29290         # Do not reduce barrier time - See LU-11873
29291         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29292                 error "(4) fail to freeze barrier"
29293
29294         b_status=$(barrier_stat)
29295         [ "$b_status" = "'frozen'" ] ||
29296                 error "(5) unexpected barrier status $b_status"
29297
29298         echo "Start barrier_thaw at: $(date)"
29299         #define OBD_FAIL_BARRIER_DELAY          0x2202
29300         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29301         do_facet mgs $LCTL barrier_thaw $FSNAME &
29302
29303         sleep 2
29304         b_status=$(barrier_stat)
29305         echo "Got barrier status at: $(date)"
29306         [ "$b_status" = "'thawing'" ] ||
29307                 error "(6) unexpected barrier status $b_status"
29308
29309         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29310         wait
29311         b_status=$(barrier_stat)
29312         [ "$b_status" = "'thawed'" ] ||
29313                 error "(7) unexpected barrier status $b_status"
29314
29315         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29316         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29317         do_facet mgs $LCTL barrier_freeze $FSNAME
29318
29319         b_status=$(barrier_stat)
29320         [ "$b_status" = "'failed'" ] ||
29321                 error "(8) unexpected barrier status $b_status"
29322
29323         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29324         do_facet mgs $LCTL barrier_thaw $FSNAME
29325
29326         post_801
29327 }
29328 run_test 801a "write barrier user interfaces and stat machine"
29329
29330 test_801b() {
29331         prep_801
29332
29333         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29334         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29335         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29336         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29337         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29338
29339         cancel_lru_locks mdc
29340
29341         # 180 seconds should be long enough
29342         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29343
29344         local b_status=$(barrier_stat)
29345         [ "$b_status" = "'frozen'" ] ||
29346                 error "(6) unexpected barrier status $b_status"
29347
29348         mkdir $DIR/$tdir/d0/d10 &
29349         mkdir_pid=$!
29350
29351         touch $DIR/$tdir/d1/f13 &
29352         touch_pid=$!
29353
29354         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29355         ln_pid=$!
29356
29357         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29358         mv_pid=$!
29359
29360         rm -f $DIR/$tdir/d4/f12 &
29361         rm_pid=$!
29362
29363         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29364
29365         # To guarantee taht the 'stat' is not blocked
29366         b_status=$(barrier_stat)
29367         [ "$b_status" = "'frozen'" ] ||
29368                 error "(8) unexpected barrier status $b_status"
29369
29370         # let above commands to run at background
29371         sleep 5
29372
29373         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29374         ps -p $touch_pid || error "(10) touch should be blocked"
29375         ps -p $ln_pid || error "(11) link should be blocked"
29376         ps -p $mv_pid || error "(12) rename should be blocked"
29377         ps -p $rm_pid || error "(13) unlink should be blocked"
29378
29379         b_status=$(barrier_stat)
29380         [ "$b_status" = "'frozen'" ] ||
29381                 error "(14) unexpected barrier status $b_status"
29382
29383         do_facet mgs $LCTL barrier_thaw $FSNAME
29384         b_status=$(barrier_stat)
29385         [ "$b_status" = "'thawed'" ] ||
29386                 error "(15) unexpected barrier status $b_status"
29387
29388         wait $mkdir_pid || error "(16) mkdir should succeed"
29389         wait $touch_pid || error "(17) touch should succeed"
29390         wait $ln_pid || error "(18) link should succeed"
29391         wait $mv_pid || error "(19) rename should succeed"
29392         wait $rm_pid || error "(20) unlink should succeed"
29393
29394         post_801
29395 }
29396 run_test 801b "modification will be blocked by write barrier"
29397
29398 test_801c() {
29399         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29400
29401         prep_801
29402
29403         stop mds2 || error "(1) Fail to stop mds2"
29404
29405         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29406
29407         local b_status=$(barrier_stat)
29408         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29409                 do_facet mgs $LCTL barrier_thaw $FSNAME
29410                 error "(2) unexpected barrier status $b_status"
29411         }
29412
29413         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29414                 error "(3) Fail to rescan barrier bitmap"
29415
29416         # Do not reduce barrier time - See LU-11873
29417         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29418
29419         b_status=$(barrier_stat)
29420         [ "$b_status" = "'frozen'" ] ||
29421                 error "(4) unexpected barrier status $b_status"
29422
29423         do_facet mgs $LCTL barrier_thaw $FSNAME
29424         b_status=$(barrier_stat)
29425         [ "$b_status" = "'thawed'" ] ||
29426                 error "(5) unexpected barrier status $b_status"
29427
29428         local devname=$(mdsdevname 2)
29429
29430         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29431
29432         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29433                 error "(7) Fail to rescan barrier bitmap"
29434
29435         post_801
29436 }
29437 run_test 801c "rescan barrier bitmap"
29438
29439 test_802b() {
29440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29441         remote_mds_nodsh && skip "remote MDS with nodsh"
29442
29443         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29444                 skip "readonly option not available"
29445
29446         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29447
29448         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29449                 error "(2) Fail to copy"
29450
29451         # write back all cached data before setting MDT to readonly
29452         cancel_lru_locks
29453         sync_all_data
29454
29455         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29456         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29457
29458         echo "Modify should be refused"
29459         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29460
29461         echo "Read should be allowed"
29462         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29463                 error "(7) Read should succeed under ro mode"
29464
29465         # disable readonly
29466         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29467 }
29468 run_test 802b "be able to set MDTs to readonly"
29469
29470 test_803a() {
29471         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29472         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29473                 skip "MDS needs to be newer than 2.10.54"
29474
29475         mkdir_on_mdt0 $DIR/$tdir
29476         # Create some objects on all MDTs to trigger related logs objects
29477         for idx in $(seq $MDSCOUNT); do
29478                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29479                         $DIR/$tdir/dir${idx} ||
29480                         error "Fail to create $DIR/$tdir/dir${idx}"
29481         done
29482
29483         wait_delete_completed # ensure old test cleanups are finished
29484         sleep 3
29485         echo "before create:"
29486         $LFS df -i $MOUNT
29487         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29488
29489         for i in {1..10}; do
29490                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29491                         error "Fail to create $DIR/$tdir/foo$i"
29492         done
29493
29494         # sync ZFS-on-MDS to refresh statfs data
29495         wait_zfs_commit mds1
29496         sleep 3
29497         echo "after create:"
29498         $LFS df -i $MOUNT
29499         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29500
29501         # allow for an llog to be cleaned up during the test
29502         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29503                 error "before ($before_used) + 10 > after ($after_used)"
29504
29505         for i in {1..10}; do
29506                 rm -rf $DIR/$tdir/foo$i ||
29507                         error "Fail to remove $DIR/$tdir/foo$i"
29508         done
29509
29510         # sync ZFS-on-MDS to refresh statfs data
29511         wait_zfs_commit mds1
29512         wait_delete_completed
29513         sleep 3 # avoid MDT return cached statfs
29514         echo "after unlink:"
29515         $LFS df -i $MOUNT
29516         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29517
29518         # allow for an llog to be created during the test
29519         [ $after_used -le $((before_used + 1)) ] ||
29520                 error "after ($after_used) > before ($before_used) + 1"
29521 }
29522 run_test 803a "verify agent object for remote object"
29523
29524 test_803b() {
29525         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29526         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29527                 skip "MDS needs to be newer than 2.13.56"
29528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29529
29530         for i in $(seq 0 $((MDSCOUNT - 1))); do
29531                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29532         done
29533
29534         local before=0
29535         local after=0
29536
29537         local tmp
29538
29539         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29540         for i in $(seq 0 $((MDSCOUNT - 1))); do
29541                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29542                         awk '/getattr/ { print $2 }')
29543                 before=$((before + tmp))
29544         done
29545         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29546         for i in $(seq 0 $((MDSCOUNT - 1))); do
29547                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29548                         awk '/getattr/ { print $2 }')
29549                 after=$((after + tmp))
29550         done
29551
29552         [ $before -eq $after ] || error "getattr count $before != $after"
29553 }
29554 run_test 803b "remote object can getattr from cache"
29555
29556 test_804() {
29557         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29558         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29559                 skip "MDS needs to be newer than 2.10.54"
29560         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29561
29562         mkdir -p $DIR/$tdir
29563         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29564                 error "Fail to create $DIR/$tdir/dir0"
29565
29566         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29567         local dev=$(mdsdevname 2)
29568
29569         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29570                 grep ${fid} || error "NOT found agent entry for dir0"
29571
29572         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29573                 error "Fail to create $DIR/$tdir/dir1"
29574
29575         touch $DIR/$tdir/dir1/foo0 ||
29576                 error "Fail to create $DIR/$tdir/dir1/foo0"
29577         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29578         local rc=0
29579
29580         for idx in $(seq $MDSCOUNT); do
29581                 dev=$(mdsdevname $idx)
29582                 do_facet mds${idx} \
29583                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29584                         grep ${fid} && rc=$idx
29585         done
29586
29587         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29588                 error "Fail to rename foo0 to foo1"
29589         if [ $rc -eq 0 ]; then
29590                 for idx in $(seq $MDSCOUNT); do
29591                         dev=$(mdsdevname $idx)
29592                         do_facet mds${idx} \
29593                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29594                         grep ${fid} && rc=$idx
29595                 done
29596         fi
29597
29598         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29599                 error "Fail to rename foo1 to foo2"
29600         if [ $rc -eq 0 ]; then
29601                 for idx in $(seq $MDSCOUNT); do
29602                         dev=$(mdsdevname $idx)
29603                         do_facet mds${idx} \
29604                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29605                         grep ${fid} && rc=$idx
29606                 done
29607         fi
29608
29609         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29610
29611         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29612                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29613         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29614                 error "Fail to rename foo2 to foo0"
29615         unlink $DIR/$tdir/dir1/foo0 ||
29616                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29617         rm -rf $DIR/$tdir/dir0 ||
29618                 error "Fail to rm $DIR/$tdir/dir0"
29619
29620         for idx in $(seq $MDSCOUNT); do
29621                 rc=0
29622
29623                 stop mds${idx}
29624                 dev=$(mdsdevname $idx)
29625                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29626                         rc=$?
29627                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29628                         error "mount mds$idx failed"
29629                 df $MOUNT > /dev/null 2>&1
29630
29631                 # e2fsck should not return error
29632                 [ $rc -eq 0 ] ||
29633                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29634         done
29635 }
29636 run_test 804 "verify agent entry for remote entry"
29637
29638 cleanup_805() {
29639         do_facet $SINGLEMDS zfs set quota=$old $fsset
29640         unlinkmany $DIR/$tdir/f- 1000000
29641         trap 0
29642 }
29643
29644 test_805() {
29645         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29646         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29647         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29648                 skip "netfree not implemented before 0.7"
29649         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29650                 skip "Need MDS version at least 2.10.57"
29651
29652         local fsset
29653         local freekb
29654         local usedkb
29655         local old
29656         local quota
29657         local pref="osd-zfs.$FSNAME-MDT0000."
29658
29659         # limit available space on MDS dataset to meet nospace issue
29660         # quickly. then ZFS 0.7.2 can use reserved space if asked
29661         # properly (using netfree flag in osd_declare_destroy()
29662         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29663         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29664                 gawk '{print $3}')
29665         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29666         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29667         let "usedkb=usedkb-freekb"
29668         let "freekb=freekb/2"
29669         if let "freekb > 5000"; then
29670                 let "freekb=5000"
29671         fi
29672         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29673         trap cleanup_805 EXIT
29674         mkdir_on_mdt0 $DIR/$tdir
29675         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29676                 error "Can't set PFL layout"
29677         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29678         rm -rf $DIR/$tdir || error "not able to remove"
29679         do_facet $SINGLEMDS zfs set quota=$old $fsset
29680         trap 0
29681 }
29682 run_test 805 "ZFS can remove from full fs"
29683
29684 # Size-on-MDS test
29685 check_lsom_data()
29686 {
29687         local file=$1
29688         local expect=$(stat -c %s $file)
29689
29690         check_lsom_size $1 $expect
29691
29692         local blocks=$($LFS getsom -b $file)
29693         expect=$(stat -c %b $file)
29694         [[ $blocks == $expect ]] ||
29695                 error "$file expected blocks: $expect, got: $blocks"
29696 }
29697
29698 check_lsom_size()
29699 {
29700         local size
29701         local expect=$2
29702
29703         cancel_lru_locks mdc
29704
29705         size=$($LFS getsom -s $1)
29706         [[ $size == $expect ]] ||
29707                 error "$file expected size: $expect, got: $size"
29708 }
29709
29710 test_806() {
29711         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29712                 skip "Need MDS version at least 2.11.52"
29713
29714         local bs=1048576
29715
29716         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29717
29718         disable_opencache
29719         stack_trap "restore_opencache"
29720
29721         # single-threaded write
29722         echo "Test SOM for single-threaded write"
29723         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29724                 error "write $tfile failed"
29725         check_lsom_size $DIR/$tfile $bs
29726
29727         local num=32
29728         local size=$(($num * $bs))
29729         local offset=0
29730         local i
29731
29732         echo "Test SOM for single client multi-threaded($num) write"
29733         $TRUNCATE $DIR/$tfile 0
29734         for ((i = 0; i < $num; i++)); do
29735                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29736                 local pids[$i]=$!
29737                 offset=$((offset + $bs))
29738         done
29739         for (( i=0; i < $num; i++ )); do
29740                 wait ${pids[$i]}
29741         done
29742         check_lsom_size $DIR/$tfile $size
29743
29744         $TRUNCATE $DIR/$tfile 0
29745         for ((i = 0; i < $num; i++)); do
29746                 offset=$((offset - $bs))
29747                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29748                 local pids[$i]=$!
29749         done
29750         for (( i=0; i < $num; i++ )); do
29751                 wait ${pids[$i]}
29752         done
29753         check_lsom_size $DIR/$tfile $size
29754
29755         # multi-client writes
29756         num=$(get_node_count ${CLIENTS//,/ })
29757         size=$(($num * $bs))
29758         offset=0
29759         i=0
29760
29761         echo "Test SOM for multi-client ($num) writes"
29762         $TRUNCATE $DIR/$tfile 0
29763         for client in ${CLIENTS//,/ }; do
29764                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29765                 local pids[$i]=$!
29766                 i=$((i + 1))
29767                 offset=$((offset + $bs))
29768         done
29769         for (( i=0; i < $num; i++ )); do
29770                 wait ${pids[$i]}
29771         done
29772         check_lsom_size $DIR/$tfile $offset
29773
29774         i=0
29775         $TRUNCATE $DIR/$tfile 0
29776         for client in ${CLIENTS//,/ }; do
29777                 offset=$((offset - $bs))
29778                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29779                 local pids[$i]=$!
29780                 i=$((i + 1))
29781         done
29782         for (( i=0; i < $num; i++ )); do
29783                 wait ${pids[$i]}
29784         done
29785         check_lsom_size $DIR/$tfile $size
29786
29787         # verify SOM blocks count
29788         echo "Verify SOM block count"
29789         $TRUNCATE $DIR/$tfile 0
29790         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29791                 error "failed to write file $tfile with fdatasync and fstat"
29792         check_lsom_data $DIR/$tfile
29793
29794         $TRUNCATE $DIR/$tfile 0
29795         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29796                 error "failed to write file $tfile with fdatasync"
29797         check_lsom_data $DIR/$tfile
29798
29799         $TRUNCATE $DIR/$tfile 0
29800         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29801                 error "failed to write file $tfile with sync IO"
29802         check_lsom_data $DIR/$tfile
29803
29804         # verify truncate
29805         echo "Test SOM for truncate"
29806         # use ftruncate to sync blocks on close request
29807         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29808         check_lsom_size $DIR/$tfile 16384
29809         check_lsom_data $DIR/$tfile
29810
29811         $TRUNCATE $DIR/$tfile 1234
29812         check_lsom_size $DIR/$tfile 1234
29813         # sync blocks on the MDT
29814         $MULTIOP $DIR/$tfile oc
29815         check_lsom_data $DIR/$tfile
29816 }
29817 run_test 806 "Verify Lazy Size on MDS"
29818
29819 test_807() {
29820         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29821         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29822                 skip "Need MDS version at least 2.11.52"
29823
29824         # Registration step
29825         changelog_register || error "changelog_register failed"
29826         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29827         changelog_users $SINGLEMDS | grep -q $cl_user ||
29828                 error "User $cl_user not found in changelog_users"
29829
29830         rm -rf $DIR/$tdir || error "rm $tdir failed"
29831         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29832         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29833         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29834         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29835                 error "truncate $tdir/trunc failed"
29836
29837         local bs=1048576
29838         echo "Test SOM for single-threaded write with fsync"
29839         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29840                 error "write $tfile failed"
29841         sync;sync;sync
29842
29843         # multi-client wirtes
29844         local num=$(get_node_count ${CLIENTS//,/ })
29845         local offset=0
29846         local i=0
29847
29848         echo "Test SOM for multi-client ($num) writes"
29849         touch $DIR/$tfile || error "touch $tfile failed"
29850         $TRUNCATE $DIR/$tfile 0
29851         for client in ${CLIENTS//,/ }; do
29852                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29853                 local pids[$i]=$!
29854                 i=$((i + 1))
29855                 offset=$((offset + $bs))
29856         done
29857         for (( i=0; i < $num; i++ )); do
29858                 wait ${pids[$i]}
29859         done
29860
29861         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29862         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29863         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29864         check_lsom_data $DIR/$tdir/trunc
29865         check_lsom_data $DIR/$tdir/single_dd
29866         check_lsom_data $DIR/$tfile
29867
29868         rm -rf $DIR/$tdir
29869         # Deregistration step
29870         changelog_deregister || error "changelog_deregister failed"
29871 }
29872 run_test 807 "verify LSOM syncing tool"
29873
29874 check_som_nologged()
29875 {
29876         local lines=$($LFS changelog $FSNAME-MDT0000 |
29877                 grep 'x=trusted.som' | wc -l)
29878         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29879 }
29880
29881 test_808() {
29882         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29883                 skip "Need MDS version at least 2.11.55"
29884
29885         # Registration step
29886         changelog_register || error "changelog_register failed"
29887
29888         touch $DIR/$tfile || error "touch $tfile failed"
29889         check_som_nologged
29890
29891         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29892                 error "write $tfile failed"
29893         check_som_nologged
29894
29895         $TRUNCATE $DIR/$tfile 1234
29896         check_som_nologged
29897
29898         $TRUNCATE $DIR/$tfile 1048576
29899         check_som_nologged
29900
29901         # Deregistration step
29902         changelog_deregister || error "changelog_deregister failed"
29903 }
29904 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29905
29906 check_som_nodata()
29907 {
29908         $LFS getsom $1
29909         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29910 }
29911
29912 test_809() {
29913         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29914                 skip "Need MDS version at least 2.11.56"
29915
29916         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29917                 error "failed to create DoM-only file $DIR/$tfile"
29918         touch $DIR/$tfile || error "touch $tfile failed"
29919         check_som_nodata $DIR/$tfile
29920
29921         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29922                 error "write $tfile failed"
29923         check_som_nodata $DIR/$tfile
29924
29925         $TRUNCATE $DIR/$tfile 1234
29926         check_som_nodata $DIR/$tfile
29927
29928         $TRUNCATE $DIR/$tfile 4097
29929         check_som_nodata $DIR/$file
29930 }
29931 run_test 809 "Verify no SOM xattr store for DoM-only files"
29932
29933 test_810() {
29934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29935         $GSS && skip_env "could not run with gss"
29936         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29937                 skip "OST < 2.12.58 doesn't align checksum"
29938
29939         set_checksums 1
29940         stack_trap "set_checksums $ORIG_CSUM" EXIT
29941         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29942
29943         local csum
29944         local before
29945         local after
29946         for csum in $CKSUM_TYPES; do
29947                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29948                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29949                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29950                         eval set -- $i
29951                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29952                         before=$(md5sum $DIR/$tfile)
29953                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29954                         after=$(md5sum $DIR/$tfile)
29955                         [ "$before" == "$after" ] ||
29956                                 error "$csum: $before != $after bs=$1 seek=$2"
29957                 done
29958         done
29959 }
29960 run_test 810 "partial page writes on ZFS (LU-11663)"
29961
29962 test_812a() {
29963         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29964                 skip "OST < 2.12.51 doesn't support this fail_loc"
29965
29966         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29967         # ensure ost1 is connected
29968         stat $DIR/$tfile >/dev/null || error "can't stat"
29969         wait_osc_import_state client ost1 FULL
29970         # no locks, no reqs to let the connection idle
29971         cancel_lru_locks osc
29972
29973         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29974 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29975         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29976         wait_osc_import_state client ost1 CONNECTING
29977         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29978
29979         stat $DIR/$tfile >/dev/null || error "can't stat file"
29980 }
29981 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29982
29983 test_812b() { # LU-12378
29984         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29985                 skip "OST < 2.12.51 doesn't support this fail_loc"
29986
29987         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29988         # ensure ost1 is connected
29989         stat $DIR/$tfile >/dev/null || error "can't stat"
29990         wait_osc_import_state client ost1 FULL
29991         # no locks, no reqs to let the connection idle
29992         cancel_lru_locks osc
29993
29994         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29995 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29996         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29997         wait_osc_import_state client ost1 CONNECTING
29998         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29999
30000         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30001         wait_osc_import_state client ost1 IDLE
30002 }
30003 run_test 812b "do not drop no resend request for idle connect"
30004
30005 test_812c() {
30006         local old
30007
30008         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30009
30010         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30011         $LFS getstripe $DIR/$tfile
30012         $LCTL set_param osc.*.idle_timeout=10
30013         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30014         # ensure ost1 is connected
30015         stat $DIR/$tfile >/dev/null || error "can't stat"
30016         wait_osc_import_state client ost1 FULL
30017         # no locks, no reqs to let the connection idle
30018         cancel_lru_locks osc
30019
30020 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30021         $LCTL set_param fail_loc=0x80000533
30022         sleep 15
30023         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30024 }
30025 run_test 812c "idle import vs lock enqueue race"
30026
30027 test_813() {
30028         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30029         [ -z "$file_heat_sav" ] && skip "no file heat support"
30030
30031         local readsample
30032         local writesample
30033         local readbyte
30034         local writebyte
30035         local readsample1
30036         local writesample1
30037         local readbyte1
30038         local writebyte1
30039
30040         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30041         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30042
30043         $LCTL set_param -n llite.*.file_heat=1
30044         echo "Turn on file heat"
30045         echo "Period second: $period_second, Decay percentage: $decay_pct"
30046
30047         echo "QQQQ" > $DIR/$tfile
30048         echo "QQQQ" > $DIR/$tfile
30049         echo "QQQQ" > $DIR/$tfile
30050         cat $DIR/$tfile > /dev/null
30051         cat $DIR/$tfile > /dev/null
30052         cat $DIR/$tfile > /dev/null
30053         cat $DIR/$tfile > /dev/null
30054
30055         local out=$($LFS heat_get $DIR/$tfile)
30056
30057         $LFS heat_get $DIR/$tfile
30058         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30059         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30060         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30061         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30062
30063         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30064         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30065         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30066         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30067
30068         sleep $((period_second + 3))
30069         echo "Sleep $((period_second + 3)) seconds..."
30070         # The recursion formula to calculate the heat of the file f is as
30071         # follow:
30072         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30073         # Where Hi is the heat value in the period between time points i*I and
30074         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30075         # to the weight of Ci.
30076         out=$($LFS heat_get $DIR/$tfile)
30077         $LFS heat_get $DIR/$tfile
30078         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30079         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30080         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30081         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30082
30083         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30084                 error "read sample ($readsample) is wrong"
30085         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30086                 error "write sample ($writesample) is wrong"
30087         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30088                 error "read bytes ($readbyte) is wrong"
30089         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30090                 error "write bytes ($writebyte) is wrong"
30091
30092         echo "QQQQ" > $DIR/$tfile
30093         echo "QQQQ" > $DIR/$tfile
30094         echo "QQQQ" > $DIR/$tfile
30095         cat $DIR/$tfile > /dev/null
30096         cat $DIR/$tfile > /dev/null
30097         cat $DIR/$tfile > /dev/null
30098         cat $DIR/$tfile > /dev/null
30099
30100         sleep $((period_second + 3))
30101         echo "Sleep $((period_second + 3)) seconds..."
30102
30103         out=$($LFS heat_get $DIR/$tfile)
30104         $LFS heat_get $DIR/$tfile
30105         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30106         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30107         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30108         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30109
30110         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30111                 4 * $decay_pct) / 100") -eq 1 ] ||
30112                 error "read sample ($readsample1) is wrong"
30113         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30114                 3 * $decay_pct) / 100") -eq 1 ] ||
30115                 error "write sample ($writesample1) is wrong"
30116         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30117                 20 * $decay_pct) / 100") -eq 1 ] ||
30118                 error "read bytes ($readbyte1) is wrong"
30119         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30120                 15 * $decay_pct) / 100") -eq 1 ] ||
30121                 error "write bytes ($writebyte1) is wrong"
30122
30123         echo "Turn off file heat for the file $DIR/$tfile"
30124         $LFS heat_set -o $DIR/$tfile
30125
30126         echo "QQQQ" > $DIR/$tfile
30127         echo "QQQQ" > $DIR/$tfile
30128         echo "QQQQ" > $DIR/$tfile
30129         cat $DIR/$tfile > /dev/null
30130         cat $DIR/$tfile > /dev/null
30131         cat $DIR/$tfile > /dev/null
30132         cat $DIR/$tfile > /dev/null
30133
30134         out=$($LFS heat_get $DIR/$tfile)
30135         $LFS heat_get $DIR/$tfile
30136         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30137         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30138         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30139         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30140
30141         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30142         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30143         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30144         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30145
30146         echo "Trun on file heat for the file $DIR/$tfile"
30147         $LFS heat_set -O $DIR/$tfile
30148
30149         echo "QQQQ" > $DIR/$tfile
30150         echo "QQQQ" > $DIR/$tfile
30151         echo "QQQQ" > $DIR/$tfile
30152         cat $DIR/$tfile > /dev/null
30153         cat $DIR/$tfile > /dev/null
30154         cat $DIR/$tfile > /dev/null
30155         cat $DIR/$tfile > /dev/null
30156
30157         out=$($LFS heat_get $DIR/$tfile)
30158         $LFS heat_get $DIR/$tfile
30159         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30160         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30161         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30162         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30163
30164         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30165         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30166         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30167         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30168
30169         $LFS heat_set -c $DIR/$tfile
30170         $LCTL set_param -n llite.*.file_heat=0
30171         echo "Turn off file heat support for the Lustre filesystem"
30172
30173         echo "QQQQ" > $DIR/$tfile
30174         echo "QQQQ" > $DIR/$tfile
30175         echo "QQQQ" > $DIR/$tfile
30176         cat $DIR/$tfile > /dev/null
30177         cat $DIR/$tfile > /dev/null
30178         cat $DIR/$tfile > /dev/null
30179         cat $DIR/$tfile > /dev/null
30180
30181         out=$($LFS heat_get $DIR/$tfile)
30182         $LFS heat_get $DIR/$tfile
30183         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30184         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30185         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30186         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30187
30188         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30189         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30190         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30191         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30192
30193         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30194         rm -f $DIR/$tfile
30195 }
30196 run_test 813 "File heat verfication"
30197
30198 test_814()
30199 {
30200         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30201         echo -n y >> $DIR/$tfile
30202         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30203         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30204 }
30205 run_test 814 "sparse cp works as expected (LU-12361)"
30206
30207 test_815()
30208 {
30209         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30210         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30211 }
30212 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30213
30214 test_816() {
30215         local ost1_imp=$(get_osc_import_name client ost1)
30216         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30217                          cut -d'.' -f2)
30218
30219         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30220         # ensure ost1 is connected
30221
30222         stat $DIR/$tfile >/dev/null || error "can't stat"
30223         wait_osc_import_state client ost1 FULL
30224         # no locks, no reqs to let the connection idle
30225         cancel_lru_locks osc
30226         lru_resize_disable osc
30227         local before
30228         local now
30229         before=$($LCTL get_param -n \
30230                  ldlm.namespaces.$imp_name.lru_size)
30231
30232         wait_osc_import_state client ost1 IDLE
30233         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30234         now=$($LCTL get_param -n \
30235               ldlm.namespaces.$imp_name.lru_size)
30236         [ $before == $now ] || error "lru_size changed $before != $now"
30237 }
30238 run_test 816 "do not reset lru_resize on idle reconnect"
30239
30240 cleanup_817() {
30241         umount $tmpdir
30242         exportfs -u localhost:$DIR/nfsexp
30243         rm -rf $DIR/nfsexp
30244 }
30245
30246 test_817() {
30247         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30248
30249         mkdir -p $DIR/nfsexp
30250         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30251                 error "failed to export nfs"
30252
30253         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30254         stack_trap cleanup_817 EXIT
30255
30256         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30257                 error "failed to mount nfs to $tmpdir"
30258
30259         cp /bin/true $tmpdir
30260         $DIR/nfsexp/true || error "failed to execute 'true' command"
30261 }
30262 run_test 817 "nfsd won't cache write lock for exec file"
30263
30264 test_818() {
30265         test_mkdir -i0 -c1 $DIR/$tdir
30266         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30267         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30268         stop $SINGLEMDS
30269
30270         # restore osp-syn threads
30271         stack_trap "fail $SINGLEMDS"
30272
30273         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30274         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30275         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30276                 error "start $SINGLEMDS failed"
30277         rm -rf $DIR/$tdir
30278
30279         local testid=$(echo $TESTNAME | tr '_' ' ')
30280
30281         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30282                 grep "run LFSCK" || error "run LFSCK is not suggested"
30283 }
30284 run_test 818 "unlink with failed llog"
30285
30286 test_819a() {
30287         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30288         cancel_lru_locks osc
30289         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30290         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30291         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30292         rm -f $TDIR/$tfile
30293 }
30294 run_test 819a "too big niobuf in read"
30295
30296 test_819b() {
30297         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30298         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30299         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30300         cancel_lru_locks osc
30301         sleep 1
30302         rm -f $TDIR/$tfile
30303 }
30304 run_test 819b "too big niobuf in write"
30305
30306
30307 function test_820_start_ost() {
30308         sleep 5
30309
30310         for num in $(seq $OSTCOUNT); do
30311                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30312         done
30313 }
30314
30315 test_820() {
30316         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30317
30318         mkdir $DIR/$tdir
30319         umount_client $MOUNT || error "umount failed"
30320         for num in $(seq $OSTCOUNT); do
30321                 stop ost$num
30322         done
30323
30324         # mount client with no active OSTs
30325         # so that the client can't initialize max LOV EA size
30326         # from OSC notifications
30327         mount_client $MOUNT || error "mount failed"
30328         # delay OST starting to keep this 0 max EA size for a while
30329         test_820_start_ost &
30330
30331         # create a directory on MDS2
30332         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30333                 error "Failed to create directory"
30334         # open intent should update default EA size
30335         # see mdc_update_max_ea_from_body()
30336         # notice this is the very first RPC to MDS2
30337         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30338         ret=$?
30339         echo $out
30340         # With SSK, this situation can lead to -EPERM being returned.
30341         # In that case, simply retry.
30342         if [ $ret -ne 0 ] && $SHARED_KEY; then
30343                 if echo "$out" | grep -q "not permitted"; then
30344                         cp /etc/services $DIR/$tdir/mds2
30345                         ret=$?
30346                 fi
30347         fi
30348         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30349 }
30350 run_test 820 "update max EA from open intent"
30351
30352 test_823() {
30353         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30354         local OST_MAX_PRECREATE=20000
30355
30356         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30357                 skip "Need MDS version at least 2.14.56"
30358
30359         save_lustre_params mds1 \
30360                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30361         do_facet $SINGLEMDS "$LCTL set_param -n \
30362                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30363         do_facet $SINGLEMDS "$LCTL set_param -n \
30364                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30365
30366         stack_trap "restore_lustre_params < $p; rm $p"
30367
30368         do_facet $SINGLEMDS "$LCTL set_param -n \
30369                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30370
30371         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30372                       osp.$FSNAME-OST0000*MDT0000.create_count")
30373         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30374                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30375         local expect_count=$(((($max/2)/256) * 256))
30376
30377         log "setting create_count to 100200:"
30378         log " -result- count: $count with max: $max, expecting: $expect_count"
30379
30380         [[ $count -eq expect_count ]] ||
30381                 error "Create count not set to max precreate."
30382 }
30383 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30384
30385 test_831() {
30386         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30387                 skip "Need MDS version 2.14.56"
30388
30389         local sync_changes=$(do_facet $SINGLEMDS \
30390                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30391
30392         [ "$sync_changes" -gt 100 ] &&
30393                 skip "Sync changes $sync_changes > 100 already"
30394
30395         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30396
30397         $LFS mkdir -i 0 $DIR/$tdir
30398         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30399
30400         save_lustre_params mds1 \
30401                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30402         save_lustre_params mds1 \
30403                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30404
30405         do_facet mds1 "$LCTL set_param -n \
30406                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30407                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30408         stack_trap "restore_lustre_params < $p" EXIT
30409
30410         createmany -o $DIR/$tdir/f- 1000
30411         unlinkmany $DIR/$tdir/f- 1000 &
30412         local UNLINK_PID=$!
30413
30414         while sleep 1; do
30415                 sync_changes=$(do_facet mds1 \
30416                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30417                 # the check in the code is racy, fail the test
30418                 # if the value above the limit by 10.
30419                 [ $sync_changes -gt 110 ] && {
30420                         kill -2 $UNLINK_PID
30421                         wait
30422                         error "osp changes throttling failed, $sync_changes>110"
30423                 }
30424                 kill -0 $UNLINK_PID 2> /dev/null || break
30425         done
30426         wait
30427 }
30428 run_test 831 "throttling unlink/setattr queuing on OSP"
30429
30430 test_832() {
30431         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30432         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30433                 skip "Need MDS version 2.15.52+"
30434         is_rmentry_supported || skip "rm_entry not supported"
30435
30436         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30437         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30438         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30439                 error "mkdir remote_dir failed"
30440         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30441                 error "mkdir striped_dir failed"
30442         touch $DIR/$tdir/file || error "touch file failed"
30443         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30444         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30445 }
30446 run_test 832 "lfs rm_entry"
30447
30448 test_833() {
30449         local file=$DIR/$tfile
30450
30451         stack_trap "rm -f $file" EXIT
30452         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30453
30454         local wpid
30455         local rpid
30456         local rpid2
30457
30458         # Buffered I/O write
30459         (
30460                 while [ ! -e $DIR/sanity.833.lck ]; do
30461                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30462                                 error "failed to write $file"
30463                         sleep 0.$((RANDOM % 4 + 1))
30464                 done
30465         )&
30466         wpid=$!
30467
30468         # Buffered I/O read
30469         (
30470                 while [ ! -e $DIR/sanity.833.lck ]; do
30471                         dd if=$file of=/dev/null bs=1M count=50 ||
30472                                 error "failed to read $file"
30473                         sleep 0.$((RANDOM % 4 + 1))
30474                 done
30475         )&
30476         rpid=$!
30477
30478         # Direct I/O read
30479         (
30480                 while [ ! -e $DIR/sanity.833.lck ]; do
30481                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30482                                 error "failed to read $file in direct I/O mode"
30483                         sleep 0.$((RANDOM % 4 + 1))
30484                 done
30485         )&
30486         rpid2=$!
30487
30488         sleep 30
30489         touch $DIR/sanity.833.lck
30490         wait $wpid || error "$?: buffered write failed"
30491         wait $rpid || error "$?: buffered read failed"
30492         wait $rpid2 || error "$?: direct read failed"
30493 }
30494 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30495
30496 #
30497 # tests that do cleanup/setup should be run at the end
30498 #
30499
30500 test_900() {
30501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30502         local ls
30503
30504         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30505         $LCTL set_param fail_loc=0x903
30506
30507         cancel_lru_locks MGC
30508
30509         FAIL_ON_ERROR=true cleanup
30510         FAIL_ON_ERROR=true setup
30511 }
30512 run_test 900 "umount should not race with any mgc requeue thread"
30513
30514 # LUS-6253/LU-11185
30515 test_901() {
30516         local old
30517         local count
30518         local oldc
30519         local newc
30520         local olds
30521         local news
30522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30523
30524         # some get_param have a bug to handle dot in param name
30525         cancel_lru_locks MGC
30526         old=$(mount -t lustre | wc -l)
30527         # 1 config+sptlrpc
30528         # 2 params
30529         # 3 nodemap
30530         # 4 IR
30531         old=$((old * 4))
30532         oldc=0
30533         count=0
30534         while [ $old -ne $oldc ]; do
30535                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30536                 sleep 1
30537                 ((count++))
30538                 if [ $count -ge $TIMEOUT ]; then
30539                         error "too large timeout"
30540                 fi
30541         done
30542         umount_client $MOUNT || error "umount failed"
30543         mount_client $MOUNT || error "mount failed"
30544         cancel_lru_locks MGC
30545         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30546
30547         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30548
30549         return 0
30550 }
30551 run_test 901 "don't leak a mgc lock on client umount"
30552
30553 # LU-13377
30554 test_902() {
30555         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30556                 skip "client does not have LU-13377 fix"
30557         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30558         $LCTL set_param fail_loc=0x1415
30559         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30560         cancel_lru_locks osc
30561         rm -f $DIR/$tfile
30562 }
30563 run_test 902 "test short write doesn't hang lustre"
30564
30565 # LU-14711
30566 test_903() {
30567         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30568         echo "blah" > $DIR/${tfile}-2
30569         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30570         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30571         $LCTL set_param fail_loc=0x417 fail_val=20
30572
30573         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30574         sleep 1 # To start the destroy
30575         wait_destroy_complete 150 || error "Destroy taking too long"
30576         cat $DIR/$tfile > /dev/null || error "Evicted"
30577 }
30578 run_test 903 "Test long page discard does not cause evictions"
30579
30580 test_904() {
30581         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30582         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30583                 grep -q project || skip "skip project quota not supported"
30584
30585         local testfile="$DIR/$tdir/$tfile"
30586         local xattr="trusted.projid"
30587         local projid
30588         local mdts=$(comma_list $(mdts_nodes))
30589         local saved=$(do_facet mds1 $LCTL get_param -n \
30590                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30591
30592         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30593         stack_trap "do_nodes $mdts $LCTL set_param \
30594                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30595
30596         mkdir -p $DIR/$tdir
30597         touch $testfile
30598         #hide projid xattr on server
30599         $LFS project -p 1 $testfile ||
30600                 error "set $testfile project id failed"
30601         getfattr -m - $testfile | grep $xattr &&
30602                 error "do not show trusted.projid when disabled on server"
30603         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30604         #should be hidden when projid is 0
30605         $LFS project -p 0 $testfile ||
30606                 error "set $testfile project id failed"
30607         getfattr -m - $testfile | grep $xattr &&
30608                 error "do not show trusted.projid with project ID 0"
30609
30610         #still can getxattr explicitly
30611         projid=$(getfattr -n $xattr $testfile |
30612                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30613         [ $projid == "0" ] ||
30614                 error "projid expected 0 not $projid"
30615
30616         #set the projid via setxattr
30617         setfattr -n $xattr -v "1000" $testfile ||
30618                 error "setattr failed with $?"
30619         projid=($($LFS project $testfile))
30620         [ ${projid[0]} == "1000" ] ||
30621                 error "projid expected 1000 not $projid"
30622
30623         #check the new projid via getxattr
30624         $LFS project -p 1001 $testfile ||
30625                 error "set $testfile project id failed"
30626         getfattr -m - $testfile | grep $xattr ||
30627                 error "should show trusted.projid when project ID != 0"
30628         projid=$(getfattr -n $xattr $testfile |
30629                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30630         [ $projid == "1001" ] ||
30631                 error "projid expected 1001 not $projid"
30632
30633         #try to set invalid projid
30634         setfattr -n $xattr -v "4294967295" $testfile &&
30635                 error "set invalid projid should fail"
30636
30637         #remove the xattr means setting projid to 0
30638         setfattr -x $xattr $testfile ||
30639                 error "setfattr failed with $?"
30640         projid=($($LFS project $testfile))
30641         [ ${projid[0]} == "0" ] ||
30642                 error "projid expected 0 not $projid"
30643
30644         #should be hidden when parent has inherit flag and same projid
30645         $LFS project -srp 1002 $DIR/$tdir ||
30646                 error "set $tdir project id failed"
30647         getfattr -m - $testfile | grep $xattr &&
30648                 error "do not show trusted.projid with inherit flag"
30649
30650         #still can getxattr explicitly
30651         projid=$(getfattr -n $xattr $testfile |
30652                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30653         [ $projid == "1002" ] ||
30654                 error "projid expected 1002 not $projid"
30655 }
30656 run_test 904 "virtual project ID xattr"
30657
30658 # LU-8582
30659 test_905() {
30660         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30661                 skip "need OST version >= 2.15.50.220 for fail_loc"
30662
30663         remote_ost_nodsh && skip "remote OST with nodsh"
30664         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30665
30666         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30667
30668         #define OBD_FAIL_OST_OPCODE 0x253
30669         # OST_LADVISE = 21
30670         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30671         $LFS ladvise -a willread $DIR/$tfile &&
30672                 error "unexpected success of ladvise with fault injection"
30673         $LFS ladvise -a willread $DIR/$tfile |&
30674                 grep -q "Operation not supported"
30675         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30676 }
30677 run_test 905 "bad or new opcode should not stuck client"
30678
30679 test_906() {
30680         grep -q io_uring_setup /proc/kallsyms ||
30681                 skip "Client OS does not support io_uring I/O engine"
30682         io_uring_probe || skip "kernel does not support io_uring fully"
30683         which fio || skip_env "no fio installed"
30684         fio --enghelp | grep -q io_uring ||
30685                 skip_env "fio does not support io_uring I/O engine"
30686
30687         local file=$DIR/$tfile
30688         local ioengine="io_uring"
30689         local numjobs=2
30690         local size=50M
30691
30692         fio --name=seqwrite --ioengine=$ioengine        \
30693                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30694                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30695                 error "fio seqwrite $file failed"
30696
30697         fio --name=seqread --ioengine=$ioengine \
30698                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30699                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30700                 error "fio seqread $file failed"
30701
30702         rm -f $file || error "rm -f $file failed"
30703 }
30704 run_test 906 "Simple test for io_uring I/O engine via fio"
30705
30706 complete_test $SECONDS
30707 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30708 check_and_cleanup_lustre
30709 if [ "$I_MOUNTED" != "yes" ]; then
30710         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30711 fi
30712 exit_status