Whamcloud - gitweb
LU-15235 tests: skip sanity/56od in interop
[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         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14491         echo "stats before reset"
14492         stack_trap "rm -f $tmpfile"
14493         local now=$(date +%s)
14494
14495         $LCTL get_param osc.*.stats | tee $tmpfile
14496
14497         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14498         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14499         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14500         local uptime=$(awk '{ print $1 }' /proc/uptime)
14501
14502         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14503         (( ${snapshot_time%\.*} >= $now - 5 &&
14504            ${snapshot_time%\.*} <= $now + 5 )) ||
14505                 error "snapshot_time=$snapshot_time != now=$now"
14506         # elapsed _should_ be from mount, but at least less than uptime
14507         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14508                 error "elapsed=$elapsed > uptime=$uptime"
14509         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14510            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14511                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14512
14513         $LCTL set_param osc.*.stats=0
14514         local reset=$(date +%s)
14515         local fsize=$((2048 * 1024))
14516
14517         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14518         cancel_lru_locks osc
14519         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14520
14521         now=$(date +%s)
14522         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14523         while read name count samp unit min max sum sumsq; do
14524                 [[ "$samp" == "samples" ]] || continue
14525
14526                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14527                 [ ! $min ] && error "Missing min value for $name proc entry"
14528                 eval $name=$count || error "Wrong proc format"
14529
14530                 case $name in
14531                 read_bytes|write_bytes)
14532                         [[ "$unit" =~ "bytes" ]] ||
14533                                 error "unit is not 'bytes': $unit"
14534                         (( $min >= 4096 )) || error "min is too small: $min"
14535                         (( $min <= $fsize )) || error "min is too big: $min"
14536                         (( $max >= 4096 )) || error "max is too small: $max"
14537                         (( $max <= $fsize )) || error "max is too big: $max"
14538                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14539                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14540                                 error "sumsquare is too small: $sumsq"
14541                         (( $sumsq <= $fsize * $fsize )) ||
14542                                 error "sumsquare is too big: $sumsq"
14543                         ;;
14544                 ost_read|ost_write)
14545                         [[ "$unit" =~ "usec" ]] ||
14546                                 error "unit is not 'usec': $unit"
14547                         ;;
14548                 *)      ;;
14549                 esac
14550         done < $tmpfile
14551
14552         #check that we actually got some stats
14553         [ "$read_bytes" ] || error "Missing read_bytes stats"
14554         [ "$write_bytes" ] || error "Missing write_bytes stats"
14555         [ "$read_bytes" != 0 ] || error "no read done"
14556         [ "$write_bytes" != 0 ] || error "no write done"
14557
14558         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14559         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14560         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14561
14562         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14563         (( ${snapshot_time%\.*} >= $now - 5 &&
14564            ${snapshot_time%\.*} <= $now + 5 )) ||
14565                 error "reset snapshot_time=$snapshot_time != now=$now"
14566         # elapsed should be from time of stats reset
14567         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14568            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14569                 error "reset elapsed=$elapsed > $now - $reset"
14570         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14571            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14572                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14573 }
14574 run_test 127a "verify the client stats are sane"
14575
14576 test_127b() { # bug LU-333
14577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14578         local name count samp unit min max sum sumsq
14579
14580         echo "stats before reset"
14581         $LCTL get_param llite.*.stats
14582         $LCTL set_param llite.*.stats=0
14583
14584         # perform 2 reads and writes so MAX is different from SUM.
14585         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14586         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14587         cancel_lru_locks osc
14588         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14589         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14590
14591         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14592         stack_trap "rm -f $TMP/$tfile.tmp"
14593         while read name count samp unit min max sum sumsq; do
14594                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14595                 eval $name=$count || error "Wrong proc format"
14596
14597                 case $name in
14598                 read_bytes|write_bytes)
14599                         [[ "$unit" =~ "bytes" ]] ||
14600                                 error "unit is not 'bytes': $unit"
14601                         (( $count == 2 )) || error "count is not 2: $count"
14602                         (( $min == $PAGE_SIZE )) ||
14603                                 error "min is not $PAGE_SIZE: $min"
14604                         (( $max == $PAGE_SIZE )) ||
14605                                 error "max is not $PAGE_SIZE: $max"
14606                         (( $sum == $PAGE_SIZE * 2 )) ||
14607                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14608                         ;;
14609                 read|write)
14610                         [[ "$unit" =~ "usec" ]] ||
14611                                 error "unit is not 'usec': $unit"
14612                         ;;
14613                 *)      ;;
14614                 esac
14615         done < $TMP/$tfile.tmp
14616
14617         #check that we actually got some stats
14618         [ "$read_bytes" ] || error "Missing read_bytes stats"
14619         [ "$write_bytes" ] || error "Missing write_bytes stats"
14620         [ "$read_bytes" != 0 ] || error "no read done"
14621         [ "$write_bytes" != 0 ] || error "no write done"
14622 }
14623 run_test 127b "verify the llite client stats are sane"
14624
14625 test_127c() { # LU-12394
14626         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14627         local size
14628         local bsize
14629         local reads
14630         local writes
14631         local count
14632
14633         $LCTL set_param llite.*.extents_stats=1
14634         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14635
14636         # Use two stripes so there is enough space in default config
14637         $LFS setstripe -c 2 $DIR/$tfile
14638
14639         # Extent stats start at 0-4K and go in power of two buckets
14640         # LL_HIST_START = 12 --> 2^12 = 4K
14641         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14642         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14643         # small configs
14644         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14645                 do
14646                 # Write and read, 2x each, second time at a non-zero offset
14647                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14648                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14649                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14650                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14651                 rm -f $DIR/$tfile
14652         done
14653
14654         $LCTL get_param llite.*.extents_stats
14655
14656         count=2
14657         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14658                 do
14659                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14660                                 grep -m 1 $bsize)
14661                 reads=$(echo $bucket | awk '{print $5}')
14662                 writes=$(echo $bucket | awk '{print $9}')
14663                 [ "$reads" -eq $count ] ||
14664                         error "$reads reads in < $bsize bucket, expect $count"
14665                 [ "$writes" -eq $count ] ||
14666                         error "$writes writes in < $bsize bucket, expect $count"
14667         done
14668
14669         # Test mmap write and read
14670         $LCTL set_param llite.*.extents_stats=c
14671         size=512
14672         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14673         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14674         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14675
14676         $LCTL get_param llite.*.extents_stats
14677
14678         count=$(((size*1024) / PAGE_SIZE))
14679
14680         bsize=$((2 * PAGE_SIZE / 1024))K
14681
14682         bucket=$($LCTL get_param -n llite.*.extents_stats |
14683                         grep -m 1 $bsize)
14684         reads=$(echo $bucket | awk '{print $5}')
14685         writes=$(echo $bucket | awk '{print $9}')
14686         # mmap writes fault in the page first, creating an additonal read
14687         [ "$reads" -eq $((2 * count)) ] ||
14688                 error "$reads reads in < $bsize bucket, expect $count"
14689         [ "$writes" -eq $count ] ||
14690                 error "$writes writes in < $bsize bucket, expect $count"
14691 }
14692 run_test 127c "test llite extent stats with regular & mmap i/o"
14693
14694 test_128() { # bug 15212
14695         touch $DIR/$tfile
14696         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14697                 find $DIR/$tfile
14698                 find $DIR/$tfile
14699         EOF
14700
14701         result=$(grep error $TMP/$tfile.log)
14702         rm -f $DIR/$tfile $TMP/$tfile.log
14703         [ -z "$result" ] ||
14704                 error "consecutive find's under interactive lfs failed"
14705 }
14706 run_test 128 "interactive lfs for 2 consecutive find's"
14707
14708 set_dir_limits () {
14709         local mntdev
14710         local canondev
14711         local node
14712
14713         local ldproc=/proc/fs/ldiskfs
14714         local facets=$(get_facets MDS)
14715
14716         for facet in ${facets//,/ }; do
14717                 canondev=$(ldiskfs_canon \
14718                            *.$(convert_facet2label $facet).mntdev $facet)
14719                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14720                         ldproc=/sys/fs/ldiskfs
14721                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14722                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14723         done
14724 }
14725
14726 check_mds_dmesg() {
14727         local facets=$(get_facets MDS)
14728         for facet in ${facets//,/ }; do
14729                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14730         done
14731         return 1
14732 }
14733
14734 test_129() {
14735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14736         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14737                 skip "Need MDS version with at least 2.5.56"
14738         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14739                 skip_env "ldiskfs only test"
14740         fi
14741         remote_mds_nodsh && skip "remote MDS with nodsh"
14742
14743         local ENOSPC=28
14744         local has_warning=false
14745
14746         rm -rf $DIR/$tdir
14747         mkdir -p $DIR/$tdir
14748
14749         # block size of mds1
14750         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14751         set_dir_limits $maxsize $((maxsize * 6 / 8))
14752         stack_trap "set_dir_limits 0 0"
14753         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14754         local dirsize=$(stat -c%s "$DIR/$tdir")
14755         local nfiles=0
14756         while (( $dirsize <= $maxsize )); do
14757                 $MCREATE $DIR/$tdir/file_base_$nfiles
14758                 rc=$?
14759                 # check two errors:
14760                 # ENOSPC for ext4 max_dir_size, which has been used since
14761                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14762                 if (( rc == ENOSPC )); then
14763                         set_dir_limits 0 0
14764                         echo "rc=$rc returned as expected after $nfiles files"
14765
14766                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14767                                 error "create failed w/o dir size limit"
14768
14769                         # messages may be rate limited if test is run repeatedly
14770                         check_mds_dmesg '"is approaching max"' ||
14771                                 echo "warning message should be output"
14772                         check_mds_dmesg '"has reached max"' ||
14773                                 echo "reached message should be output"
14774
14775                         dirsize=$(stat -c%s "$DIR/$tdir")
14776
14777                         [[ $dirsize -ge $maxsize ]] && return 0
14778                         error "dirsize $dirsize < $maxsize after $nfiles files"
14779                 elif (( rc != 0 )); then
14780                         break
14781                 fi
14782                 nfiles=$((nfiles + 1))
14783                 dirsize=$(stat -c%s "$DIR/$tdir")
14784         done
14785
14786         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14787 }
14788 run_test 129 "test directory size limit ========================"
14789
14790 OLDIFS="$IFS"
14791 cleanup_130() {
14792         trap 0
14793         IFS="$OLDIFS"
14794         rm -f $DIR/$tfile
14795 }
14796
14797 test_130a() {
14798         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14799         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14800
14801         trap cleanup_130 EXIT RETURN
14802
14803         local fm_file=$DIR/$tfile
14804         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14805         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14806                 error "dd failed for $fm_file"
14807
14808         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14809         filefrag -ves $fm_file
14810         local rc=$?
14811         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14812                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14813         (( $rc == 0 )) || error "filefrag $fm_file failed"
14814
14815         filefrag_op=$(filefrag -ve -k $fm_file |
14816                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14817         local lun=$($LFS getstripe -i $fm_file)
14818
14819         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14820         IFS=$'\n'
14821         local tot_len=0
14822         for line in $filefrag_op; do
14823                 local frag_lun=$(echo $line | cut -d: -f5)
14824                 local ext_len=$(echo $line | cut -d: -f4)
14825
14826                 if (( $frag_lun != $lun )); then
14827                         error "FIEMAP on 1-stripe file($fm_file) failed"
14828                         return
14829                 fi
14830                 (( tot_len += ext_len ))
14831         done
14832
14833         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14834                 error "FIEMAP on 1-stripe file($fm_file) failed"
14835                 return
14836         fi
14837
14838         echo "FIEMAP on single striped file succeeded"
14839 }
14840 run_test 130a "FIEMAP (1-stripe file)"
14841
14842 test_130b() {
14843         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14844
14845         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14846         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14847         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14848                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14849
14850         trap cleanup_130 EXIT RETURN
14851
14852         local fm_file=$DIR/$tfile
14853         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14854                 error "setstripe on $fm_file"
14855
14856         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14857                 error "dd failed on $fm_file"
14858
14859         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14860         filefrag_op=$(filefrag -ve -k $fm_file |
14861                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14862
14863         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14864                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14865
14866         IFS=$'\n'
14867         local tot_len=0
14868         local num_luns=1
14869
14870         for line in $filefrag_op; do
14871                 local frag_lun=$(echo $line | cut -d: -f5 |
14872                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14873                 local ext_len=$(echo $line | cut -d: -f4)
14874                 if (( $frag_lun != $last_lun )); then
14875                         if (( tot_len != 1024 )); then
14876                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14877                                 return
14878                         else
14879                                 (( num_luns += 1 ))
14880                                 tot_len=0
14881                         fi
14882                 fi
14883                 (( tot_len += ext_len ))
14884                 last_lun=$frag_lun
14885         done
14886         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14887                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14888                 return
14889         fi
14890
14891         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14892 }
14893 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14894
14895 test_130c() {
14896         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14897
14898         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14899         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14900         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14901                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14902
14903         trap cleanup_130 EXIT RETURN
14904
14905         local fm_file=$DIR/$tfile
14906         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14907
14908         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14909                 error "dd failed on $fm_file"
14910
14911         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14912         filefrag_op=$(filefrag -ve -k $fm_file |
14913                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14914
14915         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14916                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14917
14918         IFS=$'\n'
14919         local tot_len=0
14920         local num_luns=1
14921         for line in $filefrag_op; do
14922                 local frag_lun=$(echo $line | cut -d: -f5 |
14923                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14924                 local ext_len=$(echo $line | cut -d: -f4)
14925                 if (( $frag_lun != $last_lun )); then
14926                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14927                         if (( logical != 512 )); then
14928                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14929                                 return
14930                         fi
14931                         if (( tot_len != 512 )); then
14932                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14933                                 return
14934                         else
14935                                 (( num_luns += 1 ))
14936                                 tot_len=0
14937                         fi
14938                 fi
14939                 (( tot_len += ext_len ))
14940                 last_lun=$frag_lun
14941         done
14942         if (( num_luns != 2 || tot_len != 512 )); then
14943                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14944                 return
14945         fi
14946
14947         echo "FIEMAP on 2-stripe file with hole succeeded"
14948 }
14949 run_test 130c "FIEMAP (2-stripe file with hole)"
14950
14951 test_130d() {
14952         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14953
14954         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14955         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14956         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14957                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14958
14959         trap cleanup_130 EXIT RETURN
14960
14961         local fm_file=$DIR/$tfile
14962         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14963                         error "setstripe on $fm_file"
14964
14965         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14966         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14967                 error "dd failed on $fm_file"
14968
14969         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14970         filefrag_op=$(filefrag -ve -k $fm_file |
14971                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14972
14973         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14974                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14975
14976         IFS=$'\n'
14977         local tot_len=0
14978         local num_luns=1
14979         for line in $filefrag_op; do
14980                 local frag_lun=$(echo $line | cut -d: -f5 |
14981                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14982                 local ext_len=$(echo $line | cut -d: -f4)
14983                 if (( $frag_lun != $last_lun )); then
14984                         if (( tot_len != 1024 )); then
14985                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14986                                 return
14987                         else
14988                                 (( num_luns += 1 ))
14989                                 local tot_len=0
14990                         fi
14991                 fi
14992                 (( tot_len += ext_len ))
14993                 last_lun=$frag_lun
14994         done
14995         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14996                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14997                 return
14998         fi
14999
15000         echo "FIEMAP on N-stripe file succeeded"
15001 }
15002 run_test 130d "FIEMAP (N-stripe file)"
15003
15004 test_130e() {
15005         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15006
15007         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15008         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15009         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15010                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15011
15012         trap cleanup_130 EXIT RETURN
15013
15014         local fm_file=$DIR/$tfile
15015         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15016         stack_trap "rm -f $fm_file"
15017
15018         local num_blks=512
15019         local expected_len=$(( (num_blks / 2) * 64 ))
15020         for ((i = 0; i < $num_blks; i++)); do
15021                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15022                         conv=notrunc > /dev/null 2>&1
15023         done
15024
15025         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15026         filefrag_op=$(filefrag -ve -k $fm_file |
15027                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15028
15029         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15030
15031         IFS=$'\n'
15032         local tot_len=0
15033         local num_luns=1
15034         for line in $filefrag_op; do
15035                 local frag_lun=$(echo $line | cut -d: -f5)
15036                 local ext_len=$(echo $line | cut -d: -f4)
15037                 if (( $frag_lun != $last_lun )); then
15038                         if (( tot_len != $expected_len )); then
15039                                 error "OST$last_lun $tot_len != $expected_len"
15040                         else
15041                                 (( num_luns += 1 ))
15042                                 tot_len=0
15043                         fi
15044                 fi
15045                 (( tot_len += ext_len ))
15046                 last_lun=$frag_lun
15047         done
15048         if (( num_luns != 2 || tot_len != $expected_len )); then
15049                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15050         fi
15051
15052         echo "FIEMAP with continuation calls succeeded"
15053 }
15054 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15055
15056 test_130f() {
15057         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15058         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15059         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15060                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15061
15062         local fm_file=$DIR/$tfile
15063         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15064                 error "multiop create with lov_delay_create on $fm_file"
15065
15066         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15067         filefrag_extents=$(filefrag -vek $fm_file |
15068                            awk '/extents? found/ { print $2 }')
15069         if (( $filefrag_extents != 0 )); then
15070                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15071         fi
15072
15073         rm -f $fm_file
15074 }
15075 run_test 130f "FIEMAP (unstriped file)"
15076
15077 test_130g() {
15078         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15079                 skip "Need MDS version with at least 2.12.53 for overstriping"
15080         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15081         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15082         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15083                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15084
15085         local file=$DIR/$tfile
15086         local nr=$((OSTCOUNT * 100))
15087
15088         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15089
15090         stack_trap "rm -f $file"
15091         dd if=/dev/zero of=$file count=$nr bs=1M
15092         sync
15093         nr=$($LFS getstripe -c $file)
15094
15095         local extents=$(filefrag -v $file |
15096                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15097
15098         echo "filefrag list $extents extents in file with stripecount $nr"
15099         if (( extents < nr )); then
15100                 $LFS getstripe $file
15101                 filefrag -v $file
15102                 error "filefrag printed $extents < $nr extents"
15103         fi
15104 }
15105 run_test 130g "FIEMAP (overstripe file)"
15106
15107 # Test for writev/readv
15108 test_131a() {
15109         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15110                 error "writev test failed"
15111         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15112                 error "readv failed"
15113         rm -f $DIR/$tfile
15114 }
15115 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15116
15117 test_131b() {
15118         local fsize=$((524288 + 1048576 + 1572864))
15119         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15120                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15121                         error "append writev test failed"
15122
15123         ((fsize += 1572864 + 1048576))
15124         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15125                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15126                         error "append writev test failed"
15127         rm -f $DIR/$tfile
15128 }
15129 run_test 131b "test append writev"
15130
15131 test_131c() {
15132         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15133         error "NOT PASS"
15134 }
15135 run_test 131c "test read/write on file w/o objects"
15136
15137 test_131d() {
15138         rwv -f $DIR/$tfile -w -n 1 1572864
15139         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15140         if [ "$NOB" != 1572864 ]; then
15141                 error "Short read filed: read $NOB bytes instead of 1572864"
15142         fi
15143         rm -f $DIR/$tfile
15144 }
15145 run_test 131d "test short read"
15146
15147 test_131e() {
15148         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15149         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15150         error "read hitting hole failed"
15151         rm -f $DIR/$tfile
15152 }
15153 run_test 131e "test read hitting hole"
15154
15155 check_stats() {
15156         local facet=$1
15157         local op=$2
15158         local want=${3:-0}
15159         local res
15160
15161         # open             11 samples [usecs] 468 4793 13658 35791898
15162         case $facet in
15163         mds*) res=($(do_facet $facet \
15164                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15165                  ;;
15166         ost*) res=($(do_facet $facet \
15167                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15168                  ;;
15169         *) error "Wrong facet '$facet'" ;;
15170         esac
15171         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15172         # if $want is zero, it means any stat increment is ok.
15173         if (( $want > 0 )); then
15174                 local count=${res[1]}
15175
15176                 if (( $count != $want )); then
15177                         if [[ $facet =~ "mds" ]]; then
15178                                 do_nodes $(comma_list $(mdts_nodes)) \
15179                                         $LCTL get_param mdt.*.md_stats
15180                         else
15181                                 do_nodes $(comma_list $(osts-nodes)) \
15182                                         $LCTL get_param obdfilter.*.stats
15183                         fi
15184                         error "The $op counter on $facet is $count, not $want"
15185                 fi
15186         fi
15187 }
15188
15189 test_133a() {
15190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15191         remote_ost_nodsh && skip "remote OST with nodsh"
15192         remote_mds_nodsh && skip "remote MDS with nodsh"
15193         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15194                 skip_env "MDS doesn't support rename stats"
15195
15196         local testdir=$DIR/${tdir}/stats_testdir
15197
15198         mkdir -p $DIR/${tdir}
15199
15200         # clear stats.
15201         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15202         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15203
15204         # verify mdt stats first.
15205         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15206         check_stats $SINGLEMDS "mkdir" 1
15207
15208         # clear "open" from "lfs mkdir" above
15209         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15210         touch ${testdir}/${tfile} || error "touch failed"
15211         check_stats $SINGLEMDS "open" 1
15212         check_stats $SINGLEMDS "close" 1
15213         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15214                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15215                 check_stats $SINGLEMDS "mknod" 2
15216         }
15217         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15218         check_stats $SINGLEMDS "unlink" 1
15219         rm -f ${testdir}/${tfile} || error "file remove failed"
15220         check_stats $SINGLEMDS "unlink" 2
15221
15222         # remove working dir and check mdt stats again.
15223         rmdir ${testdir} || error "rmdir failed"
15224         check_stats $SINGLEMDS "rmdir" 1
15225
15226         local testdir1=$DIR/${tdir}/stats_testdir1
15227         mkdir_on_mdt0 -p ${testdir}
15228         mkdir_on_mdt0 -p ${testdir1}
15229         touch ${testdir1}/test1
15230         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15231         check_stats $SINGLEMDS "crossdir_rename" 1
15232
15233         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15234         check_stats $SINGLEMDS "samedir_rename" 1
15235
15236         rm -rf $DIR/${tdir}
15237 }
15238 run_test 133a "Verifying MDT stats ========================================"
15239
15240 test_133b() {
15241         local res
15242
15243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15244         remote_ost_nodsh && skip "remote OST with nodsh"
15245         remote_mds_nodsh && skip "remote MDS with nodsh"
15246
15247         local testdir=$DIR/${tdir}/stats_testdir
15248
15249         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15250         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15251         touch ${testdir}/${tfile} || error "touch failed"
15252         cancel_lru_locks mdc
15253
15254         # clear stats.
15255         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15256         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15257
15258         # extra mdt stats verification.
15259         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15260         check_stats $SINGLEMDS "setattr" 1
15261         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15262         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15263         then            # LU-1740
15264                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15265                 check_stats $SINGLEMDS "getattr" 1
15266         fi
15267         rm -rf $DIR/${tdir}
15268
15269         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15270         # so the check below is not reliable
15271         [ $MDSCOUNT -eq 1 ] || return 0
15272
15273         # Sleep to avoid a cached response.
15274         #define OBD_STATFS_CACHE_SECONDS 1
15275         sleep 2
15276         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15277         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15278         $LFS df || error "lfs failed"
15279         check_stats $SINGLEMDS "statfs" 1
15280
15281         # check aggregated statfs (LU-10018)
15282         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15283                 return 0
15284         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15285                 return 0
15286         sleep 2
15287         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15288         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15289         df $DIR
15290         check_stats $SINGLEMDS "statfs" 1
15291
15292         # We want to check that the client didn't send OST_STATFS to
15293         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15294         # extra care is needed here.
15295         if remote_mds; then
15296                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15297                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15298
15299                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15300                 [ "$res" ] && error "OST got STATFS"
15301         fi
15302
15303         return 0
15304 }
15305 run_test 133b "Verifying extra MDT stats =================================="
15306
15307 test_133c() {
15308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15309         remote_ost_nodsh && skip "remote OST with nodsh"
15310         remote_mds_nodsh && skip "remote MDS with nodsh"
15311
15312         local testdir=$DIR/$tdir/stats_testdir
15313
15314         test_mkdir -p $testdir
15315
15316         # verify obdfilter stats.
15317         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15318         sync
15319         cancel_lru_locks osc
15320         wait_delete_completed
15321
15322         # clear stats.
15323         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15324         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15325
15326         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15327                 error "dd failed"
15328         sync
15329         cancel_lru_locks osc
15330         check_stats ost1 "write" 1
15331
15332         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15333         check_stats ost1 "read" 1
15334
15335         > $testdir/$tfile || error "truncate failed"
15336         check_stats ost1 "punch" 1
15337
15338         rm -f $testdir/$tfile || error "file remove failed"
15339         wait_delete_completed
15340         check_stats ost1 "destroy" 1
15341
15342         rm -rf $DIR/$tdir
15343 }
15344 run_test 133c "Verifying OST stats ========================================"
15345
15346 order_2() {
15347         local value=$1
15348         local orig=$value
15349         local order=1
15350
15351         while [ $value -ge 2 ]; do
15352                 order=$((order*2))
15353                 value=$((value/2))
15354         done
15355
15356         if [ $orig -gt $order ]; then
15357                 order=$((order*2))
15358         fi
15359         echo $order
15360 }
15361
15362 size_in_KMGT() {
15363     local value=$1
15364     local size=('K' 'M' 'G' 'T');
15365     local i=0
15366     local size_string=$value
15367
15368     while [ $value -ge 1024 ]; do
15369         if [ $i -gt 3 ]; then
15370             #T is the biggest unit we get here, if that is bigger,
15371             #just return XXXT
15372             size_string=${value}T
15373             break
15374         fi
15375         value=$((value >> 10))
15376         if [ $value -lt 1024 ]; then
15377             size_string=${value}${size[$i]}
15378             break
15379         fi
15380         i=$((i + 1))
15381     done
15382
15383     echo $size_string
15384 }
15385
15386 get_rename_size() {
15387         local size=$1
15388         local context=${2:-.}
15389         local sample=$(do_facet $SINGLEMDS $LCTL \
15390                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15391                 grep -A1 $context |
15392                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15393         echo $sample
15394 }
15395
15396 test_133d() {
15397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15398         remote_ost_nodsh && skip "remote OST with nodsh"
15399         remote_mds_nodsh && skip "remote MDS with nodsh"
15400         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15401                 skip_env "MDS doesn't support rename stats"
15402
15403         local testdir1=$DIR/${tdir}/stats_testdir1
15404         local testdir2=$DIR/${tdir}/stats_testdir2
15405         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15406
15407         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15408
15409         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15410         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15411
15412         createmany -o $testdir1/test 512 || error "createmany failed"
15413
15414         # check samedir rename size
15415         mv ${testdir1}/test0 ${testdir1}/test_0
15416
15417         local testdir1_size=$(ls -l $DIR/${tdir} |
15418                 awk '/stats_testdir1/ {print $5}')
15419         local testdir2_size=$(ls -l $DIR/${tdir} |
15420                 awk '/stats_testdir2/ {print $5}')
15421
15422         testdir1_size=$(order_2 $testdir1_size)
15423         testdir2_size=$(order_2 $testdir2_size)
15424
15425         testdir1_size=$(size_in_KMGT $testdir1_size)
15426         testdir2_size=$(size_in_KMGT $testdir2_size)
15427
15428         echo "source rename dir size: ${testdir1_size}"
15429         echo "target rename dir size: ${testdir2_size}"
15430
15431         local cmd="do_facet $SINGLEMDS $LCTL "
15432         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15433
15434         eval $cmd || error "$cmd failed"
15435         local samedir=$($cmd | grep 'same_dir')
15436         local same_sample=$(get_rename_size $testdir1_size)
15437         [ -z "$samedir" ] && error "samedir_rename_size count error"
15438         [[ $same_sample -eq 1 ]] ||
15439                 error "samedir_rename_size error $same_sample"
15440         echo "Check same dir rename stats success"
15441
15442         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15443
15444         # check crossdir rename size
15445         mv ${testdir1}/test_0 ${testdir2}/test_0
15446
15447         testdir1_size=$(ls -l $DIR/${tdir} |
15448                 awk '/stats_testdir1/ {print $5}')
15449         testdir2_size=$(ls -l $DIR/${tdir} |
15450                 awk '/stats_testdir2/ {print $5}')
15451
15452         testdir1_size=$(order_2 $testdir1_size)
15453         testdir2_size=$(order_2 $testdir2_size)
15454
15455         testdir1_size=$(size_in_KMGT $testdir1_size)
15456         testdir2_size=$(size_in_KMGT $testdir2_size)
15457
15458         echo "source rename dir size: ${testdir1_size}"
15459         echo "target rename dir size: ${testdir2_size}"
15460
15461         eval $cmd || error "$cmd failed"
15462         local crossdir=$($cmd | grep 'crossdir')
15463         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15464         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15465         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15466         [[ $src_sample -eq 1 ]] ||
15467                 error "crossdir_rename_size error $src_sample"
15468         [[ $tgt_sample -eq 1 ]] ||
15469                 error "crossdir_rename_size error $tgt_sample"
15470         echo "Check cross dir rename stats success"
15471         rm -rf $DIR/${tdir}
15472 }
15473 run_test 133d "Verifying rename_stats ========================================"
15474
15475 test_133e() {
15476         remote_mds_nodsh && skip "remote MDS with nodsh"
15477         remote_ost_nodsh && skip "remote OST with nodsh"
15478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15479
15480         local testdir=$DIR/${tdir}/stats_testdir
15481         local ctr f0 f1 bs=32768 count=42 sum
15482
15483         mkdir -p ${testdir} || error "mkdir failed"
15484
15485         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15486
15487         for ctr in {write,read}_bytes; do
15488                 sync
15489                 cancel_lru_locks osc
15490
15491                 do_facet ost1 $LCTL set_param -n \
15492                         "obdfilter.*.exports.clear=clear"
15493
15494                 if [ $ctr = write_bytes ]; then
15495                         f0=/dev/zero
15496                         f1=${testdir}/${tfile}
15497                 else
15498                         f0=${testdir}/${tfile}
15499                         f1=/dev/null
15500                 fi
15501
15502                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15503                         error "dd failed"
15504                 sync
15505                 cancel_lru_locks osc
15506
15507                 sum=$(do_facet ost1 $LCTL get_param \
15508                         "obdfilter.*.exports.*.stats" |
15509                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15510                                 $1 == ctr { sum += $7 }
15511                                 END { printf("%0.0f", sum) }')
15512
15513                 if ((sum != bs * count)); then
15514                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15515                 fi
15516         done
15517
15518         rm -rf $DIR/${tdir}
15519 }
15520 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15521
15522 test_133f() {
15523         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15524                 skip "too old lustre for get_param -R ($facet_ver)"
15525
15526         # verifying readability.
15527         $LCTL get_param -R '*' &> /dev/null
15528
15529         # Verifing writability with badarea_io.
15530         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15531         local skipped_params='force_lbug|changelog_mask|daemon_file'
15532         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15533                 egrep -v "$skipped_params" |
15534                 xargs -n 1 find $proc_dirs -name |
15535                 xargs -n 1 badarea_io ||
15536                 error "client badarea_io failed"
15537
15538         # remount the FS in case writes/reads /proc break the FS
15539         cleanup || error "failed to unmount"
15540         setup || error "failed to setup"
15541 }
15542 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15543
15544 test_133g() {
15545         remote_mds_nodsh && skip "remote MDS with nodsh"
15546         remote_ost_nodsh && skip "remote OST with nodsh"
15547
15548         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15549         local proc_dirs_str=$(eval echo $proc_dirs)
15550         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15551         local facet
15552         for facet in mds1 ost1; do
15553                 local facet_ver=$(lustre_version_code $facet)
15554                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15555                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15556                 else
15557                         log "$facet: too old lustre for get_param -R"
15558                 fi
15559                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15560                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15561                                 tr -d = | egrep -v $skipped_params |
15562                                 xargs -n 1 find $proc_dirs_str -name |
15563                                 xargs -n 1 badarea_io" ||
15564                                         error "$facet badarea_io failed"
15565                 else
15566                         skip_noexit "$facet: too old lustre for get_param -R"
15567                 fi
15568         done
15569
15570         # remount the FS in case writes/reads /proc break the FS
15571         cleanup || error "failed to unmount"
15572         setup || error "failed to setup"
15573 }
15574 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15575
15576 test_133h() {
15577         remote_mds_nodsh && skip "remote MDS with nodsh"
15578         remote_ost_nodsh && skip "remote OST with nodsh"
15579         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15580                 skip "Need MDS version at least 2.9.54"
15581
15582         local facet
15583         for facet in client mds1 ost1; do
15584                 # Get the list of files that are missing the terminating newline
15585                 local plist=$(do_facet $facet
15586                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15587                 local ent
15588                 for ent in $plist; do
15589                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15590                                 awk -v FS='\v' -v RS='\v\v' \
15591                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15592                                         print FILENAME}'" 2>/dev/null)
15593                         [ -z $missing ] || {
15594                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15595                                 error "file does not end with newline: $facet-$ent"
15596                         }
15597                 done
15598         done
15599 }
15600 run_test 133h "Proc files should end with newlines"
15601
15602 test_134a() {
15603         remote_mds_nodsh && skip "remote MDS with nodsh"
15604         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15605                 skip "Need MDS version at least 2.7.54"
15606
15607         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15608         cancel_lru_locks mdc
15609
15610         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15611         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15612         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15613
15614         local nr=1000
15615         createmany -o $DIR/$tdir/f $nr ||
15616                 error "failed to create $nr files in $DIR/$tdir"
15617         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15618
15619         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15620         do_facet mds1 $LCTL set_param fail_loc=0x327
15621         do_facet mds1 $LCTL set_param fail_val=500
15622         touch $DIR/$tdir/m
15623
15624         echo "sleep 10 seconds ..."
15625         sleep 10
15626         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15627
15628         do_facet mds1 $LCTL set_param fail_loc=0
15629         do_facet mds1 $LCTL set_param fail_val=0
15630         [ $lck_cnt -lt $unused ] ||
15631                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15632
15633         rm $DIR/$tdir/m
15634         unlinkmany $DIR/$tdir/f $nr
15635 }
15636 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15637
15638 test_134b() {
15639         remote_mds_nodsh && skip "remote MDS with nodsh"
15640         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15641                 skip "Need MDS version at least 2.7.54"
15642
15643         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15644         cancel_lru_locks mdc
15645
15646         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15647                         ldlm.lock_reclaim_threshold_mb)
15648         # disable reclaim temporarily
15649         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15650
15651         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15652         do_facet mds1 $LCTL set_param fail_loc=0x328
15653         do_facet mds1 $LCTL set_param fail_val=500
15654
15655         $LCTL set_param debug=+trace
15656
15657         local nr=600
15658         createmany -o $DIR/$tdir/f $nr &
15659         local create_pid=$!
15660
15661         echo "Sleep $TIMEOUT seconds ..."
15662         sleep $TIMEOUT
15663         if ! ps -p $create_pid  > /dev/null 2>&1; then
15664                 do_facet mds1 $LCTL set_param fail_loc=0
15665                 do_facet mds1 $LCTL set_param fail_val=0
15666                 do_facet mds1 $LCTL set_param \
15667                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15668                 error "createmany finished incorrectly!"
15669         fi
15670         do_facet mds1 $LCTL set_param fail_loc=0
15671         do_facet mds1 $LCTL set_param fail_val=0
15672         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15673         wait $create_pid || return 1
15674
15675         unlinkmany $DIR/$tdir/f $nr
15676 }
15677 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15678
15679 test_135() {
15680         remote_mds_nodsh && skip "remote MDS with nodsh"
15681         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15682                 skip "Need MDS version at least 2.13.50"
15683         local fname
15684
15685         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15686
15687 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15688         #set only one record at plain llog
15689         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15690
15691         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15692
15693         #fill already existed plain llog each 64767
15694         #wrapping whole catalog
15695         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15696
15697         createmany -o $DIR/$tdir/$tfile_ 64700
15698         for (( i = 0; i < 64700; i = i + 2 ))
15699         do
15700                 rm $DIR/$tdir/$tfile_$i &
15701                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15702                 local pid=$!
15703                 wait $pid
15704         done
15705
15706         #waiting osp synchronization
15707         wait_delete_completed
15708 }
15709 run_test 135 "Race catalog processing"
15710
15711 test_136() {
15712         remote_mds_nodsh && skip "remote MDS with nodsh"
15713         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15714                 skip "Need MDS version at least 2.13.50"
15715         local fname
15716
15717         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15718         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15719         #set only one record at plain llog
15720 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15721         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15722
15723         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15724
15725         #fill already existed 2 plain llogs each 64767
15726         #wrapping whole catalog
15727         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15728         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15729         wait_delete_completed
15730
15731         createmany -o $DIR/$tdir/$tfile_ 10
15732         sleep 25
15733
15734         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15735         for (( i = 0; i < 10; i = i + 3 ))
15736         do
15737                 rm $DIR/$tdir/$tfile_$i &
15738                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15739                 local pid=$!
15740                 wait $pid
15741                 sleep 7
15742                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15743         done
15744
15745         #waiting osp synchronization
15746         wait_delete_completed
15747 }
15748 run_test 136 "Race catalog processing 2"
15749
15750 test_140() { #bug-17379
15751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15752
15753         test_mkdir $DIR/$tdir
15754         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15755         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15756
15757         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15758         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15759         local i=0
15760         while i=$((i + 1)); do
15761                 test_mkdir $i
15762                 cd $i || error "Changing to $i"
15763                 ln -s ../stat stat || error "Creating stat symlink"
15764                 # Read the symlink until ELOOP present,
15765                 # not LBUGing the system is considered success,
15766                 # we didn't overrun the stack.
15767                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15768                 if [ $ret -ne 0 ]; then
15769                         if [ $ret -eq 40 ]; then
15770                                 break  # -ELOOP
15771                         else
15772                                 error "Open stat symlink"
15773                                         return
15774                         fi
15775                 fi
15776         done
15777         i=$((i - 1))
15778         echo "The symlink depth = $i"
15779         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15780                 error "Invalid symlink depth"
15781
15782         # Test recursive symlink
15783         ln -s symlink_self symlink_self
15784         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15785         echo "open symlink_self returns $ret"
15786         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15787 }
15788 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15789
15790 test_150a() {
15791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15792
15793         local TF="$TMP/$tfile"
15794
15795         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15796         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15797         cp $TF $DIR/$tfile
15798         cancel_lru_locks $OSC
15799         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15800         remount_client $MOUNT
15801         df -P $MOUNT
15802         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15803
15804         $TRUNCATE $TF 6000
15805         $TRUNCATE $DIR/$tfile 6000
15806         cancel_lru_locks $OSC
15807         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15808
15809         echo "12345" >>$TF
15810         echo "12345" >>$DIR/$tfile
15811         cancel_lru_locks $OSC
15812         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15813
15814         echo "12345" >>$TF
15815         echo "12345" >>$DIR/$tfile
15816         cancel_lru_locks $OSC
15817         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15818 }
15819 run_test 150a "truncate/append tests"
15820
15821 test_150b() {
15822         check_set_fallocate_or_skip
15823         local out
15824
15825         touch $DIR/$tfile
15826         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15827         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15828                 skip_eopnotsupp "$out|check_fallocate failed"
15829 }
15830 run_test 150b "Verify fallocate (prealloc) functionality"
15831
15832 test_150bb() {
15833         check_set_fallocate_or_skip
15834
15835         touch $DIR/$tfile
15836         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15837         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15838         > $DIR/$tfile
15839         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15840         # precomputed md5sum for 20MB of zeroes
15841         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15842         local sum=($(md5sum $DIR/$tfile))
15843
15844         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15845
15846         check_set_fallocate 1
15847
15848         > $DIR/$tfile
15849         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15850         sum=($(md5sum $DIR/$tfile))
15851
15852         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15853 }
15854 run_test 150bb "Verify fallocate modes both zero space"
15855
15856 test_150c() {
15857         check_set_fallocate_or_skip
15858         local striping="-c2"
15859
15860         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15861         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15862         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15863         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15864         local want=$((OSTCOUNT * 1048576))
15865
15866         # Must allocate all requested space, not more than 5% extra
15867         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15868                 error "bytes $bytes is not $want"
15869
15870         rm -f $DIR/$tfile
15871
15872         echo "verify fallocate on PFL file"
15873
15874         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15875
15876         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15877                 error "Create $DIR/$tfile failed"
15878         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15879         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15880         want=$((512 * 1048576))
15881
15882         # Must allocate all requested space, not more than 5% extra
15883         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15884                 error "bytes $bytes is not $want"
15885 }
15886 run_test 150c "Verify fallocate Size and Blocks"
15887
15888 test_150d() {
15889         check_set_fallocate_or_skip
15890         local striping="-c2"
15891
15892         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15893
15894         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15895         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15896                 error "setstripe failed"
15897         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15898         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15899         local want=$((OSTCOUNT * 1048576))
15900
15901         # Must allocate all requested space, not more than 5% extra
15902         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15903                 error "bytes $bytes is not $want"
15904 }
15905 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15906
15907 test_150e() {
15908         check_set_fallocate_or_skip
15909
15910         echo "df before:"
15911         $LFS df
15912         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15913         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15914                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15915
15916         # Find OST with Minimum Size
15917         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15918                        sort -un | head -1)
15919
15920         # Get 100MB per OST of the available space to reduce run time
15921         # else 60% of the available space if we are running SLOW tests
15922         if [ $SLOW == "no" ]; then
15923                 local space=$((1024 * 100 * OSTCOUNT))
15924         else
15925                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15926         fi
15927
15928         fallocate -l${space}k $DIR/$tfile ||
15929                 error "fallocate ${space}k $DIR/$tfile failed"
15930         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15931
15932         # get size immediately after fallocate. This should be correctly
15933         # updated
15934         local size=$(stat -c '%s' $DIR/$tfile)
15935         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15936
15937         # Sleep for a while for statfs to get updated. And not pull from cache.
15938         sleep 2
15939
15940         echo "df after fallocate:"
15941         $LFS df
15942
15943         (( size / 1024 == space )) || error "size $size != requested $space"
15944         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15945                 error "used $used < space $space"
15946
15947         rm $DIR/$tfile || error "rm failed"
15948         sync
15949         wait_delete_completed
15950
15951         echo "df after unlink:"
15952         $LFS df
15953 }
15954 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15955
15956 test_150f() {
15957         local size
15958         local blocks
15959         local want_size_before=20480 # in bytes
15960         local want_blocks_before=40 # 512 sized blocks
15961         local want_blocks_after=24  # 512 sized blocks
15962         local length=$(((want_blocks_before - want_blocks_after) * 512))
15963
15964         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15965                 skip "need at least 2.14.0 for fallocate punch"
15966
15967         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15968                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15969         fi
15970
15971         check_set_fallocate_or_skip
15972         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15973
15974         [[ "x$DOM" == "xyes" ]] &&
15975                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15976
15977         echo "Verify fallocate punch: Range within the file range"
15978         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15979                 error "dd failed for bs 4096 and count 5"
15980
15981         # Call fallocate with punch range which is within the file range
15982         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15983                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15984         # client must see changes immediately after fallocate
15985         size=$(stat -c '%s' $DIR/$tfile)
15986         blocks=$(stat -c '%b' $DIR/$tfile)
15987
15988         # Verify punch worked.
15989         (( blocks == want_blocks_after )) ||
15990                 error "punch failed: blocks $blocks != $want_blocks_after"
15991
15992         (( size == want_size_before )) ||
15993                 error "punch failed: size $size != $want_size_before"
15994
15995         # Verify there is hole in file
15996         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15997         # precomputed md5sum
15998         local expect="4a9a834a2db02452929c0a348273b4aa"
15999
16000         cksum=($(md5sum $DIR/$tfile))
16001         [[ "${cksum[0]}" == "$expect" ]] ||
16002                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16003
16004         # Start second sub-case for fallocate punch.
16005         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16006         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16007                 error "dd failed for bs 4096 and count 5"
16008
16009         # Punch range less than block size will have no change in block count
16010         want_blocks_after=40  # 512 sized blocks
16011
16012         # Punch overlaps two blocks and less than blocksize
16013         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16014                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16015         size=$(stat -c '%s' $DIR/$tfile)
16016         blocks=$(stat -c '%b' $DIR/$tfile)
16017
16018         # Verify punch worked.
16019         (( blocks == want_blocks_after )) ||
16020                 error "punch failed: blocks $blocks != $want_blocks_after"
16021
16022         (( size == want_size_before )) ||
16023                 error "punch failed: size $size != $want_size_before"
16024
16025         # Verify if range is really zero'ed out. We expect Zeros.
16026         # precomputed md5sum
16027         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16028         cksum=($(md5sum $DIR/$tfile))
16029         [[ "${cksum[0]}" == "$expect" ]] ||
16030                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16031 }
16032 run_test 150f "Verify fallocate punch functionality"
16033
16034 test_150g() {
16035         local space
16036         local size
16037         local blocks
16038         local blocks_after
16039         local size_after
16040         local BS=4096 # Block size in bytes
16041
16042         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16043                 skip "need at least 2.14.0 for fallocate punch"
16044
16045         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16046                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16047         fi
16048
16049         check_set_fallocate_or_skip
16050         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16051
16052         if [[ "x$DOM" == "xyes" ]]; then
16053                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16054                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16055         else
16056                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16057                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16058         fi
16059
16060         # Get 100MB per OST of the available space to reduce run time
16061         # else 60% of the available space if we are running SLOW tests
16062         if [ $SLOW == "no" ]; then
16063                 space=$((1024 * 100 * OSTCOUNT))
16064         else
16065                 # Find OST with Minimum Size
16066                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16067                         sort -un | head -1)
16068                 echo "min size OST: $space"
16069                 space=$(((space * 60)/100 * OSTCOUNT))
16070         fi
16071         # space in 1k units, round to 4k blocks
16072         local blkcount=$((space * 1024 / $BS))
16073
16074         echo "Verify fallocate punch: Very large Range"
16075         fallocate -l${space}k $DIR/$tfile ||
16076                 error "fallocate ${space}k $DIR/$tfile failed"
16077         # write 1M at the end, start and in the middle
16078         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16079                 error "dd failed: bs $BS count 256"
16080         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16081                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16082         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16083                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16084
16085         # Gather stats.
16086         size=$(stat -c '%s' $DIR/$tfile)
16087
16088         # gather punch length.
16089         local punch_size=$((size - (BS * 2)))
16090
16091         echo "punch_size = $punch_size"
16092         echo "size - punch_size: $((size - punch_size))"
16093         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16094
16095         # Call fallocate to punch all except 2 blocks. We leave the
16096         # first and the last block
16097         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16098         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16099                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16100
16101         size_after=$(stat -c '%s' $DIR/$tfile)
16102         blocks_after=$(stat -c '%b' $DIR/$tfile)
16103
16104         # Verify punch worked.
16105         # Size should be kept
16106         (( size == size_after )) ||
16107                 error "punch failed: size $size != $size_after"
16108
16109         # two 4k data blocks to remain plus possible 1 extra extent block
16110         (( blocks_after <= ((BS / 512) * 3) )) ||
16111                 error "too many blocks remains: $blocks_after"
16112
16113         # Verify that file has hole between the first and the last blocks
16114         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16115         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16116
16117         echo "Hole at [$hole_start, $hole_end)"
16118         (( hole_start == BS )) ||
16119                 error "no hole at offset $BS after punch"
16120
16121         (( hole_end == BS + punch_size )) ||
16122                 error "data at offset $hole_end < $((BS + punch_size))"
16123 }
16124 run_test 150g "Verify fallocate punch on large range"
16125
16126 test_150h() {
16127         local file=$DIR/$tfile
16128         local size
16129
16130         check_set_fallocate_or_skip
16131         statx_supported || skip_env "Test must be statx() syscall supported"
16132
16133         # fallocate() does not update the size information on the MDT
16134         fallocate -l 16K $file || error "failed to fallocate $file"
16135         cancel_lru_locks $OSC
16136         # STATX with cached-always mode will not send glimpse RPCs to OST,
16137         # it uses the caching attrs on the client side as much as possible.
16138         size=$($STATX --cached=always -c %s $file)
16139         [ $size == 16384 ] ||
16140                 error "size after fallocate() is $size, expected 16384"
16141 }
16142 run_test 150h "Verify extend fallocate updates the file size"
16143
16144 #LU-2902 roc_hit was not able to read all values from lproc
16145 function roc_hit_init() {
16146         local list=$(comma_list $(osts_nodes))
16147         local dir=$DIR/$tdir-check
16148         local file=$dir/$tfile
16149         local BEFORE
16150         local AFTER
16151         local idx
16152
16153         test_mkdir $dir
16154         #use setstripe to do a write to every ost
16155         for i in $(seq 0 $((OSTCOUNT-1))); do
16156                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16157                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16158                 idx=$(printf %04x $i)
16159                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16160                         awk '$1 == "cache_access" {sum += $7}
16161                                 END { printf("%0.0f", sum) }')
16162
16163                 cancel_lru_locks osc
16164                 cat $file >/dev/null
16165
16166                 AFTER=$(get_osd_param $list *OST*$idx stats |
16167                         awk '$1 == "cache_access" {sum += $7}
16168                                 END { printf("%0.0f", sum) }')
16169
16170                 echo BEFORE:$BEFORE AFTER:$AFTER
16171                 if ! let "AFTER - BEFORE == 4"; then
16172                         rm -rf $dir
16173                         error "roc_hit is not safe to use"
16174                 fi
16175                 rm $file
16176         done
16177
16178         rm -rf $dir
16179 }
16180
16181 function roc_hit() {
16182         local list=$(comma_list $(osts_nodes))
16183         echo $(get_osd_param $list '' stats |
16184                 awk '$1 == "cache_hit" {sum += $7}
16185                         END { printf("%0.0f", sum) }')
16186 }
16187
16188 function set_cache() {
16189         local on=1
16190
16191         if [ "$2" == "off" ]; then
16192                 on=0;
16193         fi
16194         local list=$(comma_list $(osts_nodes))
16195         set_osd_param $list '' $1_cache_enable $on
16196
16197         cancel_lru_locks osc
16198 }
16199
16200 test_151() {
16201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16202         remote_ost_nodsh && skip "remote OST with nodsh"
16203         (( CLIENT_VERSION == OST1_VERSION )) ||
16204                 skip "LU-13081: no interop testing for OSS cache"
16205
16206         local CPAGES=3
16207         local list=$(comma_list $(osts_nodes))
16208
16209         # check whether obdfilter is cache capable at all
16210         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16211                 skip "not cache-capable obdfilter"
16212         fi
16213
16214         # check cache is enabled on all obdfilters
16215         if get_osd_param $list '' read_cache_enable | grep 0; then
16216                 skip "oss cache is disabled"
16217         fi
16218
16219         set_osd_param $list '' writethrough_cache_enable 1
16220
16221         # check write cache is enabled on all obdfilters
16222         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16223                 skip "oss write cache is NOT enabled"
16224         fi
16225
16226         roc_hit_init
16227
16228         #define OBD_FAIL_OBD_NO_LRU  0x609
16229         do_nodes $list $LCTL set_param fail_loc=0x609
16230
16231         # pages should be in the case right after write
16232         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16233                 error "dd failed"
16234
16235         local BEFORE=$(roc_hit)
16236         cancel_lru_locks osc
16237         cat $DIR/$tfile >/dev/null
16238         local AFTER=$(roc_hit)
16239
16240         do_nodes $list $LCTL set_param fail_loc=0
16241
16242         if ! let "AFTER - BEFORE == CPAGES"; then
16243                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16244         fi
16245
16246         cancel_lru_locks osc
16247         # invalidates OST cache
16248         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16249         set_osd_param $list '' read_cache_enable 0
16250         cat $DIR/$tfile >/dev/null
16251
16252         # now data shouldn't be found in the cache
16253         BEFORE=$(roc_hit)
16254         cancel_lru_locks osc
16255         cat $DIR/$tfile >/dev/null
16256         AFTER=$(roc_hit)
16257         if let "AFTER - BEFORE != 0"; then
16258                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16259         fi
16260
16261         set_osd_param $list '' read_cache_enable 1
16262         rm -f $DIR/$tfile
16263 }
16264 run_test 151 "test cache on oss and controls ==============================="
16265
16266 test_152() {
16267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16268
16269         local TF="$TMP/$tfile"
16270
16271         # simulate ENOMEM during write
16272 #define OBD_FAIL_OST_NOMEM      0x226
16273         lctl set_param fail_loc=0x80000226
16274         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16275         cp $TF $DIR/$tfile
16276         sync || error "sync failed"
16277         lctl set_param fail_loc=0
16278
16279         # discard client's cache
16280         cancel_lru_locks osc
16281
16282         # simulate ENOMEM during read
16283         lctl set_param fail_loc=0x80000226
16284         cmp $TF $DIR/$tfile || error "cmp failed"
16285         lctl set_param fail_loc=0
16286
16287         rm -f $TF
16288 }
16289 run_test 152 "test read/write with enomem ============================"
16290
16291 test_153() {
16292         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16293 }
16294 run_test 153 "test if fdatasync does not crash ======================="
16295
16296 dot_lustre_fid_permission_check() {
16297         local fid=$1
16298         local ffid=$MOUNT/.lustre/fid/$fid
16299         local test_dir=$2
16300
16301         echo "stat fid $fid"
16302         stat $ffid || error "stat $ffid failed."
16303         echo "touch fid $fid"
16304         touch $ffid || error "touch $ffid failed."
16305         echo "write to fid $fid"
16306         cat /etc/hosts > $ffid || error "write $ffid failed."
16307         echo "read fid $fid"
16308         diff /etc/hosts $ffid || error "read $ffid failed."
16309         echo "append write to fid $fid"
16310         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16311         echo "rename fid $fid"
16312         mv $ffid $test_dir/$tfile.1 &&
16313                 error "rename $ffid to $tfile.1 should fail."
16314         touch $test_dir/$tfile.1
16315         mv $test_dir/$tfile.1 $ffid &&
16316                 error "rename $tfile.1 to $ffid should fail."
16317         rm -f $test_dir/$tfile.1
16318         echo "truncate fid $fid"
16319         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16320         echo "link fid $fid"
16321         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16322         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16323                 id $USER0 || skip_env "missing user $USER0"
16324                 echo "setfacl fid $fid"
16325                 setfacl -R -m u:$USER0:rwx $ffid ||
16326                         error "setfacl $ffid failed"
16327                 echo "getfacl fid $fid"
16328                 getfacl $ffid || error "getfacl $ffid failed."
16329         fi
16330         echo "unlink fid $fid"
16331         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16332         echo "mknod fid $fid"
16333         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16334
16335         fid=[0xf00000400:0x1:0x0]
16336         ffid=$MOUNT/.lustre/fid/$fid
16337
16338         echo "stat non-exist fid $fid"
16339         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16340         echo "write to non-exist fid $fid"
16341         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16342         echo "link new fid $fid"
16343         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16344
16345         mkdir -p $test_dir/$tdir
16346         touch $test_dir/$tdir/$tfile
16347         fid=$($LFS path2fid $test_dir/$tdir)
16348         rc=$?
16349         [ $rc -ne 0 ] &&
16350                 error "error: could not get fid for $test_dir/$dir/$tfile."
16351
16352         ffid=$MOUNT/.lustre/fid/$fid
16353
16354         echo "ls $fid"
16355         ls $ffid || error "ls $ffid failed."
16356         echo "touch $fid/$tfile.1"
16357         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16358
16359         echo "touch $MOUNT/.lustre/fid/$tfile"
16360         touch $MOUNT/.lustre/fid/$tfile && \
16361                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16362
16363         echo "setxattr to $MOUNT/.lustre/fid"
16364         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16365
16366         echo "listxattr for $MOUNT/.lustre/fid"
16367         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16368
16369         echo "delxattr from $MOUNT/.lustre/fid"
16370         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16371
16372         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16373         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16374                 error "touch invalid fid should fail."
16375
16376         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16377         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16378                 error "touch non-normal fid should fail."
16379
16380         echo "rename $tdir to $MOUNT/.lustre/fid"
16381         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16382                 error "rename to $MOUNT/.lustre/fid should fail."
16383
16384         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16385         then            # LU-3547
16386                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16387                 local new_obf_mode=777
16388
16389                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16390                 chmod $new_obf_mode $DIR/.lustre/fid ||
16391                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16392
16393                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16394                 [ $obf_mode -eq $new_obf_mode ] ||
16395                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16396
16397                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16398                 chmod $old_obf_mode $DIR/.lustre/fid ||
16399                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16400         fi
16401
16402         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16403         fid=$($LFS path2fid $test_dir/$tfile-2)
16404
16405         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16406         then # LU-5424
16407                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16408                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16409                         error "create lov data thru .lustre failed"
16410         fi
16411         echo "cp /etc/passwd $test_dir/$tfile-2"
16412         cp /etc/passwd $test_dir/$tfile-2 ||
16413                 error "copy to $test_dir/$tfile-2 failed."
16414         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16415         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16416                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16417
16418         rm -rf $test_dir/tfile.lnk
16419         rm -rf $test_dir/$tfile-2
16420 }
16421
16422 test_154A() {
16423         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16424                 skip "Need MDS version at least 2.4.1"
16425
16426         local tf=$DIR/$tfile
16427         touch $tf
16428
16429         local fid=$($LFS path2fid $tf)
16430         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16431
16432         # check that we get the same pathname back
16433         local rootpath
16434         local found
16435         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16436                 echo "$rootpath $fid"
16437                 found=$($LFS fid2path $rootpath "$fid")
16438                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16439                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16440         done
16441
16442         # check wrong root path format
16443         rootpath=$MOUNT"_wrong"
16444         found=$($LFS fid2path $rootpath "$fid")
16445         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16446 }
16447 run_test 154A "lfs path2fid and fid2path basic checks"
16448
16449 test_154B() {
16450         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16451                 skip "Need MDS version at least 2.4.1"
16452
16453         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16454         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16455         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16456         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16457
16458         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16459         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16460
16461         # check that we get the same pathname
16462         echo "PFID: $PFID, name: $name"
16463         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16464         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16465         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16466                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16467
16468         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16469 }
16470 run_test 154B "verify the ll_decode_linkea tool"
16471
16472 test_154a() {
16473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16474         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16475         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16476                 skip "Need MDS version at least 2.2.51"
16477         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16478
16479         cp /etc/hosts $DIR/$tfile
16480
16481         fid=$($LFS path2fid $DIR/$tfile)
16482         rc=$?
16483         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16484
16485         dot_lustre_fid_permission_check "$fid" $DIR ||
16486                 error "dot lustre permission check $fid failed"
16487
16488         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16489
16490         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16491
16492         touch $MOUNT/.lustre/file &&
16493                 error "creation is not allowed under .lustre"
16494
16495         mkdir $MOUNT/.lustre/dir &&
16496                 error "mkdir is not allowed under .lustre"
16497
16498         rm -rf $DIR/$tfile
16499 }
16500 run_test 154a "Open-by-FID"
16501
16502 test_154b() {
16503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16504         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16506         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16507                 skip "Need MDS version at least 2.2.51"
16508
16509         local remote_dir=$DIR/$tdir/remote_dir
16510         local MDTIDX=1
16511         local rc=0
16512
16513         mkdir -p $DIR/$tdir
16514         $LFS mkdir -i $MDTIDX $remote_dir ||
16515                 error "create remote directory failed"
16516
16517         cp /etc/hosts $remote_dir/$tfile
16518
16519         fid=$($LFS path2fid $remote_dir/$tfile)
16520         rc=$?
16521         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16522
16523         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16524                 error "dot lustre permission check $fid failed"
16525         rm -rf $DIR/$tdir
16526 }
16527 run_test 154b "Open-by-FID for remote directory"
16528
16529 test_154c() {
16530         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16531                 skip "Need MDS version at least 2.4.1"
16532
16533         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16534         local FID1=$($LFS path2fid $DIR/$tfile.1)
16535         local FID2=$($LFS path2fid $DIR/$tfile.2)
16536         local FID3=$($LFS path2fid $DIR/$tfile.3)
16537
16538         local N=1
16539         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16540                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16541                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16542                 local want=FID$N
16543                 [ "$FID" = "${!want}" ] ||
16544                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16545                 N=$((N + 1))
16546         done
16547
16548         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16549         do
16550                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16551                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16552                 N=$((N + 1))
16553         done
16554 }
16555 run_test 154c "lfs path2fid and fid2path multiple arguments"
16556
16557 test_154d() {
16558         remote_mds_nodsh && skip "remote MDS with nodsh"
16559         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16560                 skip "Need MDS version at least 2.5.53"
16561
16562         if remote_mds; then
16563                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16564         else
16565                 nid="0@lo"
16566         fi
16567         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16568         local fd
16569         local cmd
16570
16571         rm -f $DIR/$tfile
16572         touch $DIR/$tfile
16573
16574         local fid=$($LFS path2fid $DIR/$tfile)
16575         # Open the file
16576         fd=$(free_fd)
16577         cmd="exec $fd<$DIR/$tfile"
16578         eval $cmd
16579         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16580         echo "$fid_list" | grep "$fid"
16581         rc=$?
16582
16583         cmd="exec $fd>/dev/null"
16584         eval $cmd
16585         if [ $rc -ne 0 ]; then
16586                 error "FID $fid not found in open files list $fid_list"
16587         fi
16588 }
16589 run_test 154d "Verify open file fid"
16590
16591 test_154e()
16592 {
16593         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16594                 skip "Need MDS version at least 2.6.50"
16595
16596         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16597                 error ".lustre returned by readdir"
16598         fi
16599 }
16600 run_test 154e ".lustre is not returned by readdir"
16601
16602 test_154f() {
16603         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16604
16605         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16606         mkdir_on_mdt0 $DIR/$tdir
16607         # test dirs inherit from its stripe
16608         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16609         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16610         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16611         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16612         touch $DIR/f
16613
16614         # get fid of parents
16615         local FID0=$($LFS path2fid $DIR/$tdir)
16616         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16617         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16618         local FID3=$($LFS path2fid $DIR)
16619
16620         # check that path2fid --parents returns expected <parent_fid>/name
16621         # 1) test for a directory (single parent)
16622         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16623         [ "$parent" == "$FID0/foo1" ] ||
16624                 error "expected parent: $FID0/foo1, got: $parent"
16625
16626         # 2) test for a file with nlink > 1 (multiple parents)
16627         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16628         echo "$parent" | grep -F "$FID1/$tfile" ||
16629                 error "$FID1/$tfile not returned in parent list"
16630         echo "$parent" | grep -F "$FID2/link" ||
16631                 error "$FID2/link not returned in parent list"
16632
16633         # 3) get parent by fid
16634         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16635         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16636         echo "$parent" | grep -F "$FID1/$tfile" ||
16637                 error "$FID1/$tfile not returned in parent list (by fid)"
16638         echo "$parent" | grep -F "$FID2/link" ||
16639                 error "$FID2/link not returned in parent list (by fid)"
16640
16641         # 4) test for entry in root directory
16642         parent=$($LFS path2fid --parents $DIR/f)
16643         echo "$parent" | grep -F "$FID3/f" ||
16644                 error "$FID3/f not returned in parent list"
16645
16646         # 5) test it on root directory
16647         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16648                 error "$MOUNT should not have parents"
16649
16650         # enable xattr caching and check that linkea is correctly updated
16651         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16652         save_lustre_params client "llite.*.xattr_cache" > $save
16653         lctl set_param llite.*.xattr_cache 1
16654
16655         # 6.1) linkea update on rename
16656         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16657
16658         # get parents by fid
16659         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16660         # foo1 should no longer be returned in parent list
16661         echo "$parent" | grep -F "$FID1" &&
16662                 error "$FID1 should no longer be in parent list"
16663         # the new path should appear
16664         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16665                 error "$FID2/$tfile.moved is not in parent list"
16666
16667         # 6.2) linkea update on unlink
16668         rm -f $DIR/$tdir/foo2/link
16669         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16670         # foo2/link should no longer be returned in parent list
16671         echo "$parent" | grep -F "$FID2/link" &&
16672                 error "$FID2/link should no longer be in parent list"
16673         true
16674
16675         rm -f $DIR/f
16676         restore_lustre_params < $save
16677         rm -f $save
16678 }
16679 run_test 154f "get parent fids by reading link ea"
16680
16681 test_154g()
16682 {
16683         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16684            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16685                 skip "Need MDS version at least 2.6.92"
16686
16687         mkdir_on_mdt0 $DIR/$tdir
16688         llapi_fid_test -d $DIR/$tdir
16689 }
16690 run_test 154g "various llapi FID tests"
16691
16692 test_154h()
16693 {
16694         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16695                 skip "Need client at least version 2.15.55.1"
16696
16697         # Create an empty file
16698         touch $DIR/$tfile
16699
16700         # Get FID (interactive mode) and save under $TMP/$tfile.log
16701         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16702                 path2fid $DIR/$tfile
16703         EOF
16704
16705         fid=$(cat $TMP/$tfile.log)
16706         # $fid should not be empty
16707         [[ ! -z $fid ]] || error "FID is empty"
16708         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16709 }
16710 run_test 154h "Verify interactive path2fid"
16711
16712 test_155_small_load() {
16713     local temp=$TMP/$tfile
16714     local file=$DIR/$tfile
16715
16716     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16717         error "dd of=$temp bs=6096 count=1 failed"
16718     cp $temp $file
16719     cancel_lru_locks $OSC
16720     cmp $temp $file || error "$temp $file differ"
16721
16722     $TRUNCATE $temp 6000
16723     $TRUNCATE $file 6000
16724     cmp $temp $file || error "$temp $file differ (truncate1)"
16725
16726     echo "12345" >>$temp
16727     echo "12345" >>$file
16728     cmp $temp $file || error "$temp $file differ (append1)"
16729
16730     echo "12345" >>$temp
16731     echo "12345" >>$file
16732     cmp $temp $file || error "$temp $file differ (append2)"
16733
16734     rm -f $temp $file
16735     true
16736 }
16737
16738 test_155_big_load() {
16739         remote_ost_nodsh && skip "remote OST with nodsh"
16740
16741         local temp=$TMP/$tfile
16742         local file=$DIR/$tfile
16743
16744         free_min_max
16745         local cache_size=$(do_facet ost$((MAXI+1)) \
16746                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16747
16748         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16749         # pre-set value
16750         if [ -z "$cache_size" ]; then
16751                 cache_size=256
16752         fi
16753         local large_file_size=$((cache_size * 2))
16754
16755         echo "OSS cache size: $cache_size KB"
16756         echo "Large file size: $large_file_size KB"
16757
16758         [ $MAXV -le $large_file_size ] &&
16759                 skip_env "max available OST size needs > $large_file_size KB"
16760
16761         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16762
16763         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16764                 error "dd of=$temp bs=$large_file_size count=1k failed"
16765         cp $temp $file
16766         ls -lh $temp $file
16767         cancel_lru_locks osc
16768         cmp $temp $file || error "$temp $file differ"
16769
16770         rm -f $temp $file
16771         true
16772 }
16773
16774 save_writethrough() {
16775         local facets=$(get_facets OST)
16776
16777         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16778 }
16779
16780 test_155a() {
16781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16782
16783         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16784
16785         save_writethrough $p
16786
16787         set_cache read on
16788         set_cache writethrough on
16789         test_155_small_load
16790         restore_lustre_params < $p
16791         rm -f $p
16792 }
16793 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16794
16795 test_155b() {
16796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16797
16798         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16799
16800         save_writethrough $p
16801
16802         set_cache read on
16803         set_cache writethrough off
16804         test_155_small_load
16805         restore_lustre_params < $p
16806         rm -f $p
16807 }
16808 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16809
16810 test_155c() {
16811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16812
16813         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16814
16815         save_writethrough $p
16816
16817         set_cache read off
16818         set_cache writethrough on
16819         test_155_small_load
16820         restore_lustre_params < $p
16821         rm -f $p
16822 }
16823 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16824
16825 test_155d() {
16826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16827
16828         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16829
16830         save_writethrough $p
16831
16832         set_cache read off
16833         set_cache writethrough off
16834         test_155_small_load
16835         restore_lustre_params < $p
16836         rm -f $p
16837 }
16838 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16839
16840 test_155e() {
16841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16842
16843         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16844
16845         save_writethrough $p
16846
16847         set_cache read on
16848         set_cache writethrough on
16849         test_155_big_load
16850         restore_lustre_params < $p
16851         rm -f $p
16852 }
16853 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16854
16855 test_155f() {
16856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16857
16858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16859
16860         save_writethrough $p
16861
16862         set_cache read on
16863         set_cache writethrough off
16864         test_155_big_load
16865         restore_lustre_params < $p
16866         rm -f $p
16867 }
16868 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16869
16870 test_155g() {
16871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16872
16873         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16874
16875         save_writethrough $p
16876
16877         set_cache read off
16878         set_cache writethrough on
16879         test_155_big_load
16880         restore_lustre_params < $p
16881         rm -f $p
16882 }
16883 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16884
16885 test_155h() {
16886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16887
16888         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16889
16890         save_writethrough $p
16891
16892         set_cache read off
16893         set_cache writethrough off
16894         test_155_big_load
16895         restore_lustre_params < $p
16896         rm -f $p
16897 }
16898 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16899
16900 test_156() {
16901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16902         remote_ost_nodsh && skip "remote OST with nodsh"
16903         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16904                 skip "stats not implemented on old servers"
16905         [ "$ost1_FSTYPE" = "zfs" ] &&
16906                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16907         (( CLIENT_VERSION == OST1_VERSION )) ||
16908                 skip "LU-13081: no interop testing for OSS cache"
16909
16910         local CPAGES=3
16911         local BEFORE
16912         local AFTER
16913         local file="$DIR/$tfile"
16914         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16915
16916         save_writethrough $p
16917         roc_hit_init
16918
16919         log "Turn on read and write cache"
16920         set_cache read on
16921         set_cache writethrough on
16922
16923         log "Write data and read it back."
16924         log "Read should be satisfied from the cache."
16925         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16926         BEFORE=$(roc_hit)
16927         cancel_lru_locks osc
16928         cat $file >/dev/null
16929         AFTER=$(roc_hit)
16930         if ! let "AFTER - BEFORE == CPAGES"; then
16931                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16932         else
16933                 log "cache hits: before: $BEFORE, after: $AFTER"
16934         fi
16935
16936         log "Read again; it should be satisfied from the cache."
16937         BEFORE=$AFTER
16938         cancel_lru_locks osc
16939         cat $file >/dev/null
16940         AFTER=$(roc_hit)
16941         if ! let "AFTER - BEFORE == CPAGES"; then
16942                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16943         else
16944                 log "cache hits:: before: $BEFORE, after: $AFTER"
16945         fi
16946
16947         log "Turn off the read cache and turn on the write cache"
16948         set_cache read off
16949         set_cache writethrough on
16950
16951         log "Read again; it should be satisfied from the cache."
16952         BEFORE=$(roc_hit)
16953         cancel_lru_locks osc
16954         cat $file >/dev/null
16955         AFTER=$(roc_hit)
16956         if ! let "AFTER - BEFORE == CPAGES"; then
16957                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16958         else
16959                 log "cache hits:: before: $BEFORE, after: $AFTER"
16960         fi
16961
16962         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16963                 # > 2.12.56 uses pagecache if cached
16964                 log "Read again; it should not be satisfied from the cache."
16965                 BEFORE=$AFTER
16966                 cancel_lru_locks osc
16967                 cat $file >/dev/null
16968                 AFTER=$(roc_hit)
16969                 if ! let "AFTER - BEFORE == 0"; then
16970                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16971                 else
16972                         log "cache hits:: before: $BEFORE, after: $AFTER"
16973                 fi
16974         fi
16975
16976         log "Write data and read it back."
16977         log "Read should be satisfied from the cache."
16978         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16979         BEFORE=$(roc_hit)
16980         cancel_lru_locks osc
16981         cat $file >/dev/null
16982         AFTER=$(roc_hit)
16983         if ! let "AFTER - BEFORE == CPAGES"; then
16984                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16985         else
16986                 log "cache hits:: before: $BEFORE, after: $AFTER"
16987         fi
16988
16989         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16990                 # > 2.12.56 uses pagecache if cached
16991                 log "Read again; it should not be satisfied from the cache."
16992                 BEFORE=$AFTER
16993                 cancel_lru_locks osc
16994                 cat $file >/dev/null
16995                 AFTER=$(roc_hit)
16996                 if ! let "AFTER - BEFORE == 0"; then
16997                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16998                 else
16999                         log "cache hits:: before: $BEFORE, after: $AFTER"
17000                 fi
17001         fi
17002
17003         log "Turn off read and write cache"
17004         set_cache read off
17005         set_cache writethrough off
17006
17007         log "Write data and read it back"
17008         log "It should not be satisfied from the cache."
17009         rm -f $file
17010         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17011         cancel_lru_locks osc
17012         BEFORE=$(roc_hit)
17013         cat $file >/dev/null
17014         AFTER=$(roc_hit)
17015         if ! let "AFTER - BEFORE == 0"; then
17016                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17017         else
17018                 log "cache hits:: before: $BEFORE, after: $AFTER"
17019         fi
17020
17021         log "Turn on the read cache and turn off the write cache"
17022         set_cache read on
17023         set_cache writethrough off
17024
17025         log "Write data and read it back"
17026         log "It should not be satisfied from the cache."
17027         rm -f $file
17028         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17029         BEFORE=$(roc_hit)
17030         cancel_lru_locks osc
17031         cat $file >/dev/null
17032         AFTER=$(roc_hit)
17033         if ! let "AFTER - BEFORE == 0"; then
17034                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17035         else
17036                 log "cache hits:: before: $BEFORE, after: $AFTER"
17037         fi
17038
17039         log "Read again; it should be satisfied from the cache."
17040         BEFORE=$(roc_hit)
17041         cancel_lru_locks osc
17042         cat $file >/dev/null
17043         AFTER=$(roc_hit)
17044         if ! let "AFTER - BEFORE == CPAGES"; then
17045                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17046         else
17047                 log "cache hits:: before: $BEFORE, after: $AFTER"
17048         fi
17049
17050         restore_lustre_params < $p
17051         rm -f $p $file
17052 }
17053 run_test 156 "Verification of tunables"
17054
17055 test_160a() {
17056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17057         remote_mds_nodsh && skip "remote MDS with nodsh"
17058         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17059                 skip "Need MDS version at least 2.2.0"
17060
17061         changelog_register || error "changelog_register failed"
17062         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17063         changelog_users $SINGLEMDS | grep -q $cl_user ||
17064                 error "User $cl_user not found in changelog_users"
17065
17066         mkdir_on_mdt0 $DIR/$tdir
17067
17068         # change something
17069         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17070         changelog_clear 0 || error "changelog_clear failed"
17071         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17072         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17073         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17074         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17075         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17076         rm $DIR/$tdir/pics/desktop.jpg
17077
17078         echo "verifying changelog mask"
17079         changelog_chmask "-MKDIR"
17080         changelog_chmask "-CLOSE"
17081
17082         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17083         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17084
17085         changelog_chmask "+MKDIR"
17086         changelog_chmask "+CLOSE"
17087
17088         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17089         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17090
17091         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17092         CLOSES=$(changelog_dump | grep -c "CLOSE")
17093         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17094         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17095
17096         # verify contents
17097         echo "verifying target fid"
17098         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17099         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17100         [ "$fidc" == "$fidf" ] ||
17101                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17102         echo "verifying parent fid"
17103         # The FID returned from the Changelog may be the directory shard on
17104         # a different MDT, and not the FID returned by path2fid on the parent.
17105         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17106         # since this is what will matter when recreating this file in the tree.
17107         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17108         local pathp=$($LFS fid2path $MOUNT "$fidp")
17109         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17110                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17111
17112         echo "getting records for $cl_user"
17113         changelog_users $SINGLEMDS
17114         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17115         local nclr=3
17116         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17117                 error "changelog_clear failed"
17118         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17119         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17120         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17121                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17122
17123         local min0_rec=$(changelog_users $SINGLEMDS |
17124                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17125         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17126                           awk '{ print $1; exit; }')
17127
17128         changelog_dump | tail -n 5
17129         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17130         [ $first_rec == $((min0_rec + 1)) ] ||
17131                 error "first index should be $min0_rec + 1 not $first_rec"
17132
17133         # LU-3446 changelog index reset on MDT restart
17134         local cur_rec1=$(changelog_users $SINGLEMDS |
17135                          awk '/^current.index:/ { print $NF }')
17136         changelog_clear 0 ||
17137                 error "clear all changelog records for $cl_user failed"
17138         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17139         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17140                 error "Fail to start $SINGLEMDS"
17141         local cur_rec2=$(changelog_users $SINGLEMDS |
17142                          awk '/^current.index:/ { print $NF }')
17143         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17144         [ $cur_rec1 == $cur_rec2 ] ||
17145                 error "current index should be $cur_rec1 not $cur_rec2"
17146
17147         echo "verifying users from this test are deregistered"
17148         changelog_deregister || error "changelog_deregister failed"
17149         changelog_users $SINGLEMDS | grep -q $cl_user &&
17150                 error "User '$cl_user' still in changelog_users"
17151
17152         # lctl get_param -n mdd.*.changelog_users
17153         # current_index: 144
17154         # ID    index (idle seconds)
17155         # cl3   144   (2) mask=<list>
17156         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17157                 # this is the normal case where all users were deregistered
17158                 # make sure no new records are added when no users are present
17159                 local last_rec1=$(changelog_users $SINGLEMDS |
17160                                   awk '/^current.index:/ { print $NF }')
17161                 touch $DIR/$tdir/chloe
17162                 local last_rec2=$(changelog_users $SINGLEMDS |
17163                                   awk '/^current.index:/ { print $NF }')
17164                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17165                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17166         else
17167                 # any changelog users must be leftovers from a previous test
17168                 changelog_users $SINGLEMDS
17169                 echo "other changelog users; can't verify off"
17170         fi
17171 }
17172 run_test 160a "changelog sanity"
17173
17174 test_160b() { # LU-3587
17175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17176         remote_mds_nodsh && skip "remote MDS with nodsh"
17177         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17178                 skip "Need MDS version at least 2.2.0"
17179
17180         changelog_register || error "changelog_register failed"
17181         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17182         changelog_users $SINGLEMDS | grep -q $cl_user ||
17183                 error "User '$cl_user' not found in changelog_users"
17184
17185         local longname1=$(str_repeat a 255)
17186         local longname2=$(str_repeat b 255)
17187
17188         cd $DIR
17189         echo "creating very long named file"
17190         touch $longname1 || error "create of '$longname1' failed"
17191         echo "renaming very long named file"
17192         mv $longname1 $longname2
17193
17194         changelog_dump | grep RENME | tail -n 5
17195         rm -f $longname2
17196 }
17197 run_test 160b "Verify that very long rename doesn't crash in changelog"
17198
17199 test_160c() {
17200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17201         remote_mds_nodsh && skip "remote MDS with nodsh"
17202
17203         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17204                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17205                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17206                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17207
17208         local rc=0
17209
17210         # Registration step
17211         changelog_register || error "changelog_register failed"
17212
17213         rm -rf $DIR/$tdir
17214         mkdir -p $DIR/$tdir
17215         $MCREATE $DIR/$tdir/foo_160c
17216         changelog_chmask "-TRUNC"
17217         $TRUNCATE $DIR/$tdir/foo_160c 200
17218         changelog_chmask "+TRUNC"
17219         $TRUNCATE $DIR/$tdir/foo_160c 199
17220         changelog_dump | tail -n 5
17221         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17222         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17223 }
17224 run_test 160c "verify that changelog log catch the truncate event"
17225
17226 test_160d() {
17227         remote_mds_nodsh && skip "remote MDS with nodsh"
17228         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17230         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17231                 skip "Need MDS version at least 2.7.60"
17232
17233         # Registration step
17234         changelog_register || error "changelog_register failed"
17235
17236         mkdir -p $DIR/$tdir/migrate_dir
17237         changelog_clear 0 || error "changelog_clear failed"
17238
17239         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17240         changelog_dump | tail -n 5
17241         local migrates=$(changelog_dump | grep -c "MIGRT")
17242         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17243 }
17244 run_test 160d "verify that changelog log catch the migrate event"
17245
17246 test_160e() {
17247         remote_mds_nodsh && skip "remote MDS with nodsh"
17248
17249         # Create a user
17250         changelog_register || error "changelog_register failed"
17251
17252         local MDT0=$(facet_svc $SINGLEMDS)
17253         local rc
17254
17255         # No user (expect fail)
17256         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17257         rc=$?
17258         if [ $rc -eq 0 ]; then
17259                 error "Should fail without user"
17260         elif [ $rc -ne 4 ]; then
17261                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17262         fi
17263
17264         # Delete a future user (expect fail)
17265         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17266         rc=$?
17267         if [ $rc -eq 0 ]; then
17268                 error "Deleted non-existant user cl77"
17269         elif [ $rc -ne 2 ]; then
17270                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17271         fi
17272
17273         # Clear to a bad index (1 billion should be safe)
17274         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17275         rc=$?
17276
17277         if [ $rc -eq 0 ]; then
17278                 error "Successfully cleared to invalid CL index"
17279         elif [ $rc -ne 22 ]; then
17280                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17281         fi
17282 }
17283 run_test 160e "changelog negative testing (should return errors)"
17284
17285 test_160f() {
17286         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17287         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17288                 skip "Need MDS version at least 2.10.56"
17289
17290         local mdts=$(comma_list $(mdts_nodes))
17291
17292         # Create a user
17293         changelog_register || error "first changelog_register failed"
17294         changelog_register || error "second changelog_register failed"
17295         local cl_users
17296         declare -A cl_user1
17297         declare -A cl_user2
17298         local user_rec1
17299         local user_rec2
17300         local i
17301
17302         # generate some changelog records to accumulate on each MDT
17303         # use all_char because created files should be evenly distributed
17304         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17305                 error "test_mkdir $tdir failed"
17306         log "$(date +%s): creating first files"
17307         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17308                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17309                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17310         done
17311
17312         # check changelogs have been generated
17313         local start=$SECONDS
17314         local idle_time=$((MDSCOUNT * 5 + 5))
17315         local nbcl=$(changelog_dump | wc -l)
17316         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17317
17318         for param in "changelog_max_idle_time=$idle_time" \
17319                      "changelog_gc=1" \
17320                      "changelog_min_gc_interval=2" \
17321                      "changelog_min_free_cat_entries=3"; do
17322                 local MDT0=$(facet_svc $SINGLEMDS)
17323                 local var="${param%=*}"
17324                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17325
17326                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17327                 do_nodes $mdts $LCTL set_param mdd.*.$param
17328         done
17329
17330         # force cl_user2 to be idle (1st part), but also cancel the
17331         # cl_user1 records so that it is not evicted later in the test.
17332         local sleep1=$((idle_time / 2))
17333         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17334         sleep $sleep1
17335
17336         # simulate changelog catalog almost full
17337         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17338         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17339
17340         for i in $(seq $MDSCOUNT); do
17341                 cl_users=(${CL_USERS[mds$i]})
17342                 cl_user1[mds$i]="${cl_users[0]}"
17343                 cl_user2[mds$i]="${cl_users[1]}"
17344
17345                 [ -n "${cl_user1[mds$i]}" ] ||
17346                         error "mds$i: no user registered"
17347                 [ -n "${cl_user2[mds$i]}" ] ||
17348                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17349
17350                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17351                 [ -n "$user_rec1" ] ||
17352                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17353                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17354                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17355                 [ -n "$user_rec2" ] ||
17356                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17357                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17358                      "$user_rec1 + 2 == $user_rec2"
17359                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17360                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17361                               "$user_rec1 + 2, but is $user_rec2"
17362                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17363                 [ -n "$user_rec2" ] ||
17364                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17365                 [ $user_rec1 == $user_rec2 ] ||
17366                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17367                               "$user_rec1, but is $user_rec2"
17368         done
17369
17370         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17371         local sleep2=$((idle_time - (SECONDS - start) + 1))
17372         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17373         sleep $sleep2
17374
17375         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17376         # cl_user1 should be OK because it recently processed records.
17377         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17378         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17379                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17380                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17381         done
17382
17383         # ensure gc thread is done
17384         for i in $(mdts_nodes); do
17385                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17386                         error "$i: GC-thread not done"
17387         done
17388
17389         local first_rec
17390         for (( i = 1; i <= MDSCOUNT; i++ )); do
17391                 # check cl_user1 still registered
17392                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17393                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17394                 # check cl_user2 unregistered
17395                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17396                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17397
17398                 # check changelogs are present and starting at $user_rec1 + 1
17399                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17400                 [ -n "$user_rec1" ] ||
17401                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17402                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17403                             awk '{ print $1; exit; }')
17404
17405                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17406                 [ $((user_rec1 + 1)) == $first_rec ] ||
17407                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17408         done
17409 }
17410 run_test 160f "changelog garbage collect (timestamped users)"
17411
17412 test_160g() {
17413         remote_mds_nodsh && skip "remote MDS with nodsh"
17414         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17415                 skip "Need MDS version at least 2.14.55"
17416
17417         local mdts=$(comma_list $(mdts_nodes))
17418
17419         # Create a user
17420         changelog_register || error "first changelog_register failed"
17421         changelog_register || error "second changelog_register failed"
17422         local cl_users
17423         declare -A cl_user1
17424         declare -A cl_user2
17425         local user_rec1
17426         local user_rec2
17427         local i
17428
17429         # generate some changelog records to accumulate on each MDT
17430         # use all_char because created files should be evenly distributed
17431         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17432                 error "test_mkdir $tdir failed"
17433         for ((i = 0; i < MDSCOUNT; i++)); do
17434                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17435                         error "create $DIR/$tdir/d$i.1 failed"
17436         done
17437
17438         # check changelogs have been generated
17439         local nbcl=$(changelog_dump | wc -l)
17440         (( $nbcl > 0 )) || error "no changelogs found"
17441
17442         # reduce the max_idle_indexes value to make sure we exceed it
17443         for param in "changelog_max_idle_indexes=2" \
17444                      "changelog_gc=1" \
17445                      "changelog_min_gc_interval=2"; do
17446                 local MDT0=$(facet_svc $SINGLEMDS)
17447                 local var="${param%=*}"
17448                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17449
17450                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17451                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17452                         error "unable to set mdd.*.$param"
17453         done
17454
17455         local start=$SECONDS
17456         for i in $(seq $MDSCOUNT); do
17457                 cl_users=(${CL_USERS[mds$i]})
17458                 cl_user1[mds$i]="${cl_users[0]}"
17459                 cl_user2[mds$i]="${cl_users[1]}"
17460
17461                 [ -n "${cl_user1[mds$i]}" ] ||
17462                         error "mds$i: user1 is not registered"
17463                 [ -n "${cl_user2[mds$i]}" ] ||
17464                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17465
17466                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17467                 [ -n "$user_rec1" ] ||
17468                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17469                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17470                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17471                 [ -n "$user_rec2" ] ||
17472                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17473                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17474                      "$user_rec1 + 2 == $user_rec2"
17475                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17476                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17477                               "expected $user_rec1 + 2, but is $user_rec2"
17478                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17479                 [ -n "$user_rec2" ] ||
17480                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17481                 [ $user_rec1 == $user_rec2 ] ||
17482                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17483                               "expected $user_rec1, but is $user_rec2"
17484         done
17485
17486         # ensure we are past the previous changelog_min_gc_interval set above
17487         local sleep2=$((start + 2 - SECONDS))
17488         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17489         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17490         # cl_user1 should be OK because it recently processed records.
17491         for ((i = 0; i < MDSCOUNT; i++)); do
17492                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17493                         error "create $DIR/$tdir/d$i.3 failed"
17494         done
17495
17496         # ensure gc thread is done
17497         for i in $(mdts_nodes); do
17498                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17499                         error "$i: GC-thread not done"
17500         done
17501
17502         local first_rec
17503         for (( i = 1; i <= MDSCOUNT; i++ )); do
17504                 # check cl_user1 still registered
17505                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17506                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17507                 # check cl_user2 unregistered
17508                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17509                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17510
17511                 # check changelogs are present and starting at $user_rec1 + 1
17512                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17513                 [ -n "$user_rec1" ] ||
17514                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17515                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17516                             awk '{ print $1; exit; }')
17517
17518                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17519                 [ $((user_rec1 + 1)) == $first_rec ] ||
17520                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17521         done
17522 }
17523 run_test 160g "changelog garbage collect on idle records"
17524
17525 test_160h() {
17526         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17527         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17528                 skip "Need MDS version at least 2.10.56"
17529
17530         local mdts=$(comma_list $(mdts_nodes))
17531
17532         # Create a user
17533         changelog_register || error "first changelog_register failed"
17534         changelog_register || error "second changelog_register failed"
17535         local cl_users
17536         declare -A cl_user1
17537         declare -A cl_user2
17538         local user_rec1
17539         local user_rec2
17540         local i
17541
17542         # generate some changelog records to accumulate on each MDT
17543         # use all_char because created files should be evenly distributed
17544         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17545                 error "test_mkdir $tdir failed"
17546         for ((i = 0; i < MDSCOUNT; i++)); do
17547                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17548                         error "create $DIR/$tdir/d$i.1 failed"
17549         done
17550
17551         # check changelogs have been generated
17552         local nbcl=$(changelog_dump | wc -l)
17553         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17554
17555         for param in "changelog_max_idle_time=10" \
17556                      "changelog_gc=1" \
17557                      "changelog_min_gc_interval=2"; do
17558                 local MDT0=$(facet_svc $SINGLEMDS)
17559                 local var="${param%=*}"
17560                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17561
17562                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17563                 do_nodes $mdts $LCTL set_param mdd.*.$param
17564         done
17565
17566         # force cl_user2 to be idle (1st part)
17567         sleep 9
17568
17569         for i in $(seq $MDSCOUNT); do
17570                 cl_users=(${CL_USERS[mds$i]})
17571                 cl_user1[mds$i]="${cl_users[0]}"
17572                 cl_user2[mds$i]="${cl_users[1]}"
17573
17574                 [ -n "${cl_user1[mds$i]}" ] ||
17575                         error "mds$i: no user registered"
17576                 [ -n "${cl_user2[mds$i]}" ] ||
17577                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17578
17579                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17580                 [ -n "$user_rec1" ] ||
17581                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17582                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17583                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17584                 [ -n "$user_rec2" ] ||
17585                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17586                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17587                      "$user_rec1 + 2 == $user_rec2"
17588                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17589                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17590                               "$user_rec1 + 2, but is $user_rec2"
17591                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17592                 [ -n "$user_rec2" ] ||
17593                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17594                 [ $user_rec1 == $user_rec2 ] ||
17595                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17596                               "$user_rec1, but is $user_rec2"
17597         done
17598
17599         # force cl_user2 to be idle (2nd part) and to reach
17600         # changelog_max_idle_time
17601         sleep 2
17602
17603         # force each GC-thread start and block then
17604         # one per MDT/MDD, set fail_val accordingly
17605         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17606         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17607
17608         # generate more changelogs to trigger fail_loc
17609         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17610                 error "create $DIR/$tdir/${tfile}bis failed"
17611
17612         # stop MDT to stop GC-thread, should be done in back-ground as it will
17613         # block waiting for the thread to be released and exit
17614         declare -A stop_pids
17615         for i in $(seq $MDSCOUNT); do
17616                 stop mds$i &
17617                 stop_pids[mds$i]=$!
17618         done
17619
17620         for i in $(mdts_nodes); do
17621                 local facet
17622                 local nb=0
17623                 local facets=$(facets_up_on_host $i)
17624
17625                 for facet in ${facets//,/ }; do
17626                         if [[ $facet == mds* ]]; then
17627                                 nb=$((nb + 1))
17628                         fi
17629                 done
17630                 # ensure each MDS's gc threads are still present and all in "R"
17631                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17632                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17633                         error "$i: expected $nb GC-thread"
17634                 wait_update $i \
17635                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17636                         "R" 20 ||
17637                         error "$i: GC-thread not found in R-state"
17638                 # check umounts of each MDT on MDS have reached kthread_stop()
17639                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17640                         error "$i: expected $nb umount"
17641                 wait_update $i \
17642                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17643                         error "$i: umount not found in D-state"
17644         done
17645
17646         # release all GC-threads
17647         do_nodes $mdts $LCTL set_param fail_loc=0
17648
17649         # wait for MDT stop to complete
17650         for i in $(seq $MDSCOUNT); do
17651                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17652         done
17653
17654         # XXX
17655         # may try to check if any orphan changelog records are present
17656         # via ldiskfs/zfs and llog_reader...
17657
17658         # re-start/mount MDTs
17659         for i in $(seq $MDSCOUNT); do
17660                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17661                         error "Fail to start mds$i"
17662         done
17663
17664         local first_rec
17665         for i in $(seq $MDSCOUNT); do
17666                 # check cl_user1 still registered
17667                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17668                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17669                 # check cl_user2 unregistered
17670                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17671                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17672
17673                 # check changelogs are present and starting at $user_rec1 + 1
17674                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17675                 [ -n "$user_rec1" ] ||
17676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17677                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17678                             awk '{ print $1; exit; }')
17679
17680                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17681                 [ $((user_rec1 + 1)) == $first_rec ] ||
17682                         error "mds$i: first index should be $user_rec1 + 1, " \
17683                               "but is $first_rec"
17684         done
17685 }
17686 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17687               "during mount"
17688
17689 test_160i() {
17690
17691         local mdts=$(comma_list $(mdts_nodes))
17692
17693         changelog_register || error "first changelog_register failed"
17694
17695         # generate some changelog records to accumulate on each MDT
17696         # use all_char because created files should be evenly distributed
17697         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17698                 error "test_mkdir $tdir failed"
17699         for ((i = 0; i < MDSCOUNT; i++)); do
17700                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17701                         error "create $DIR/$tdir/d$i.1 failed"
17702         done
17703
17704         # check changelogs have been generated
17705         local nbcl=$(changelog_dump | wc -l)
17706         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17707
17708         # simulate race between register and unregister
17709         # XXX as fail_loc is set per-MDS, with DNE configs the race
17710         # simulation will only occur for one MDT per MDS and for the
17711         # others the normal race scenario will take place
17712         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17713         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17714         do_nodes $mdts $LCTL set_param fail_val=1
17715
17716         # unregister 1st user
17717         changelog_deregister &
17718         local pid1=$!
17719         # wait some time for deregister work to reach race rdv
17720         sleep 2
17721         # register 2nd user
17722         changelog_register || error "2nd user register failed"
17723
17724         wait $pid1 || error "1st user deregister failed"
17725
17726         local i
17727         local last_rec
17728         declare -A LAST_REC
17729         for i in $(seq $MDSCOUNT); do
17730                 if changelog_users mds$i | grep "^cl"; then
17731                         # make sure new records are added with one user present
17732                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17733                                           awk '/^current.index:/ { print $NF }')
17734                 else
17735                         error "mds$i has no user registered"
17736                 fi
17737         done
17738
17739         # generate more changelog records to accumulate on each MDT
17740         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17741                 error "create $DIR/$tdir/${tfile}bis failed"
17742
17743         for i in $(seq $MDSCOUNT); do
17744                 last_rec=$(changelog_users $SINGLEMDS |
17745                            awk '/^current.index:/ { print $NF }')
17746                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17747                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17748                         error "changelogs are off on mds$i"
17749         done
17750 }
17751 run_test 160i "changelog user register/unregister race"
17752
17753 test_160j() {
17754         remote_mds_nodsh && skip "remote MDS with nodsh"
17755         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17756                 skip "Need MDS version at least 2.12.56"
17757
17758         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17759         stack_trap "umount $MOUNT2" EXIT
17760
17761         changelog_register || error "first changelog_register failed"
17762         stack_trap "changelog_deregister" EXIT
17763
17764         # generate some changelog
17765         # use all_char because created files should be evenly distributed
17766         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17767                 error "mkdir $tdir failed"
17768         for ((i = 0; i < MDSCOUNT; i++)); do
17769                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17770                         error "create $DIR/$tdir/d$i.1 failed"
17771         done
17772
17773         # open the changelog device
17774         exec 3>/dev/changelog-$FSNAME-MDT0000
17775         stack_trap "exec 3>&-" EXIT
17776         exec 4</dev/changelog-$FSNAME-MDT0000
17777         stack_trap "exec 4<&-" EXIT
17778
17779         # umount the first lustre mount
17780         umount $MOUNT
17781         stack_trap "mount_client $MOUNT" EXIT
17782
17783         # read changelog, which may or may not fail, but should not crash
17784         cat <&4 >/dev/null
17785
17786         # clear changelog
17787         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17788         changelog_users $SINGLEMDS | grep -q $cl_user ||
17789                 error "User $cl_user not found in changelog_users"
17790
17791         printf 'clear:'$cl_user':0' >&3
17792 }
17793 run_test 160j "client can be umounted while its chanangelog is being used"
17794
17795 test_160k() {
17796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17797         remote_mds_nodsh && skip "remote MDS with nodsh"
17798
17799         mkdir -p $DIR/$tdir/1/1
17800
17801         changelog_register || error "changelog_register failed"
17802         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17803
17804         changelog_users $SINGLEMDS | grep -q $cl_user ||
17805                 error "User '$cl_user' not found in changelog_users"
17806 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17807         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17808         rmdir $DIR/$tdir/1/1 & sleep 1
17809         mkdir $DIR/$tdir/2
17810         touch $DIR/$tdir/2/2
17811         rm -rf $DIR/$tdir/2
17812
17813         wait
17814         sleep 4
17815
17816         changelog_dump | grep rmdir || error "rmdir not recorded"
17817 }
17818 run_test 160k "Verify that changelog records are not lost"
17819
17820 # Verifies that a file passed as a parameter has recently had an operation
17821 # performed on it that has generated an MTIME changelog which contains the
17822 # correct parent FID. As files might reside on a different MDT from the
17823 # parent directory in DNE configurations, the FIDs are translated to paths
17824 # before being compared, which should be identical
17825 compare_mtime_changelog() {
17826         local file="${1}"
17827         local mdtidx
17828         local mtime
17829         local cl_fid
17830         local pdir
17831         local dir
17832
17833         mdtidx=$($LFS getstripe --mdt-index $file)
17834         mdtidx=$(printf "%04x" $mdtidx)
17835
17836         # Obtain the parent FID from the MTIME changelog
17837         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17838         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17839
17840         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17841         [ -z "$cl_fid" ] && error "parent FID not present"
17842
17843         # Verify that the path for the parent FID is the same as the path for
17844         # the test directory
17845         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17846
17847         dir=$(dirname $1)
17848
17849         [[ "${pdir%/}" == "$dir" ]] ||
17850                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17851 }
17852
17853 test_160l() {
17854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17855
17856         remote_mds_nodsh && skip "remote MDS with nodsh"
17857         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17858                 skip "Need MDS version at least 2.13.55"
17859
17860         local cl_user
17861
17862         changelog_register || error "changelog_register failed"
17863         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17864
17865         changelog_users $SINGLEMDS | grep -q $cl_user ||
17866                 error "User '$cl_user' not found in changelog_users"
17867
17868         # Clear some types so that MTIME changelogs are generated
17869         changelog_chmask "-CREAT"
17870         changelog_chmask "-CLOSE"
17871
17872         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17873
17874         # Test CL_MTIME during setattr
17875         touch $DIR/$tdir/$tfile
17876         compare_mtime_changelog $DIR/$tdir/$tfile
17877
17878         # Test CL_MTIME during close
17879         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17880         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17881 }
17882 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17883
17884 test_160m() {
17885         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17886         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17887                 skip "Need MDS version at least 2.14.51"
17888         local cl_users
17889         local cl_user1
17890         local cl_user2
17891         local pid1
17892
17893         # Create a user
17894         changelog_register || error "first changelog_register failed"
17895         changelog_register || error "second changelog_register failed"
17896
17897         cl_users=(${CL_USERS[mds1]})
17898         cl_user1="${cl_users[0]}"
17899         cl_user2="${cl_users[1]}"
17900         # generate some changelog records to accumulate on MDT0
17901         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17902         createmany -m $DIR/$tdir/$tfile 50 ||
17903                 error "create $DIR/$tdir/$tfile failed"
17904         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17905         rm -f $DIR/$tdir
17906
17907         # check changelogs have been generated
17908         local nbcl=$(changelog_dump | wc -l)
17909         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17910
17911 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17912         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17913
17914         __changelog_clear mds1 $cl_user1 +10
17915         __changelog_clear mds1 $cl_user2 0 &
17916         pid1=$!
17917         sleep 2
17918         __changelog_clear mds1 $cl_user1 0 ||
17919                 error "fail to cancel record for $cl_user1"
17920         wait $pid1
17921         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17922 }
17923 run_test 160m "Changelog clear race"
17924
17925 test_160n() {
17926         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17927         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17928                 skip "Need MDS version at least 2.14.51"
17929         local cl_users
17930         local cl_user1
17931         local cl_user2
17932         local pid1
17933         local first_rec
17934         local last_rec=0
17935
17936         # Create a user
17937         changelog_register || error "first changelog_register failed"
17938
17939         cl_users=(${CL_USERS[mds1]})
17940         cl_user1="${cl_users[0]}"
17941
17942         # generate some changelog records to accumulate on MDT0
17943         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17944         first_rec=$(changelog_users $SINGLEMDS |
17945                         awk '/^current.index:/ { print $NF }')
17946         while (( last_rec < (( first_rec + 65000)) )); do
17947                 createmany -m $DIR/$tdir/$tfile 10000 ||
17948                         error "create $DIR/$tdir/$tfile failed"
17949
17950                 for i in $(seq 0 10000); do
17951                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17952                                 > /dev/null
17953                 done
17954
17955                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17956                         error "unlinkmany failed unlink"
17957                 last_rec=$(changelog_users $SINGLEMDS |
17958                         awk '/^current.index:/ { print $NF }')
17959                 echo last record $last_rec
17960                 (( last_rec == 0 )) && error "no changelog found"
17961         done
17962
17963 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17964         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17965
17966         __changelog_clear mds1 $cl_user1 0 &
17967         pid1=$!
17968         sleep 2
17969         __changelog_clear mds1 $cl_user1 0 ||
17970                 error "fail to cancel record for $cl_user1"
17971         wait $pid1
17972         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17973 }
17974 run_test 160n "Changelog destroy race"
17975
17976 test_160o() {
17977         local mdt="$(facet_svc $SINGLEMDS)"
17978
17979         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17980         remote_mds_nodsh && skip "remote MDS with nodsh"
17981         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17982                 skip "Need MDS version at least 2.14.52"
17983
17984         changelog_register --user test_160o -m unlnk+close+open ||
17985                 error "changelog_register failed"
17986
17987         do_facet $SINGLEMDS $LCTL --device $mdt \
17988                                 changelog_register -u "Tt3_-#" &&
17989                 error "bad symbols in name should fail"
17990
17991         do_facet $SINGLEMDS $LCTL --device $mdt \
17992                                 changelog_register -u test_160o &&
17993                 error "the same name registration should fail"
17994
17995         do_facet $SINGLEMDS $LCTL --device $mdt \
17996                         changelog_register -u test_160toolongname &&
17997                 error "too long name registration should fail"
17998
17999         changelog_chmask "MARK+HSM"
18000         lctl get_param mdd.*.changelog*mask
18001         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18002         changelog_users $SINGLEMDS | grep -q $cl_user ||
18003                 error "User $cl_user not found in changelog_users"
18004         #verify username
18005         echo $cl_user | grep -q test_160o ||
18006                 error "User $cl_user has no specific name 'test160o'"
18007
18008         # change something
18009         changelog_clear 0 || error "changelog_clear failed"
18010         # generate some changelog records to accumulate on MDT0
18011         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18012         touch $DIR/$tdir/$tfile                 # open 1
18013
18014         OPENS=$(changelog_dump | grep -c "OPEN")
18015         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18016
18017         # must be no MKDIR it wasn't set as user mask
18018         MKDIR=$(changelog_dump | grep -c "MKDIR")
18019         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18020
18021         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18022                                 mdd.$mdt.changelog_current_mask -n)
18023         # register maskless user
18024         changelog_register || error "changelog_register failed"
18025         # effective mask should be not changed because it is not minimal
18026         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18027                                 mdd.$mdt.changelog_current_mask -n)
18028         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18029         # set server mask to minimal value
18030         changelog_chmask "MARK"
18031         # check effective mask again, should be treated as DEFMASK now
18032         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18033                                 mdd.$mdt.changelog_current_mask -n)
18034         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18035
18036         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18037                 # set server mask back to some value
18038                 changelog_chmask "CLOSE,UNLNK"
18039                 # check effective mask again, should not remain as DEFMASK
18040                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18041                                 mdd.$mdt.changelog_current_mask -n)
18042                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18043         fi
18044
18045         do_facet $SINGLEMDS $LCTL --device $mdt \
18046                                 changelog_deregister -u test_160o ||
18047                 error "cannot deregister by name"
18048 }
18049 run_test 160o "changelog user name and mask"
18050
18051 test_160p() {
18052         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18053         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18054                 skip "Need MDS version at least 2.14.51"
18055         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18056         local cl_users
18057         local cl_user1
18058         local entry_count
18059
18060         # Create a user
18061         changelog_register || error "first changelog_register failed"
18062
18063         cl_users=(${CL_USERS[mds1]})
18064         cl_user1="${cl_users[0]}"
18065
18066         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18067         createmany -m $DIR/$tdir/$tfile 50 ||
18068                 error "create $DIR/$tdir/$tfile failed"
18069         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18070         rm -rf $DIR/$tdir
18071
18072         # check changelogs have been generated
18073         entry_count=$(changelog_dump | wc -l)
18074         ((entry_count != 0)) || error "no changelog entries found"
18075
18076         # remove changelog_users and check that orphan entries are removed
18077         stop mds1
18078         local dev=$(mdsdevname 1)
18079         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18080         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18081         entry_count=$(changelog_dump | wc -l)
18082         ((entry_count == 0)) ||
18083                 error "found $entry_count changelog entries, expected none"
18084 }
18085 run_test 160p "Changelog orphan cleanup with no users"
18086
18087 test_160q() {
18088         local mdt="$(facet_svc $SINGLEMDS)"
18089         local clu
18090
18091         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18092         remote_mds_nodsh && skip "remote MDS with nodsh"
18093         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18094                 skip "Need MDS version at least 2.14.54"
18095
18096         # set server mask to minimal value like server init does
18097         changelog_chmask "MARK"
18098         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18099                 error "changelog_register failed"
18100         # check effective mask again, should be treated as DEFMASK now
18101         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18102                                 mdd.$mdt.changelog_current_mask -n)
18103         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18104                 error "changelog_deregister failed"
18105         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18106 }
18107 run_test 160q "changelog effective mask is DEFMASK if not set"
18108
18109 test_160s() {
18110         remote_mds_nodsh && skip "remote MDS with nodsh"
18111         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18112                 skip "Need MDS version at least 2.14.55"
18113
18114         local mdts=$(comma_list $(mdts_nodes))
18115
18116         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18117         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18118                                        fail_val=$((24 * 3600 * 10))
18119
18120         # Create a user which is 10 days old
18121         changelog_register || error "first changelog_register failed"
18122         local cl_users
18123         declare -A cl_user1
18124         local i
18125
18126         # generate some changelog records to accumulate on each MDT
18127         # use all_char because created files should be evenly distributed
18128         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18129                 error "test_mkdir $tdir failed"
18130         for ((i = 0; i < MDSCOUNT; i++)); do
18131                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18132                         error "create $DIR/$tdir/d$i.1 failed"
18133         done
18134
18135         # check changelogs have been generated
18136         local nbcl=$(changelog_dump | wc -l)
18137         (( nbcl > 0 )) || error "no changelogs found"
18138
18139         # reduce the max_idle_indexes value to make sure we exceed it
18140         for param in "changelog_max_idle_indexes=2097446912" \
18141                      "changelog_max_idle_time=2592000" \
18142                      "changelog_gc=1" \
18143                      "changelog_min_gc_interval=2"; do
18144                 local MDT0=$(facet_svc $SINGLEMDS)
18145                 local var="${param%=*}"
18146                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18147
18148                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18149                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18150                         error "unable to set mdd.*.$param"
18151         done
18152
18153         local start=$SECONDS
18154         for i in $(seq $MDSCOUNT); do
18155                 cl_users=(${CL_USERS[mds$i]})
18156                 cl_user1[mds$i]="${cl_users[0]}"
18157
18158                 [[ -n "${cl_user1[mds$i]}" ]] ||
18159                         error "mds$i: no user registered"
18160         done
18161
18162         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18163         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18164
18165         # ensure we are past the previous changelog_min_gc_interval set above
18166         local sleep2=$((start + 2 - SECONDS))
18167         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18168
18169         # Generate one more changelog to trigger GC
18170         for ((i = 0; i < MDSCOUNT; i++)); do
18171                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18172                         error "create $DIR/$tdir/d$i.3 failed"
18173         done
18174
18175         # ensure gc thread is done
18176         for node in $(mdts_nodes); do
18177                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18178                         error "$node: GC-thread not done"
18179         done
18180
18181         do_nodes $mdts $LCTL set_param fail_loc=0
18182
18183         for (( i = 1; i <= MDSCOUNT; i++ )); do
18184                 # check cl_user1 is purged
18185                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18186                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18187         done
18188         return 0
18189 }
18190 run_test 160s "changelog garbage collect on idle records * time"
18191
18192 test_160t() {
18193         remote_mds_nodsh && skip "remote MDS with nodsh"
18194         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18195                 skip "Need MDS version at least 2.15.50"
18196
18197         local MDT0=$(facet_svc $SINGLEMDS)
18198         local cl_users
18199         local cl_user1
18200         local cl_user2
18201         local start
18202
18203         changelog_register --user user1 -m all ||
18204                 error "user1 failed to register"
18205
18206         mkdir_on_mdt0 $DIR/$tdir
18207         # create default overstripe to maximize changelog size
18208         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18209         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18210         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18211
18212         # user2 consumes less records so less space
18213         changelog_register --user user2 || error "user2 failed to register"
18214         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18215         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18216
18217         # check changelogs have been generated
18218         local nbcl=$(changelog_dump | wc -l)
18219         (( nbcl > 0 )) || error "no changelogs found"
18220
18221         # reduce the changelog_min_gc_interval to force check
18222         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18223                 local var="${param%=*}"
18224                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18225
18226                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18227                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18228                         error "unable to set mdd.*.$param"
18229         done
18230
18231         start=$SECONDS
18232         cl_users=(${CL_USERS[mds1]})
18233         cl_user1="${cl_users[0]}"
18234         cl_user2="${cl_users[1]}"
18235
18236         [[ -n $cl_user1 ]] ||
18237                 error "mds1: user #1 isn't registered"
18238         [[ -n $cl_user2 ]] ||
18239                 error "mds1: user #2 isn't registered"
18240
18241         # ensure we are past the previous changelog_min_gc_interval set above
18242         local sleep2=$((start + 2 - SECONDS))
18243         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18244
18245         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18246         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18247                         fail_val=$(((llog_size1 + llog_size2) / 2))
18248
18249         # Generate more changelog to trigger GC
18250         createmany -o $DIR/$tdir/u3_ 4 ||
18251                 error "create failed for more files"
18252
18253         # ensure gc thread is done
18254         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18255                 error "mds1: GC-thread not done"
18256
18257         do_facet mds1 $LCTL set_param fail_loc=0
18258
18259         # check cl_user1 is purged
18260         changelog_users mds1 | grep -q "$cl_user1" &&
18261                 error "User $cl_user1 is registered"
18262         # check cl_user2 is not purged
18263         changelog_users mds1 | grep -q "$cl_user2" ||
18264                 error "User $cl_user2 is not registered"
18265 }
18266 run_test 160t "changelog garbage collect on lack of space"
18267
18268 test_161a() {
18269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18270
18271         test_mkdir -c1 $DIR/$tdir
18272         cp /etc/hosts $DIR/$tdir/$tfile
18273         test_mkdir -c1 $DIR/$tdir/foo1
18274         test_mkdir -c1 $DIR/$tdir/foo2
18275         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18276         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18277         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18278         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18279         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18280         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18281                 $LFS fid2path $DIR $FID
18282                 error "bad link ea"
18283         fi
18284         # middle
18285         rm $DIR/$tdir/foo2/zachary
18286         # last
18287         rm $DIR/$tdir/foo2/thor
18288         # first
18289         rm $DIR/$tdir/$tfile
18290         # rename
18291         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18292         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18293                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18294         rm $DIR/$tdir/foo2/maggie
18295
18296         # overflow the EA
18297         local longname=$tfile.avg_len_is_thirty_two_
18298         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18299                 error_noexit 'failed to unlink many hardlinks'" EXIT
18300         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18301                 error "failed to hardlink many files"
18302         links=$($LFS fid2path $DIR $FID | wc -l)
18303         echo -n "${links}/1000 links in link EA"
18304         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18305 }
18306 run_test 161a "link ea sanity"
18307
18308 test_161b() {
18309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18310         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18311
18312         local MDTIDX=1
18313         local remote_dir=$DIR/$tdir/remote_dir
18314
18315         mkdir -p $DIR/$tdir
18316         $LFS mkdir -i $MDTIDX $remote_dir ||
18317                 error "create remote directory failed"
18318
18319         cp /etc/hosts $remote_dir/$tfile
18320         mkdir -p $remote_dir/foo1
18321         mkdir -p $remote_dir/foo2
18322         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18323         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18324         ln $remote_dir/$tfile $remote_dir/foo1/luna
18325         ln $remote_dir/$tfile $remote_dir/foo2/thor
18326
18327         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18328                      tr -d ']')
18329         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18330                 $LFS fid2path $DIR $FID
18331                 error "bad link ea"
18332         fi
18333         # middle
18334         rm $remote_dir/foo2/zachary
18335         # last
18336         rm $remote_dir/foo2/thor
18337         # first
18338         rm $remote_dir/$tfile
18339         # rename
18340         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18341         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18342         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18343                 $LFS fid2path $DIR $FID
18344                 error "bad link rename"
18345         fi
18346         rm $remote_dir/foo2/maggie
18347
18348         # overflow the EA
18349         local longname=filename_avg_len_is_thirty_two_
18350         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18351                 error "failed to hardlink many files"
18352         links=$($LFS fid2path $DIR $FID | wc -l)
18353         echo -n "${links}/1000 links in link EA"
18354         [[ ${links} -gt 60 ]] ||
18355                 error "expected at least 60 links in link EA"
18356         unlinkmany $remote_dir/foo2/$longname 1000 ||
18357         error "failed to unlink many hardlinks"
18358 }
18359 run_test 161b "link ea sanity under remote directory"
18360
18361 test_161c() {
18362         remote_mds_nodsh && skip "remote MDS with nodsh"
18363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18364         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18365                 skip "Need MDS version at least 2.1.5"
18366
18367         # define CLF_RENAME_LAST 0x0001
18368         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18369         changelog_register || error "changelog_register failed"
18370
18371         rm -rf $DIR/$tdir
18372         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18373         touch $DIR/$tdir/foo_161c
18374         touch $DIR/$tdir/bar_161c
18375         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18376         changelog_dump | grep RENME | tail -n 5
18377         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18378         changelog_clear 0 || error "changelog_clear failed"
18379         if [ x$flags != "x0x1" ]; then
18380                 error "flag $flags is not 0x1"
18381         fi
18382
18383         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18384         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18385         touch $DIR/$tdir/foo_161c
18386         touch $DIR/$tdir/bar_161c
18387         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18388         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18389         changelog_dump | grep RENME | tail -n 5
18390         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18391         changelog_clear 0 || error "changelog_clear failed"
18392         if [ x$flags != "x0x0" ]; then
18393                 error "flag $flags is not 0x0"
18394         fi
18395         echo "rename overwrite a target having nlink > 1," \
18396                 "changelog record has flags of $flags"
18397
18398         # rename doesn't overwrite a target (changelog flag 0x0)
18399         touch $DIR/$tdir/foo_161c
18400         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18401         changelog_dump | grep RENME | tail -n 5
18402         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18403         changelog_clear 0 || error "changelog_clear failed"
18404         if [ x$flags != "x0x0" ]; then
18405                 error "flag $flags is not 0x0"
18406         fi
18407         echo "rename doesn't overwrite a target," \
18408                 "changelog record has flags of $flags"
18409
18410         # define CLF_UNLINK_LAST 0x0001
18411         # unlink a file having nlink = 1 (changelog flag 0x1)
18412         rm -f $DIR/$tdir/foo2_161c
18413         changelog_dump | grep UNLNK | tail -n 5
18414         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18415         changelog_clear 0 || error "changelog_clear failed"
18416         if [ x$flags != "x0x1" ]; then
18417                 error "flag $flags is not 0x1"
18418         fi
18419         echo "unlink a file having nlink = 1," \
18420                 "changelog record has flags of $flags"
18421
18422         # unlink a file having nlink > 1 (changelog flag 0x0)
18423         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18424         rm -f $DIR/$tdir/foobar_161c
18425         changelog_dump | grep UNLNK | tail -n 5
18426         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18427         changelog_clear 0 || error "changelog_clear failed"
18428         if [ x$flags != "x0x0" ]; then
18429                 error "flag $flags is not 0x0"
18430         fi
18431         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18432 }
18433 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18434
18435 test_161d() {
18436         remote_mds_nodsh && skip "remote MDS with nodsh"
18437         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18438
18439         local pid
18440         local fid
18441
18442         changelog_register || error "changelog_register failed"
18443
18444         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18445         # interfer with $MOUNT/.lustre/fid/ access
18446         mkdir $DIR/$tdir
18447         [[ $? -eq 0 ]] || error "mkdir failed"
18448
18449         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18450         $LCTL set_param fail_loc=0x8000140c
18451         # 5s pause
18452         $LCTL set_param fail_val=5
18453
18454         # create file
18455         echo foofoo > $DIR/$tdir/$tfile &
18456         pid=$!
18457
18458         # wait for create to be delayed
18459         sleep 2
18460
18461         ps -p $pid
18462         [[ $? -eq 0 ]] || error "create should be blocked"
18463
18464         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18465         stack_trap "rm -f $tempfile"
18466         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18467         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18468         # some delay may occur during ChangeLog publishing and file read just
18469         # above, that could allow file write to happen finally
18470         [[ -s $tempfile ]] && echo "file should be empty"
18471
18472         $LCTL set_param fail_loc=0
18473
18474         wait $pid
18475         [[ $? -eq 0 ]] || error "create failed"
18476 }
18477 run_test 161d "create with concurrent .lustre/fid access"
18478
18479 check_path() {
18480         local expected="$1"
18481         shift
18482         local fid="$2"
18483
18484         local path
18485         path=$($LFS fid2path "$@")
18486         local rc=$?
18487
18488         if [ $rc -ne 0 ]; then
18489                 error "path looked up of '$expected' failed: rc=$rc"
18490         elif [ "$path" != "$expected" ]; then
18491                 error "path looked up '$path' instead of '$expected'"
18492         else
18493                 echo "FID '$fid' resolves to path '$path' as expected"
18494         fi
18495 }
18496
18497 test_162a() { # was test_162
18498         test_mkdir -p -c1 $DIR/$tdir/d2
18499         touch $DIR/$tdir/d2/$tfile
18500         touch $DIR/$tdir/d2/x1
18501         touch $DIR/$tdir/d2/x2
18502         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18503         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18504         # regular file
18505         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18506         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18507
18508         # softlink
18509         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18510         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18511         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18512
18513         # softlink to wrong file
18514         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18515         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18516         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18517
18518         # hardlink
18519         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18520         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18521         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18522         # fid2path dir/fsname should both work
18523         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18524         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18525
18526         # hardlink count: check that there are 2 links
18527         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18528         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18529
18530         # hardlink indexing: remove the first link
18531         rm $DIR/$tdir/d2/p/q/r/hlink
18532         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18533 }
18534 run_test 162a "path lookup sanity"
18535
18536 test_162b() {
18537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18539
18540         mkdir $DIR/$tdir
18541         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18542                                 error "create striped dir failed"
18543
18544         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18545                                         tail -n 1 | awk '{print $2}')
18546         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18547
18548         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18549         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18550
18551         # regular file
18552         for ((i=0;i<5;i++)); do
18553                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18554                         error "get fid for f$i failed"
18555                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18556
18557                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18558                         error "get fid for d$i failed"
18559                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18560         done
18561
18562         return 0
18563 }
18564 run_test 162b "striped directory path lookup sanity"
18565
18566 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18567 test_162c() {
18568         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18569                 skip "Need MDS version at least 2.7.51"
18570
18571         local lpath=$tdir.local
18572         local rpath=$tdir.remote
18573
18574         test_mkdir $DIR/$lpath
18575         test_mkdir $DIR/$rpath
18576
18577         for ((i = 0; i <= 101; i++)); do
18578                 lpath="$lpath/$i"
18579                 mkdir $DIR/$lpath
18580                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18581                         error "get fid for local directory $DIR/$lpath failed"
18582                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18583
18584                 rpath="$rpath/$i"
18585                 test_mkdir $DIR/$rpath
18586                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18587                         error "get fid for remote directory $DIR/$rpath failed"
18588                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18589         done
18590
18591         return 0
18592 }
18593 run_test 162c "fid2path works with paths 100 or more directories deep"
18594
18595 oalr_event_count() {
18596         local event="${1}"
18597         local trace="${2}"
18598
18599         awk -v name="${FSNAME}-OST0000" \
18600             -v event="${event}" \
18601             '$1 == "TRACE" && $2 == event && $3 == name' \
18602             "${trace}" |
18603         wc -l
18604 }
18605
18606 oalr_expect_event_count() {
18607         local event="${1}"
18608         local trace="${2}"
18609         local expect="${3}"
18610         local count
18611
18612         count=$(oalr_event_count "${event}" "${trace}")
18613         if ((count == expect)); then
18614                 return 0
18615         fi
18616
18617         error_noexit "${event} event count was '${count}', expected ${expect}"
18618         cat "${trace}" >&2
18619         exit 1
18620 }
18621
18622 cleanup_165() {
18623         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18624         stop ost1
18625         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18626 }
18627
18628 setup_165() {
18629         sync # Flush previous IOs so we can count log entries.
18630         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18631         stack_trap cleanup_165 EXIT
18632 }
18633
18634 test_165a() {
18635         local trace="/tmp/${tfile}.trace"
18636         local rc
18637         local count
18638
18639         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18640                 skip "OFD access log unsupported"
18641
18642         setup_165
18643         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18644         sleep 5
18645
18646         do_facet ost1 ofd_access_log_reader --list
18647         stop ost1
18648
18649         do_facet ost1 killall -TERM ofd_access_log_reader
18650         wait
18651         rc=$?
18652
18653         if ((rc != 0)); then
18654                 error "ofd_access_log_reader exited with rc = '${rc}'"
18655         fi
18656
18657         # Parse trace file for discovery events:
18658         oalr_expect_event_count alr_log_add "${trace}" 1
18659         oalr_expect_event_count alr_log_eof "${trace}" 1
18660         oalr_expect_event_count alr_log_free "${trace}" 1
18661 }
18662 run_test 165a "ofd access log discovery"
18663
18664 test_165b() {
18665         local trace="/tmp/${tfile}.trace"
18666         local file="${DIR}/${tfile}"
18667         local pfid1
18668         local pfid2
18669         local -a entry
18670         local rc
18671         local count
18672         local size
18673         local flags
18674
18675         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18676                 skip "OFD access log unsupported"
18677
18678         setup_165
18679         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18680         sleep 5
18681
18682         do_facet ost1 ofd_access_log_reader --list
18683
18684         lfs setstripe -c 1 -i 0 "${file}"
18685         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18686                 error "cannot create '${file}'"
18687
18688         sleep 5
18689         do_facet ost1 killall -TERM ofd_access_log_reader
18690         wait
18691         rc=$?
18692
18693         if ((rc != 0)); then
18694                 error "ofd_access_log_reader exited with rc = '${rc}'"
18695         fi
18696
18697         oalr_expect_event_count alr_log_entry "${trace}" 1
18698
18699         pfid1=$($LFS path2fid "${file}")
18700
18701         # 1     2             3   4    5     6   7    8    9     10
18702         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18703         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18704
18705         echo "entry = '${entry[*]}'" >&2
18706
18707         pfid2=${entry[4]}
18708         if [[ "${pfid1}" != "${pfid2}" ]]; then
18709                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18710         fi
18711
18712         size=${entry[8]}
18713         if ((size != 1048576)); then
18714                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18715         fi
18716
18717         flags=${entry[10]}
18718         if [[ "${flags}" != "w" ]]; then
18719                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18720         fi
18721
18722         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18723         sleep 5
18724
18725         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18726                 error "cannot read '${file}'"
18727         sleep 5
18728
18729         do_facet ost1 killall -TERM ofd_access_log_reader
18730         wait
18731         rc=$?
18732
18733         if ((rc != 0)); then
18734                 error "ofd_access_log_reader exited with rc = '${rc}'"
18735         fi
18736
18737         oalr_expect_event_count alr_log_entry "${trace}" 1
18738
18739         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18740         echo "entry = '${entry[*]}'" >&2
18741
18742         pfid2=${entry[4]}
18743         if [[ "${pfid1}" != "${pfid2}" ]]; then
18744                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18745         fi
18746
18747         size=${entry[8]}
18748         if ((size != 524288)); then
18749                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18750         fi
18751
18752         flags=${entry[10]}
18753         if [[ "${flags}" != "r" ]]; then
18754                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18755         fi
18756 }
18757 run_test 165b "ofd access log entries are produced and consumed"
18758
18759 test_165c() {
18760         local trace="/tmp/${tfile}.trace"
18761         local file="${DIR}/${tdir}/${tfile}"
18762
18763         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18764                 skip "OFD access log unsupported"
18765
18766         test_mkdir "${DIR}/${tdir}"
18767
18768         setup_165
18769         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18770         sleep 5
18771
18772         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18773
18774         # 4096 / 64 = 64. Create twice as many entries.
18775         for ((i = 0; i < 128; i++)); do
18776                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18777                         error "cannot create file"
18778         done
18779
18780         sync
18781
18782         do_facet ost1 killall -TERM ofd_access_log_reader
18783         wait
18784         rc=$?
18785         if ((rc != 0)); then
18786                 error "ofd_access_log_reader exited with rc = '${rc}'"
18787         fi
18788
18789         unlinkmany  "${file}-%d" 128
18790 }
18791 run_test 165c "full ofd access logs do not block IOs"
18792
18793 oal_get_read_count() {
18794         local stats="$1"
18795
18796         # STATS lustre-OST0001 alr_read_count 1
18797
18798         do_facet ost1 cat "${stats}" |
18799         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18800              END { print count; }'
18801 }
18802
18803 oal_expect_read_count() {
18804         local stats="$1"
18805         local count
18806         local expect="$2"
18807
18808         # Ask ofd_access_log_reader to write stats.
18809         do_facet ost1 killall -USR1 ofd_access_log_reader
18810
18811         # Allow some time for things to happen.
18812         sleep 1
18813
18814         count=$(oal_get_read_count "${stats}")
18815         if ((count == expect)); then
18816                 return 0
18817         fi
18818
18819         error_noexit "bad read count, got ${count}, expected ${expect}"
18820         do_facet ost1 cat "${stats}" >&2
18821         exit 1
18822 }
18823
18824 test_165d() {
18825         local stats="/tmp/${tfile}.stats"
18826         local file="${DIR}/${tdir}/${tfile}"
18827         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18828
18829         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18830                 skip "OFD access log unsupported"
18831
18832         test_mkdir "${DIR}/${tdir}"
18833
18834         setup_165
18835         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18836         sleep 5
18837
18838         lfs setstripe -c 1 -i 0 "${file}"
18839
18840         do_facet ost1 lctl set_param "${param}=rw"
18841         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18842                 error "cannot create '${file}'"
18843         oal_expect_read_count "${stats}" 1
18844
18845         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18846                 error "cannot read '${file}'"
18847         oal_expect_read_count "${stats}" 2
18848
18849         do_facet ost1 lctl set_param "${param}=r"
18850         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18851                 error "cannot create '${file}'"
18852         oal_expect_read_count "${stats}" 2
18853
18854         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18855                 error "cannot read '${file}'"
18856         oal_expect_read_count "${stats}" 3
18857
18858         do_facet ost1 lctl set_param "${param}=w"
18859         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18860                 error "cannot create '${file}'"
18861         oal_expect_read_count "${stats}" 4
18862
18863         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18864                 error "cannot read '${file}'"
18865         oal_expect_read_count "${stats}" 4
18866
18867         do_facet ost1 lctl set_param "${param}=0"
18868         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18869                 error "cannot create '${file}'"
18870         oal_expect_read_count "${stats}" 4
18871
18872         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18873                 error "cannot read '${file}'"
18874         oal_expect_read_count "${stats}" 4
18875
18876         do_facet ost1 killall -TERM ofd_access_log_reader
18877         wait
18878         rc=$?
18879         if ((rc != 0)); then
18880                 error "ofd_access_log_reader exited with rc = '${rc}'"
18881         fi
18882 }
18883 run_test 165d "ofd_access_log mask works"
18884
18885 test_165e() {
18886         local stats="/tmp/${tfile}.stats"
18887         local file0="${DIR}/${tdir}-0/${tfile}"
18888         local file1="${DIR}/${tdir}-1/${tfile}"
18889
18890         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18891                 skip "OFD access log unsupported"
18892
18893         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18894
18895         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18896         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18897
18898         lfs setstripe -c 1 -i 0 "${file0}"
18899         lfs setstripe -c 1 -i 0 "${file1}"
18900
18901         setup_165
18902         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18903         sleep 5
18904
18905         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18906                 error "cannot create '${file0}'"
18907         sync
18908         oal_expect_read_count "${stats}" 0
18909
18910         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18911                 error "cannot create '${file1}'"
18912         sync
18913         oal_expect_read_count "${stats}" 1
18914
18915         do_facet ost1 killall -TERM ofd_access_log_reader
18916         wait
18917         rc=$?
18918         if ((rc != 0)); then
18919                 error "ofd_access_log_reader exited with rc = '${rc}'"
18920         fi
18921 }
18922 run_test 165e "ofd_access_log MDT index filter works"
18923
18924 test_165f() {
18925         local trace="/tmp/${tfile}.trace"
18926         local rc
18927         local count
18928
18929         setup_165
18930         do_facet ost1 timeout 60 ofd_access_log_reader \
18931                 --exit-on-close --debug=- --trace=- > "${trace}" &
18932         sleep 5
18933         stop ost1
18934
18935         wait
18936         rc=$?
18937
18938         if ((rc != 0)); then
18939                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18940                 cat "${trace}"
18941                 exit 1
18942         fi
18943 }
18944 run_test 165f "ofd_access_log_reader --exit-on-close works"
18945
18946 test_169() {
18947         # do directio so as not to populate the page cache
18948         log "creating a 10 Mb file"
18949         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18950                 error "multiop failed while creating a file"
18951         log "starting reads"
18952         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18953         log "truncating the file"
18954         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18955                 error "multiop failed while truncating the file"
18956         log "killing dd"
18957         kill %+ || true # reads might have finished
18958         echo "wait until dd is finished"
18959         wait
18960         log "removing the temporary file"
18961         rm -rf $DIR/$tfile || error "tmp file removal failed"
18962 }
18963 run_test 169 "parallel read and truncate should not deadlock"
18964
18965 test_170() {
18966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18967
18968         $LCTL clear     # bug 18514
18969         $LCTL debug_daemon start $TMP/${tfile}_log_good
18970         touch $DIR/$tfile
18971         $LCTL debug_daemon stop
18972         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18973                 error "sed failed to read log_good"
18974
18975         $LCTL debug_daemon start $TMP/${tfile}_log_good
18976         rm -rf $DIR/$tfile
18977         $LCTL debug_daemon stop
18978
18979         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18980                error "lctl df log_bad failed"
18981
18982         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18983         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18984
18985         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18986         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18987
18988         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18989                 error "bad_line good_line1 good_line2 are empty"
18990
18991         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18992         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18993         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18994
18995         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18996         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18997         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18998
18999         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19000                 error "bad_line_new good_line_new are empty"
19001
19002         local expected_good=$((good_line1 + good_line2*2))
19003
19004         rm -f $TMP/${tfile}*
19005         # LU-231, short malformed line may not be counted into bad lines
19006         if [ $bad_line -ne $bad_line_new ] &&
19007                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19008                 error "expected $bad_line bad lines, but got $bad_line_new"
19009                 return 1
19010         fi
19011
19012         if [ $expected_good -ne $good_line_new ]; then
19013                 error "expected $expected_good good lines, but got $good_line_new"
19014                 return 2
19015         fi
19016         true
19017 }
19018 run_test 170 "test lctl df to handle corrupted log ====================="
19019
19020 test_171() { # bug20592
19021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19022
19023         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19024         $LCTL set_param fail_loc=0x50e
19025         $LCTL set_param fail_val=3000
19026         multiop_bg_pause $DIR/$tfile O_s || true
19027         local MULTIPID=$!
19028         kill -USR1 $MULTIPID
19029         # cause log dump
19030         sleep 3
19031         wait $MULTIPID
19032         if dmesg | grep "recursive fault"; then
19033                 error "caught a recursive fault"
19034         fi
19035         $LCTL set_param fail_loc=0
19036         true
19037 }
19038 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19039
19040 test_172() {
19041
19042         #define OBD_FAIL_OBD_CLEANUP  0x60e
19043         $LCTL set_param fail_loc=0x60e
19044         umount $MOUNT || error "umount $MOUNT failed"
19045         stack_trap "mount_client $MOUNT"
19046
19047         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19048                 error "no client OBDs are remained"
19049
19050         $LCTL dl | while read devno state type name foo; do
19051                 case $type in
19052                 lov|osc|lmv|mdc)
19053                         $LCTL --device $name cleanup
19054                         $LCTL --device $name detach
19055                         ;;
19056                 *)
19057                         # skip server devices
19058                         ;;
19059                 esac
19060         done
19061
19062         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19063                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19064                 error "some client OBDs are still remained"
19065         fi
19066
19067 }
19068 run_test 172 "manual device removal with lctl cleanup/detach ======"
19069
19070 # it would be good to share it with obdfilter-survey/iokit-libecho code
19071 setup_obdecho_osc () {
19072         local rc=0
19073         local ost_nid=$1
19074         local obdfilter_name=$2
19075         echo "Creating new osc for $obdfilter_name on $ost_nid"
19076         # make sure we can find loopback nid
19077         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19078
19079         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19080                            ${obdfilter_name}_osc_UUID || rc=2; }
19081         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19082                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19083         return $rc
19084 }
19085
19086 cleanup_obdecho_osc () {
19087         local obdfilter_name=$1
19088         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19089         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19090         return 0
19091 }
19092
19093 obdecho_test() {
19094         local OBD=$1
19095         local node=$2
19096         local pages=${3:-64}
19097         local rc=0
19098         local id
19099
19100         local count=10
19101         local obd_size=$(get_obd_size $node $OBD)
19102         local page_size=$(get_page_size $node)
19103         if [[ -n "$obd_size" ]]; then
19104                 local new_count=$((obd_size / (pages * page_size / 1024)))
19105                 [[ $new_count -ge $count ]] || count=$new_count
19106         fi
19107
19108         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19109         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19110                            rc=2; }
19111         if [ $rc -eq 0 ]; then
19112             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19113             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19114         fi
19115         echo "New object id is $id"
19116         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19117                            rc=4; }
19118         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19119                            "test_brw $count w v $pages $id" || rc=4; }
19120         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19121                            rc=4; }
19122         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19123                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19124         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19125                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19126         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19127         return $rc
19128 }
19129
19130 test_180a() {
19131         skip "obdecho on osc is no longer supported"
19132 }
19133 run_test 180a "test obdecho on osc"
19134
19135 test_180b() {
19136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19137         remote_ost_nodsh && skip "remote OST with nodsh"
19138
19139         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19140                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19141                 error "failed to load module obdecho"
19142
19143         local target=$(do_facet ost1 $LCTL dl |
19144                        awk '/obdfilter/ { print $4; exit; }')
19145
19146         if [ -n "$target" ]; then
19147                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19148         else
19149                 do_facet ost1 $LCTL dl
19150                 error "there is no obdfilter target on ost1"
19151         fi
19152 }
19153 run_test 180b "test obdecho directly on obdfilter"
19154
19155 test_180c() { # LU-2598
19156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19157         remote_ost_nodsh && skip "remote OST with nodsh"
19158         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19159                 skip "Need MDS version at least 2.4.0"
19160
19161         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19162                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19163                 error "failed to load module obdecho"
19164
19165         local target=$(do_facet ost1 $LCTL dl |
19166                        awk '/obdfilter/ { print $4; exit; }')
19167
19168         if [ -n "$target" ]; then
19169                 local pages=16384 # 64MB bulk I/O RPC size
19170
19171                 obdecho_test "$target" ost1 "$pages" ||
19172                         error "obdecho_test with pages=$pages failed with $?"
19173         else
19174                 do_facet ost1 $LCTL dl
19175                 error "there is no obdfilter target on ost1"
19176         fi
19177 }
19178 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19179
19180 test_181() { # bug 22177
19181         test_mkdir $DIR/$tdir
19182         # create enough files to index the directory
19183         createmany -o $DIR/$tdir/foobar 4000
19184         # print attributes for debug purpose
19185         lsattr -d .
19186         # open dir
19187         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19188         MULTIPID=$!
19189         # remove the files & current working dir
19190         unlinkmany $DIR/$tdir/foobar 4000
19191         rmdir $DIR/$tdir
19192         kill -USR1 $MULTIPID
19193         wait $MULTIPID
19194         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19195         return 0
19196 }
19197 run_test 181 "Test open-unlinked dir ========================"
19198
19199 test_182a() {
19200         local fcount=1000
19201         local tcount=10
19202
19203         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19204
19205         $LCTL set_param mdc.*.rpc_stats=clear
19206
19207         for (( i = 0; i < $tcount; i++ )) ; do
19208                 mkdir $DIR/$tdir/$i
19209         done
19210
19211         for (( i = 0; i < $tcount; i++ )) ; do
19212                 createmany -o $DIR/$tdir/$i/f- $fcount &
19213         done
19214         wait
19215
19216         for (( i = 0; i < $tcount; i++ )) ; do
19217                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19218         done
19219         wait
19220
19221         $LCTL get_param mdc.*.rpc_stats
19222
19223         rm -rf $DIR/$tdir
19224 }
19225 run_test 182a "Test parallel modify metadata operations from mdc"
19226
19227 test_182b() {
19228         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19230         local dcount=1000
19231         local tcount=10
19232         local stime
19233         local etime
19234         local delta
19235
19236         do_facet mds1 $LCTL list_param \
19237                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19238                 skip "MDS lacks parallel RPC handling"
19239
19240         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19241
19242         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19243                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19244
19245         stime=$(date +%s)
19246         createmany -i 0 -d $DIR/$tdir/t- $tcount
19247
19248         for (( i = 0; i < $tcount; i++ )) ; do
19249                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19250         done
19251         wait
19252         etime=$(date +%s)
19253         delta=$((etime - stime))
19254         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19255
19256         stime=$(date +%s)
19257         for (( i = 0; i < $tcount; i++ )) ; do
19258                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19259         done
19260         wait
19261         etime=$(date +%s)
19262         delta=$((etime - stime))
19263         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19264
19265         rm -rf $DIR/$tdir
19266
19267         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19268
19269         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19270
19271         stime=$(date +%s)
19272         createmany -i 0 -d $DIR/$tdir/t- $tcount
19273
19274         for (( i = 0; i < $tcount; i++ )) ; do
19275                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19276         done
19277         wait
19278         etime=$(date +%s)
19279         delta=$((etime - stime))
19280         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19281
19282         stime=$(date +%s)
19283         for (( i = 0; i < $tcount; i++ )) ; do
19284                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19285         done
19286         wait
19287         etime=$(date +%s)
19288         delta=$((etime - stime))
19289         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19290
19291         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19292 }
19293 run_test 182b "Test parallel modify metadata operations from osp"
19294
19295 test_183() { # LU-2275
19296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19297         remote_mds_nodsh && skip "remote MDS with nodsh"
19298         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19299                 skip "Need MDS version at least 2.3.56"
19300
19301         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19302         echo aaa > $DIR/$tdir/$tfile
19303
19304 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19305         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19306
19307         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19308         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19309
19310         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19311
19312         # Flush negative dentry cache
19313         touch $DIR/$tdir/$tfile
19314
19315         # We are not checking for any leaked references here, they'll
19316         # become evident next time we do cleanup with module unload.
19317         rm -rf $DIR/$tdir
19318 }
19319 run_test 183 "No crash or request leak in case of strange dispositions ========"
19320
19321 # test suite 184 is for LU-2016, LU-2017
19322 test_184a() {
19323         check_swap_layouts_support
19324
19325         dir0=$DIR/$tdir/$testnum
19326         test_mkdir -p -c1 $dir0
19327         ref1=/etc/passwd
19328         ref2=/etc/group
19329         file1=$dir0/f1
19330         file2=$dir0/f2
19331         $LFS setstripe -c1 $file1
19332         cp $ref1 $file1
19333         $LFS setstripe -c2 $file2
19334         cp $ref2 $file2
19335         gen1=$($LFS getstripe -g $file1)
19336         gen2=$($LFS getstripe -g $file2)
19337
19338         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19339         gen=$($LFS getstripe -g $file1)
19340         [[ $gen1 != $gen ]] ||
19341                 error "Layout generation on $file1 does not change"
19342         gen=$($LFS getstripe -g $file2)
19343         [[ $gen2 != $gen ]] ||
19344                 error "Layout generation on $file2 does not change"
19345
19346         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19347         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19348
19349         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19350 }
19351 run_test 184a "Basic layout swap"
19352
19353 test_184b() {
19354         check_swap_layouts_support
19355
19356         dir0=$DIR/$tdir/$testnum
19357         mkdir -p $dir0 || error "creating dir $dir0"
19358         file1=$dir0/f1
19359         file2=$dir0/f2
19360         file3=$dir0/f3
19361         dir1=$dir0/d1
19362         dir2=$dir0/d2
19363         mkdir $dir1 $dir2
19364         $LFS setstripe -c1 $file1
19365         $LFS setstripe -c2 $file2
19366         $LFS setstripe -c1 $file3
19367         chown $RUNAS_ID $file3
19368         gen1=$($LFS getstripe -g $file1)
19369         gen2=$($LFS getstripe -g $file2)
19370
19371         $LFS swap_layouts $dir1 $dir2 &&
19372                 error "swap of directories layouts should fail"
19373         $LFS swap_layouts $dir1 $file1 &&
19374                 error "swap of directory and file layouts should fail"
19375         $RUNAS $LFS swap_layouts $file1 $file2 &&
19376                 error "swap of file we cannot write should fail"
19377         $LFS swap_layouts $file1 $file3 &&
19378                 error "swap of file with different owner should fail"
19379         /bin/true # to clear error code
19380 }
19381 run_test 184b "Forbidden layout swap (will generate errors)"
19382
19383 test_184c() {
19384         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19385         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19386         check_swap_layouts_support
19387         check_swap_layout_no_dom $DIR
19388
19389         local dir0=$DIR/$tdir/$testnum
19390         mkdir -p $dir0 || error "creating dir $dir0"
19391
19392         local ref1=$dir0/ref1
19393         local ref2=$dir0/ref2
19394         local file1=$dir0/file1
19395         local file2=$dir0/file2
19396         # create a file large enough for the concurrent test
19397         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19398         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19399         echo "ref file size: ref1($(stat -c %s $ref1))," \
19400              "ref2($(stat -c %s $ref2))"
19401
19402         cp $ref2 $file2
19403         dd if=$ref1 of=$file1 bs=16k &
19404         local DD_PID=$!
19405
19406         # Make sure dd starts to copy file, but wait at most 5 seconds
19407         local loops=0
19408         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19409
19410         $LFS swap_layouts $file1 $file2
19411         local rc=$?
19412         wait $DD_PID
19413         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19414         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19415
19416         # how many bytes copied before swapping layout
19417         local copied=$(stat -c %s $file2)
19418         local remaining=$(stat -c %s $ref1)
19419         remaining=$((remaining - copied))
19420         echo "Copied $copied bytes before swapping layout..."
19421
19422         cmp -n $copied $file1 $ref2 | grep differ &&
19423                 error "Content mismatch [0, $copied) of ref2 and file1"
19424         cmp -n $copied $file2 $ref1 ||
19425                 error "Content mismatch [0, $copied) of ref1 and file2"
19426         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19427                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19428
19429         # clean up
19430         rm -f $ref1 $ref2 $file1 $file2
19431 }
19432 run_test 184c "Concurrent write and layout swap"
19433
19434 test_184d() {
19435         check_swap_layouts_support
19436         check_swap_layout_no_dom $DIR
19437         [ -z "$(which getfattr 2>/dev/null)" ] &&
19438                 skip_env "no getfattr command"
19439
19440         local file1=$DIR/$tdir/$tfile-1
19441         local file2=$DIR/$tdir/$tfile-2
19442         local file3=$DIR/$tdir/$tfile-3
19443         local lovea1
19444         local lovea2
19445
19446         mkdir -p $DIR/$tdir
19447         touch $file1 || error "create $file1 failed"
19448         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19449                 error "create $file2 failed"
19450         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19451                 error "create $file3 failed"
19452         lovea1=$(get_layout_param $file1)
19453
19454         $LFS swap_layouts $file2 $file3 ||
19455                 error "swap $file2 $file3 layouts failed"
19456         $LFS swap_layouts $file1 $file2 ||
19457                 error "swap $file1 $file2 layouts failed"
19458
19459         lovea2=$(get_layout_param $file2)
19460         echo "$lovea1"
19461         echo "$lovea2"
19462         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19463
19464         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19465         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19466 }
19467 run_test 184d "allow stripeless layouts swap"
19468
19469 test_184e() {
19470         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19471                 skip "Need MDS version at least 2.6.94"
19472         check_swap_layouts_support
19473         check_swap_layout_no_dom $DIR
19474         [ -z "$(which getfattr 2>/dev/null)" ] &&
19475                 skip_env "no getfattr command"
19476
19477         local file1=$DIR/$tdir/$tfile-1
19478         local file2=$DIR/$tdir/$tfile-2
19479         local file3=$DIR/$tdir/$tfile-3
19480         local lovea
19481
19482         mkdir -p $DIR/$tdir
19483         touch $file1 || error "create $file1 failed"
19484         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19485                 error "create $file2 failed"
19486         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19487                 error "create $file3 failed"
19488
19489         $LFS swap_layouts $file1 $file2 ||
19490                 error "swap $file1 $file2 layouts failed"
19491
19492         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19493         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19494
19495         echo 123 > $file1 || error "Should be able to write into $file1"
19496
19497         $LFS swap_layouts $file1 $file3 ||
19498                 error "swap $file1 $file3 layouts failed"
19499
19500         echo 123 > $file1 || error "Should be able to write into $file1"
19501
19502         rm -rf $file1 $file2 $file3
19503 }
19504 run_test 184e "Recreate layout after stripeless layout swaps"
19505
19506 test_184f() {
19507         # Create a file with name longer than sizeof(struct stat) ==
19508         # 144 to see if we can get chars from the file name to appear
19509         # in the returned striping. Note that 'f' == 0x66.
19510         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19511
19512         mkdir -p $DIR/$tdir
19513         mcreate $DIR/$tdir/$file
19514         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19515                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19516         fi
19517 }
19518 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19519
19520 test_185() { # LU-2441
19521         # LU-3553 - no volatile file support in old servers
19522         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19523                 skip "Need MDS version at least 2.3.60"
19524
19525         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19526         touch $DIR/$tdir/spoo
19527         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19528         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19529                 error "cannot create/write a volatile file"
19530         [ "$FILESET" == "" ] &&
19531         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19532                 error "FID is still valid after close"
19533
19534         multiop_bg_pause $DIR/$tdir Vw4096_c
19535         local multi_pid=$!
19536
19537         local OLD_IFS=$IFS
19538         IFS=":"
19539         local fidv=($fid)
19540         IFS=$OLD_IFS
19541         # assume that the next FID for this client is sequential, since stdout
19542         # is unfortunately eaten by multiop_bg_pause
19543         local n=$((${fidv[1]} + 1))
19544         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19545         if [ "$FILESET" == "" ]; then
19546                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19547                         error "FID is missing before close"
19548         fi
19549         kill -USR1 $multi_pid
19550         # 1 second delay, so if mtime change we will see it
19551         sleep 1
19552         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19553         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19554 }
19555 run_test 185 "Volatile file support"
19556
19557 function create_check_volatile() {
19558         local idx=$1
19559         local tgt
19560
19561         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19562         local PID=$!
19563         sleep 1
19564         local FID=$(cat /tmp/${tfile}.fid)
19565         [ "$FID" == "" ] && error "can't get FID for volatile"
19566         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19567         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19568         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19569         kill -USR1 $PID
19570         wait
19571         sleep 1
19572         cancel_lru_locks mdc # flush opencache
19573         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19574         return 0
19575 }
19576
19577 test_185a(){
19578         # LU-12516 - volatile creation via .lustre
19579         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19580                 skip "Need MDS version at least 2.3.55"
19581
19582         create_check_volatile 0
19583         [ $MDSCOUNT -lt 2 ] && return 0
19584
19585         # DNE case
19586         create_check_volatile 1
19587
19588         return 0
19589 }
19590 run_test 185a "Volatile file creation in .lustre/fid/"
19591
19592 test_187a() {
19593         remote_mds_nodsh && skip "remote MDS with nodsh"
19594         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19595                 skip "Need MDS version at least 2.3.0"
19596
19597         local dir0=$DIR/$tdir/$testnum
19598         mkdir -p $dir0 || error "creating dir $dir0"
19599
19600         local file=$dir0/file1
19601         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19602         stack_trap "rm -f $file"
19603         local dv1=$($LFS data_version $file)
19604         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19605         local dv2=$($LFS data_version $file)
19606         [[ $dv1 != $dv2 ]] ||
19607                 error "data version did not change on write $dv1 == $dv2"
19608 }
19609 run_test 187a "Test data version change"
19610
19611 test_187b() {
19612         remote_mds_nodsh && skip "remote MDS with nodsh"
19613         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19614                 skip "Need MDS version at least 2.3.0"
19615
19616         local dir0=$DIR/$tdir/$testnum
19617         mkdir -p $dir0 || error "creating dir $dir0"
19618
19619         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19620         [[ ${DV[0]} != ${DV[1]} ]] ||
19621                 error "data version did not change on write"\
19622                       " ${DV[0]} == ${DV[1]}"
19623
19624         # clean up
19625         rm -f $file1
19626 }
19627 run_test 187b "Test data version change on volatile file"
19628
19629 test_200() {
19630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19631         remote_mgs_nodsh && skip "remote MGS with nodsh"
19632         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19633
19634         local POOL=${POOL:-cea1}
19635         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19636         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19637         # Pool OST targets
19638         local first_ost=0
19639         local last_ost=$(($OSTCOUNT - 1))
19640         local ost_step=2
19641         local ost_list=$(seq $first_ost $ost_step $last_ost)
19642         local ost_range="$first_ost $last_ost $ost_step"
19643         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19644         local file_dir=$POOL_ROOT/file_tst
19645         local subdir=$test_path/subdir
19646         local rc=0
19647
19648         while : ; do
19649                 # former test_200a test_200b
19650                 pool_add $POOL                          || { rc=$? ; break; }
19651                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19652                 # former test_200c test_200d
19653                 mkdir -p $test_path
19654                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19655                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19656                 mkdir -p $subdir
19657                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19658                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19659                                                         || { rc=$? ; break; }
19660                 # former test_200e test_200f
19661                 local files=$((OSTCOUNT*3))
19662                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19663                                                         || { rc=$? ; break; }
19664                 pool_create_files $POOL $file_dir $files "$ost_list" \
19665                                                         || { rc=$? ; break; }
19666                 # former test_200g test_200h
19667                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19668                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19669
19670                 # former test_201a test_201b test_201c
19671                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19672
19673                 local f=$test_path/$tfile
19674                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19675                 pool_remove $POOL $f                    || { rc=$? ; break; }
19676                 break
19677         done
19678
19679         destroy_test_pools
19680
19681         return $rc
19682 }
19683 run_test 200 "OST pools"
19684
19685 # usage: default_attr <count | size | offset>
19686 default_attr() {
19687         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19688 }
19689
19690 # usage: check_default_stripe_attr
19691 check_default_stripe_attr() {
19692         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19693         case $1 in
19694         --stripe-count|-c)
19695                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19696         --stripe-size|-S)
19697                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19698         --stripe-index|-i)
19699                 EXPECTED=-1;;
19700         *)
19701                 error "unknown getstripe attr '$1'"
19702         esac
19703
19704         [ $ACTUAL == $EXPECTED ] ||
19705                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19706 }
19707
19708 test_204a() {
19709         test_mkdir $DIR/$tdir
19710         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19711
19712         check_default_stripe_attr --stripe-count
19713         check_default_stripe_attr --stripe-size
19714         check_default_stripe_attr --stripe-index
19715 }
19716 run_test 204a "Print default stripe attributes"
19717
19718 test_204b() {
19719         test_mkdir $DIR/$tdir
19720         $LFS setstripe --stripe-count 1 $DIR/$tdir
19721
19722         check_default_stripe_attr --stripe-size
19723         check_default_stripe_attr --stripe-index
19724 }
19725 run_test 204b "Print default stripe size and offset"
19726
19727 test_204c() {
19728         test_mkdir $DIR/$tdir
19729         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19730
19731         check_default_stripe_attr --stripe-count
19732         check_default_stripe_attr --stripe-index
19733 }
19734 run_test 204c "Print default stripe count and offset"
19735
19736 test_204d() {
19737         test_mkdir $DIR/$tdir
19738         $LFS setstripe --stripe-index 0 $DIR/$tdir
19739
19740         check_default_stripe_attr --stripe-count
19741         check_default_stripe_attr --stripe-size
19742 }
19743 run_test 204d "Print default stripe count and size"
19744
19745 test_204e() {
19746         test_mkdir $DIR/$tdir
19747         $LFS setstripe -d $DIR/$tdir
19748
19749         # LU-16904 check if root is set as PFL layout
19750         local numcomp=$($LFS getstripe --component-count $MOUNT)
19751
19752         if [[ $numcomp -gt 0 ]]; then
19753                 check_default_stripe_attr --stripe-count
19754         else
19755                 check_default_stripe_attr --stripe-count --raw
19756         fi
19757         check_default_stripe_attr --stripe-size --raw
19758         check_default_stripe_attr --stripe-index --raw
19759 }
19760 run_test 204e "Print raw stripe attributes"
19761
19762 test_204f() {
19763         test_mkdir $DIR/$tdir
19764         $LFS setstripe --stripe-count 1 $DIR/$tdir
19765
19766         check_default_stripe_attr --stripe-size --raw
19767         check_default_stripe_attr --stripe-index --raw
19768 }
19769 run_test 204f "Print raw stripe size and offset"
19770
19771 test_204g() {
19772         test_mkdir $DIR/$tdir
19773         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19774
19775         check_default_stripe_attr --stripe-count --raw
19776         check_default_stripe_attr --stripe-index --raw
19777 }
19778 run_test 204g "Print raw stripe count and offset"
19779
19780 test_204h() {
19781         test_mkdir $DIR/$tdir
19782         $LFS setstripe --stripe-index 0 $DIR/$tdir
19783
19784         check_default_stripe_attr --stripe-count --raw
19785         check_default_stripe_attr --stripe-size --raw
19786 }
19787 run_test 204h "Print raw stripe count and size"
19788
19789 # Figure out which job scheduler is being used, if any,
19790 # or use a fake one
19791 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19792         JOBENV=SLURM_JOB_ID
19793 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19794         JOBENV=LSB_JOBID
19795 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19796         JOBENV=PBS_JOBID
19797 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19798         JOBENV=LOADL_STEP_ID
19799 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19800         JOBENV=JOB_ID
19801 else
19802         $LCTL list_param jobid_name > /dev/null 2>&1
19803         if [ $? -eq 0 ]; then
19804                 JOBENV=nodelocal
19805         else
19806                 JOBENV=FAKE_JOBID
19807         fi
19808 fi
19809 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19810
19811 verify_jobstats() {
19812         local cmd=($1)
19813         shift
19814         local facets="$@"
19815
19816 # we don't really need to clear the stats for this test to work, since each
19817 # command has a unique jobid, but it makes debugging easier if needed.
19818 #       for facet in $facets; do
19819 #               local dev=$(convert_facet2label $facet)
19820 #               # clear old jobstats
19821 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19822 #       done
19823
19824         # use a new JobID for each test, or we might see an old one
19825         [ "$JOBENV" = "FAKE_JOBID" ] &&
19826                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19827
19828         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19829
19830         [ "$JOBENV" = "nodelocal" ] && {
19831                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19832                 $LCTL set_param jobid_name=$FAKE_JOBID
19833                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19834         }
19835
19836         log "Test: ${cmd[*]}"
19837         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19838
19839         if [ $JOBENV = "FAKE_JOBID" ]; then
19840                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19841         else
19842                 ${cmd[*]}
19843         fi
19844
19845         # all files are created on OST0000
19846         for facet in $facets; do
19847                 local stats="*.$(convert_facet2label $facet).job_stats"
19848
19849                 # strip out libtool wrappers for in-tree executables
19850                 if (( $(do_facet $facet lctl get_param $stats |
19851                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19852                         do_facet $facet lctl get_param $stats
19853                         error "No jobstats for $JOBVAL found on $facet::$stats"
19854                 fi
19855         done
19856 }
19857
19858 jobstats_set() {
19859         local new_jobenv=$1
19860
19861         set_persistent_param_and_check client "jobid_var" \
19862                 "$FSNAME.sys.jobid_var" $new_jobenv
19863 }
19864
19865 test_205a() { # Job stats
19866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19867         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19868                 skip "Need MDS version with at least 2.7.1"
19869         remote_mgs_nodsh && skip "remote MGS with nodsh"
19870         remote_mds_nodsh && skip "remote MDS with nodsh"
19871         remote_ost_nodsh && skip "remote OST with nodsh"
19872         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19873                 skip "Server doesn't support jobstats"
19874         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19875
19876         local old_jobenv=$($LCTL get_param -n jobid_var)
19877         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19878         stack_trap "jobstats_set $old_jobenv" EXIT
19879
19880         changelog_register
19881
19882         local old_jobid_name=$($LCTL get_param jobid_name)
19883         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19884
19885         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19886                                 mdt.*.job_cleanup_interval | head -n 1)
19887         local new_interval=5
19888         do_facet $SINGLEMDS \
19889                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19890         stack_trap "do_facet $SINGLEMDS \
19891                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19892         local start=$SECONDS
19893
19894         local cmd
19895         # mkdir
19896         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19897         verify_jobstats "$cmd" "$SINGLEMDS"
19898         # rmdir
19899         cmd="rmdir $DIR/$tdir"
19900         verify_jobstats "$cmd" "$SINGLEMDS"
19901         # mkdir on secondary MDT
19902         if [ $MDSCOUNT -gt 1 ]; then
19903                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19904                 verify_jobstats "$cmd" "mds2"
19905         fi
19906         # mknod
19907         cmd="mknod $DIR/$tfile c 1 3"
19908         verify_jobstats "$cmd" "$SINGLEMDS"
19909         # unlink
19910         cmd="rm -f $DIR/$tfile"
19911         verify_jobstats "$cmd" "$SINGLEMDS"
19912         # create all files on OST0000 so verify_jobstats can find OST stats
19913         # open & close
19914         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19915         verify_jobstats "$cmd" "$SINGLEMDS"
19916         # setattr
19917         cmd="touch $DIR/$tfile"
19918         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19919         # write
19920         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19921         verify_jobstats "$cmd" "ost1"
19922         # read
19923         cancel_lru_locks osc
19924         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19925         verify_jobstats "$cmd" "ost1"
19926         # truncate
19927         cmd="$TRUNCATE $DIR/$tfile 0"
19928         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19929         # rename
19930         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19931         verify_jobstats "$cmd" "$SINGLEMDS"
19932         # jobstats expiry - sleep until old stats should be expired
19933         local left=$((new_interval + 5 - (SECONDS - start)))
19934         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19935                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19936                         "0" $left
19937         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19938         verify_jobstats "$cmd" "$SINGLEMDS"
19939         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19940             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19941
19942         # Ensure that jobid are present in changelog (if supported by MDS)
19943         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19944                 changelog_dump | tail -10
19945                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19946                 [ $jobids -eq 9 ] ||
19947                         error "Wrong changelog jobid count $jobids != 9"
19948
19949                 # LU-5862
19950                 JOBENV="disable"
19951                 jobstats_set $JOBENV
19952                 touch $DIR/$tfile
19953                 changelog_dump | grep $tfile
19954                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19955                 [ $jobids -eq 0 ] ||
19956                         error "Unexpected jobids when jobid_var=$JOBENV"
19957         fi
19958
19959         # test '%j' access to environment variable - if supported
19960         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19961                 JOBENV="JOBCOMPLEX"
19962                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19963
19964                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19965         fi
19966
19967         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19968                 JOBENV="JOBCOMPLEX"
19969                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19970
19971                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19972         fi
19973
19974         # test '%j' access to per-session jobid - if supported
19975         if lctl list_param jobid_this_session > /dev/null 2>&1
19976         then
19977                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19978                 lctl set_param jobid_this_session=$USER
19979
19980                 JOBENV="JOBCOMPLEX"
19981                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19982
19983                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19984         fi
19985 }
19986 run_test 205a "Verify job stats"
19987
19988 # LU-13117, LU-13597, LU-16599
19989 test_205b() {
19990         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19991                 skip "Need MDS version at least 2.13.54.91"
19992
19993         local job_stats="mdt.*.job_stats"
19994         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19995
19996         do_facet mds1 $LCTL set_param $job_stats=clear
19997
19998         # Setting jobid_var to USER might not be supported
19999         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20000         $LCTL set_param jobid_var=USER || true
20001         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20002         $LCTL set_param jobid_name="%j.%e.%u"
20003
20004         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20005         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20006                 { do_facet mds1 $LCTL get_param $job_stats;
20007                   error "Unexpected jobid found"; }
20008         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20009                 { do_facet mds1 $LCTL get_param $job_stats;
20010                   error "wrong job_stats format found"; }
20011
20012         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20013                 echo "MDS does not yet escape jobid" && return 0
20014
20015         mkdir_on_mdt0 $DIR/$tdir
20016         $LCTL set_param jobid_var=TEST205b
20017         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20018         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20019                       awk '/has\\x20sp/ {print $3}')
20020         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20021                   error "jobid not escaped"; }
20022
20023         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20024                 # need to run such a command on mds1:
20025                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20026                 #
20027                 # there might be multiple MDTs on single mds server, so need to
20028                 # specifiy MDT0000. Or the command will fail due to other MDTs
20029                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20030                         error "cannot clear escaped jobid in job_stats";
20031         else
20032                 echo "MDS does not support clearing escaped jobid"
20033         fi
20034 }
20035 run_test 205b "Verify job stats jobid and output format"
20036
20037 # LU-13733
20038 test_205c() {
20039         $LCTL set_param llite.*.stats=0
20040         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20041         $LCTL get_param llite.*.stats
20042         $LCTL get_param llite.*.stats | grep \
20043                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20044                         error "wrong client stats format found"
20045 }
20046 run_test 205c "Verify client stats format"
20047
20048 test_205d() {
20049         local file=$DIR/$tdir/$tfile
20050
20051         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20052                 skip "need lustre >= 2.15.53 for lljobstat"
20053         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20054                 skip "need lustre >= 2.15.53 for lljobstat"
20055         verify_yaml_available || skip_env "YAML verification not installed"
20056
20057         test_mkdir -i 0 $DIR/$tdir
20058         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20059         stack_trap "rm -rf $DIR/$tdir"
20060
20061         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20062                 error "failed to write data to $file"
20063         mv $file $file.2
20064
20065         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20066         echo -n 'verify rename_stats...'
20067         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20068                 verify_yaml || error "rename_stats is not valid YAML"
20069         echo " OK"
20070
20071         echo -n 'verify mdt job_stats...'
20072         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20073                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20074         echo " OK"
20075
20076         echo -n 'verify ost job_stats...'
20077         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20078                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20079         echo " OK"
20080 }
20081 run_test 205d "verify the format of some stats files"
20082
20083 test_205e() {
20084         local ops_comma
20085         local file=$DIR/$tdir/$tfile
20086         local -a cli_params
20087
20088         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20089                 skip "need lustre >= 2.15.53 for lljobstat"
20090         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20091                 skip "need lustre >= 2.15.53 for lljobstat"
20092         verify_yaml_available || skip_env "YAML verification not installed"
20093
20094         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20095         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20096         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20097
20098         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20099         stack_trap "rm -rf $DIR/$tdir"
20100
20101         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20102                 error "failed to create $file on ost1"
20103         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20104                 error "failed to write data to $file"
20105
20106         do_facet mds1 "$LCTL get_param *.*.job_stats"
20107         do_facet ost1 "$LCTL get_param *.*.job_stats"
20108
20109         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20110         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20111                 error "The output of lljobstat is not an valid YAML"
20112
20113         # verify that job dd.0 does exist and has some ops on ost1
20114         # typically this line is like:
20115         # - 205e.dd.0:            {ops: 20, ...}
20116         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20117                     awk '$2=="205e.dd.0:" {print $4}')
20118
20119         (( ${ops_comma%,} >= 10 )) ||
20120                 error "cannot find job 205e.dd.0 with ops >= 10"
20121 }
20122 run_test 205e "verify the output of lljobstat"
20123
20124 test_205f() {
20125         verify_yaml_available || skip_env "YAML verification not installed"
20126
20127         # check both qos_ost_weights and qos_mdt_weights
20128         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20129         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20130                 error "qos_ost_weights is not valid YAML"
20131 }
20132 run_test 205f "verify qos_ost_weights YAML format "
20133
20134 __test_205_jobstats_dump() {
20135         local -a pids
20136         local nbr_instance=$1
20137
20138         while true; do
20139                 if (( ${#pids[@]} >= nbr_instance )); then
20140                         wait ${pids[@]}
20141                         pids=()
20142                 fi
20143
20144                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20145                 pids+=( $! )
20146         done
20147 }
20148
20149 __test_205_cleanup() {
20150         kill $@
20151         # Clear all job entries
20152         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20153 }
20154
20155 test_205g() {
20156         local -a mds1_params
20157         local -a cli_params
20158         local pids
20159         local interval=5
20160
20161         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20162         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20163         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20164
20165         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20166         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20167         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20168
20169         # start jobs loop
20170         export TEST205G_ID=205g
20171         stack_trap "unset TEST205G_ID" EXIT
20172         while true; do
20173                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20174         done & pids="$! "
20175
20176         __test_205_jobstats_dump 4 & pids+="$! "
20177         stack_trap "__test_205_cleanup $pids" EXIT INT
20178
20179         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20180 }
20181 run_test 205g "stress test for job_stats procfile"
20182
20183 test_205h() {
20184         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20185
20186         local dir=$DIR/$tdir
20187         local f=$dir/$tfile
20188         local f2=$dir/$tfile-2
20189         local f3=$dir/$tfile-3
20190         local subdir=$DIR/dir
20191         local val
20192
20193         local mdts=$(comma_list $(mdts_nodes))
20194         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20195         local client_saved=$($LCTL get_param -n jobid_var)
20196
20197         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20198         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20199
20200         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20201                 error "failed to set job_xattr parameter to user.job"
20202         $LCTL set_param jobid_var=procname.uid ||
20203                 error "failed to set jobid_var parameter"
20204
20205         test_mkdir $dir
20206
20207         touch $f
20208         val=$(getfattr -n user.job $f | grep user.job)
20209         [[ $val = user.job=\"touch.0\" ]] ||
20210                 error "expected user.job=\"touch.0\", got '$val'"
20211
20212         mkdir $subdir
20213         val=$(getfattr -n user.job $subdir | grep user.job)
20214         [[ $val = user.job=\"mkdir.0\" ]] ||
20215                 error "expected user.job=\"mkdir.0\", got '$val'"
20216
20217         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20218                 error "failed to set job_xattr parameter to NONE"
20219
20220         touch $f2
20221         val=$(getfattr -d $f2)
20222         [[ -z $val ]] ||
20223                 error "expected no user xattr, got '$val'"
20224
20225         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20226                 error "failed to set job_xattr parameter to trusted.job"
20227
20228         touch $f3
20229         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20230         [[ $val = trusted.job=\"touch.0\" ]] ||
20231                 error "expected trusted.job=\"touch.0\", got '$val'"
20232 }
20233 run_test 205h "check jobid xattr is stored correctly"
20234
20235 test_205i() {
20236         local mdts=$(comma_list $(mdts_nodes))
20237         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20238
20239         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20240
20241         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20242                 error "failed to set mdt.*.job_xattr to user.1234567"
20243
20244         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20245                 error "failed to reject too long job_xattr name"
20246
20247         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20248                 error "failed to reject job_xattr name in bad format"
20249
20250         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20251                 error "failed to reject job_xattr name with invalid character"
20252
20253         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20254                         xargs $LCTL set_param" &&
20255                 error "failed to reject job_xattr name with non-ascii character"
20256
20257         return 0
20258 }
20259 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20260
20261 # LU-1480, LU-1773 and LU-1657
20262 test_206() {
20263         mkdir -p $DIR/$tdir
20264         $LFS setstripe -c -1 $DIR/$tdir
20265 #define OBD_FAIL_LOV_INIT 0x1403
20266         $LCTL set_param fail_loc=0xa0001403
20267         $LCTL set_param fail_val=1
20268         touch $DIR/$tdir/$tfile || true
20269 }
20270 run_test 206 "fail lov_init_raid0() doesn't lbug"
20271
20272 test_207a() {
20273         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20274         local fsz=`stat -c %s $DIR/$tfile`
20275         cancel_lru_locks mdc
20276
20277         # do not return layout in getattr intent
20278 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20279         $LCTL set_param fail_loc=0x170
20280         local sz=`stat -c %s $DIR/$tfile`
20281
20282         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20283
20284         rm -rf $DIR/$tfile
20285 }
20286 run_test 207a "can refresh layout at glimpse"
20287
20288 test_207b() {
20289         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20290         local cksum=`md5sum $DIR/$tfile`
20291         local fsz=`stat -c %s $DIR/$tfile`
20292         cancel_lru_locks mdc
20293         cancel_lru_locks osc
20294
20295         # do not return layout in getattr intent
20296 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20297         $LCTL set_param fail_loc=0x171
20298
20299         # it will refresh layout after the file is opened but before read issues
20300         echo checksum is "$cksum"
20301         echo "$cksum" |md5sum -c --quiet || error "file differs"
20302
20303         rm -rf $DIR/$tfile
20304 }
20305 run_test 207b "can refresh layout at open"
20306
20307 test_208() {
20308         # FIXME: in this test suite, only RD lease is used. This is okay
20309         # for now as only exclusive open is supported. After generic lease
20310         # is done, this test suite should be revised. - Jinshan
20311
20312         remote_mds_nodsh && skip "remote MDS with nodsh"
20313         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20314                 skip "Need MDS version at least 2.4.52"
20315
20316         echo "==== test 1: verify get lease work"
20317         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20318
20319         echo "==== test 2: verify lease can be broken by upcoming open"
20320         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20321         local PID=$!
20322         sleep 2
20323
20324         $MULTIOP $DIR/$tfile oO_RDWR:c
20325         kill -USR1 $PID && wait $PID || error "break lease error"
20326
20327         echo "==== test 3: verify lease can't be granted if an open already exists"
20328         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20329         local PID=$!
20330         sleep 2
20331
20332         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20333         kill -USR1 $PID && wait $PID || error "open file error"
20334
20335         echo "==== test 4: lease can sustain over recovery"
20336         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20337         PID=$!
20338         sleep 2
20339
20340         fail mds1
20341
20342         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20343
20344         echo "==== test 5: lease broken can't be regained by replay"
20345         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20346         PID=$!
20347         sleep 2
20348
20349         # open file to break lease and then recovery
20350         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20351         fail mds1
20352
20353         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20354
20355         rm -f $DIR/$tfile
20356 }
20357 run_test 208 "Exclusive open"
20358
20359 test_209() {
20360         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20361                 skip_env "must have disp_stripe"
20362
20363         touch $DIR/$tfile
20364         sync; sleep 5; sync;
20365
20366         echo 3 > /proc/sys/vm/drop_caches
20367         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20368                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20369         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20370
20371         # open/close 500 times
20372         for i in $(seq 500); do
20373                 cat $DIR/$tfile
20374         done
20375
20376         echo 3 > /proc/sys/vm/drop_caches
20377         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20378                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20379         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20380
20381         echo "before: $req_before, after: $req_after"
20382         [ $((req_after - req_before)) -ge 300 ] &&
20383                 error "open/close requests are not freed"
20384         return 0
20385 }
20386 run_test 209 "read-only open/close requests should be freed promptly"
20387
20388 test_210() {
20389         local pid
20390
20391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20392         pid=$!
20393         sleep 1
20394
20395         $LFS getstripe $DIR/$tfile
20396         kill -USR1 $pid
20397         wait $pid || error "multiop failed"
20398
20399         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20400         pid=$!
20401         sleep 1
20402
20403         $LFS getstripe $DIR/$tfile
20404         kill -USR1 $pid
20405         wait $pid || error "multiop failed"
20406 }
20407 run_test 210 "lfs getstripe does not break leases"
20408
20409 test_212() {
20410         size=`date +%s`
20411         size=$((size % 8192 + 1))
20412         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20413         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20414         rm -f $DIR/f212 $DIR/f212.xyz
20415 }
20416 run_test 212 "Sendfile test ============================================"
20417
20418 test_213() {
20419         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20420         cancel_lru_locks osc
20421         lctl set_param fail_loc=0x8000040f
20422         # generate a read lock
20423         cat $DIR/$tfile > /dev/null
20424         # write to the file, it will try to cancel the above read lock.
20425         cat /etc/hosts >> $DIR/$tfile
20426 }
20427 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20428
20429 test_214() { # for bug 20133
20430         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20431         for (( i=0; i < 340; i++ )) ; do
20432                 touch $DIR/$tdir/d214c/a$i
20433         done
20434
20435         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20436         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20437         ls $DIR/d214c || error "ls $DIR/d214c failed"
20438         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20439         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20440 }
20441 run_test 214 "hash-indexed directory test - bug 20133"
20442
20443 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20444 create_lnet_proc_files() {
20445         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20446 }
20447
20448 # counterpart of create_lnet_proc_files
20449 remove_lnet_proc_files() {
20450         rm -f $TMP/lnet_$1.sys
20451 }
20452
20453 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20454 # 3rd arg as regexp for body
20455 check_lnet_proc_stats() {
20456         local l=$(cat "$TMP/lnet_$1" |wc -l)
20457         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20458
20459         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20460 }
20461
20462 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20463 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20464 # optional and can be regexp for 2nd line (lnet.routes case)
20465 check_lnet_proc_entry() {
20466         local blp=2          # blp stands for 'position of 1st line of body'
20467         [ -z "$5" ] || blp=3 # lnet.routes case
20468
20469         local l=$(cat "$TMP/lnet_$1" |wc -l)
20470         # subtracting one from $blp because the body can be empty
20471         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20472
20473         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20474                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20475
20476         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20477                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20478
20479         # bail out if any unexpected line happened
20480         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20481         [ "$?" != 0 ] || error "$2 misformatted"
20482 }
20483
20484 test_215() { # for bugs 18102, 21079, 21517
20485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20486
20487         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20488         local P='[1-9][0-9]*'           # positive numeric
20489         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20490         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20491         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20492         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20493
20494         local L1 # regexp for 1st line
20495         local L2 # regexp for 2nd line (optional)
20496         local BR # regexp for the rest (body)
20497
20498         # lnet.stats should look as 11 space-separated non-negative numerics
20499         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20500         create_lnet_proc_files "stats"
20501         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20502         remove_lnet_proc_files "stats"
20503
20504         # lnet.routes should look like this:
20505         # Routing disabled/enabled
20506         # net hops priority state router
20507         # where net is a string like tcp0, hops > 0, priority >= 0,
20508         # state is up/down,
20509         # router is a string like 192.168.1.1@tcp2
20510         L1="^Routing (disabled|enabled)$"
20511         L2="^net +hops +priority +state +router$"
20512         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20513         create_lnet_proc_files "routes"
20514         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20515         remove_lnet_proc_files "routes"
20516
20517         # lnet.routers should look like this:
20518         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20519         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20520         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20521         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20522         L1="^ref +rtr_ref +alive +router$"
20523         BR="^$P +$P +(up|down) +$NID$"
20524         create_lnet_proc_files "routers"
20525         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20526         remove_lnet_proc_files "routers"
20527
20528         # lnet.peers should look like this:
20529         # nid refs state last max rtr min tx min queue
20530         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20531         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20532         # numeric (0 or >0 or <0), queue >= 0.
20533         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20534         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20535         create_lnet_proc_files "peers"
20536         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20537         remove_lnet_proc_files "peers"
20538
20539         # lnet.buffers  should look like this:
20540         # pages count credits min
20541         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20542         L1="^pages +count +credits +min$"
20543         BR="^ +$N +$N +$I +$I$"
20544         create_lnet_proc_files "buffers"
20545         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20546         remove_lnet_proc_files "buffers"
20547
20548         # lnet.nis should look like this:
20549         # nid status alive refs peer rtr max tx min
20550         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20551         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20552         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20553         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20554         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20555         create_lnet_proc_files "nis"
20556         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20557         remove_lnet_proc_files "nis"
20558
20559         # can we successfully write to lnet.stats?
20560         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20561 }
20562 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20563
20564 test_216() { # bug 20317
20565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20566         remote_ost_nodsh && skip "remote OST with nodsh"
20567
20568         local node
20569         local facets=$(get_facets OST)
20570         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20571
20572         save_lustre_params client "osc.*.contention_seconds" > $p
20573         save_lustre_params $facets \
20574                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20575         save_lustre_params $facets \
20576                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20577         save_lustre_params $facets \
20578                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20579         clear_stats osc.*.osc_stats
20580
20581         # agressive lockless i/o settings
20582         do_nodes $(comma_list $(osts_nodes)) \
20583                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20584                         ldlm.namespaces.filter-*.contended_locks=0 \
20585                         ldlm.namespaces.filter-*.contention_seconds=60"
20586         lctl set_param -n osc.*.contention_seconds=60
20587
20588         $DIRECTIO write $DIR/$tfile 0 10 4096
20589         $CHECKSTAT -s 40960 $DIR/$tfile
20590
20591         # disable lockless i/o
20592         do_nodes $(comma_list $(osts_nodes)) \
20593                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20594                         ldlm.namespaces.filter-*.contended_locks=32 \
20595                         ldlm.namespaces.filter-*.contention_seconds=0"
20596         lctl set_param -n osc.*.contention_seconds=0
20597         clear_stats osc.*.osc_stats
20598
20599         dd if=/dev/zero of=$DIR/$tfile count=0
20600         $CHECKSTAT -s 0 $DIR/$tfile
20601
20602         restore_lustre_params <$p
20603         rm -f $p
20604         rm $DIR/$tfile
20605 }
20606 run_test 216 "check lockless direct write updates file size and kms correctly"
20607
20608 test_217() { # bug 22430
20609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20610
20611         local node
20612
20613         for node in $(nodes_list); do
20614                 local nid=$(host_nids_address $node $NETTYPE)
20615                 local node_ip=$(do_node $node getent ahostsv4 $node |
20616                                 awk '{ print $1; exit; }')
20617
20618                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20619                 # if hostname matches any NID, use hostname for better testing
20620                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20621                         echo "lctl ping node $node@$NETTYPE"
20622                         lctl ping $node@$NETTYPE
20623                 else # otherwise, at least test 'lctl ping' is working
20624                         echo "lctl ping nid $(h2nettype $nid)"
20625                         lctl ping $(h2nettype $nid)
20626                         echo "skipping $node (no hyphen detected)"
20627                 fi
20628         done
20629 }
20630 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20631
20632 test_218() {
20633         # do directio so as not to populate the page cache
20634         log "creating a 10 Mb file"
20635         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20636                 error "multiop failed while creating a file"
20637         log "starting reads"
20638         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20639         log "truncating the file"
20640         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20641                 error "multiop failed while truncating the file"
20642         log "killing dd"
20643         kill %+ || true # reads might have finished
20644         echo "wait until dd is finished"
20645         wait
20646         log "removing the temporary file"
20647         rm -rf $DIR/$tfile || error "tmp file removal failed"
20648 }
20649 run_test 218 "parallel read and truncate should not deadlock"
20650
20651 test_219() {
20652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20653
20654         # write one partial page
20655         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20656         # set no grant so vvp_io_commit_write will do sync write
20657         $LCTL set_param fail_loc=0x411
20658         # write a full page at the end of file
20659         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20660
20661         $LCTL set_param fail_loc=0
20662         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20663         $LCTL set_param fail_loc=0x411
20664         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20665
20666         # LU-4201
20667         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20668         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20669 }
20670 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20671
20672 test_220() { #LU-325
20673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20674         remote_ost_nodsh && skip "remote OST with nodsh"
20675         remote_mds_nodsh && skip "remote MDS with nodsh"
20676         remote_mgs_nodsh && skip "remote MGS with nodsh"
20677
20678         local OSTIDX=0
20679
20680         # create on MDT0000 so the last_id and next_id are correct
20681         mkdir_on_mdt0 $DIR/$tdir
20682         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20683         OST=${OST%_UUID}
20684
20685         # on the mdt's osc
20686         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20687         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20688                         osp.$mdtosc_proc1.prealloc_last_id)
20689         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20690                         osp.$mdtosc_proc1.prealloc_next_id)
20691
20692         $LFS df -i
20693
20694         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20695         #define OBD_FAIL_OST_ENOINO              0x229
20696         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20697         create_pool $FSNAME.$TESTNAME || return 1
20698         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20699
20700         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20701
20702         MDSOBJS=$((last_id - next_id))
20703         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20704
20705         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20706         echo "OST still has $count kbytes free"
20707
20708         echo "create $MDSOBJS files @next_id..."
20709         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20710
20711         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20712                         osp.$mdtosc_proc1.prealloc_last_id)
20713         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20714                         osp.$mdtosc_proc1.prealloc_next_id)
20715
20716         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20717         $LFS df -i
20718
20719         echo "cleanup..."
20720
20721         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20722         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20723
20724         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20725                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20726         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20727                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20728         echo "unlink $MDSOBJS files @$next_id..."
20729         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20730 }
20731 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20732
20733 test_221() {
20734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20735
20736         dd if=`which date` of=$MOUNT/date oflag=sync
20737         chmod +x $MOUNT/date
20738
20739         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20740         $LCTL set_param fail_loc=0x80001401
20741
20742         $MOUNT/date > /dev/null
20743         rm -f $MOUNT/date
20744 }
20745 run_test 221 "make sure fault and truncate race to not cause OOM"
20746
20747 test_222a () {
20748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20749
20750         rm -rf $DIR/$tdir
20751         test_mkdir $DIR/$tdir
20752         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20753         createmany -o $DIR/$tdir/$tfile 10
20754         cancel_lru_locks mdc
20755         cancel_lru_locks osc
20756         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20757         $LCTL set_param fail_loc=0x31a
20758         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20759         $LCTL set_param fail_loc=0
20760         rm -r $DIR/$tdir
20761 }
20762 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20763
20764 test_222b () {
20765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20766
20767         rm -rf $DIR/$tdir
20768         test_mkdir $DIR/$tdir
20769         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20770         createmany -o $DIR/$tdir/$tfile 10
20771         cancel_lru_locks mdc
20772         cancel_lru_locks osc
20773         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20774         $LCTL set_param fail_loc=0x31a
20775         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20776         $LCTL set_param fail_loc=0
20777 }
20778 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20779
20780 test_223 () {
20781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20782
20783         rm -rf $DIR/$tdir
20784         test_mkdir $DIR/$tdir
20785         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20786         createmany -o $DIR/$tdir/$tfile 10
20787         cancel_lru_locks mdc
20788         cancel_lru_locks osc
20789         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20790         $LCTL set_param fail_loc=0x31b
20791         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20792         $LCTL set_param fail_loc=0
20793         rm -r $DIR/$tdir
20794 }
20795 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20796
20797 test_224a() { # LU-1039, MRP-303
20798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20799         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20800         $LCTL set_param fail_loc=0x508
20801         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20802         $LCTL set_param fail_loc=0
20803         df $DIR
20804 }
20805 run_test 224a "Don't panic on bulk IO failure"
20806
20807 test_224bd_sub() { # LU-1039, MRP-303
20808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20809         local timeout=$1
20810
20811         shift
20812         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20813
20814         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20815
20816         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20817         cancel_lru_locks osc
20818         set_checksums 0
20819         stack_trap "set_checksums $ORIG_CSUM" EXIT
20820         local at_max_saved=0
20821
20822         # adaptive timeouts may prevent seeing the issue
20823         if at_is_enabled; then
20824                 at_max_saved=$(at_max_get mds)
20825                 at_max_set 0 mds client
20826                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20827         fi
20828
20829         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20830         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20831         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20832
20833         do_facet ost1 $LCTL set_param fail_loc=0
20834         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20835         df $DIR
20836 }
20837
20838 test_224b() {
20839         test_224bd_sub 3 error "dd failed"
20840 }
20841 run_test 224b "Don't panic on bulk IO failure"
20842
20843 test_224c() { # LU-6441
20844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20845         remote_mds_nodsh && skip "remote MDS with nodsh"
20846
20847         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20848         save_writethrough $p
20849         set_cache writethrough on
20850
20851         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20852         local at_max=$($LCTL get_param -n at_max)
20853         local timeout=$($LCTL get_param -n timeout)
20854         local test_at="at_max"
20855         local param_at="$FSNAME.sys.at_max"
20856         local test_timeout="timeout"
20857         local param_timeout="$FSNAME.sys.timeout"
20858
20859         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20860
20861         set_persistent_param_and_check client "$test_at" "$param_at" 0
20862         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20863
20864         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20865         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20866         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20867         stack_trap "rm -f $DIR/$tfile"
20868         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20869         sync
20870         do_facet ost1 "$LCTL set_param fail_loc=0"
20871
20872         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20873         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20874                 $timeout
20875
20876         $LCTL set_param -n $pages_per_rpc
20877         restore_lustre_params < $p
20878         rm -f $p
20879 }
20880 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20881
20882 test_224d() { # LU-11169
20883         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20884 }
20885 run_test 224d "Don't corrupt data on bulk IO timeout"
20886
20887 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20888 test_225a () {
20889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20890         if [ -z ${MDSSURVEY} ]; then
20891                 skip_env "mds-survey not found"
20892         fi
20893         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20894                 skip "Need MDS version at least 2.2.51"
20895
20896         local mds=$(facet_host $SINGLEMDS)
20897         local target=$(do_nodes $mds 'lctl dl' |
20898                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20899
20900         local cmd1="file_count=1000 thrhi=4"
20901         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20902         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20903         local cmd="$cmd1 $cmd2 $cmd3"
20904
20905         rm -f ${TMP}/mds_survey*
20906         echo + $cmd
20907         eval $cmd || error "mds-survey with zero-stripe failed"
20908         cat ${TMP}/mds_survey*
20909         rm -f ${TMP}/mds_survey*
20910 }
20911 run_test 225a "Metadata survey sanity with zero-stripe"
20912
20913 test_225b () {
20914         if [ -z ${MDSSURVEY} ]; then
20915                 skip_env "mds-survey not found"
20916         fi
20917         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20918                 skip "Need MDS version at least 2.2.51"
20919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20920         remote_mds_nodsh && skip "remote MDS with nodsh"
20921         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20922                 skip_env "Need to mount OST to test"
20923         fi
20924
20925         local mds=$(facet_host $SINGLEMDS)
20926         local target=$(do_nodes $mds 'lctl dl' |
20927                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20928
20929         local cmd1="file_count=1000 thrhi=4"
20930         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20931         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20932         local cmd="$cmd1 $cmd2 $cmd3"
20933
20934         rm -f ${TMP}/mds_survey*
20935         echo + $cmd
20936         eval $cmd || error "mds-survey with stripe_count failed"
20937         cat ${TMP}/mds_survey*
20938         rm -f ${TMP}/mds_survey*
20939 }
20940 run_test 225b "Metadata survey sanity with stripe_count = 1"
20941
20942 mcreate_path2fid () {
20943         local mode=$1
20944         local major=$2
20945         local minor=$3
20946         local name=$4
20947         local desc=$5
20948         local path=$DIR/$tdir/$name
20949         local fid
20950         local rc
20951         local fid_path
20952
20953         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20954                 error "cannot create $desc"
20955
20956         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20957         rc=$?
20958         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20959
20960         fid_path=$($LFS fid2path $MOUNT $fid)
20961         rc=$?
20962         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20963
20964         [ "$path" == "$fid_path" ] ||
20965                 error "fid2path returned $fid_path, expected $path"
20966
20967         echo "pass with $path and $fid"
20968 }
20969
20970 test_226a () {
20971         rm -rf $DIR/$tdir
20972         mkdir -p $DIR/$tdir
20973
20974         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20975         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20976         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20977         mcreate_path2fid 0040666 0 0 dir "directory"
20978         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20979         mcreate_path2fid 0100666 0 0 file "regular file"
20980         mcreate_path2fid 0120666 0 0 link "symbolic link"
20981         mcreate_path2fid 0140666 0 0 sock "socket"
20982 }
20983 run_test 226a "call path2fid and fid2path on files of all type"
20984
20985 test_226b () {
20986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20987
20988         local MDTIDX=1
20989
20990         rm -rf $DIR/$tdir
20991         mkdir -p $DIR/$tdir
20992         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20993                 error "create remote directory failed"
20994         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20995         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20996                                 "character special file (null)"
20997         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20998                                 "character special file (no device)"
20999         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21000         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21001                                 "block special file (loop)"
21002         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21003         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21004         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21005 }
21006 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21007
21008 test_226c () {
21009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21010         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21011                 skip "Need MDS version at least 2.13.55"
21012
21013         local submnt=/mnt/submnt
21014         local srcfile=/etc/passwd
21015         local dstfile=$submnt/passwd
21016         local path
21017         local fid
21018
21019         rm -rf $DIR/$tdir
21020         rm -rf $submnt
21021         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21022                 error "create remote directory failed"
21023         mkdir -p $submnt || error "create $submnt failed"
21024         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21025                 error "mount $submnt failed"
21026         stack_trap "umount $submnt" EXIT
21027
21028         cp $srcfile $dstfile
21029         fid=$($LFS path2fid $dstfile)
21030         path=$($LFS fid2path $submnt "$fid")
21031         [ "$path" = "$dstfile" ] ||
21032                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21033 }
21034 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21035
21036 test_226e () {
21037         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21038                 skip "Need client at least version 2.15.56"
21039
21040         # Define filename with 'newline' and a space
21041         local testfile="Test"$'\n'"file 01"
21042         # Define link name with multiple 'newline' and a space
21043         local linkfile="Link"$'\n'"file "$'\n'"01"
21044         # Remove prior hard link
21045         rm -f $DIR/"$linkfile"
21046
21047         # Create file
21048         touch $DIR/"$testfile"
21049         # Create link
21050         ln $DIR/"$testfile" $DIR/"$linkfile"
21051
21052         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21053                 error "getstripe failed on $DIR/$testfile"
21054
21055         # Call with -0 option
21056         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21057                 echo "FILE:" | grep -c "FILE:")
21058
21059         # With -0 option the output should be exactly 2 lines.
21060         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21061 }
21062 run_test 226e "Verify path2fid -0 option with newline and space"
21063
21064 # LU-1299 Executing or running ldd on a truncated executable does not
21065 # cause an out-of-memory condition.
21066 test_227() {
21067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21068         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21069
21070         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21071         chmod +x $MOUNT/date
21072
21073         $MOUNT/date > /dev/null
21074         ldd $MOUNT/date > /dev/null
21075         rm -f $MOUNT/date
21076 }
21077 run_test 227 "running truncated executable does not cause OOM"
21078
21079 # LU-1512 try to reuse idle OI blocks
21080 test_228a() {
21081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21082         remote_mds_nodsh && skip "remote MDS with nodsh"
21083         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21084
21085         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21086         local myDIR=$DIR/$tdir
21087
21088         mkdir -p $myDIR
21089         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21090         $LCTL set_param fail_loc=0x80001002
21091         createmany -o $myDIR/t- 10000
21092         $LCTL set_param fail_loc=0
21093         # The guard is current the largest FID holder
21094         touch $myDIR/guard
21095         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21096                     tr -d '[')
21097         local IDX=$(($SEQ % 64))
21098
21099         do_facet $SINGLEMDS sync
21100         # Make sure journal flushed.
21101         sleep 6
21102         local blk1=$(do_facet $SINGLEMDS \
21103                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21104                      grep Blockcount | awk '{print $4}')
21105
21106         # Remove old files, some OI blocks will become idle.
21107         unlinkmany $myDIR/t- 10000
21108         # Create new files, idle OI blocks should be reused.
21109         createmany -o $myDIR/t- 2000
21110         do_facet $SINGLEMDS sync
21111         # Make sure journal flushed.
21112         sleep 6
21113         local blk2=$(do_facet $SINGLEMDS \
21114                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21115                      grep Blockcount | awk '{print $4}')
21116
21117         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21118 }
21119 run_test 228a "try to reuse idle OI blocks"
21120
21121 test_228b() {
21122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21123         remote_mds_nodsh && skip "remote MDS with nodsh"
21124         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21125
21126         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21127         local myDIR=$DIR/$tdir
21128
21129         mkdir -p $myDIR
21130         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21131         $LCTL set_param fail_loc=0x80001002
21132         createmany -o $myDIR/t- 10000
21133         $LCTL set_param fail_loc=0
21134         # The guard is current the largest FID holder
21135         touch $myDIR/guard
21136         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21137                     tr -d '[')
21138         local IDX=$(($SEQ % 64))
21139
21140         do_facet $SINGLEMDS sync
21141         # Make sure journal flushed.
21142         sleep 6
21143         local blk1=$(do_facet $SINGLEMDS \
21144                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21145                      grep Blockcount | awk '{print $4}')
21146
21147         # Remove old files, some OI blocks will become idle.
21148         unlinkmany $myDIR/t- 10000
21149
21150         # stop the MDT
21151         stop $SINGLEMDS || error "Fail to stop MDT."
21152         # remount the MDT
21153         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21154                 error "Fail to start MDT."
21155
21156         client_up || error "Fail to df."
21157         # Create new files, idle OI blocks should be reused.
21158         createmany -o $myDIR/t- 2000
21159         do_facet $SINGLEMDS sync
21160         # Make sure journal flushed.
21161         sleep 6
21162         local blk2=$(do_facet $SINGLEMDS \
21163                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21164                      grep Blockcount | awk '{print $4}')
21165
21166         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21167 }
21168 run_test 228b "idle OI blocks can be reused after MDT restart"
21169
21170 #LU-1881
21171 test_228c() {
21172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21173         remote_mds_nodsh && skip "remote MDS with nodsh"
21174         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21175
21176         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21177         local myDIR=$DIR/$tdir
21178
21179         mkdir -p $myDIR
21180         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21181         $LCTL set_param fail_loc=0x80001002
21182         # 20000 files can guarantee there are index nodes in the OI file
21183         createmany -o $myDIR/t- 20000
21184         $LCTL set_param fail_loc=0
21185         # The guard is current the largest FID holder
21186         touch $myDIR/guard
21187         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21188                     tr -d '[')
21189         local IDX=$(($SEQ % 64))
21190
21191         do_facet $SINGLEMDS sync
21192         # Make sure journal flushed.
21193         sleep 6
21194         local blk1=$(do_facet $SINGLEMDS \
21195                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21196                      grep Blockcount | awk '{print $4}')
21197
21198         # Remove old files, some OI blocks will become idle.
21199         unlinkmany $myDIR/t- 20000
21200         rm -f $myDIR/guard
21201         # The OI file should become empty now
21202
21203         # Create new files, idle OI blocks should be reused.
21204         createmany -o $myDIR/t- 2000
21205         do_facet $SINGLEMDS sync
21206         # Make sure journal flushed.
21207         sleep 6
21208         local blk2=$(do_facet $SINGLEMDS \
21209                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21210                      grep Blockcount | awk '{print $4}')
21211
21212         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21213 }
21214 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21215
21216 test_229() { # LU-2482, LU-3448
21217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21218         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21219         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21220                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21221
21222         rm -f $DIR/$tfile
21223
21224         # Create a file with a released layout and stripe count 2.
21225         $MULTIOP $DIR/$tfile H2c ||
21226                 error "failed to create file with released layout"
21227
21228         $LFS getstripe -v $DIR/$tfile
21229
21230         local pattern=$($LFS getstripe -L $DIR/$tfile)
21231         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21232
21233         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21234                 error "getstripe"
21235         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21236         stat $DIR/$tfile || error "failed to stat released file"
21237
21238         chown $RUNAS_ID $DIR/$tfile ||
21239                 error "chown $RUNAS_ID $DIR/$tfile failed"
21240
21241         chgrp $RUNAS_ID $DIR/$tfile ||
21242                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21243
21244         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21245         rm $DIR/$tfile || error "failed to remove released file"
21246 }
21247 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21248
21249 test_230a() {
21250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21251         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21252         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21253                 skip "Need MDS version at least 2.11.52"
21254
21255         local MDTIDX=1
21256
21257         test_mkdir $DIR/$tdir
21258         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21259         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21260         [ $mdt_idx -ne 0 ] &&
21261                 error "create local directory on wrong MDT $mdt_idx"
21262
21263         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21264                         error "create remote directory failed"
21265         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21266         [ $mdt_idx -ne $MDTIDX ] &&
21267                 error "create remote directory on wrong MDT $mdt_idx"
21268
21269         createmany -o $DIR/$tdir/test_230/t- 10 ||
21270                 error "create files on remote directory failed"
21271         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21272         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21273         rm -r $DIR/$tdir || error "unlink remote directory failed"
21274 }
21275 run_test 230a "Create remote directory and files under the remote directory"
21276
21277 test_230b() {
21278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21281                 skip "Need MDS version at least 2.11.52"
21282
21283         local MDTIDX=1
21284         local mdt_index
21285         local i
21286         local file
21287         local pid
21288         local stripe_count
21289         local migrate_dir=$DIR/$tdir/migrate_dir
21290         local other_dir=$DIR/$tdir/other_dir
21291
21292         test_mkdir $DIR/$tdir
21293         test_mkdir -i0 -c1 $migrate_dir
21294         test_mkdir -i0 -c1 $other_dir
21295         for ((i=0; i<10; i++)); do
21296                 mkdir -p $migrate_dir/dir_${i}
21297                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21298                         error "create files under remote dir failed $i"
21299         done
21300
21301         cp /etc/passwd $migrate_dir/$tfile
21302         cp /etc/passwd $other_dir/$tfile
21303         chattr +SAD $migrate_dir
21304         chattr +SAD $migrate_dir/$tfile
21305
21306         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21307         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21308         local old_dir_mode=$(stat -c%f $migrate_dir)
21309         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21310
21311         mkdir -p $migrate_dir/dir_default_stripe2
21312         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21313         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21314
21315         mkdir -p $other_dir
21316         ln $migrate_dir/$tfile $other_dir/luna
21317         ln $migrate_dir/$tfile $migrate_dir/sofia
21318         ln $other_dir/$tfile $migrate_dir/david
21319         ln -s $migrate_dir/$tfile $other_dir/zachary
21320         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21321         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21322
21323         local len
21324         local lnktgt
21325
21326         # inline symlink
21327         for len in 58 59 60; do
21328                 lnktgt=$(str_repeat 'l' $len)
21329                 touch $migrate_dir/$lnktgt
21330                 ln -s $lnktgt $migrate_dir/${len}char_ln
21331         done
21332
21333         # PATH_MAX
21334         for len in 4094 4095; do
21335                 lnktgt=$(str_repeat 'l' $len)
21336                 ln -s $lnktgt $migrate_dir/${len}char_ln
21337         done
21338
21339         # NAME_MAX
21340         for len in 254 255; do
21341                 touch $migrate_dir/$(str_repeat 'l' $len)
21342         done
21343
21344         $LFS migrate -m $MDTIDX $migrate_dir ||
21345                 error "fails on migrating remote dir to MDT1"
21346
21347         echo "migratate to MDT1, then checking.."
21348         for ((i = 0; i < 10; i++)); do
21349                 for file in $(find $migrate_dir/dir_${i}); do
21350                         mdt_index=$($LFS getstripe -m $file)
21351                         # broken symlink getstripe will fail
21352                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21353                                 error "$file is not on MDT${MDTIDX}"
21354                 done
21355         done
21356
21357         # the multiple link file should still in MDT0
21358         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21359         [ $mdt_index == 0 ] ||
21360                 error "$file is not on MDT${MDTIDX}"
21361
21362         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21363         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21364                 error " expect $old_dir_flag get $new_dir_flag"
21365
21366         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21367         [ "$old_file_flag" = "$new_file_flag" ] ||
21368                 error " expect $old_file_flag get $new_file_flag"
21369
21370         local new_dir_mode=$(stat -c%f $migrate_dir)
21371         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21372                 error "expect mode $old_dir_mode get $new_dir_mode"
21373
21374         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21375         [ "$old_file_mode" = "$new_file_mode" ] ||
21376                 error "expect mode $old_file_mode get $new_file_mode"
21377
21378         diff /etc/passwd $migrate_dir/$tfile ||
21379                 error "$tfile different after migration"
21380
21381         diff /etc/passwd $other_dir/luna ||
21382                 error "luna different after migration"
21383
21384         diff /etc/passwd $migrate_dir/sofia ||
21385                 error "sofia different after migration"
21386
21387         diff /etc/passwd $migrate_dir/david ||
21388                 error "david different after migration"
21389
21390         diff /etc/passwd $other_dir/zachary ||
21391                 error "zachary different after migration"
21392
21393         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21394                 error "${tfile}_ln different after migration"
21395
21396         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21397                 error "${tfile}_ln_other different after migration"
21398
21399         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21400         [ $stripe_count = 2 ] ||
21401                 error "dir strpe_count $d != 2 after migration."
21402
21403         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21404         [ $stripe_count = 2 ] ||
21405                 error "file strpe_count $d != 2 after migration."
21406
21407         #migrate back to MDT0
21408         MDTIDX=0
21409
21410         $LFS migrate -m $MDTIDX $migrate_dir ||
21411                 error "fails on migrating remote dir to MDT0"
21412
21413         echo "migrate back to MDT0, checking.."
21414         for file in $(find $migrate_dir); do
21415                 mdt_index=$($LFS getstripe -m $file)
21416                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21417                         error "$file is not on MDT${MDTIDX}"
21418         done
21419
21420         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21421         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21422                 error " expect $old_dir_flag get $new_dir_flag"
21423
21424         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21425         [ "$old_file_flag" = "$new_file_flag" ] ||
21426                 error " expect $old_file_flag get $new_file_flag"
21427
21428         local new_dir_mode=$(stat -c%f $migrate_dir)
21429         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21430                 error "expect mode $old_dir_mode get $new_dir_mode"
21431
21432         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21433         [ "$old_file_mode" = "$new_file_mode" ] ||
21434                 error "expect mode $old_file_mode get $new_file_mode"
21435
21436         diff /etc/passwd ${migrate_dir}/$tfile ||
21437                 error "$tfile different after migration"
21438
21439         diff /etc/passwd ${other_dir}/luna ||
21440                 error "luna different after migration"
21441
21442         diff /etc/passwd ${migrate_dir}/sofia ||
21443                 error "sofia different after migration"
21444
21445         diff /etc/passwd ${other_dir}/zachary ||
21446                 error "zachary different after migration"
21447
21448         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21449                 error "${tfile}_ln different after migration"
21450
21451         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21452                 error "${tfile}_ln_other different after migration"
21453
21454         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21455         [ $stripe_count = 2 ] ||
21456                 error "dir strpe_count $d != 2 after migration."
21457
21458         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21459         [ $stripe_count = 2 ] ||
21460                 error "file strpe_count $d != 2 after migration."
21461
21462         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21463 }
21464 run_test 230b "migrate directory"
21465
21466 test_230c() {
21467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21469         remote_mds_nodsh && skip "remote MDS with nodsh"
21470         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21471                 skip "Need MDS version at least 2.11.52"
21472
21473         local MDTIDX=1
21474         local total=3
21475         local mdt_index
21476         local file
21477         local migrate_dir=$DIR/$tdir/migrate_dir
21478
21479         #If migrating directory fails in the middle, all entries of
21480         #the directory is still accessiable.
21481         test_mkdir $DIR/$tdir
21482         test_mkdir -i0 -c1 $migrate_dir
21483         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21484         stat $migrate_dir
21485         createmany -o $migrate_dir/f $total ||
21486                 error "create files under ${migrate_dir} failed"
21487
21488         # fail after migrating top dir, and this will fail only once, so the
21489         # first sub file migration will fail (currently f3), others succeed.
21490         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21491         do_facet mds1 lctl set_param fail_loc=0x1801
21492         local t=$(ls $migrate_dir | wc -l)
21493         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21494                 error "migrate should fail"
21495         local u=$(ls $migrate_dir | wc -l)
21496         [ "$u" == "$t" ] || error "$u != $t during migration"
21497
21498         # add new dir/file should succeed
21499         mkdir $migrate_dir/dir ||
21500                 error "mkdir failed under migrating directory"
21501         touch $migrate_dir/file ||
21502                 error "create file failed under migrating directory"
21503
21504         # add file with existing name should fail
21505         for file in $migrate_dir/f*; do
21506                 stat $file > /dev/null || error "stat $file failed"
21507                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21508                         error "open(O_CREAT|O_EXCL) $file should fail"
21509                 $MULTIOP $file m && error "create $file should fail"
21510                 touch $DIR/$tdir/remote_dir/$tfile ||
21511                         error "touch $tfile failed"
21512                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21513                         error "link $file should fail"
21514                 mdt_index=$($LFS getstripe -m $file)
21515                 if [ $mdt_index == 0 ]; then
21516                         # file failed to migrate is not allowed to rename to
21517                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21518                                 error "rename to $file should fail"
21519                 else
21520                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21521                                 error "rename to $file failed"
21522                 fi
21523                 echo hello >> $file || error "write $file failed"
21524         done
21525
21526         # resume migration with different options should fail
21527         $LFS migrate -m 0 $migrate_dir &&
21528                 error "migrate -m 0 $migrate_dir should fail"
21529
21530         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21531                 error "migrate -c 2 $migrate_dir should fail"
21532
21533         # resume migration should succeed
21534         $LFS migrate -m $MDTIDX $migrate_dir ||
21535                 error "migrate $migrate_dir failed"
21536
21537         echo "Finish migration, then checking.."
21538         for file in $(find $migrate_dir); do
21539                 mdt_index=$($LFS getstripe -m $file)
21540                 [ $mdt_index == $MDTIDX ] ||
21541                         error "$file is not on MDT${MDTIDX}"
21542         done
21543
21544         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21545 }
21546 run_test 230c "check directory accessiblity if migration failed"
21547
21548 test_230d() {
21549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21551         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21552                 skip "Need MDS version at least 2.11.52"
21553         # LU-11235
21554         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21555
21556         local migrate_dir=$DIR/$tdir/migrate_dir
21557         local old_index
21558         local new_index
21559         local old_count
21560         local new_count
21561         local new_hash
21562         local mdt_index
21563         local i
21564         local j
21565
21566         old_index=$((RANDOM % MDSCOUNT))
21567         old_count=$((MDSCOUNT - old_index))
21568         new_index=$((RANDOM % MDSCOUNT))
21569         new_count=$((MDSCOUNT - new_index))
21570         new_hash=1 # for all_char
21571
21572         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21573         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21574
21575         test_mkdir $DIR/$tdir
21576         test_mkdir -i $old_index -c $old_count $migrate_dir
21577
21578         for ((i=0; i<100; i++)); do
21579                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21580                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21581                         error "create files under remote dir failed $i"
21582         done
21583
21584         echo -n "Migrate from MDT$old_index "
21585         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21586         echo -n "to MDT$new_index"
21587         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21588         echo
21589
21590         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21591         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21592                 error "migrate remote dir error"
21593
21594         echo "Finish migration, then checking.."
21595         for file in $(find $migrate_dir -maxdepth 1); do
21596                 mdt_index=$($LFS getstripe -m $file)
21597                 if [ $mdt_index -lt $new_index ] ||
21598                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21599                         error "$file is on MDT$mdt_index"
21600                 fi
21601         done
21602
21603         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21604 }
21605 run_test 230d "check migrate big directory"
21606
21607 test_230e() {
21608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21610         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21611                 skip "Need MDS version at least 2.11.52"
21612
21613         local i
21614         local j
21615         local a_fid
21616         local b_fid
21617
21618         mkdir_on_mdt0 $DIR/$tdir
21619         mkdir $DIR/$tdir/migrate_dir
21620         mkdir $DIR/$tdir/other_dir
21621         touch $DIR/$tdir/migrate_dir/a
21622         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21623         ls $DIR/$tdir/other_dir
21624
21625         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21626                 error "migrate dir fails"
21627
21628         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21629         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21630
21631         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21632         [ $mdt_index == 0 ] || error "a is not on MDT0"
21633
21634         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21635                 error "migrate dir fails"
21636
21637         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21638         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21639
21640         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21641         [ $mdt_index == 1 ] || error "a is not on MDT1"
21642
21643         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21644         [ $mdt_index == 1 ] || error "b is not on MDT1"
21645
21646         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21647         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21648
21649         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21650
21651         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21652 }
21653 run_test 230e "migrate mulitple local link files"
21654
21655 test_230f() {
21656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21658         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21659                 skip "Need MDS version at least 2.11.52"
21660
21661         local a_fid
21662         local ln_fid
21663
21664         mkdir -p $DIR/$tdir
21665         mkdir $DIR/$tdir/migrate_dir
21666         $LFS mkdir -i1 $DIR/$tdir/other_dir
21667         touch $DIR/$tdir/migrate_dir/a
21668         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21669         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21670         ls $DIR/$tdir/other_dir
21671
21672         # a should be migrated to MDT1, since no other links on MDT0
21673         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21674                 error "#1 migrate dir fails"
21675         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21676         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21677         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21678         [ $mdt_index == 1 ] || error "a is not on MDT1"
21679
21680         # a should stay on MDT1, because it is a mulitple link file
21681         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21682                 error "#2 migrate dir fails"
21683         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21684         [ $mdt_index == 1 ] || error "a is not on MDT1"
21685
21686         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21687                 error "#3 migrate dir fails"
21688
21689         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21690         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21691         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21692
21693         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21694         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21695
21696         # a should be migrated to MDT0, since no other links on MDT1
21697         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21698                 error "#4 migrate dir fails"
21699         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21700         [ $mdt_index == 0 ] || error "a is not on MDT0"
21701
21702         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21703 }
21704 run_test 230f "migrate mulitple remote link files"
21705
21706 test_230g() {
21707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21709         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21710                 skip "Need MDS version at least 2.11.52"
21711
21712         mkdir -p $DIR/$tdir/migrate_dir
21713
21714         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21715                 error "migrating dir to non-exist MDT succeeds"
21716         true
21717 }
21718 run_test 230g "migrate dir to non-exist MDT"
21719
21720 test_230h() {
21721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21723         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21724                 skip "Need MDS version at least 2.11.52"
21725
21726         local mdt_index
21727
21728         mkdir -p $DIR/$tdir/migrate_dir
21729
21730         $LFS migrate -m1 $DIR &&
21731                 error "migrating mountpoint1 should fail"
21732
21733         $LFS migrate -m1 $DIR/$tdir/.. &&
21734                 error "migrating mountpoint2 should fail"
21735
21736         # same as mv
21737         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21738                 error "migrating $tdir/migrate_dir/.. should fail"
21739
21740         true
21741 }
21742 run_test 230h "migrate .. and root"
21743
21744 test_230i() {
21745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21747         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21748                 skip "Need MDS version at least 2.11.52"
21749
21750         mkdir -p $DIR/$tdir/migrate_dir
21751
21752         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21753                 error "migration fails with a tailing slash"
21754
21755         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21756                 error "migration fails with two tailing slashes"
21757 }
21758 run_test 230i "lfs migrate -m tolerates trailing slashes"
21759
21760 test_230j() {
21761         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21762         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21763                 skip "Need MDS version at least 2.11.52"
21764
21765         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21766         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21767                 error "create $tfile failed"
21768         cat /etc/passwd > $DIR/$tdir/$tfile
21769
21770         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21771
21772         cmp /etc/passwd $DIR/$tdir/$tfile ||
21773                 error "DoM file mismatch after migration"
21774 }
21775 run_test 230j "DoM file data not changed after dir migration"
21776
21777 test_230k() {
21778         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21779         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21780                 skip "Need MDS version at least 2.11.56"
21781
21782         local total=20
21783         local files_on_starting_mdt=0
21784
21785         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21786         $LFS getdirstripe $DIR/$tdir
21787         for i in $(seq $total); do
21788                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21789                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21790                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21791         done
21792
21793         echo "$files_on_starting_mdt files on MDT0"
21794
21795         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21796         $LFS getdirstripe $DIR/$tdir
21797
21798         files_on_starting_mdt=0
21799         for i in $(seq $total); do
21800                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21801                         error "file $tfile.$i mismatch after migration"
21802                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21803                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21804         done
21805
21806         echo "$files_on_starting_mdt files on MDT1 after migration"
21807         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21808
21809         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21810         $LFS getdirstripe $DIR/$tdir
21811
21812         files_on_starting_mdt=0
21813         for i in $(seq $total); do
21814                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21815                         error "file $tfile.$i mismatch after 2nd migration"
21816                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21817                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21818         done
21819
21820         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21821         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21822
21823         true
21824 }
21825 run_test 230k "file data not changed after dir migration"
21826
21827 test_230l() {
21828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21829         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21830                 skip "Need MDS version at least 2.11.56"
21831
21832         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21833         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21834                 error "create files under remote dir failed $i"
21835         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21836 }
21837 run_test 230l "readdir between MDTs won't crash"
21838
21839 test_230m() {
21840         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21841         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21842                 skip "Need MDS version at least 2.11.56"
21843
21844         local MDTIDX=1
21845         local mig_dir=$DIR/$tdir/migrate_dir
21846         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21847         local shortstr="b"
21848         local val
21849
21850         echo "Creating files and dirs with xattrs"
21851         test_mkdir $DIR/$tdir
21852         test_mkdir -i0 -c1 $mig_dir
21853         mkdir $mig_dir/dir
21854         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21855                 error "cannot set xattr attr1 on dir"
21856         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21857                 error "cannot set xattr attr2 on dir"
21858         touch $mig_dir/dir/f0
21859         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21860                 error "cannot set xattr attr1 on file"
21861         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21862                 error "cannot set xattr attr2 on file"
21863         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21864         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21865         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21866         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21867         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21868         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21869         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21870         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21871         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21872
21873         echo "Migrating to MDT1"
21874         $LFS migrate -m $MDTIDX $mig_dir ||
21875                 error "fails on migrating dir to MDT1"
21876
21877         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21878         echo "Checking xattrs"
21879         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21880         [ "$val" = $longstr ] ||
21881                 error "expecting xattr1 $longstr on dir, found $val"
21882         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21883         [ "$val" = $shortstr ] ||
21884                 error "expecting xattr2 $shortstr on dir, found $val"
21885         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21886         [ "$val" = $longstr ] ||
21887                 error "expecting xattr1 $longstr on file, found $val"
21888         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21889         [ "$val" = $shortstr ] ||
21890                 error "expecting xattr2 $shortstr on file, found $val"
21891 }
21892 run_test 230m "xattrs not changed after dir migration"
21893
21894 test_230n() {
21895         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21896         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21897                 skip "Need MDS version at least 2.13.53"
21898
21899         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21900         cat /etc/hosts > $DIR/$tdir/$tfile
21901         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21902         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21903
21904         cmp /etc/hosts $DIR/$tdir/$tfile ||
21905                 error "File data mismatch after migration"
21906 }
21907 run_test 230n "Dir migration with mirrored file"
21908
21909 test_230o() {
21910         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21911         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21912                 skip "Need MDS version at least 2.13.52"
21913
21914         local mdts=$(comma_list $(mdts_nodes))
21915         local timeout=100
21916         local restripe_status
21917         local delta
21918         local i
21919
21920         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21921
21922         # in case "crush" hash type is not set
21923         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21924
21925         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21926                            mdt.*MDT0000.enable_dir_restripe)
21927         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21928         stack_trap "do_nodes $mdts $LCTL set_param \
21929                     mdt.*.enable_dir_restripe=$restripe_status"
21930
21931         mkdir $DIR/$tdir
21932         createmany -m $DIR/$tdir/f 100 ||
21933                 error "create files under remote dir failed $i"
21934         createmany -d $DIR/$tdir/d 100 ||
21935                 error "create dirs under remote dir failed $i"
21936
21937         for i in $(seq 2 $MDSCOUNT); do
21938                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21939                 $LFS setdirstripe -c $i $DIR/$tdir ||
21940                         error "split -c $i $tdir failed"
21941                 wait_update $HOSTNAME \
21942                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21943                         error "dir split not finished"
21944                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21945                         awk '/migrate/ {sum += $2} END { print sum }')
21946                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21947                 # delta is around total_files/stripe_count
21948                 (( $delta < 200 / (i - 1) + 4 )) ||
21949                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21950         done
21951 }
21952 run_test 230o "dir split"
21953
21954 test_230p() {
21955         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21956         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21957                 skip "Need MDS version at least 2.13.52"
21958
21959         local mdts=$(comma_list $(mdts_nodes))
21960         local timeout=100
21961         local restripe_status
21962         local delta
21963         local c
21964
21965         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21966
21967         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21968
21969         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21970                            mdt.*MDT0000.enable_dir_restripe)
21971         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21972         stack_trap "do_nodes $mdts $LCTL set_param \
21973                     mdt.*.enable_dir_restripe=$restripe_status"
21974
21975         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21976         createmany -m $DIR/$tdir/f 100 ||
21977                 error "create files under remote dir failed"
21978         createmany -d $DIR/$tdir/d 100 ||
21979                 error "create dirs under remote dir failed"
21980
21981         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21982                 local mdt_hash="crush"
21983
21984                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21985                 $LFS setdirstripe -c $c $DIR/$tdir ||
21986                         error "split -c $c $tdir failed"
21987                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21988                         mdt_hash="$mdt_hash,fixed"
21989                 elif [ $c -eq 1 ]; then
21990                         mdt_hash="none"
21991                 fi
21992                 wait_update $HOSTNAME \
21993                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21994                         error "dir merge not finished"
21995                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21996                         awk '/migrate/ {sum += $2} END { print sum }')
21997                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21998                 # delta is around total_files/stripe_count
21999                 (( delta < 200 / c + 4 )) ||
22000                         error "$delta files migrated >= $((200 / c + 4))"
22001         done
22002 }
22003 run_test 230p "dir merge"
22004
22005 test_230q() {
22006         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22007         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22008                 skip "Need MDS version at least 2.13.52"
22009
22010         local mdts=$(comma_list $(mdts_nodes))
22011         local saved_threshold=$(do_facet mds1 \
22012                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22013         local saved_delta=$(do_facet mds1 \
22014                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22015         local threshold=100
22016         local delta=2
22017         local total=0
22018         local stripe_count=0
22019         local stripe_index
22020         local nr_files
22021         local create
22022
22023         # test with fewer files on ZFS
22024         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22025
22026         stack_trap "do_nodes $mdts $LCTL set_param \
22027                     mdt.*.dir_split_count=$saved_threshold"
22028         stack_trap "do_nodes $mdts $LCTL set_param \
22029                     mdt.*.dir_split_delta=$saved_delta"
22030         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22031         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22032         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22033         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22034         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22035         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22036
22037         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22038         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22039
22040         create=$((threshold * 3 / 2))
22041         while [ $stripe_count -lt $MDSCOUNT ]; do
22042                 createmany -m $DIR/$tdir/f $total $create ||
22043                         error "create sub files failed"
22044                 stat $DIR/$tdir > /dev/null
22045                 total=$((total + create))
22046                 stripe_count=$((stripe_count + delta))
22047                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22048
22049                 wait_update $HOSTNAME \
22050                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22051                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22052
22053                 wait_update $HOSTNAME \
22054                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22055                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22056
22057                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22058                 echo "$nr_files/$total files on MDT$stripe_index after split"
22059                 # allow 10% margin of imbalance with crush hash
22060                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22061                         error "$nr_files files on MDT$stripe_index after split"
22062
22063                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22064                 [ $nr_files -eq $total ] ||
22065                         error "total sub files $nr_files != $total"
22066         done
22067
22068         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22069
22070         echo "fixed layout directory won't auto split"
22071         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22072         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22073                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22074         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22075                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22076 }
22077 run_test 230q "dir auto split"
22078
22079 test_230r() {
22080         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22081         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22082         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22083                 skip "Need MDS version at least 2.13.54"
22084
22085         # maximum amount of local locks:
22086         # parent striped dir - 2 locks
22087         # new stripe in parent to migrate to - 1 lock
22088         # source and target - 2 locks
22089         # Total 5 locks for regular file
22090         mkdir -p $DIR/$tdir
22091         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22092         touch $DIR/$tdir/dir1/eee
22093
22094         # create 4 hardlink for 4 more locks
22095         # Total: 9 locks > RS_MAX_LOCKS (8)
22096         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22097         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22098         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22099         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22100         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22101         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22102         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22103         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22104
22105         cancel_lru_locks mdc
22106
22107         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22108                 error "migrate dir fails"
22109
22110         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22111 }
22112 run_test 230r "migrate with too many local locks"
22113
22114 test_230s() {
22115         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22116                 skip "Need MDS version at least 2.14.52"
22117
22118         local mdts=$(comma_list $(mdts_nodes))
22119         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22120                                 mdt.*MDT0000.enable_dir_restripe)
22121
22122         stack_trap "do_nodes $mdts $LCTL set_param \
22123                     mdt.*.enable_dir_restripe=$restripe_status"
22124
22125         local st
22126         for st in 0 1; do
22127                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22128                 test_mkdir $DIR/$tdir
22129                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22130                         error "$LFS mkdir should return EEXIST if target exists"
22131                 rmdir $DIR/$tdir
22132         done
22133 }
22134 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22135
22136 test_230t()
22137 {
22138         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22139         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22140                 skip "Need MDS version at least 2.14.50"
22141
22142         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22143         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22144         $LFS project -p 1 -s $DIR/$tdir ||
22145                 error "set $tdir project id failed"
22146         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22147                 error "set subdir project id failed"
22148         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22149 }
22150 run_test 230t "migrate directory with project ID set"
22151
22152 test_230u()
22153 {
22154         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22155         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22156                 skip "Need MDS version at least 2.14.53"
22157
22158         local count
22159
22160         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22161         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22162         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22163         for i in $(seq 0 $((MDSCOUNT - 1))); do
22164                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22165                 echo "$count dirs migrated to MDT$i"
22166         done
22167         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22168         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22169 }
22170 run_test 230u "migrate directory by QOS"
22171
22172 test_230v()
22173 {
22174         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22175         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22176                 skip "Need MDS version at least 2.14.53"
22177
22178         local count
22179
22180         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22181         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22182         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22183         for i in $(seq 0 $((MDSCOUNT - 1))); do
22184                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22185                 echo "$count subdirs migrated to MDT$i"
22186                 (( i == 3 )) && (( count > 0 )) &&
22187                         error "subdir shouldn't be migrated to MDT3"
22188         done
22189         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22190         (( count == 3 )) || error "dirs migrated to $count MDTs"
22191 }
22192 run_test 230v "subdir migrated to the MDT where its parent is located"
22193
22194 test_230w() {
22195         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22196         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22197                 skip "Need MDS version at least 2.15.0"
22198
22199         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22200         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22201         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22202
22203         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22204                 error "migrate failed"
22205
22206         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22207                 error "$tdir stripe count mismatch"
22208
22209         for i in $(seq 0 9); do
22210                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22211                         error "d$i is striped"
22212         done
22213 }
22214 run_test 230w "non-recursive mode dir migration"
22215
22216 test_230x() {
22217         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22218         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22219                 skip "Need MDS version at least 2.15.0"
22220
22221         mkdir -p $DIR/$tdir || error "mkdir failed"
22222         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22223
22224         local mdt_name=$(mdtname_from_index 0)
22225         local low=$(do_facet mds2 $LCTL get_param -n \
22226                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22227         local high=$(do_facet mds2 $LCTL get_param -n \
22228                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22229         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22230         local maxage=$(do_facet mds2 $LCTL get_param -n \
22231                 osp.*$mdt_name-osp-MDT0001.maxage)
22232
22233         stack_trap "do_facet mds2 $LCTL set_param -n \
22234                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22235                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22236         stack_trap "do_facet mds2 $LCTL set_param -n \
22237                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22238
22239         do_facet mds2 $LCTL set_param -n \
22240                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22241         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22242         sleep 4
22243         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22244                 error "migrate $tdir should fail"
22245
22246         do_facet mds2 $LCTL set_param -n \
22247                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22248         do_facet mds2 $LCTL set_param -n \
22249                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22250         sleep 4
22251         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22252                 error "migrate failed"
22253         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22254                 error "$tdir stripe count mismatch"
22255 }
22256 run_test 230x "dir migration check space"
22257
22258 test_230y() {
22259         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22260         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22261                 skip "Need MDS version at least 2.15.55.45"
22262
22263         local pid
22264
22265         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22266         $LFS getdirstripe $DIR/$tdir
22267         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22268         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22269         pid=$!
22270         sleep 1
22271
22272         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22273         do_facet mds2 lctl set_param fail_loc=0x1802
22274
22275         wait $pid
22276         do_facet mds2 lctl set_param fail_loc=0
22277         $LFS getdirstripe $DIR/$tdir
22278         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22279         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22280 }
22281 run_test 230y "unlink dir with bad hash type"
22282
22283 test_230z() {
22284         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22285         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22286                 skip "Need MDS version at least 2.15.55.45"
22287
22288         local pid
22289
22290         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22291         $LFS getdirstripe $DIR/$tdir
22292         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22293         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22294         pid=$!
22295         sleep 1
22296
22297         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22298         do_facet mds2 lctl set_param fail_loc=0x1802
22299
22300         wait $pid
22301         do_facet mds2 lctl set_param fail_loc=0
22302         $LFS getdirstripe $DIR/$tdir
22303
22304         # resume migration
22305         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22306                 error "resume migration failed"
22307         $LFS getdirstripe $DIR/$tdir
22308         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22309                 error "migration is not finished"
22310 }
22311 run_test 230z "resume dir migration with bad hash type"
22312
22313 test_231a()
22314 {
22315         # For simplicity this test assumes that max_pages_per_rpc
22316         # is the same across all OSCs
22317         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22318         local bulk_size=$((max_pages * PAGE_SIZE))
22319         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22320                                        head -n 1)
22321
22322         mkdir -p $DIR/$tdir
22323         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22324                 error "failed to set stripe with -S ${brw_size}M option"
22325         stack_trap "rm -rf $DIR/$tdir"
22326
22327         # clear the OSC stats
22328         $LCTL set_param osc.*.stats=0 &>/dev/null
22329         stop_writeback
22330
22331         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22332         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22333                 oflag=direct &>/dev/null || error "dd failed"
22334
22335         sync; sleep 1; sync # just to be safe
22336         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22337         if [ x$nrpcs != "x1" ]; then
22338                 $LCTL get_param osc.*.stats
22339                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22340         fi
22341
22342         start_writeback
22343         # Drop the OSC cache, otherwise we will read from it
22344         cancel_lru_locks osc
22345
22346         # clear the OSC stats
22347         $LCTL set_param osc.*.stats=0 &>/dev/null
22348
22349         # Client reads $bulk_size.
22350         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22351                 iflag=direct &>/dev/null || error "dd failed"
22352
22353         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22354         if [ x$nrpcs != "x1" ]; then
22355                 $LCTL get_param osc.*.stats
22356                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22357         fi
22358 }
22359 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22360
22361 test_231b() {
22362         mkdir -p $DIR/$tdir
22363         stack_trap "rm -rf $DIR/$tdir"
22364         local i
22365         for i in {0..1023}; do
22366                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22367                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22368                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22369         done
22370         sync
22371 }
22372 run_test 231b "must not assert on fully utilized OST request buffer"
22373
22374 test_232a() {
22375         mkdir -p $DIR/$tdir
22376         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22377
22378         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22379         do_facet ost1 $LCTL set_param fail_loc=0x31c
22380
22381         # ignore dd failure
22382         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22383         stack_trap "rm -f $DIR/$tdir/$tfile"
22384
22385         do_facet ost1 $LCTL set_param fail_loc=0
22386         umount_client $MOUNT || error "umount failed"
22387         mount_client $MOUNT || error "mount failed"
22388         stop ost1 || error "cannot stop ost1"
22389         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22390 }
22391 run_test 232a "failed lock should not block umount"
22392
22393 test_232b() {
22394         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22395                 skip "Need MDS version at least 2.10.58"
22396
22397         mkdir -p $DIR/$tdir
22398         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22399         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22400         stack_trap "rm -f $DIR/$tdir/$tfile"
22401         sync
22402         cancel_lru_locks osc
22403
22404         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22405         do_facet ost1 $LCTL set_param fail_loc=0x31c
22406
22407         # ignore failure
22408         $LFS data_version $DIR/$tdir/$tfile || true
22409
22410         do_facet ost1 $LCTL set_param fail_loc=0
22411         umount_client $MOUNT || error "umount failed"
22412         mount_client $MOUNT || error "mount failed"
22413         stop ost1 || error "cannot stop ost1"
22414         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22415 }
22416 run_test 232b "failed data version lock should not block umount"
22417
22418 test_233a() {
22419         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22420                 skip "Need MDS version at least 2.3.64"
22421         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22422
22423         local fid=$($LFS path2fid $MOUNT)
22424
22425         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22426                 error "cannot access $MOUNT using its FID '$fid'"
22427 }
22428 run_test 233a "checking that OBF of the FS root succeeds"
22429
22430 test_233b() {
22431         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22432                 skip "Need MDS version at least 2.5.90"
22433         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22434
22435         local fid=$($LFS path2fid $MOUNT/.lustre)
22436
22437         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22438                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22439
22440         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22441         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22442                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22443 }
22444 run_test 233b "checking that OBF of the FS .lustre succeeds"
22445
22446 test_234() {
22447         local p="$TMP/sanityN-$TESTNAME.parameters"
22448         save_lustre_params client "llite.*.xattr_cache" > $p
22449         lctl set_param llite.*.xattr_cache 1 ||
22450                 skip_env "xattr cache is not supported"
22451
22452         mkdir -p $DIR/$tdir || error "mkdir failed"
22453         touch $DIR/$tdir/$tfile || error "touch failed"
22454         # OBD_FAIL_LLITE_XATTR_ENOMEM
22455         $LCTL set_param fail_loc=0x1405
22456         getfattr -n user.attr $DIR/$tdir/$tfile &&
22457                 error "getfattr should have failed with ENOMEM"
22458         $LCTL set_param fail_loc=0x0
22459         rm -rf $DIR/$tdir
22460
22461         restore_lustre_params < $p
22462         rm -f $p
22463 }
22464 run_test 234 "xattr cache should not crash on ENOMEM"
22465
22466 test_235() {
22467         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22468                 skip "Need MDS version at least 2.4.52"
22469
22470         flock_deadlock $DIR/$tfile
22471         local RC=$?
22472         case $RC in
22473                 0)
22474                 ;;
22475                 124) error "process hangs on a deadlock"
22476                 ;;
22477                 *) error "error executing flock_deadlock $DIR/$tfile"
22478                 ;;
22479         esac
22480 }
22481 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22482
22483 #LU-2935
22484 test_236() {
22485         check_swap_layouts_support
22486
22487         local ref1=/etc/passwd
22488         local ref2=/etc/group
22489         local file1=$DIR/$tdir/f1
22490         local file2=$DIR/$tdir/f2
22491
22492         test_mkdir -c1 $DIR/$tdir
22493         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22494         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22495         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22496         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22497         local fd=$(free_fd)
22498         local cmd="exec $fd<>$file2"
22499         eval $cmd
22500         rm $file2
22501         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22502                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22503         cmd="exec $fd>&-"
22504         eval $cmd
22505         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22506
22507         #cleanup
22508         rm -rf $DIR/$tdir
22509 }
22510 run_test 236 "Layout swap on open unlinked file"
22511
22512 # LU-4659 linkea consistency
22513 test_238() {
22514         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22515                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22516                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22517                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22518
22519         touch $DIR/$tfile
22520         ln $DIR/$tfile $DIR/$tfile.lnk
22521         touch $DIR/$tfile.new
22522         mv $DIR/$tfile.new $DIR/$tfile
22523         local fid1=$($LFS path2fid $DIR/$tfile)
22524         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22525         local path1=$($LFS fid2path $FSNAME "$fid1")
22526         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22527         local path2=$($LFS fid2path $FSNAME "$fid2")
22528         [ $tfile.lnk == $path2 ] ||
22529                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22530         rm -f $DIR/$tfile*
22531 }
22532 run_test 238 "Verify linkea consistency"
22533
22534 test_239A() { # was test_239
22535         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22536                 skip "Need MDS version at least 2.5.60"
22537
22538         local list=$(comma_list $(mdts_nodes))
22539
22540         mkdir -p $DIR/$tdir
22541         createmany -o $DIR/$tdir/f- 5000
22542         unlinkmany $DIR/$tdir/f- 5000
22543         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22544                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22545         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22546                         osp.*MDT*.sync_in_flight" | calc_sum)
22547         [ "$changes" -eq 0 ] || error "$changes not synced"
22548 }
22549 run_test 239A "osp_sync test"
22550
22551 test_239a() { #LU-5297
22552         remote_mds_nodsh && skip "remote MDS with nodsh"
22553
22554         touch $DIR/$tfile
22555         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22556         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22557         chgrp $RUNAS_GID $DIR/$tfile
22558         wait_delete_completed
22559 }
22560 run_test 239a "process invalid osp sync record correctly"
22561
22562 test_239b() { #LU-5297
22563         remote_mds_nodsh && skip "remote MDS with nodsh"
22564
22565         touch $DIR/$tfile1
22566         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22567         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22568         chgrp $RUNAS_GID $DIR/$tfile1
22569         wait_delete_completed
22570         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22571         touch $DIR/$tfile2
22572         chgrp $RUNAS_GID $DIR/$tfile2
22573         wait_delete_completed
22574 }
22575 run_test 239b "process osp sync record with ENOMEM error correctly"
22576
22577 test_240() {
22578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22579         remote_mds_nodsh && skip "remote MDS with nodsh"
22580
22581         mkdir -p $DIR/$tdir
22582
22583         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22584                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22585         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22586                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22587
22588         umount_client $MOUNT || error "umount failed"
22589         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22590         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22591         mount_client $MOUNT || error "failed to mount client"
22592
22593         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22594         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22595 }
22596 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22597
22598 test_241_bio() {
22599         local count=$1
22600         local bsize=$2
22601
22602         for LOOP in $(seq $count); do
22603                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22604                 cancel_lru_locks $OSC || true
22605         done
22606 }
22607
22608 test_241_dio() {
22609         local count=$1
22610         local bsize=$2
22611
22612         for LOOP in $(seq $1); do
22613                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22614                         2>/dev/null
22615         done
22616 }
22617
22618 test_241a() { # was test_241
22619         local bsize=$PAGE_SIZE
22620
22621         (( bsize < 40960 )) && bsize=40960
22622         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22623         ls -la $DIR/$tfile
22624         cancel_lru_locks $OSC
22625         test_241_bio 1000 $bsize &
22626         PID=$!
22627         test_241_dio 1000 $bsize
22628         wait $PID
22629 }
22630 run_test 241a "bio vs dio"
22631
22632 test_241b() {
22633         local bsize=$PAGE_SIZE
22634
22635         (( bsize < 40960 )) && bsize=40960
22636         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22637         ls -la $DIR/$tfile
22638         test_241_dio 1000 $bsize &
22639         PID=$!
22640         test_241_dio 1000 $bsize
22641         wait $PID
22642 }
22643 run_test 241b "dio vs dio"
22644
22645 test_242() {
22646         remote_mds_nodsh && skip "remote MDS with nodsh"
22647
22648         mkdir_on_mdt0 $DIR/$tdir
22649         touch $DIR/$tdir/$tfile
22650
22651         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22652         do_facet mds1 lctl set_param fail_loc=0x105
22653         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22654
22655         do_facet mds1 lctl set_param fail_loc=0
22656         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22657 }
22658 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22659
22660 test_243()
22661 {
22662         test_mkdir $DIR/$tdir
22663         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22664 }
22665 run_test 243 "various group lock tests"
22666
22667 test_244a()
22668 {
22669         test_mkdir $DIR/$tdir
22670         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22671         sendfile_grouplock $DIR/$tdir/$tfile || \
22672                 error "sendfile+grouplock failed"
22673         rm -rf $DIR/$tdir
22674 }
22675 run_test 244a "sendfile with group lock tests"
22676
22677 test_244b()
22678 {
22679         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22680
22681         local threads=50
22682         local size=$((1024*1024))
22683
22684         test_mkdir $DIR/$tdir
22685         for i in $(seq 1 $threads); do
22686                 local file=$DIR/$tdir/file_$((i / 10))
22687                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22688                 local pids[$i]=$!
22689         done
22690         for i in $(seq 1 $threads); do
22691                 wait ${pids[$i]}
22692         done
22693 }
22694 run_test 244b "multi-threaded write with group lock"
22695
22696 test_245a() {
22697         local flagname="multi_mod_rpcs"
22698         local connect_data_name="max_mod_rpcs"
22699         local out
22700
22701         # check if multiple modify RPCs flag is set
22702         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22703                 grep "connect_flags:")
22704         echo "$out"
22705
22706         echo "$out" | grep -qw $flagname
22707         if [ $? -ne 0 ]; then
22708                 echo "connect flag $flagname is not set"
22709                 return
22710         fi
22711
22712         # check if multiple modify RPCs data is set
22713         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22714         echo "$out"
22715
22716         echo "$out" | grep -qw $connect_data_name ||
22717                 error "import should have connect data $connect_data_name"
22718 }
22719 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22720
22721 test_245b() {
22722         local flagname="multi_mod_rpcs"
22723         local connect_data_name="max_mod_rpcs"
22724         local out
22725
22726         remote_mds_nodsh && skip "remote MDS with nodsh"
22727         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22728
22729         # check if multiple modify RPCs flag is set
22730         out=$(do_facet mds1 \
22731               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22732               grep "connect_flags:")
22733         echo "$out"
22734
22735         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22736
22737         # check if multiple modify RPCs data is set
22738         out=$(do_facet mds1 \
22739               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22740
22741         [[ "$out" =~ $connect_data_name ]] ||
22742                 {
22743                         echo "$out"
22744                         error "missing connect data $connect_data_name"
22745                 }
22746 }
22747 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22748
22749 cleanup_247() {
22750         local submount=$1
22751
22752         trap 0
22753         umount_client $submount
22754         rmdir $submount
22755 }
22756
22757 test_247a() {
22758         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22759                 grep -q subtree ||
22760                 skip_env "Fileset feature is not supported"
22761
22762         local submount=${MOUNT}_$tdir
22763
22764         mkdir $MOUNT/$tdir
22765         mkdir -p $submount || error "mkdir $submount failed"
22766         FILESET="$FILESET/$tdir" mount_client $submount ||
22767                 error "mount $submount failed"
22768         trap "cleanup_247 $submount" EXIT
22769         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22770         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22771                 error "read $MOUNT/$tdir/$tfile failed"
22772         cleanup_247 $submount
22773 }
22774 run_test 247a "mount subdir as fileset"
22775
22776 test_247b() {
22777         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22778                 skip_env "Fileset feature is not supported"
22779
22780         local submount=${MOUNT}_$tdir
22781
22782         rm -rf $MOUNT/$tdir
22783         mkdir -p $submount || error "mkdir $submount failed"
22784         SKIP_FILESET=1
22785         FILESET="$FILESET/$tdir" mount_client $submount &&
22786                 error "mount $submount should fail"
22787         rmdir $submount
22788 }
22789 run_test 247b "mount subdir that dose not exist"
22790
22791 test_247c() {
22792         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22793                 skip_env "Fileset feature is not supported"
22794
22795         local submount=${MOUNT}_$tdir
22796
22797         mkdir -p $MOUNT/$tdir/dir1
22798         mkdir -p $submount || error "mkdir $submount failed"
22799         trap "cleanup_247 $submount" EXIT
22800         FILESET="$FILESET/$tdir" mount_client $submount ||
22801                 error "mount $submount failed"
22802         local fid=$($LFS path2fid $MOUNT/)
22803         $LFS fid2path $submount $fid && error "fid2path should fail"
22804         cleanup_247 $submount
22805 }
22806 run_test 247c "running fid2path outside subdirectory root"
22807
22808 test_247d() {
22809         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22810                 skip "Fileset feature is not supported"
22811
22812         local submount=${MOUNT}_$tdir
22813
22814         mkdir -p $MOUNT/$tdir/dir1
22815         mkdir -p $submount || error "mkdir $submount failed"
22816         FILESET="$FILESET/$tdir" mount_client $submount ||
22817                 error "mount $submount failed"
22818         trap "cleanup_247 $submount" EXIT
22819
22820         local td=$submount/dir1
22821         local fid=$($LFS path2fid $td)
22822         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22823
22824         # check that we get the same pathname back
22825         local rootpath
22826         local found
22827         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22828                 echo "$rootpath $fid"
22829                 found=$($LFS fid2path $rootpath "$fid")
22830                 [ -n "$found" ] || error "fid2path should succeed"
22831                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22832         done
22833         # check wrong root path format
22834         rootpath=$submount"_wrong"
22835         found=$($LFS fid2path $rootpath "$fid")
22836         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22837
22838         cleanup_247 $submount
22839 }
22840 run_test 247d "running fid2path inside subdirectory root"
22841
22842 # LU-8037
22843 test_247e() {
22844         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22845                 grep -q subtree ||
22846                 skip "Fileset feature is not supported"
22847
22848         local submount=${MOUNT}_$tdir
22849
22850         mkdir $MOUNT/$tdir
22851         mkdir -p $submount || error "mkdir $submount failed"
22852         FILESET="$FILESET/.." mount_client $submount &&
22853                 error "mount $submount should fail"
22854         rmdir $submount
22855 }
22856 run_test 247e "mount .. as fileset"
22857
22858 test_247f() {
22859         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22860         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22861                 skip "Need at least version 2.14.50.162"
22862         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22863                 skip "Fileset feature is not supported"
22864
22865         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22866         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22867                 error "mkdir remote failed"
22868         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22869                 error "mkdir remote/subdir failed"
22870         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22871                 error "mkdir striped failed"
22872         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22873
22874         local submount=${MOUNT}_$tdir
22875
22876         mkdir -p $submount || error "mkdir $submount failed"
22877         stack_trap "rmdir $submount"
22878
22879         local dir
22880         local fileset=$FILESET
22881         local mdts=$(comma_list $(mdts_nodes))
22882
22883         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22884         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22885                 $tdir/striped/subdir $tdir/striped/.; do
22886                 FILESET="$fileset/$dir" mount_client $submount ||
22887                         error "mount $dir failed"
22888                 umount_client $submount
22889         done
22890 }
22891 run_test 247f "mount striped or remote directory as fileset"
22892
22893 test_subdir_mount_lock()
22894 {
22895         local testdir=$1
22896         local submount=${MOUNT}_$(basename $testdir)
22897
22898         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22899
22900         mkdir -p $submount || error "mkdir $submount failed"
22901         stack_trap "rmdir $submount"
22902
22903         FILESET="$fileset/$testdir" mount_client $submount ||
22904                 error "mount $FILESET failed"
22905         stack_trap "umount $submount"
22906
22907         local mdts=$(comma_list $(mdts_nodes))
22908
22909         local nrpcs
22910
22911         stat $submount > /dev/null || error "stat $submount failed"
22912         cancel_lru_locks $MDC
22913         stat $submount > /dev/null || error "stat $submount failed"
22914         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22915         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22916         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22917         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22918                 awk '/getattr/ {sum += $2} END {print sum}')
22919
22920         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22921 }
22922
22923 test_247g() {
22924         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22925
22926         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22927                 error "mkdir $tdir failed"
22928         test_subdir_mount_lock $tdir
22929 }
22930 run_test 247g "striped directory submount revalidate ROOT from cache"
22931
22932 test_247h() {
22933         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22934         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22935                 skip "Need MDS version at least 2.15.51"
22936
22937         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22938         test_subdir_mount_lock $tdir
22939         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22940         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22941                 error "mkdir $tdir.1 failed"
22942         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22943 }
22944 run_test 247h "remote directory submount revalidate ROOT from cache"
22945
22946 test_248a() {
22947         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22948         [ -z "$fast_read_sav" ] && skip "no fast read support"
22949
22950         # create a large file for fast read verification
22951         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22952
22953         # make sure the file is created correctly
22954         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22955                 { rm -f $DIR/$tfile; skip "file creation error"; }
22956
22957         echo "Test 1: verify that fast read is 4 times faster on cache read"
22958
22959         # small read with fast read enabled
22960         $LCTL set_param -n llite.*.fast_read=1
22961         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22962                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22963                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22964         # small read with fast read disabled
22965         $LCTL set_param -n llite.*.fast_read=0
22966         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22967                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22968                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22969
22970         # verify that fast read is 4 times faster for cache read
22971         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22972                 error_not_in_vm "fast read was not 4 times faster: " \
22973                            "$t_fast vs $t_slow"
22974
22975         echo "Test 2: verify the performance between big and small read"
22976         $LCTL set_param -n llite.*.fast_read=1
22977
22978         # 1k non-cache read
22979         cancel_lru_locks osc
22980         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22981                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22982                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22983
22984         # 1M non-cache read
22985         cancel_lru_locks osc
22986         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22987                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22988                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22989
22990         # verify that big IO is not 4 times faster than small IO
22991         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22992                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22993
22994         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22995         rm -f $DIR/$tfile
22996 }
22997 run_test 248a "fast read verification"
22998
22999 test_248b() {
23000         # Default short_io_bytes=16384, try both smaller and larger sizes.
23001         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23002         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23003         echo "bs=53248 count=113 normal buffered write"
23004         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23005                 error "dd of initial data file failed"
23006         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23007
23008         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23009         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23010                 error "dd with sync normal writes failed"
23011         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23012
23013         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23014         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23015                 error "dd with sync small writes failed"
23016         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23017
23018         cancel_lru_locks osc
23019
23020         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23021         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23022         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23023         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23024                 iflag=direct || error "dd with O_DIRECT small read failed"
23025         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23026         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23027                 error "compare $TMP/$tfile.1 failed"
23028
23029         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23030         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23031
23032         # just to see what the maximum tunable value is, and test parsing
23033         echo "test invalid parameter 2MB"
23034         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23035                 error "too-large short_io_bytes allowed"
23036         echo "test maximum parameter 512KB"
23037         # if we can set a larger short_io_bytes, run test regardless of version
23038         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23039                 # older clients may not allow setting it this large, that's OK
23040                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23041                         skip "Need at least client version 2.13.50"
23042                 error "medium short_io_bytes failed"
23043         fi
23044         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23045         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23046
23047         echo "test large parameter 64KB"
23048         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23049         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23050
23051         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23052         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23053                 error "dd with sync large writes failed"
23054         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23055
23056         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23057         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23058         num=$((113 * 4096 / PAGE_SIZE))
23059         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23060         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23061                 error "dd with O_DIRECT large writes failed"
23062         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23063                 error "compare $DIR/$tfile.3 failed"
23064
23065         cancel_lru_locks osc
23066
23067         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23068         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23069                 error "dd with O_DIRECT large read failed"
23070         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23071                 error "compare $TMP/$tfile.2 failed"
23072
23073         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23074         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23075                 error "dd with O_DIRECT large read failed"
23076         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23077                 error "compare $TMP/$tfile.3 failed"
23078 }
23079 run_test 248b "test short_io read and write for both small and large sizes"
23080
23081 test_249() { # LU-7890
23082         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23083                 skip "Need at least version 2.8.54"
23084
23085         rm -f $DIR/$tfile
23086         $LFS setstripe -c 1 $DIR/$tfile
23087         # Offset 2T == 4k * 512M
23088         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23089                 error "dd to 2T offset failed"
23090 }
23091 run_test 249 "Write above 2T file size"
23092
23093 test_250() {
23094         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23095          && skip "no 16TB file size limit on ZFS"
23096
23097         $LFS setstripe -c 1 $DIR/$tfile
23098         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23099         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23100         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23101         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23102                 conv=notrunc,fsync && error "append succeeded"
23103         return 0
23104 }
23105 run_test 250 "Write above 16T limit"
23106
23107 test_251() {
23108         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23109
23110         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23111         #Skip once - writing the first stripe will succeed
23112         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23113         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23114                 error "short write happened"
23115
23116         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23117         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23118                 error "short read happened"
23119
23120         rm -f $DIR/$tfile
23121 }
23122 run_test 251 "Handling short read and write correctly"
23123
23124 test_252() {
23125         remote_mds_nodsh && skip "remote MDS with nodsh"
23126         remote_ost_nodsh && skip "remote OST with nodsh"
23127         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23128                 skip_env "ldiskfs only test"
23129         fi
23130
23131         local tgt
23132         local dev
23133         local out
23134         local uuid
23135         local num
23136         local gen
23137
23138         # check lr_reader on OST0000
23139         tgt=ost1
23140         dev=$(facet_device $tgt)
23141         out=$(do_facet $tgt $LR_READER $dev)
23142         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23143         echo "$out"
23144         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23145         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23146                 error "Invalid uuid returned by $LR_READER on target $tgt"
23147         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23148
23149         # check lr_reader -c on MDT0000
23150         tgt=mds1
23151         dev=$(facet_device $tgt)
23152         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23153                 skip "$LR_READER does not support additional options"
23154         fi
23155         out=$(do_facet $tgt $LR_READER -c $dev)
23156         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23157         echo "$out"
23158         num=$(echo "$out" | grep -c "mdtlov")
23159         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23160                 error "Invalid number of mdtlov clients returned by $LR_READER"
23161         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23162
23163         # check lr_reader -cr on MDT0000
23164         out=$(do_facet $tgt $LR_READER -cr $dev)
23165         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23166         echo "$out"
23167         echo "$out" | grep -q "^reply_data:$" ||
23168                 error "$LR_READER should have returned 'reply_data' section"
23169         num=$(echo "$out" | grep -c "client_generation")
23170         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23171 }
23172 run_test 252 "check lr_reader tool"
23173
23174 test_253() {
23175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23176         remote_mds_nodsh && skip "remote MDS with nodsh"
23177         remote_mgs_nodsh && skip "remote MGS with nodsh"
23178
23179         local ostidx=0
23180         local rc=0
23181         local ost_name=$(ostname_from_index $ostidx)
23182
23183         # on the mdt's osc
23184         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23185         do_facet $SINGLEMDS $LCTL get_param -n \
23186                 osp.$mdtosc_proc1.reserved_mb_high ||
23187                 skip  "remote MDS does not support reserved_mb_high"
23188
23189         rm -rf $DIR/$tdir
23190         wait_mds_ost_sync
23191         wait_delete_completed
23192         mkdir $DIR/$tdir
23193         stack_trap "rm -rf $DIR/$tdir"
23194
23195         pool_add $TESTNAME || error "Pool creation failed"
23196         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23197
23198         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23199                 error "Setstripe failed"
23200
23201         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23202
23203         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23204                     grep "watermarks")
23205         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23206
23207         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23208                         osp.$mdtosc_proc1.prealloc_status)
23209         echo "prealloc_status $oa_status"
23210
23211         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23212                 error "File creation should fail"
23213
23214         #object allocation was stopped, but we still able to append files
23215         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23216                 oflag=append || error "Append failed"
23217
23218         rm -f $DIR/$tdir/$tfile.0
23219
23220         # For this test, we want to delete the files we created to go out of
23221         # space but leave the watermark, so we remain nearly out of space
23222         ost_watermarks_enospc_delete_files $tfile $ostidx
23223
23224         wait_delete_completed
23225
23226         sleep_maxage
23227
23228         for i in $(seq 10 12); do
23229                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23230                         2>/dev/null || error "File creation failed after rm"
23231         done
23232
23233         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23234                         osp.$mdtosc_proc1.prealloc_status)
23235         echo "prealloc_status $oa_status"
23236
23237         if (( oa_status != 0 )); then
23238                 error "Object allocation still disable after rm"
23239         fi
23240 }
23241 run_test 253 "Check object allocation limit"
23242
23243 test_254() {
23244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23245         remote_mds_nodsh && skip "remote MDS with nodsh"
23246
23247         local mdt=$(facet_svc $SINGLEMDS)
23248
23249         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23250                 skip "MDS does not support changelog_size"
23251
23252         local cl_user
23253
23254         changelog_register || error "changelog_register failed"
23255
23256         changelog_clear 0 || error "changelog_clear failed"
23257
23258         local size1=$(do_facet $SINGLEMDS \
23259                       $LCTL get_param -n mdd.$mdt.changelog_size)
23260         echo "Changelog size $size1"
23261
23262         rm -rf $DIR/$tdir
23263         $LFS mkdir -i 0 $DIR/$tdir
23264         # change something
23265         mkdir -p $DIR/$tdir/pics/2008/zachy
23266         touch $DIR/$tdir/pics/2008/zachy/timestamp
23267         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23268         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23269         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23270         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23271         rm $DIR/$tdir/pics/desktop.jpg
23272
23273         local size2=$(do_facet $SINGLEMDS \
23274                       $LCTL get_param -n mdd.$mdt.changelog_size)
23275         echo "Changelog size after work $size2"
23276
23277         (( $size2 > $size1 )) ||
23278                 error "new Changelog size=$size2 less than old size=$size1"
23279 }
23280 run_test 254 "Check changelog size"
23281
23282 ladvise_no_type()
23283 {
23284         local type=$1
23285         local file=$2
23286
23287         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23288                 awk -F: '{print $2}' | grep $type > /dev/null
23289         if [ $? -ne 0 ]; then
23290                 return 0
23291         fi
23292         return 1
23293 }
23294
23295 ladvise_no_ioctl()
23296 {
23297         local file=$1
23298
23299         lfs ladvise -a willread $file > /dev/null 2>&1
23300         if [ $? -eq 0 ]; then
23301                 return 1
23302         fi
23303
23304         lfs ladvise -a willread $file 2>&1 |
23305                 grep "Inappropriate ioctl for device" > /dev/null
23306         if [ $? -eq 0 ]; then
23307                 return 0
23308         fi
23309         return 1
23310 }
23311
23312 percent() {
23313         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23314 }
23315
23316 # run a random read IO workload
23317 # usage: random_read_iops <filename> <filesize> <iosize>
23318 random_read_iops() {
23319         local file=$1
23320         local fsize=$2
23321         local iosize=${3:-4096}
23322
23323         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23324                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23325 }
23326
23327 drop_file_oss_cache() {
23328         local file="$1"
23329         local nodes="$2"
23330
23331         $LFS ladvise -a dontneed $file 2>/dev/null ||
23332                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23333 }
23334
23335 ladvise_willread_performance()
23336 {
23337         local repeat=10
23338         local average_origin=0
23339         local average_cache=0
23340         local average_ladvise=0
23341
23342         for ((i = 1; i <= $repeat; i++)); do
23343                 echo "Iter $i/$repeat: reading without willread hint"
23344                 cancel_lru_locks osc
23345                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23346                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23347                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23348                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23349
23350                 cancel_lru_locks osc
23351                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23352                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23353                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23354
23355                 cancel_lru_locks osc
23356                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23357                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23358                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23359                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23360                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23361         done
23362         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23363         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23364         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23365
23366         speedup_cache=$(percent $average_cache $average_origin)
23367         speedup_ladvise=$(percent $average_ladvise $average_origin)
23368
23369         echo "Average uncached read: $average_origin"
23370         echo "Average speedup with OSS cached read: " \
23371                 "$average_cache = +$speedup_cache%"
23372         echo "Average speedup with ladvise willread: " \
23373                 "$average_ladvise = +$speedup_ladvise%"
23374
23375         local lowest_speedup=20
23376         if (( ${average_cache%.*} < $lowest_speedup )); then
23377                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23378                      " got $average_cache%. Skipping ladvise willread check."
23379                 return 0
23380         fi
23381
23382         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23383         # it is still good to run until then to exercise 'ladvise willread'
23384         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23385                 [ "$ost1_FSTYPE" = "zfs" ] &&
23386                 echo "osd-zfs does not support dontneed or drop_caches" &&
23387                 return 0
23388
23389         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23390         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23391                 error_not_in_vm "Speedup with willread is less than " \
23392                         "$lowest_speedup%, got $average_ladvise%"
23393 }
23394
23395 test_255a() {
23396         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23397                 skip "lustre < 2.8.54 does not support ladvise "
23398         remote_ost_nodsh && skip "remote OST with nodsh"
23399
23400         stack_trap "rm -f $DIR/$tfile"
23401         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23402
23403         ladvise_no_type willread $DIR/$tfile &&
23404                 skip "willread ladvise is not supported"
23405
23406         ladvise_no_ioctl $DIR/$tfile &&
23407                 skip "ladvise ioctl is not supported"
23408
23409         local size_mb=100
23410         local size=$((size_mb * 1048576))
23411         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23412                 error "dd to $DIR/$tfile failed"
23413
23414         lfs ladvise -a willread $DIR/$tfile ||
23415                 error "Ladvise failed with no range argument"
23416
23417         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23418                 error "Ladvise failed with no -l or -e argument"
23419
23420         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23421                 error "Ladvise failed with only -e argument"
23422
23423         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23424                 error "Ladvise failed with only -l argument"
23425
23426         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23427                 error "End offset should not be smaller than start offset"
23428
23429         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23430                 error "End offset should not be equal to start offset"
23431
23432         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23433                 error "Ladvise failed with overflowing -s argument"
23434
23435         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23436                 error "Ladvise failed with overflowing -e argument"
23437
23438         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23439                 error "Ladvise failed with overflowing -l argument"
23440
23441         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23442                 error "Ladvise succeeded with conflicting -l and -e arguments"
23443
23444         echo "Synchronous ladvise should wait"
23445         local delay=8
23446 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23447         do_nodes $(comma_list $(osts_nodes)) \
23448                 $LCTL set_param fail_val=$delay fail_loc=0x237
23449         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23450                 $LCTL set_param fail_loc=0"
23451
23452         local start_ts=$SECONDS
23453         lfs ladvise -a willread $DIR/$tfile ||
23454                 error "Ladvise failed with no range argument"
23455         local end_ts=$SECONDS
23456         local inteval_ts=$((end_ts - start_ts))
23457
23458         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23459                 error "Synchronous advice didn't wait reply"
23460         fi
23461
23462         echo "Asynchronous ladvise shouldn't wait"
23463         local start_ts=$SECONDS
23464         lfs ladvise -a willread -b $DIR/$tfile ||
23465                 error "Ladvise failed with no range argument"
23466         local end_ts=$SECONDS
23467         local inteval_ts=$((end_ts - start_ts))
23468
23469         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23470                 error "Asynchronous advice blocked"
23471         fi
23472
23473         ladvise_willread_performance
23474 }
23475 run_test 255a "check 'lfs ladvise -a willread'"
23476
23477 facet_meminfo() {
23478         local facet=$1
23479         local info=$2
23480
23481         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23482 }
23483
23484 test_255b() {
23485         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23486                 skip "lustre < 2.8.54 does not support ladvise "
23487         remote_ost_nodsh && skip "remote OST with nodsh"
23488
23489         stack_trap "rm -f $DIR/$tfile"
23490         lfs setstripe -c 1 -i 0 $DIR/$tfile
23491
23492         ladvise_no_type dontneed $DIR/$tfile &&
23493                 skip "dontneed ladvise is not supported"
23494
23495         ladvise_no_ioctl $DIR/$tfile &&
23496                 skip "ladvise ioctl is not supported"
23497
23498         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23499                 [ "$ost1_FSTYPE" = "zfs" ] &&
23500                 skip "zfs-osd does not support 'ladvise dontneed'"
23501
23502         local size_mb=100
23503         local size=$((size_mb * 1048576))
23504         # In order to prevent disturbance of other processes, only check 3/4
23505         # of the memory usage
23506         local kibibytes=$((size_mb * 1024 * 3 / 4))
23507
23508         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23509                 error "dd to $DIR/$tfile failed"
23510
23511         #force write to complete before dropping OST cache & checking memory
23512         sync
23513
23514         local total=$(facet_meminfo ost1 MemTotal)
23515         echo "Total memory: $total KiB"
23516
23517         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23518         local before_read=$(facet_meminfo ost1 Cached)
23519         echo "Cache used before read: $before_read KiB"
23520
23521         lfs ladvise -a willread $DIR/$tfile ||
23522                 error "Ladvise willread failed"
23523         local after_read=$(facet_meminfo ost1 Cached)
23524         echo "Cache used after read: $after_read KiB"
23525
23526         lfs ladvise -a dontneed $DIR/$tfile ||
23527                 error "Ladvise dontneed again failed"
23528         local no_read=$(facet_meminfo ost1 Cached)
23529         echo "Cache used after dontneed ladvise: $no_read KiB"
23530
23531         if [ $total -lt $((before_read + kibibytes)) ]; then
23532                 echo "Memory is too small, abort checking"
23533                 return 0
23534         fi
23535
23536         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23537                 error "Ladvise willread should use more memory" \
23538                         "than $kibibytes KiB"
23539         fi
23540
23541         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23542                 error "Ladvise dontneed should release more memory" \
23543                         "than $kibibytes KiB"
23544         fi
23545 }
23546 run_test 255b "check 'lfs ladvise -a dontneed'"
23547
23548 test_255c() {
23549         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23550                 skip "lustre < 2.10.50 does not support lockahead"
23551
23552         local ost1_imp=$(get_osc_import_name client ost1)
23553         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23554                          cut -d'.' -f2)
23555         local count
23556         local new_count
23557         local difference
23558         local i
23559         local rc
23560
23561         test_mkdir -p $DIR/$tdir
23562         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23563
23564         #test 10 returns only success/failure
23565         i=10
23566         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23567         rc=$?
23568         if [ $rc -eq 255 ]; then
23569                 error "Ladvise test${i} failed, ${rc}"
23570         fi
23571
23572         #test 11 counts lock enqueue requests, all others count new locks
23573         i=11
23574         count=$(do_facet ost1 \
23575                 $LCTL get_param -n ost.OSS.ost.stats)
23576         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23577
23578         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23579         rc=$?
23580         if [ $rc -eq 255 ]; then
23581                 error "Ladvise test${i} failed, ${rc}"
23582         fi
23583
23584         new_count=$(do_facet ost1 \
23585                 $LCTL get_param -n ost.OSS.ost.stats)
23586         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23587                    awk '{ print $2 }')
23588
23589         difference="$((new_count - count))"
23590         if [ $difference -ne $rc ]; then
23591                 error "Ladvise test${i}, bad enqueue count, returned " \
23592                       "${rc}, actual ${difference}"
23593         fi
23594
23595         for i in $(seq 12 21); do
23596                 # If we do not do this, we run the risk of having too many
23597                 # locks and starting lock cancellation while we are checking
23598                 # lock counts.
23599                 cancel_lru_locks osc
23600
23601                 count=$($LCTL get_param -n \
23602                        ldlm.namespaces.$imp_name.lock_unused_count)
23603
23604                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23605                 rc=$?
23606                 if [ $rc -eq 255 ]; then
23607                         error "Ladvise test ${i} failed, ${rc}"
23608                 fi
23609
23610                 new_count=$($LCTL get_param -n \
23611                        ldlm.namespaces.$imp_name.lock_unused_count)
23612                 difference="$((new_count - count))"
23613
23614                 # Test 15 output is divided by 100 to map down to valid return
23615                 if [ $i -eq 15 ]; then
23616                         rc="$((rc * 100))"
23617                 fi
23618
23619                 if [ $difference -ne $rc ]; then
23620                         error "Ladvise test ${i}, bad lock count, returned " \
23621                               "${rc}, actual ${difference}"
23622                 fi
23623         done
23624
23625         #test 22 returns only success/failure
23626         i=22
23627         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23628         rc=$?
23629         if [ $rc -eq 255 ]; then
23630                 error "Ladvise test${i} failed, ${rc}"
23631         fi
23632 }
23633 run_test 255c "suite of ladvise lockahead tests"
23634
23635 test_256() {
23636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23637         remote_mds_nodsh && skip "remote MDS with nodsh"
23638         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23639         changelog_users $SINGLEMDS | grep "^cl" &&
23640                 skip "active changelog user"
23641
23642         local cl_user
23643         local cat_sl
23644         local mdt_dev
23645
23646         mdt_dev=$(facet_device $SINGLEMDS)
23647         echo $mdt_dev
23648
23649         changelog_register || error "changelog_register failed"
23650
23651         rm -rf $DIR/$tdir
23652         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23653
23654         changelog_clear 0 || error "changelog_clear failed"
23655
23656         # change something
23657         touch $DIR/$tdir/{1..10}
23658
23659         # stop the MDT
23660         stop $SINGLEMDS || error "Fail to stop MDT"
23661
23662         # remount the MDT
23663         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23664                 error "Fail to start MDT"
23665
23666         #after mount new plainllog is used
23667         touch $DIR/$tdir/{11..19}
23668         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23669         stack_trap "rm -f $tmpfile"
23670         cat_sl=$(do_facet $SINGLEMDS "sync; \
23671                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23672                  llog_reader $tmpfile | grep -c type=1064553b")
23673         do_facet $SINGLEMDS llog_reader $tmpfile
23674
23675         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23676
23677         changelog_clear 0 || error "changelog_clear failed"
23678
23679         cat_sl=$(do_facet $SINGLEMDS "sync; \
23680                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23681                  llog_reader $tmpfile | grep -c type=1064553b")
23682
23683         if (( cat_sl == 2 )); then
23684                 error "Empty plain llog was not deleted from changelog catalog"
23685         elif (( cat_sl != 1 )); then
23686                 error "Active plain llog shouldn't be deleted from catalog"
23687         fi
23688 }
23689 run_test 256 "Check llog delete for empty and not full state"
23690
23691 test_257() {
23692         remote_mds_nodsh && skip "remote MDS with nodsh"
23693         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23694                 skip "Need MDS version at least 2.8.55"
23695
23696         test_mkdir $DIR/$tdir
23697
23698         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23699                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23700         stat $DIR/$tdir
23701
23702 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23703         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23704         local facet=mds$((mdtidx + 1))
23705         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23706         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23707
23708         stop $facet || error "stop MDS failed"
23709         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23710                 error "start MDS fail"
23711         wait_recovery_complete $facet
23712 }
23713 run_test 257 "xattr locks are not lost"
23714
23715 # Verify we take the i_mutex when security requires it
23716 test_258a() {
23717 #define OBD_FAIL_IMUTEX_SEC 0x141c
23718         $LCTL set_param fail_loc=0x141c
23719         touch $DIR/$tfile
23720         chmod u+s $DIR/$tfile
23721         chmod a+rwx $DIR/$tfile
23722         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23723         RC=$?
23724         if [ $RC -ne 0 ]; then
23725                 error "error, failed to take i_mutex, rc=$?"
23726         fi
23727         rm -f $DIR/$tfile
23728 }
23729 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23730
23731 # Verify we do NOT take the i_mutex in the normal case
23732 test_258b() {
23733 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23734         $LCTL set_param fail_loc=0x141d
23735         touch $DIR/$tfile
23736         chmod a+rwx $DIR
23737         chmod a+rw $DIR/$tfile
23738         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23739         RC=$?
23740         if [ $RC -ne 0 ]; then
23741                 error "error, took i_mutex unnecessarily, rc=$?"
23742         fi
23743         rm -f $DIR/$tfile
23744
23745 }
23746 run_test 258b "verify i_mutex security behavior"
23747
23748 test_259() {
23749         local file=$DIR/$tfile
23750         local before
23751         local after
23752
23753         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23754
23755         stack_trap "rm -f $file" EXIT
23756
23757         wait_delete_completed
23758         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23759         echo "before: $before"
23760
23761         $LFS setstripe -i 0 -c 1 $file
23762         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23763         sync_all_data
23764         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23765         echo "after write: $after"
23766
23767 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23768         do_facet ost1 $LCTL set_param fail_loc=0x2301
23769         $TRUNCATE $file 0
23770         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23771         echo "after truncate: $after"
23772
23773         stop ost1
23774         do_facet ost1 $LCTL set_param fail_loc=0
23775         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23776         sleep 2
23777         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23778         echo "after restart: $after"
23779         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23780                 error "missing truncate?"
23781
23782         return 0
23783 }
23784 run_test 259 "crash at delayed truncate"
23785
23786 test_260() {
23787 #define OBD_FAIL_MDC_CLOSE               0x806
23788         $LCTL set_param fail_loc=0x80000806
23789         touch $DIR/$tfile
23790
23791 }
23792 run_test 260 "Check mdc_close fail"
23793
23794 ### Data-on-MDT sanity tests ###
23795 test_270a() {
23796         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23797                 skip "Need MDS version at least 2.10.55 for DoM"
23798
23799         # create DoM file
23800         local dom=$DIR/$tdir/dom_file
23801         local tmp=$DIR/$tdir/tmp_file
23802
23803         mkdir_on_mdt0 $DIR/$tdir
23804
23805         # basic checks for DoM component creation
23806         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23807                 error "Can set MDT layout to non-first entry"
23808
23809         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23810                 error "Can define multiple entries as MDT layout"
23811
23812         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23813
23814         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23815         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23816         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23817
23818         local mdtidx=$($LFS getstripe -m $dom)
23819         local mdtname=MDT$(printf %04x $mdtidx)
23820         local facet=mds$((mdtidx + 1))
23821         local space_check=1
23822
23823         # Skip free space checks with ZFS
23824         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23825
23826         # write
23827         sync
23828         local size_tmp=$((65536 * 3))
23829         local mdtfree1=$(do_facet $facet \
23830                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23831
23832         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23833         # check also direct IO along write
23834         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23835         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23836         sync
23837         cmp $tmp $dom || error "file data is different"
23838         [ $(stat -c%s $dom) == $size_tmp ] ||
23839                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23840         if [ $space_check == 1 ]; then
23841                 local mdtfree2=$(do_facet $facet \
23842                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23843
23844                 # increase in usage from by $size_tmp
23845                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23846                         error "MDT free space wrong after write: " \
23847                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23848         fi
23849
23850         # truncate
23851         local size_dom=10000
23852
23853         $TRUNCATE $dom $size_dom
23854         [ $(stat -c%s $dom) == $size_dom ] ||
23855                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23856         if [ $space_check == 1 ]; then
23857                 mdtfree1=$(do_facet $facet \
23858                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23859                 # decrease in usage from $size_tmp to new $size_dom
23860                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23861                   $(((size_tmp - size_dom) / 1024)) ] ||
23862                         error "MDT free space is wrong after truncate: " \
23863                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23864         fi
23865
23866         # append
23867         cat $tmp >> $dom
23868         sync
23869         size_dom=$((size_dom + size_tmp))
23870         [ $(stat -c%s $dom) == $size_dom ] ||
23871                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23872         if [ $space_check == 1 ]; then
23873                 mdtfree2=$(do_facet $facet \
23874                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23875                 # increase in usage by $size_tmp from previous
23876                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23877                         error "MDT free space is wrong after append: " \
23878                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23879         fi
23880
23881         # delete
23882         rm $dom
23883         if [ $space_check == 1 ]; then
23884                 mdtfree1=$(do_facet $facet \
23885                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23886                 # decrease in usage by $size_dom from previous
23887                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23888                         error "MDT free space is wrong after removal: " \
23889                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23890         fi
23891
23892         # combined striping
23893         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23894                 error "Can't create DoM + OST striping"
23895
23896         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23897         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23898         # check also direct IO along write
23899         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23900         sync
23901         cmp $tmp $dom || error "file data is different"
23902         [ $(stat -c%s $dom) == $size_tmp ] ||
23903                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23904         rm $dom $tmp
23905
23906         return 0
23907 }
23908 run_test 270a "DoM: basic functionality tests"
23909
23910 test_270b() {
23911         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23912                 skip "Need MDS version at least 2.10.55"
23913
23914         local dom=$DIR/$tdir/dom_file
23915         local max_size=1048576
23916
23917         mkdir -p $DIR/$tdir
23918         $LFS setstripe -E $max_size -L mdt $dom
23919
23920         # truncate over the limit
23921         $TRUNCATE $dom $(($max_size + 1)) &&
23922                 error "successful truncate over the maximum size"
23923         # write over the limit
23924         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23925                 error "successful write over the maximum size"
23926         # append over the limit
23927         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23928         echo "12345" >> $dom && error "successful append over the maximum size"
23929         rm $dom
23930
23931         return 0
23932 }
23933 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23934
23935 test_270c() {
23936         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23937                 skip "Need MDS version at least 2.10.55"
23938
23939         mkdir -p $DIR/$tdir
23940         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23941
23942         # check files inherit DoM EA
23943         touch $DIR/$tdir/first
23944         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23945                 error "bad pattern"
23946         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23947                 error "bad stripe count"
23948         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23949                 error "bad stripe size"
23950
23951         # check directory inherits DoM EA and uses it as default
23952         mkdir $DIR/$tdir/subdir
23953         touch $DIR/$tdir/subdir/second
23954         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23955                 error "bad pattern in sub-directory"
23956         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23957                 error "bad stripe count in sub-directory"
23958         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23959                 error "bad stripe size in sub-directory"
23960         return 0
23961 }
23962 run_test 270c "DoM: DoM EA inheritance tests"
23963
23964 test_270d() {
23965         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23966                 skip "Need MDS version at least 2.10.55"
23967
23968         mkdir -p $DIR/$tdir
23969         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23970
23971         # inherit default DoM striping
23972         mkdir $DIR/$tdir/subdir
23973         touch $DIR/$tdir/subdir/f1
23974
23975         # change default directory striping
23976         $LFS setstripe -c 1 $DIR/$tdir/subdir
23977         touch $DIR/$tdir/subdir/f2
23978         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23979                 error "wrong default striping in file 2"
23980         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23981                 error "bad pattern in file 2"
23982         return 0
23983 }
23984 run_test 270d "DoM: change striping from DoM to RAID0"
23985
23986 test_270e() {
23987         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23988                 skip "Need MDS version at least 2.10.55"
23989
23990         mkdir -p $DIR/$tdir/dom
23991         mkdir -p $DIR/$tdir/norm
23992         DOMFILES=20
23993         NORMFILES=10
23994         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23995         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23996
23997         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23998         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23999
24000         # find DoM files by layout
24001         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24002         [ $NUM -eq  $DOMFILES ] ||
24003                 error "lfs find -L: found $NUM, expected $DOMFILES"
24004         echo "Test 1: lfs find 20 DOM files by layout: OK"
24005
24006         # there should be 1 dir with default DOM striping
24007         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24008         [ $NUM -eq  1 ] ||
24009                 error "lfs find -L: found $NUM, expected 1 dir"
24010         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24011
24012         # find DoM files by stripe size
24013         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24014         [ $NUM -eq  $DOMFILES ] ||
24015                 error "lfs find -S: found $NUM, expected $DOMFILES"
24016         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24017
24018         # find files by stripe offset except DoM files
24019         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24020         [ $NUM -eq  $NORMFILES ] ||
24021                 error "lfs find -i: found $NUM, expected $NORMFILES"
24022         echo "Test 5: lfs find no DOM files by stripe index: OK"
24023         return 0
24024 }
24025 run_test 270e "DoM: lfs find with DoM files test"
24026
24027 test_270f() {
24028         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24029                 skip "Need MDS version at least 2.10.55"
24030
24031         local mdtname=${FSNAME}-MDT0000-mdtlov
24032         local dom=$DIR/$tdir/dom_file
24033         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24034                                                 lod.$mdtname.dom_stripesize)
24035         local dom_limit=131072
24036
24037         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24038         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24039                                                 lod.$mdtname.dom_stripesize)
24040         [ ${dom_limit} -eq ${dom_current} ] ||
24041                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24042
24043         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24044         $LFS setstripe -d $DIR/$tdir
24045         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24046                 error "Can't set directory default striping"
24047
24048         # exceed maximum stripe size
24049         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24050                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24051         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24052                 error "Able to create DoM component size more than LOD limit"
24053
24054         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24055         dom_current=$(do_facet mds1 $LCTL get_param -n \
24056                                                 lod.$mdtname.dom_stripesize)
24057         [ 0 -eq ${dom_current} ] ||
24058                 error "Can't set zero DoM stripe limit"
24059         rm $dom
24060
24061         # attempt to create DoM file on server with disabled DoM should
24062         # remove DoM entry from layout and be succeed
24063         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24064                 error "Can't create DoM file (DoM is disabled)"
24065         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24066                 error "File has DoM component while DoM is disabled"
24067         rm $dom
24068
24069         # attempt to create DoM file with only DoM stripe should return error
24070         $LFS setstripe -E $dom_limit -L mdt $dom &&
24071                 error "Able to create DoM-only file while DoM is disabled"
24072
24073         # too low values to be aligned with smallest stripe size 64K
24074         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24075         dom_current=$(do_facet mds1 $LCTL get_param -n \
24076                                                 lod.$mdtname.dom_stripesize)
24077         [ 30000 -eq ${dom_current} ] &&
24078                 error "Can set too small DoM stripe limit"
24079
24080         # 64K is a minimal stripe size in Lustre, expect limit of that size
24081         [ 65536 -eq ${dom_current} ] ||
24082                 error "Limit is not set to 64K but ${dom_current}"
24083
24084         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24085         dom_current=$(do_facet mds1 $LCTL get_param -n \
24086                                                 lod.$mdtname.dom_stripesize)
24087         echo $dom_current
24088         [ 2147483648 -eq ${dom_current} ] &&
24089                 error "Can set too large DoM stripe limit"
24090
24091         do_facet mds1 $LCTL set_param -n \
24092                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24093         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24094                 error "Can't create DoM component size after limit change"
24095         do_facet mds1 $LCTL set_param -n \
24096                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24097         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24098                 error "Can't create DoM file after limit decrease"
24099         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24100                 error "Can create big DoM component after limit decrease"
24101         touch ${dom}_def ||
24102                 error "Can't create file with old default layout"
24103
24104         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24105         return 0
24106 }
24107 run_test 270f "DoM: maximum DoM stripe size checks"
24108
24109 test_270g() {
24110         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24111                 skip "Need MDS version at least 2.13.52"
24112         local dom=$DIR/$tdir/$tfile
24113
24114         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24115         local lodname=${FSNAME}-MDT0000-mdtlov
24116
24117         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24118         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24119         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24120         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24121
24122         local dom_limit=1024
24123         local dom_threshold="50%"
24124
24125         $LFS setstripe -d $DIR/$tdir
24126         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24127                 error "Can't set directory default striping"
24128
24129         do_facet mds1 $LCTL set_param -n \
24130                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24131         # set 0 threshold and create DOM file to change tunable stripesize
24132         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24133         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24134                 error "Failed to create $dom file"
24135         # now tunable dom_cur_stripesize should reach maximum
24136         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24137                                         lod.${lodname}.dom_stripesize_cur_kb)
24138         [[ $dom_current == $dom_limit ]] ||
24139                 error "Current DOM stripesize is not maximum"
24140         rm $dom
24141
24142         # set threshold for further tests
24143         do_facet mds1 $LCTL set_param -n \
24144                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24145         echo "DOM threshold is $dom_threshold free space"
24146         local dom_def
24147         local dom_set
24148         # Spoof bfree to exceed threshold
24149         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24150         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24151         for spfree in 40 20 0 15 30 55; do
24152                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24153                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24154                         error "Failed to create $dom file"
24155                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24156                                         lod.${lodname}.dom_stripesize_cur_kb)
24157                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24158                 [[ $dom_def != $dom_current ]] ||
24159                         error "Default stripe size was not changed"
24160                 if (( spfree > 0 )) ; then
24161                         dom_set=$($LFS getstripe -S $dom)
24162                         (( dom_set == dom_def * 1024 )) ||
24163                                 error "DOM component size is still old"
24164                 else
24165                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24166                                 error "DoM component is set with no free space"
24167                 fi
24168                 rm $dom
24169                 dom_current=$dom_def
24170         done
24171 }
24172 run_test 270g "DoM: default DoM stripe size depends on free space"
24173
24174 test_270h() {
24175         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24176                 skip "Need MDS version at least 2.13.53"
24177
24178         local mdtname=${FSNAME}-MDT0000-mdtlov
24179         local dom=$DIR/$tdir/$tfile
24180         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24181
24182         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24183         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24184
24185         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24186         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24187                 error "can't create OST file"
24188         # mirrored file with DOM entry in the second mirror
24189         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24190                 error "can't create mirror with DoM component"
24191
24192         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24193
24194         # DOM component in the middle and has other enries in the same mirror,
24195         # should succeed but lost DoM component
24196         $LFS setstripe --copy=${dom}_1 $dom ||
24197                 error "Can't create file from OST|DOM mirror layout"
24198         # check new file has no DoM layout after all
24199         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24200                 error "File has DoM component while DoM is disabled"
24201 }
24202 run_test 270h "DoM: DoM stripe removal when disabled on server"
24203
24204 test_270i() {
24205         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24206                 skip "Need MDS version at least 2.14.54"
24207
24208         mkdir $DIR/$tdir
24209         # DoM with plain layout
24210         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24211                 error "default plain layout with DoM must fail"
24212         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24213                 error "setstripe plain file layout with DoM must fail"
24214         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24215                 error "default DoM layout with bad striping must fail"
24216         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24217                 error "setstripe to DoM layout with bad striping must fail"
24218         return 0
24219 }
24220 run_test 270i "DoM: setting invalid DoM striping should fail"
24221
24222 test_270j() {
24223         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24224                 skip "Need MDS version at least 2.15.55.203"
24225
24226         local dom=$DIR/$tdir/$tfile
24227         local odv
24228         local ndv
24229
24230         mkdir -p $DIR/$tdir
24231
24232         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24233
24234         odv=$($LFS data_version $dom)
24235         chmod 666 $dom
24236         mv $dom ${dom}_moved
24237         link ${dom}_moved $dom
24238         setfattr -n user.attrx -v "some_attr" $dom
24239         ndv=$($LFS data_version $dom)
24240         (( $ndv == $odv )) ||
24241                 error "data version was changed by metadata operations"
24242
24243         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24244                 error "failed to write data into $dom"
24245         cancel_lru_locks mdc
24246         ndv=$($LFS data_version $dom)
24247         (( $ndv != $odv )) ||
24248                 error "data version wasn't changed on write"
24249
24250         odv=$ndv
24251         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24252         ndv=$($LFS data_version $dom)
24253         (( $ndv != $odv )) ||
24254                 error "data version wasn't changed on truncate down"
24255
24256         odv=$ndv
24257         $TRUNCATE $dom 25000
24258         ndv=$($LFS data_version $dom)
24259         (( $ndv != $odv )) ||
24260                 error "data version wasn't changed on truncate up"
24261
24262         # check also fallocate for ldiskfs
24263         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24264                 odv=$ndv
24265                 fallocate -l 1048576 $dom
24266                 ndv=$($LFS data_version $dom)
24267                 (( $ndv != $odv )) ||
24268                         error "data version wasn't changed on fallocate"
24269
24270                 odv=$ndv
24271                 fallocate -p --offset 4096 -l 4096 $dom
24272                 ndv=$($LFS data_version $dom)
24273                 (( $ndv != $odv )) ||
24274                         error "data version wasn't changed on fallocate punch"
24275         fi
24276 }
24277 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24278
24279 test_271a() {
24280         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24281                 skip "Need MDS version at least 2.10.55"
24282
24283         local dom=$DIR/$tdir/dom
24284
24285         mkdir -p $DIR/$tdir
24286
24287         $LFS setstripe -E 1024K -L mdt $dom
24288
24289         lctl set_param -n mdc.*.stats=clear
24290         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24291         cat $dom > /dev/null
24292         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24293         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24294         ls $dom
24295         rm -f $dom
24296 }
24297 run_test 271a "DoM: data is cached for read after write"
24298
24299 test_271b() {
24300         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24301                 skip "Need MDS version at least 2.10.55"
24302
24303         local dom=$DIR/$tdir/dom
24304
24305         mkdir -p $DIR/$tdir
24306
24307         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24308
24309         lctl set_param -n mdc.*.stats=clear
24310         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24311         cancel_lru_locks mdc
24312         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24313         # second stat to check size is cached on client
24314         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24315         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24316         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24317         rm -f $dom
24318 }
24319 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24320
24321 test_271ba() {
24322         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24323                 skip "Need MDS version at least 2.10.55"
24324
24325         local dom=$DIR/$tdir/dom
24326
24327         mkdir -p $DIR/$tdir
24328
24329         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24330
24331         lctl set_param -n mdc.*.stats=clear
24332         lctl set_param -n osc.*.stats=clear
24333         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24334         cancel_lru_locks mdc
24335         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24336         # second stat to check size is cached on client
24337         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24338         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24339         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24340         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24341         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24342         rm -f $dom
24343 }
24344 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24345
24346
24347 get_mdc_stats() {
24348         local mdtidx=$1
24349         local param=$2
24350         local mdt=MDT$(printf %04x $mdtidx)
24351
24352         if [ -z $param ]; then
24353                 lctl get_param -n mdc.*$mdt*.stats
24354         else
24355                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24356         fi
24357 }
24358
24359 test_271c() {
24360         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24361                 skip "Need MDS version at least 2.10.55"
24362
24363         local dom=$DIR/$tdir/dom
24364
24365         mkdir -p $DIR/$tdir
24366
24367         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24368
24369         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24370         local facet=mds$((mdtidx + 1))
24371
24372         cancel_lru_locks mdc
24373         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24374         createmany -o $dom 1000
24375         lctl set_param -n mdc.*.stats=clear
24376         smalliomany -w $dom 1000 200
24377         get_mdc_stats $mdtidx
24378         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24379         # Each file has 1 open, 1 IO enqueues, total 2000
24380         # but now we have also +1 getxattr for security.capability, total 3000
24381         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24382         unlinkmany $dom 1000
24383
24384         cancel_lru_locks mdc
24385         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24386         createmany -o $dom 1000
24387         lctl set_param -n mdc.*.stats=clear
24388         smalliomany -w $dom 1000 200
24389         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24390         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24391         # for OPEN and IO lock.
24392         [ $((enq - enq_2)) -ge 1000 ] ||
24393                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24394         unlinkmany $dom 1000
24395         return 0
24396 }
24397 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24398
24399 cleanup_271def_tests() {
24400         trap 0
24401         rm -f $1
24402 }
24403
24404 test_271d() {
24405         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24406                 skip "Need MDS version at least 2.10.57"
24407
24408         local dom=$DIR/$tdir/dom
24409         local tmp=$TMP/$tfile
24410         trap "cleanup_271def_tests $tmp" EXIT
24411
24412         mkdir -p $DIR/$tdir
24413
24414         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24415
24416         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24417
24418         cancel_lru_locks mdc
24419         dd if=/dev/urandom of=$tmp bs=1000 count=1
24420         dd if=$tmp of=$dom bs=1000 count=1
24421         cancel_lru_locks mdc
24422
24423         cat /etc/hosts >> $tmp
24424         lctl set_param -n mdc.*.stats=clear
24425
24426         # append data to the same file it should update local page
24427         echo "Append to the same page"
24428         cat /etc/hosts >> $dom
24429         local num=$(get_mdc_stats $mdtidx ost_read)
24430         local ra=$(get_mdc_stats $mdtidx req_active)
24431         local rw=$(get_mdc_stats $mdtidx req_waittime)
24432
24433         [ -z $num ] || error "$num READ RPC occured"
24434         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24435         echo "... DONE"
24436
24437         # compare content
24438         cmp $tmp $dom || error "file miscompare"
24439
24440         cancel_lru_locks mdc
24441         lctl set_param -n mdc.*.stats=clear
24442
24443         echo "Open and read file"
24444         cat $dom > /dev/null
24445         local num=$(get_mdc_stats $mdtidx ost_read)
24446         local ra=$(get_mdc_stats $mdtidx req_active)
24447         local rw=$(get_mdc_stats $mdtidx req_waittime)
24448
24449         [ -z $num ] || error "$num READ RPC occured"
24450         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24451         echo "... DONE"
24452
24453         # compare content
24454         cmp $tmp $dom || error "file miscompare"
24455
24456         return 0
24457 }
24458 run_test 271d "DoM: read on open (1K file in reply buffer)"
24459
24460 test_271f() {
24461         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24462                 skip "Need MDS version at least 2.10.57"
24463
24464         local dom=$DIR/$tdir/dom
24465         local tmp=$TMP/$tfile
24466         trap "cleanup_271def_tests $tmp" EXIT
24467
24468         mkdir -p $DIR/$tdir
24469
24470         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24471
24472         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24473
24474         cancel_lru_locks mdc
24475         dd if=/dev/urandom of=$tmp bs=265000 count=1
24476         dd if=$tmp of=$dom bs=265000 count=1
24477         cancel_lru_locks mdc
24478         cat /etc/hosts >> $tmp
24479         lctl set_param -n mdc.*.stats=clear
24480
24481         echo "Append to the same page"
24482         cat /etc/hosts >> $dom
24483         local num=$(get_mdc_stats $mdtidx ost_read)
24484         local ra=$(get_mdc_stats $mdtidx req_active)
24485         local rw=$(get_mdc_stats $mdtidx req_waittime)
24486
24487         [ -z $num ] || error "$num READ RPC occured"
24488         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24489         echo "... DONE"
24490
24491         # compare content
24492         cmp $tmp $dom || error "file miscompare"
24493
24494         cancel_lru_locks mdc
24495         lctl set_param -n mdc.*.stats=clear
24496
24497         echo "Open and read file"
24498         cat $dom > /dev/null
24499         local num=$(get_mdc_stats $mdtidx ost_read)
24500         local ra=$(get_mdc_stats $mdtidx req_active)
24501         local rw=$(get_mdc_stats $mdtidx req_waittime)
24502
24503         [ -z $num ] && num=0
24504         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24505         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24506         echo "... DONE"
24507
24508         # compare content
24509         cmp $tmp $dom || error "file miscompare"
24510
24511         return 0
24512 }
24513 run_test 271f "DoM: read on open (200K file and read tail)"
24514
24515 test_271g() {
24516         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24517                 skip "Skipping due to old client or server version"
24518
24519         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24520         # to get layout
24521         $CHECKSTAT -t file $DIR1/$tfile
24522
24523         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24524         MULTIOP_PID=$!
24525         sleep 1
24526         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24527         $LCTL set_param fail_loc=0x80000314
24528         rm $DIR1/$tfile || error "Unlink fails"
24529         RC=$?
24530         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24531         [ $RC -eq 0 ] || error "Failed write to stale object"
24532 }
24533 run_test 271g "Discard DoM data vs client flush race"
24534
24535 test_272a() {
24536         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24537                 skip "Need MDS version at least 2.11.50"
24538
24539         local dom=$DIR/$tdir/dom
24540         mkdir -p $DIR/$tdir
24541
24542         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24543         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24544                 error "failed to write data into $dom"
24545         local old_md5=$(md5sum $dom)
24546
24547         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24548                 error "failed to migrate to the same DoM component"
24549
24550         local new_md5=$(md5sum $dom)
24551
24552         [ "$old_md5" == "$new_md5" ] ||
24553                 error "md5sum differ: $old_md5, $new_md5"
24554
24555         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24556                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24557 }
24558 run_test 272a "DoM migration: new layout with the same DOM component"
24559
24560 test_272b() {
24561         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24562                 skip "Need MDS version at least 2.11.50"
24563
24564         local dom=$DIR/$tdir/dom
24565         mkdir -p $DIR/$tdir
24566         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24567         stack_trap "rm -rf $DIR/$tdir"
24568
24569         local mdtidx=$($LFS getstripe -m $dom)
24570         local mdtname=MDT$(printf %04x $mdtidx)
24571         local facet=mds$((mdtidx + 1))
24572
24573         local mdtfree1=$(do_facet $facet \
24574                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24575         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24576                 error "failed to write data into $dom"
24577         local old_md5=$(md5sum $dom)
24578         cancel_lru_locks mdc
24579         local mdtfree1=$(do_facet $facet \
24580                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24581
24582         $LFS migrate -c2 $dom ||
24583                 error "failed to migrate to the new composite layout"
24584         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24585                 error "MDT stripe was not removed"
24586         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24587                 error "$dir1 shouldn't have DATAVER EA"
24588
24589         cancel_lru_locks mdc
24590         local new_md5=$(md5sum $dom)
24591         [ "$old_md5" == "$new_md5" ] ||
24592                 error "$old_md5 != $new_md5"
24593
24594         # Skip free space checks with ZFS
24595         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24596                 local mdtfree2=$(do_facet $facet \
24597                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24598                 [ $mdtfree2 -gt $mdtfree1 ] ||
24599                         error "MDT space is not freed after migration"
24600         fi
24601         return 0
24602 }
24603 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24604
24605 test_272c() {
24606         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24607                 skip "Need MDS version at least 2.11.50"
24608
24609         local dom=$DIR/$tdir/$tfile
24610         mkdir -p $DIR/$tdir
24611         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24612         stack_trap "rm -rf $DIR/$tdir"
24613
24614         local mdtidx=$($LFS getstripe -m $dom)
24615         local mdtname=MDT$(printf %04x $mdtidx)
24616         local facet=mds$((mdtidx + 1))
24617
24618         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24619                 error "failed to write data into $dom"
24620         local old_md5=$(md5sum $dom)
24621         cancel_lru_locks mdc
24622         local mdtfree1=$(do_facet $facet \
24623                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24624
24625         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24626                 error "failed to migrate to the new composite layout"
24627         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24628                 error "MDT stripe was not removed"
24629
24630         cancel_lru_locks mdc
24631         local new_md5=$(md5sum $dom)
24632         [ "$old_md5" == "$new_md5" ] ||
24633                 error "$old_md5 != $new_md5"
24634
24635         # Skip free space checks with ZFS
24636         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24637                 local mdtfree2=$(do_facet $facet \
24638                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24639                 [ $mdtfree2 -gt $mdtfree1 ] ||
24640                         error "MDS space is not freed after migration"
24641         fi
24642         return 0
24643 }
24644 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24645
24646 test_272d() {
24647         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24648                 skip "Need MDS version at least 2.12.55"
24649
24650         local dom=$DIR/$tdir/$tfile
24651         mkdir -p $DIR/$tdir
24652         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24653
24654         local mdtidx=$($LFS getstripe -m $dom)
24655         local mdtname=MDT$(printf %04x $mdtidx)
24656         local facet=mds$((mdtidx + 1))
24657
24658         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24659                 error "failed to write data into $dom"
24660         local old_md5=$(md5sum $dom)
24661         cancel_lru_locks mdc
24662         local mdtfree1=$(do_facet $facet \
24663                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24664
24665         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24666                 error "failed mirroring to the new composite layout"
24667         $LFS mirror resync $dom ||
24668                 error "failed mirror resync"
24669         $LFS mirror split --mirror-id 1 -d $dom ||
24670                 error "failed mirror split"
24671
24672         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24673                 error "MDT stripe was not removed"
24674
24675         cancel_lru_locks mdc
24676         local new_md5=$(md5sum $dom)
24677         [ "$old_md5" == "$new_md5" ] ||
24678                 error "$old_md5 != $new_md5"
24679
24680         # Skip free space checks with ZFS
24681         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24682                 local mdtfree2=$(do_facet $facet \
24683                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24684                 [ $mdtfree2 -gt $mdtfree1 ] ||
24685                         error "MDS space is not freed after DOM mirror deletion"
24686         fi
24687         return 0
24688 }
24689 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24690
24691 test_272e() {
24692         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24693                 skip "Need MDS version at least 2.12.55"
24694
24695         local dom=$DIR/$tdir/$tfile
24696         mkdir -p $DIR/$tdir
24697         $LFS setstripe -c 2 $dom
24698
24699         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24700                 error "failed to write data into $dom"
24701         local old_md5=$(md5sum $dom)
24702         cancel_lru_locks
24703
24704         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24705                 error "failed mirroring to the DOM layout"
24706         $LFS mirror resync $dom ||
24707                 error "failed mirror resync"
24708         $LFS mirror split --mirror-id 1 -d $dom ||
24709                 error "failed mirror split"
24710
24711         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24712                 error "MDT stripe wasn't set"
24713
24714         cancel_lru_locks
24715         local new_md5=$(md5sum $dom)
24716         [ "$old_md5" == "$new_md5" ] ||
24717                 error "$old_md5 != $new_md5"
24718
24719         return 0
24720 }
24721 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24722
24723 test_272f() {
24724         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24725                 skip "Need MDS version at least 2.12.55"
24726
24727         local dom=$DIR/$tdir/$tfile
24728         mkdir -p $DIR/$tdir
24729         $LFS setstripe -c 2 $dom
24730
24731         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24732                 error "failed to write data into $dom"
24733         local old_md5=$(md5sum $dom)
24734         cancel_lru_locks
24735
24736         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24737                 error "failed migrating to the DOM file"
24738
24739         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24740                 error "MDT stripe wasn't set"
24741
24742         cancel_lru_locks
24743         local new_md5=$(md5sum $dom)
24744         [ "$old_md5" != "$new_md5" ] &&
24745                 error "$old_md5 != $new_md5"
24746
24747         return 0
24748 }
24749 run_test 272f "DoM migration: OST-striped file to DOM file"
24750
24751 test_273a() {
24752         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24753                 skip "Need MDS version at least 2.11.50"
24754
24755         # Layout swap cannot be done if either file has DOM component,
24756         # this will never be supported, migration should be used instead
24757
24758         local dom=$DIR/$tdir/$tfile
24759         mkdir -p $DIR/$tdir
24760
24761         $LFS setstripe -c2 ${dom}_plain
24762         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24763         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24764                 error "can swap layout with DoM component"
24765         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24766                 error "can swap layout with DoM component"
24767
24768         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24769         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24770                 error "can swap layout with DoM component"
24771         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24772                 error "can swap layout with DoM component"
24773         return 0
24774 }
24775 run_test 273a "DoM: layout swapping should fail with DOM"
24776
24777 test_273b() {
24778         mkdir -p $DIR/$tdir
24779         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24780
24781 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24782         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24783
24784         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24785 }
24786 run_test 273b "DoM: race writeback and object destroy"
24787
24788 test_273c() {
24789         mkdir -p $DIR/$tdir
24790         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24791
24792         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24793         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24794
24795         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24796 }
24797 run_test 273c "race writeback and object destroy"
24798
24799 test_275() {
24800         remote_ost_nodsh && skip "remote OST with nodsh"
24801         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24802                 skip "Need OST version >= 2.10.57"
24803
24804         local file=$DIR/$tfile
24805         local oss
24806
24807         oss=$(comma_list $(osts_nodes))
24808
24809         dd if=/dev/urandom of=$file bs=1M count=2 ||
24810                 error "failed to create a file"
24811         stack_trap "rm -f $file"
24812         cancel_lru_locks osc
24813
24814         #lock 1
24815         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24816                 error "failed to read a file"
24817
24818 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24819         $LCTL set_param fail_loc=0x8000031f
24820
24821         cancel_lru_locks osc &
24822         sleep 1
24823
24824 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24825         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24826         #IO takes another lock, but matches the PENDING one
24827         #and places it to the IO RPC
24828         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24829                 error "failed to read a file with PENDING lock"
24830 }
24831 run_test 275 "Read on a canceled duplicate lock"
24832
24833 test_276() {
24834         remote_ost_nodsh && skip "remote OST with nodsh"
24835         local pid
24836
24837         do_facet ost1 "(while true; do \
24838                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24839                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24840         pid=$!
24841
24842         for LOOP in $(seq 20); do
24843                 stop ost1
24844                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24845         done
24846         kill -9 $pid
24847         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24848                 rm $TMP/sanity_276_pid"
24849 }
24850 run_test 276 "Race between mount and obd_statfs"
24851
24852 test_277() {
24853         $LCTL set_param ldlm.namespaces.*.lru_size=0
24854         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24855         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24856                         grep ^used_mb | awk '{print $2}')
24857         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24858         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24859                 oflag=direct conv=notrunc
24860         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24861                         grep ^used_mb | awk '{print $2}')
24862         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24863 }
24864 run_test 277 "Direct IO shall drop page cache"
24865
24866 test_278() {
24867         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24868         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24869         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24870                 skip "needs the same host for mdt1 mdt2" && return
24871
24872         local pid1
24873         local pid2
24874
24875 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24876         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24877         stop mds2 &
24878         pid2=$!
24879
24880         stop mds1
24881
24882         echo "Starting MDTs"
24883         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24884         wait $pid2
24885 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24886 #will return NULL
24887         do_facet mds2 $LCTL set_param fail_loc=0
24888
24889         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24890         wait_recovery_complete mds2
24891 }
24892 run_test 278 "Race starting MDS between MDTs stop/start"
24893
24894 test_280() {
24895         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24896                 skip "Need MGS version at least 2.13.52"
24897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24898         combined_mgs_mds || skip "needs combined MGS/MDT"
24899
24900         umount_client $MOUNT
24901 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24902         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24903
24904         mount_client $MOUNT &
24905         sleep 1
24906         stop mgs || error "stop mgs failed"
24907         #for a race mgs would crash
24908         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24909         # make sure we unmount client before remounting
24910         wait
24911         umount_client $MOUNT
24912         mount_client $MOUNT || error "mount client failed"
24913 }
24914 run_test 280 "Race between MGS umount and client llog processing"
24915
24916 cleanup_test_300() {
24917         trap 0
24918         umask $SAVE_UMASK
24919 }
24920 test_striped_dir() {
24921         local mdt_index=$1
24922         local stripe_count
24923         local stripe_index
24924
24925         mkdir -p $DIR/$tdir
24926
24927         SAVE_UMASK=$(umask)
24928         trap cleanup_test_300 RETURN EXIT
24929
24930         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24931                                                 $DIR/$tdir/striped_dir ||
24932                 error "set striped dir error"
24933
24934         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24935         [ "$mode" = "755" ] || error "expect 755 got $mode"
24936
24937         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24938                 error "getdirstripe failed"
24939         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24940         if [ "$stripe_count" != "2" ]; then
24941                 error "1:stripe_count is $stripe_count, expect 2"
24942         fi
24943         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24944         if [ "$stripe_count" != "2" ]; then
24945                 error "2:stripe_count is $stripe_count, expect 2"
24946         fi
24947
24948         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24949         if [ "$stripe_index" != "$mdt_index" ]; then
24950                 error "stripe_index is $stripe_index, expect $mdt_index"
24951         fi
24952
24953         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24954                 error "nlink error after create striped dir"
24955
24956         mkdir $DIR/$tdir/striped_dir/a
24957         mkdir $DIR/$tdir/striped_dir/b
24958
24959         stat $DIR/$tdir/striped_dir/a ||
24960                 error "create dir under striped dir failed"
24961         stat $DIR/$tdir/striped_dir/b ||
24962                 error "create dir under striped dir failed"
24963
24964         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24965                 error "nlink error after mkdir"
24966
24967         rmdir $DIR/$tdir/striped_dir/a
24968         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24969                 error "nlink error after rmdir"
24970
24971         rmdir $DIR/$tdir/striped_dir/b
24972         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24973                 error "nlink error after rmdir"
24974
24975         chattr +i $DIR/$tdir/striped_dir
24976         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24977                 error "immutable flags not working under striped dir!"
24978         chattr -i $DIR/$tdir/striped_dir
24979
24980         rmdir $DIR/$tdir/striped_dir ||
24981                 error "rmdir striped dir error"
24982
24983         cleanup_test_300
24984
24985         true
24986 }
24987
24988 test_300a() {
24989         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24990                 skip "skipped for lustre < 2.7.0"
24991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24993
24994         test_striped_dir 0 || error "failed on striped dir on MDT0"
24995         test_striped_dir 1 || error "failed on striped dir on MDT0"
24996 }
24997 run_test 300a "basic striped dir sanity test"
24998
24999 test_300b() {
25000         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25001                 skip "skipped for lustre < 2.7.0"
25002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25004
25005         local i
25006         local mtime1
25007         local mtime2
25008         local mtime3
25009
25010         test_mkdir $DIR/$tdir || error "mkdir fail"
25011         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25012                 error "set striped dir error"
25013         for i in {0..9}; do
25014                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25015                 sleep 1
25016                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25017                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25018                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25019                 sleep 1
25020                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25021                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25022                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25023         done
25024         true
25025 }
25026 run_test 300b "check ctime/mtime for striped dir"
25027
25028 test_300c() {
25029         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25030                 skip "skipped for lustre < 2.7.0"
25031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25033
25034         local file_count
25035
25036         mkdir_on_mdt0 $DIR/$tdir
25037         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25038                 error "set striped dir error"
25039
25040         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25041                 error "chown striped dir failed"
25042
25043         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25044                 error "create 5k files failed"
25045
25046         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25047
25048         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25049
25050         rm -rf $DIR/$tdir
25051 }
25052 run_test 300c "chown && check ls under striped directory"
25053
25054 test_300d() {
25055         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25056                 skip "skipped for lustre < 2.7.0"
25057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25059
25060         local stripe_count
25061         local file
25062
25063         mkdir -p $DIR/$tdir
25064         $LFS setstripe -c 2 $DIR/$tdir
25065
25066         #local striped directory
25067         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25068                 error "set striped dir error"
25069         #look at the directories for debug purposes
25070         ls -l $DIR/$tdir
25071         $LFS getdirstripe $DIR/$tdir
25072         ls -l $DIR/$tdir/striped_dir
25073         $LFS getdirstripe $DIR/$tdir/striped_dir
25074         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25075                 error "create 10 files failed"
25076
25077         #remote striped directory
25078         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25079                 error "set striped dir error"
25080         #look at the directories for debug purposes
25081         ls -l $DIR/$tdir
25082         $LFS getdirstripe $DIR/$tdir
25083         ls -l $DIR/$tdir/remote_striped_dir
25084         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25085         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25086                 error "create 10 files failed"
25087
25088         for file in $(find $DIR/$tdir); do
25089                 stripe_count=$($LFS getstripe -c $file)
25090                 [ $stripe_count -eq 2 ] ||
25091                         error "wrong stripe $stripe_count for $file"
25092         done
25093
25094         rm -rf $DIR/$tdir
25095 }
25096 run_test 300d "check default stripe under striped directory"
25097
25098 test_300e() {
25099         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25100                 skip "Need MDS version at least 2.7.55"
25101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25103
25104         local stripe_count
25105         local file
25106
25107         mkdir -p $DIR/$tdir
25108
25109         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25110                 error "set striped dir error"
25111
25112         touch $DIR/$tdir/striped_dir/a
25113         touch $DIR/$tdir/striped_dir/b
25114         touch $DIR/$tdir/striped_dir/c
25115
25116         mkdir $DIR/$tdir/striped_dir/dir_a
25117         mkdir $DIR/$tdir/striped_dir/dir_b
25118         mkdir $DIR/$tdir/striped_dir/dir_c
25119
25120         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25121                 error "set striped adir under striped dir error"
25122
25123         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25124                 error "set striped bdir under striped dir error"
25125
25126         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25127                 error "set striped cdir under striped dir error"
25128
25129         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25130                 error "rename dir under striped dir fails"
25131
25132         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25133                 error "rename dir under different stripes fails"
25134
25135         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25136                 error "rename file under striped dir should succeed"
25137
25138         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25139                 error "rename dir under striped dir should succeed"
25140
25141         rm -rf $DIR/$tdir
25142 }
25143 run_test 300e "check rename under striped directory"
25144
25145 test_300f() {
25146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25148         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25149                 skip "Need MDS version at least 2.7.55"
25150
25151         local stripe_count
25152         local file
25153
25154         rm -rf $DIR/$tdir
25155         mkdir -p $DIR/$tdir
25156
25157         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25158                 error "set striped dir error"
25159
25160         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25161                 error "set striped dir error"
25162
25163         touch $DIR/$tdir/striped_dir/a
25164         mkdir $DIR/$tdir/striped_dir/dir_a
25165         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25166                 error "create striped dir under striped dir fails"
25167
25168         touch $DIR/$tdir/striped_dir1/b
25169         mkdir $DIR/$tdir/striped_dir1/dir_b
25170         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25171                 error "create striped dir under striped dir fails"
25172
25173         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25174                 error "rename dir under different striped dir should fail"
25175
25176         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25177                 error "rename striped dir under diff striped dir should fail"
25178
25179         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25180                 error "rename file under diff striped dirs fails"
25181
25182         rm -rf $DIR/$tdir
25183 }
25184 run_test 300f "check rename cross striped directory"
25185
25186 test_300_check_default_striped_dir()
25187 {
25188         local dirname=$1
25189         local default_count=$2
25190         local default_index=$3
25191         local stripe_count
25192         local stripe_index
25193         local dir_stripe_index
25194         local dir
25195
25196         echo "checking $dirname $default_count $default_index"
25197         $LFS setdirstripe -D -c $default_count -i $default_index \
25198                                 -H all_char $DIR/$tdir/$dirname ||
25199                 error "set default stripe on striped dir error"
25200         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25201         [ $stripe_count -eq $default_count ] ||
25202                 error "expect $default_count get $stripe_count for $dirname"
25203
25204         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25205         [ $stripe_index -eq $default_index ] ||
25206                 error "expect $default_index get $stripe_index for $dirname"
25207
25208         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25209                                                 error "create dirs failed"
25210
25211         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25212         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25213         for dir in $(find $DIR/$tdir/$dirname/*); do
25214                 stripe_count=$($LFS getdirstripe -c $dir)
25215                 (( $stripe_count == $default_count )) ||
25216                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25217                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25218                 error "stripe count $default_count != $stripe_count for $dir"
25219
25220                 stripe_index=$($LFS getdirstripe -i $dir)
25221                 [ $default_index -eq -1 ] ||
25222                         [ $stripe_index -eq $default_index ] ||
25223                         error "$stripe_index != $default_index for $dir"
25224
25225                 #check default stripe
25226                 stripe_count=$($LFS getdirstripe -D -c $dir)
25227                 [ $stripe_count -eq $default_count ] ||
25228                 error "default count $default_count != $stripe_count for $dir"
25229
25230                 stripe_index=$($LFS getdirstripe -D -i $dir)
25231                 [ $stripe_index -eq $default_index ] ||
25232                 error "default index $default_index != $stripe_index for $dir"
25233         done
25234         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25235 }
25236
25237 test_300g() {
25238         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25239         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25240                 skip "Need MDS version at least 2.7.55"
25241
25242         local dir
25243         local stripe_count
25244         local stripe_index
25245
25246         mkdir_on_mdt0 $DIR/$tdir
25247         mkdir $DIR/$tdir/normal_dir
25248
25249         #Checking when client cache stripe index
25250         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25251         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25252                 error "create striped_dir failed"
25253
25254         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25255                 error "create dir0 fails"
25256         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25257         [ $stripe_index -eq 0 ] ||
25258                 error "dir0 expect index 0 got $stripe_index"
25259
25260         mkdir $DIR/$tdir/striped_dir/dir1 ||
25261                 error "create dir1 fails"
25262         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25263         [ $stripe_index -eq 1 ] ||
25264                 error "dir1 expect index 1 got $stripe_index"
25265
25266         #check default stripe count/stripe index
25267         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25268         test_300_check_default_striped_dir normal_dir 1 0
25269         test_300_check_default_striped_dir normal_dir -1 1
25270         test_300_check_default_striped_dir normal_dir 2 -1
25271
25272         #delete default stripe information
25273         echo "delete default stripeEA"
25274         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25275                 error "set default stripe on striped dir error"
25276
25277         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25278         for dir in $(find $DIR/$tdir/normal_dir/*); do
25279                 stripe_count=$($LFS getdirstripe -c $dir)
25280                 [ $stripe_count -eq 0 ] ||
25281                         error "expect 1 get $stripe_count for $dir"
25282         done
25283 }
25284 run_test 300g "check default striped directory for normal directory"
25285
25286 test_300h() {
25287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25288         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25289                 skip "Need MDS version at least 2.7.55"
25290
25291         local dir
25292         local stripe_count
25293
25294         mkdir $DIR/$tdir
25295         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25296                 error "set striped dir error"
25297
25298         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25299         test_300_check_default_striped_dir striped_dir 1 0
25300         test_300_check_default_striped_dir striped_dir -1 1
25301         test_300_check_default_striped_dir striped_dir 2 -1
25302
25303         #delete default stripe information
25304         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25305                 error "set default stripe on striped dir error"
25306
25307         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25308         for dir in $(find $DIR/$tdir/striped_dir/*); do
25309                 stripe_count=$($LFS getdirstripe -c $dir)
25310                 [ $stripe_count -eq 0 ] ||
25311                         error "expect 1 get $stripe_count for $dir"
25312         done
25313 }
25314 run_test 300h "check default striped directory for striped directory"
25315
25316 test_300i() {
25317         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25318         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25319         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25320                 skip "Need MDS version at least 2.7.55"
25321
25322         local stripe_count
25323         local file
25324
25325         mkdir $DIR/$tdir
25326
25327         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25328                 error "set striped dir error"
25329
25330         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25331                 error "create files under striped dir failed"
25332
25333         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25334                 error "set striped hashdir error"
25335
25336         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25337                 error "create dir0 under hash dir failed"
25338         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25339                 error "create dir1 under hash dir failed"
25340         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25341                 error "create dir2 under hash dir failed"
25342
25343         # unfortunately, we need to umount to clear dir layout cache for now
25344         # once we fully implement dir layout, we can drop this
25345         umount_client $MOUNT || error "umount failed"
25346         mount_client $MOUNT || error "mount failed"
25347
25348         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25349         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25350         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25351
25352         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25353                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25354                         error "create crush2 dir $tdir/hashdir/d3 failed"
25355                 $LFS find -H crush2 $DIR/$tdir/hashdir
25356                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25357                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25358
25359                 # mkdir with an invalid hash type (hash=fail_val) from client
25360                 # should be replaced on MDS with a valid (default) hash type
25361                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25362                 $LCTL set_param fail_loc=0x1901 fail_val=99
25363                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25364
25365                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25366                 local expect=$(do_facet mds1 \
25367                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25368                 [[ $hash == $expect ]] ||
25369                         error "d99 hash '$hash' != expected hash '$expect'"
25370         fi
25371
25372         #set the stripe to be unknown hash type on read
25373         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25374         $LCTL set_param fail_loc=0x1901 fail_val=99
25375         for ((i = 0; i < 10; i++)); do
25376                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25377                         error "stat f-$i failed"
25378                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25379         done
25380
25381         touch $DIR/$tdir/striped_dir/f0 &&
25382                 error "create under striped dir with unknown hash should fail"
25383
25384         $LCTL set_param fail_loc=0
25385
25386         umount_client $MOUNT || error "umount failed"
25387         mount_client $MOUNT || error "mount failed"
25388
25389         return 0
25390 }
25391 run_test 300i "client handle unknown hash type striped directory"
25392
25393 test_300j() {
25394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25396         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25397                 skip "Need MDS version at least 2.7.55"
25398
25399         local stripe_count
25400         local file
25401
25402         mkdir $DIR/$tdir
25403
25404         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25405         $LCTL set_param fail_loc=0x1702
25406         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25407                 error "set striped dir error"
25408
25409         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25410                 error "create files under striped dir failed"
25411
25412         $LCTL set_param fail_loc=0
25413
25414         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25415
25416         return 0
25417 }
25418 run_test 300j "test large update record"
25419
25420 test_300k() {
25421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25423         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25424                 skip "Need MDS version at least 2.7.55"
25425
25426         # this test needs a huge transaction
25427         local kb
25428         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25429              osd*.$FSNAME-MDT0000.kbytestotal")
25430         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25431
25432         local stripe_count
25433         local file
25434
25435         mkdir $DIR/$tdir
25436
25437         #define OBD_FAIL_LARGE_STRIPE   0x1703
25438         $LCTL set_param fail_loc=0x1703
25439         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25440                 error "set striped dir error"
25441         $LCTL set_param fail_loc=0
25442
25443         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25444                 error "getstripeddir fails"
25445         rm -rf $DIR/$tdir/striped_dir ||
25446                 error "unlink striped dir fails"
25447
25448         return 0
25449 }
25450 run_test 300k "test large striped directory"
25451
25452 test_300l() {
25453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25455         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25456                 skip "Need MDS version at least 2.7.55"
25457
25458         local stripe_index
25459
25460         test_mkdir -p $DIR/$tdir/striped_dir
25461         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25462                         error "chown $RUNAS_ID failed"
25463         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25464                 error "set default striped dir failed"
25465
25466         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25467         $LCTL set_param fail_loc=0x80000158
25468         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25469
25470         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25471         [ $stripe_index -eq 1 ] ||
25472                 error "expect 1 get $stripe_index for $dir"
25473 }
25474 run_test 300l "non-root user to create dir under striped dir with stale layout"
25475
25476 test_300m() {
25477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25478         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25479         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25480                 skip "Need MDS version at least 2.7.55"
25481
25482         mkdir -p $DIR/$tdir/striped_dir
25483         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25484                 error "set default stripes dir error"
25485
25486         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25487
25488         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25489         [ $stripe_count -eq 0 ] ||
25490                         error "expect 0 get $stripe_count for a"
25491
25492         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25493                 error "set default stripes dir error"
25494
25495         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25496
25497         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25498         [ $stripe_count -eq 0 ] ||
25499                         error "expect 0 get $stripe_count for b"
25500
25501         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25502                 error "set default stripes dir error"
25503
25504         mkdir $DIR/$tdir/striped_dir/c &&
25505                 error "default stripe_index is invalid, mkdir c should fails"
25506
25507         rm -rf $DIR/$tdir || error "rmdir fails"
25508 }
25509 run_test 300m "setstriped directory on single MDT FS"
25510
25511 cleanup_300n() {
25512         local list=$(comma_list $(mdts_nodes))
25513
25514         trap 0
25515         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25516 }
25517
25518 test_300n() {
25519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25521         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25522                 skip "Need MDS version at least 2.7.55"
25523         remote_mds_nodsh && skip "remote MDS with nodsh"
25524
25525         local stripe_index
25526         local list=$(comma_list $(mdts_nodes))
25527
25528         trap cleanup_300n RETURN EXIT
25529         mkdir -p $DIR/$tdir
25530         chmod 777 $DIR/$tdir
25531         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25532                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25533                 error "create striped dir succeeds with gid=0"
25534
25535         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25536         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25537                 error "create striped dir fails with gid=-1"
25538
25539         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25540         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25541                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25542                 error "set default striped dir succeeds with gid=0"
25543
25544
25545         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25546         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25547                 error "set default striped dir fails with gid=-1"
25548
25549
25550         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25551         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25552                                         error "create test_dir fails"
25553         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25554                                         error "create test_dir1 fails"
25555         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25556                                         error "create test_dir2 fails"
25557         cleanup_300n
25558 }
25559 run_test 300n "non-root user to create dir under striped dir with default EA"
25560
25561 test_300o() {
25562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25564         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25565                 skip "Need MDS version at least 2.7.55"
25566
25567         local numfree1
25568         local numfree2
25569
25570         mkdir -p $DIR/$tdir
25571
25572         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25573         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25574         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25575                 skip "not enough free inodes $numfree1 $numfree2"
25576         fi
25577
25578         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25579         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25580         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25581                 skip "not enough free space $numfree1 $numfree2"
25582         fi
25583
25584         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25585                 error "setdirstripe fails"
25586
25587         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25588                 error "create dirs fails"
25589
25590         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25591         ls $DIR/$tdir/striped_dir > /dev/null ||
25592                 error "ls striped dir fails"
25593         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25594                 error "unlink big striped dir fails"
25595 }
25596 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25597
25598 test_300p() {
25599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25601         remote_mds_nodsh && skip "remote MDS with nodsh"
25602
25603         mkdir_on_mdt0 $DIR/$tdir
25604
25605         #define OBD_FAIL_OUT_ENOSPC     0x1704
25606         do_facet mds2 lctl set_param fail_loc=0x80001704
25607         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25608                  && error "create striped directory should fail"
25609
25610         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25611
25612         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25613         true
25614 }
25615 run_test 300p "create striped directory without space"
25616
25617 test_300q() {
25618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25620
25621         local fd=$(free_fd)
25622         local cmd="exec $fd<$tdir"
25623         cd $DIR
25624         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25625         eval $cmd
25626         cmd="exec $fd<&-"
25627         trap "eval $cmd" EXIT
25628         cd $tdir || error "cd $tdir fails"
25629         rmdir  ../$tdir || error "rmdir $tdir fails"
25630         mkdir local_dir && error "create dir succeeds"
25631         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25632         eval $cmd
25633         return 0
25634 }
25635 run_test 300q "create remote directory under orphan directory"
25636
25637 test_300r() {
25638         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25639                 skip "Need MDS version at least 2.7.55" && return
25640         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25641
25642         mkdir $DIR/$tdir
25643
25644         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25645                 error "set striped dir error"
25646
25647         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25648                 error "getstripeddir fails"
25649
25650         local stripe_count
25651         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25652                       awk '/lmv_stripe_count:/ { print $2 }')
25653
25654         [ $MDSCOUNT -ne $stripe_count ] &&
25655                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25656
25657         rm -rf $DIR/$tdir/striped_dir ||
25658                 error "unlink striped dir fails"
25659 }
25660 run_test 300r "test -1 striped directory"
25661
25662 test_300s_helper() {
25663         local count=$1
25664
25665         local stripe_dir=$DIR/$tdir/striped_dir.$count
25666
25667         $LFS mkdir -c $count $stripe_dir ||
25668                 error "lfs mkdir -c error"
25669
25670         $LFS getdirstripe $stripe_dir ||
25671                 error "lfs getdirstripe fails"
25672
25673         local stripe_count
25674         stripe_count=$($LFS getdirstripe $stripe_dir |
25675                       awk '/lmv_stripe_count:/ { print $2 }')
25676
25677         [ $count -ne $stripe_count ] &&
25678                 error_noexit "bad stripe count $stripe_count expected $count"
25679
25680         local dupe_stripes
25681         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25682                 awk '/0x/ {count[$1] += 1}; END {
25683                         for (idx in count) {
25684                                 if (count[idx]>1) {
25685                                         print "index " idx " count " count[idx]
25686                                 }
25687                         }
25688                 }')
25689
25690         if [[ -n "$dupe_stripes" ]] ; then
25691                 lfs getdirstripe $stripe_dir
25692                 error_noexit "Dupe MDT above: $dupe_stripes "
25693         fi
25694
25695         rm -rf $stripe_dir ||
25696                 error_noexit "unlink $stripe_dir fails"
25697 }
25698
25699 test_300s() {
25700         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25701                 skip "Need MDS version at least 2.7.55" && return
25702         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25703
25704         mkdir $DIR/$tdir
25705         for count in $(seq 2 $MDSCOUNT); do
25706                 test_300s_helper $count
25707         done
25708 }
25709 run_test 300s "test lfs mkdir -c without -i"
25710
25711 test_300t() {
25712         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25713                 skip "need MDS 2.14.55 or later"
25714         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25715
25716         local testdir="$DIR/$tdir/striped_dir"
25717         local dir1=$testdir/dir1
25718         local dir2=$testdir/dir2
25719
25720         mkdir -p $testdir
25721
25722         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25723                 error "failed to set default stripe count for $testdir"
25724
25725         mkdir $dir1
25726         local stripe_count=$($LFS getdirstripe -c $dir1)
25727
25728         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25729
25730         local max_count=$((MDSCOUNT - 1))
25731         local mdts=$(comma_list $(mdts_nodes))
25732
25733         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25734         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25735
25736         mkdir $dir2
25737         stripe_count=$($LFS getdirstripe -c $dir2)
25738
25739         (( $stripe_count == $max_count )) || error "wrong stripe count"
25740 }
25741 run_test 300t "test max_mdt_stripecount"
25742
25743 prepare_remote_file() {
25744         mkdir $DIR/$tdir/src_dir ||
25745                 error "create remote source failed"
25746
25747         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25748                  error "cp to remote source failed"
25749         touch $DIR/$tdir/src_dir/a
25750
25751         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25752                 error "create remote target dir failed"
25753
25754         touch $DIR/$tdir/tgt_dir/b
25755
25756         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25757                 error "rename dir cross MDT failed!"
25758
25759         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25760                 error "src_child still exists after rename"
25761
25762         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25763                 error "missing file(a) after rename"
25764
25765         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25766                 error "diff after rename"
25767 }
25768
25769 test_310a() {
25770         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25772
25773         local remote_file=$DIR/$tdir/tgt_dir/b
25774
25775         mkdir -p $DIR/$tdir
25776
25777         prepare_remote_file || error "prepare remote file failed"
25778
25779         #open-unlink file
25780         $OPENUNLINK $remote_file $remote_file ||
25781                 error "openunlink $remote_file failed"
25782         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25783 }
25784 run_test 310a "open unlink remote file"
25785
25786 test_310b() {
25787         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25789
25790         local remote_file=$DIR/$tdir/tgt_dir/b
25791
25792         mkdir -p $DIR/$tdir
25793
25794         prepare_remote_file || error "prepare remote file failed"
25795
25796         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25797         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25798         $CHECKSTAT -t file $remote_file || error "check file failed"
25799 }
25800 run_test 310b "unlink remote file with multiple links while open"
25801
25802 test_310c() {
25803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25804         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25805
25806         local remote_file=$DIR/$tdir/tgt_dir/b
25807
25808         mkdir -p $DIR/$tdir
25809
25810         prepare_remote_file || error "prepare remote file failed"
25811
25812         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25813         multiop_bg_pause $remote_file O_uc ||
25814                         error "mulitop failed for remote file"
25815         MULTIPID=$!
25816         $MULTIOP $DIR/$tfile Ouc
25817         kill -USR1 $MULTIPID
25818         wait $MULTIPID
25819 }
25820 run_test 310c "open-unlink remote file with multiple links"
25821
25822 #LU-4825
25823 test_311() {
25824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25825         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25826         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25827                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25828         remote_mds_nodsh && skip "remote MDS with nodsh"
25829
25830         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25831         local mdts=$(comma_list $(mdts_nodes))
25832
25833         mkdir -p $DIR/$tdir
25834         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25835         createmany -o $DIR/$tdir/$tfile. 1000
25836
25837         # statfs data is not real time, let's just calculate it
25838         old_iused=$((old_iused + 1000))
25839
25840         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25841                         osp.*OST0000*MDT0000.create_count")
25842         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25843                                 osp.*OST0000*MDT0000.max_create_count")
25844         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25845
25846         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25847         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25848         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25849
25850         unlinkmany $DIR/$tdir/$tfile. 1000
25851
25852         do_nodes $mdts "$LCTL set_param -n \
25853                         osp.*OST0000*.max_create_count=$max_count"
25854         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25855                 do_nodes $mdts "$LCTL set_param -n \
25856                                 osp.*OST0000*.create_count=$count"
25857         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25858                         grep "=0" && error "create_count is zero"
25859
25860         local new_iused
25861         for i in $(seq 120); do
25862                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25863                 # system may be too busy to destroy all objs in time, use
25864                 # a somewhat small value to not fail autotest
25865                 [ $((old_iused - new_iused)) -gt 400 ] && break
25866                 sleep 1
25867         done
25868
25869         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25870         [ $((old_iused - new_iused)) -gt 400 ] ||
25871                 error "objs not destroyed after unlink"
25872 }
25873 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25874
25875 zfs_get_objid()
25876 {
25877         local ost=$1
25878         local tf=$2
25879         local fid=($($LFS getstripe $tf | grep 0x))
25880         local seq=${fid[3]#0x}
25881         local objid=${fid[1]}
25882
25883         local vdevdir=$(dirname $(facet_vdevice $ost))
25884         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25885         local zfs_zapid=$(do_facet $ost $cmd |
25886                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25887                           awk '/Object/{getline; print $1}')
25888         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25889                           awk "/$objid = /"'{printf $3}')
25890
25891         echo $zfs_objid
25892 }
25893
25894 zfs_object_blksz() {
25895         local ost=$1
25896         local objid=$2
25897
25898         local vdevdir=$(dirname $(facet_vdevice $ost))
25899         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25900         local blksz=$(do_facet $ost $cmd $objid |
25901                       awk '/dblk/{getline; printf $4}')
25902
25903         case "${blksz: -1}" in
25904                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25905                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25906                 *) ;;
25907         esac
25908
25909         echo $blksz
25910 }
25911
25912 test_312() { # LU-4856
25913         remote_ost_nodsh && skip "remote OST with nodsh"
25914         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25915
25916         local max_blksz=$(do_facet ost1 \
25917                           $ZFS get -p recordsize $(facet_device ost1) |
25918                           awk '!/VALUE/{print $3}')
25919         local tf=$DIR/$tfile
25920
25921         $LFS setstripe -c1 $tf
25922         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25923
25924         # Get ZFS object id
25925         local zfs_objid=$(zfs_get_objid $facet $tf)
25926         # block size change by sequential overwrite
25927         local bs
25928
25929         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25930                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25931
25932                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25933                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25934         done
25935         rm -f $tf
25936
25937         $LFS setstripe -c1 $tf
25938         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25939
25940         # block size change by sequential append write
25941         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25942         zfs_objid=$(zfs_get_objid $facet $tf)
25943         local count
25944
25945         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25946                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25947                         oflag=sync conv=notrunc
25948
25949                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25950                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25951                         error "blksz error, actual $blksz, " \
25952                                 "expected: 2 * $count * $PAGE_SIZE"
25953         done
25954         rm -f $tf
25955
25956         # random write
25957         $LFS setstripe -c1 $tf
25958         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25959         zfs_objid=$(zfs_get_objid $facet $tf)
25960
25961         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25962         blksz=$(zfs_object_blksz $facet $zfs_objid)
25963         (( blksz == PAGE_SIZE )) ||
25964                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25965
25966         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25967         blksz=$(zfs_object_blksz $facet $zfs_objid)
25968         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25969
25970         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25971         blksz=$(zfs_object_blksz $facet $zfs_objid)
25972         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25973 }
25974 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25975
25976 test_313() {
25977         remote_ost_nodsh && skip "remote OST with nodsh"
25978
25979         local file=$DIR/$tfile
25980
25981         rm -f $file
25982         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25983
25984         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25985         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25986         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25987                 error "write should failed"
25988         do_facet ost1 "$LCTL set_param fail_loc=0"
25989         rm -f $file
25990 }
25991 run_test 313 "io should fail after last_rcvd update fail"
25992
25993 test_314() {
25994         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25995
25996         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25997         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25998         rm -f $DIR/$tfile
25999         wait_delete_completed
26000         do_facet ost1 "$LCTL set_param fail_loc=0"
26001 }
26002 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26003
26004 test_315() { # LU-618
26005         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26006
26007         local file=$DIR/$tfile
26008         rm -f $file
26009
26010         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26011                 error "multiop file write failed"
26012         $MULTIOP $file oO_RDONLY:r4063232_c &
26013         PID=$!
26014
26015         sleep 2
26016
26017         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26018         kill -USR1 $PID
26019
26020         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26021         rm -f $file
26022 }
26023 run_test 315 "read should be accounted"
26024
26025 test_316() {
26026         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26027         large_xattr_enabled || skip "ea_inode feature disabled"
26028
26029         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26030         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26031         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26032         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26033
26034         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26035 }
26036 run_test 316 "lfs migrate of file with large_xattr enabled"
26037
26038 test_317() {
26039         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26040                 skip "Need MDS version at least 2.11.53"
26041         if [ "$ost1_FSTYPE" == "zfs" ]; then
26042                 skip "LU-10370: no implementation for ZFS"
26043         fi
26044
26045         local trunc_sz
26046         local grant_blk_size
26047
26048         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26049                         awk '/grant_block_size:/ { print $2; exit; }')
26050         #
26051         # Create File of size 5M. Truncate it to below size's and verify
26052         # blocks count.
26053         #
26054         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26055                 error "Create file $DIR/$tfile failed"
26056         stack_trap "rm -f $DIR/$tfile" EXIT
26057
26058         for trunc_sz in 2097152 4097 4000 509 0; do
26059                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26060                         error "truncate $tfile to $trunc_sz failed"
26061                 local sz=$(stat --format=%s $DIR/$tfile)
26062                 local blk=$(stat --format=%b $DIR/$tfile)
26063                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26064                                      grant_blk_size) * 8))
26065
26066                 if [[ $blk -ne $trunc_blk ]]; then
26067                         $(which stat) $DIR/$tfile
26068                         error "Expected Block $trunc_blk got $blk for $tfile"
26069                 fi
26070
26071                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26072                         error "Expected Size $trunc_sz got $sz for $tfile"
26073         done
26074
26075         #
26076         # sparse file test
26077         # Create file with a hole and write actual 65536 bytes which aligned
26078         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26079         #
26080         local bs=65536
26081         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26082                 error "Create file : $DIR/$tfile"
26083
26084         #
26085         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26086         # blocks. The block count must drop to 8.
26087         #
26088         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26089                 ((bs - grant_blk_size) + 1)))
26090         $TRUNCATE $DIR/$tfile $trunc_sz ||
26091                 error "truncate $tfile to $trunc_sz failed"
26092
26093         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26094         sz=$(stat --format=%s $DIR/$tfile)
26095         blk=$(stat --format=%b $DIR/$tfile)
26096
26097         if [[ $blk -ne $trunc_bsz ]]; then
26098                 $(which stat) $DIR/$tfile
26099                 error "Expected Block $trunc_bsz got $blk for $tfile"
26100         fi
26101
26102         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26103                 error "Expected Size $trunc_sz got $sz for $tfile"
26104 }
26105 run_test 317 "Verify blocks get correctly update after truncate"
26106
26107 test_318() {
26108         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26109         local old_max_active=$($LCTL get_param -n \
26110                             ${llite_name}.max_read_ahead_async_active \
26111                             2>/dev/null)
26112
26113         $LCTL set_param llite.*.max_read_ahead_async_active=256
26114         local max_active=$($LCTL get_param -n \
26115                            ${llite_name}.max_read_ahead_async_active \
26116                            2>/dev/null)
26117         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26118
26119         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26120                 error "set max_read_ahead_async_active should succeed"
26121
26122         $LCTL set_param llite.*.max_read_ahead_async_active=512
26123         max_active=$($LCTL get_param -n \
26124                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26125         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26126
26127         # restore @max_active
26128         [ $old_max_active -ne 0 ] && $LCTL set_param \
26129                 llite.*.max_read_ahead_async_active=$old_max_active
26130
26131         local old_threshold=$($LCTL get_param -n \
26132                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26133         local max_per_file_mb=$($LCTL get_param -n \
26134                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26135
26136         local invalid=$(($max_per_file_mb + 1))
26137         $LCTL set_param \
26138                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26139                         && error "set $invalid should fail"
26140
26141         local valid=$(($invalid - 1))
26142         $LCTL set_param \
26143                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26144                         error "set $valid should succeed"
26145         local threshold=$($LCTL get_param -n \
26146                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26147         [ $threshold -eq $valid ] || error \
26148                 "expect threshold $valid got $threshold"
26149         $LCTL set_param \
26150                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26151 }
26152 run_test 318 "Verify async readahead tunables"
26153
26154 test_319() {
26155         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26156
26157         local before=$(date +%s)
26158         local evict
26159         local mdir=$DIR/$tdir
26160         local file=$mdir/xxx
26161
26162         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26163         touch $file
26164
26165 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26166         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26167         $LFS migrate -m1 $mdir &
26168
26169         sleep 1
26170         dd if=$file of=/dev/null
26171         wait
26172         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26173           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26174
26175         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26176 }
26177 run_test 319 "lost lease lock on migrate error"
26178
26179 test_398a() { # LU-4198
26180         local ost1_imp=$(get_osc_import_name client ost1)
26181         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26182                          cut -d'.' -f2)
26183
26184         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26185         stack_trap "rm -f $DIR/$tfile"
26186         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26187
26188         # request a new lock on client
26189         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26190
26191         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26192         local lock_count=$($LCTL get_param -n \
26193                            ldlm.namespaces.$imp_name.lru_size)
26194         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26195
26196         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26197
26198         # no lock cached, should use lockless DIO and not enqueue new lock
26199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26200         lock_count=$($LCTL get_param -n \
26201                      ldlm.namespaces.$imp_name.lru_size)
26202         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26203
26204         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26205
26206         # no lock cached, should use locked DIO append
26207         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26208                 conv=notrunc || error "DIO append failed"
26209         lock_count=$($LCTL get_param -n \
26210                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26211         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26212 }
26213 run_test 398a "direct IO should cancel lock otherwise lockless"
26214
26215 test_398b() { # LU-4198
26216         local before=$(date +%s)
26217         local njobs=4
26218         local size=48
26219
26220         which fio || skip_env "no fio installed"
26221         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26222         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26223
26224         # Single page, multiple pages, stripe size, 4*stripe size
26225         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26226                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26227                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26228                         --numjobs=$njobs --fallocate=none \
26229                         --iodepth=16 --allow_file_create=0 \
26230                         --size=$((size/njobs))M \
26231                         --filename=$DIR/$tfile &
26232                 bg_pid=$!
26233
26234                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26235                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26236                         --numjobs=$njobs --fallocate=none \
26237                         --iodepth=16 --allow_file_create=0 \
26238                         --size=$((size/njobs))M \
26239                         --filename=$DIR/$tfile || true
26240                 wait $bg_pid
26241         done
26242
26243         evict=$(do_facet client $LCTL get_param \
26244                 osc.$FSNAME-OST*-osc-*/state |
26245             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26246
26247         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26248                 (do_facet client $LCTL get_param \
26249                         osc.$FSNAME-OST*-osc-*/state;
26250                     error "eviction happened: $evict before:$before")
26251
26252         rm -f $DIR/$tfile
26253 }
26254 run_test 398b "DIO and buffer IO race"
26255
26256 test_398c() { # LU-4198
26257         local ost1_imp=$(get_osc_import_name client ost1)
26258         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26259                          cut -d'.' -f2)
26260
26261         which fio || skip_env "no fio installed"
26262
26263         saved_debug=$($LCTL get_param -n debug)
26264         $LCTL set_param debug=0
26265
26266         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26267         ((size /= 1024)) # by megabytes
26268         ((size /= 2)) # write half of the OST at most
26269         [ $size -gt 40 ] && size=40 #reduce test time anyway
26270
26271         $LFS setstripe -c 1 $DIR/$tfile
26272
26273         # it seems like ldiskfs reserves more space than necessary if the
26274         # writing blocks are not mapped, so it extends the file firstly
26275         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26276         cancel_lru_locks osc
26277
26278         # clear and verify rpc_stats later
26279         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26280
26281         local njobs=4
26282         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26283         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26284                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26285                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26286                 --filename=$DIR/$tfile
26287         [ $? -eq 0 ] || error "fio write error"
26288
26289         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26290                 error "Locks were requested while doing AIO"
26291
26292         # get the percentage of 1-page I/O
26293         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26294                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26295                 awk '{print $7}')
26296         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26297
26298         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26299         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26300                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26301                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26302                 --filename=$DIR/$tfile
26303         [ $? -eq 0 ] || error "fio mixed read write error"
26304
26305         echo "AIO with large block size ${size}M"
26306         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26307                 --numjobs=1 --fallocate=none --ioengine=libaio \
26308                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26309                 --filename=$DIR/$tfile
26310         [ $? -eq 0 ] || error "fio large block size failed"
26311
26312         rm -f $DIR/$tfile
26313         $LCTL set_param debug="$saved_debug"
26314 }
26315 run_test 398c "run fio to test AIO"
26316
26317 test_398d() { #  LU-13846
26318         which aiocp || skip_env "no aiocp installed"
26319         local aio_file=$DIR/$tfile.aio
26320
26321         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26322
26323         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26324         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26325         stack_trap "rm -f $DIR/$tfile $aio_file"
26326
26327         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26328
26329         # make sure we don't crash and fail properly
26330         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26331                 error "aio not aligned with PAGE SIZE should fail"
26332
26333         rm -f $DIR/$tfile $aio_file
26334 }
26335 run_test 398d "run aiocp to verify block size > stripe size"
26336
26337 test_398e() {
26338         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26339         touch $DIR/$tfile.new
26340         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26341 }
26342 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26343
26344 test_398f() { #  LU-14687
26345         which aiocp || skip_env "no aiocp installed"
26346         local aio_file=$DIR/$tfile.aio
26347
26348         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26349
26350         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26351         stack_trap "rm -f $DIR/$tfile $aio_file"
26352
26353         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26354         $LCTL set_param fail_loc=0x1418
26355         # make sure we don't crash and fail properly
26356         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26357                 error "aio with page allocation failure succeeded"
26358         $LCTL set_param fail_loc=0
26359         diff $DIR/$tfile $aio_file
26360         [[ $? != 0 ]] || error "no diff after failed aiocp"
26361 }
26362 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26363
26364 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26365 # stripe and i/o size must be > stripe size
26366 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26367 # single RPC in flight.  This test shows async DIO submission is working by
26368 # showing multiple RPCs in flight.
26369 test_398g() { #  LU-13798
26370         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26371
26372         # We need to do some i/o first to acquire enough grant to put our RPCs
26373         # in flight; otherwise a new connection may not have enough grant
26374         # available
26375         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26376                 error "parallel dio failed"
26377         stack_trap "rm -f $DIR/$tfile"
26378
26379         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26380         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26381         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26382         stack_trap "$LCTL set_param -n $pages_per_rpc"
26383
26384         # Recreate file so it's empty
26385         rm -f $DIR/$tfile
26386         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26387         #Pause rpc completion to guarantee we see multiple rpcs in flight
26388         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26389         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26390         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26391
26392         # Clear rpc stats
26393         $LCTL set_param osc.*.rpc_stats=c
26394
26395         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26396                 error "parallel dio failed"
26397         stack_trap "rm -f $DIR/$tfile"
26398
26399         $LCTL get_param osc.*-OST0000-*.rpc_stats
26400         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26401                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26402                 grep "8:" | awk '{print $8}')
26403         # We look at the "8 rpcs in flight" field, and verify A) it is present
26404         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26405         # as expected for an 8M DIO to a file with 1M stripes.
26406         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26407
26408         # Verify turning off parallel dio works as expected
26409         # Clear rpc stats
26410         $LCTL set_param osc.*.rpc_stats=c
26411         $LCTL set_param llite.*.parallel_dio=0
26412         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26413
26414         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26415                 error "dio with parallel dio disabled failed"
26416
26417         # Ideally, we would see only one RPC in flight here, but there is an
26418         # unavoidable race between i/o completion and RPC in flight counting,
26419         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26420         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26421         # So instead we just verify it's always < 8.
26422         $LCTL get_param osc.*-OST0000-*.rpc_stats
26423         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26424                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26425                 grep '^$' -B1 | grep . | awk '{print $1}')
26426         [ $ret != "8:" ] ||
26427                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26428 }
26429 run_test 398g "verify parallel dio async RPC submission"
26430
26431 test_398h() { #  LU-13798
26432         local dio_file=$DIR/$tfile.dio
26433
26434         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26435
26436         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26437         stack_trap "rm -f $DIR/$tfile $dio_file"
26438
26439         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26440                 error "parallel dio failed"
26441         diff $DIR/$tfile $dio_file
26442         [[ $? == 0 ]] || error "file diff after aiocp"
26443 }
26444 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26445
26446 test_398i() { #  LU-13798
26447         local dio_file=$DIR/$tfile.dio
26448
26449         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26450
26451         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26452         stack_trap "rm -f $DIR/$tfile $dio_file"
26453
26454         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26455         $LCTL set_param fail_loc=0x1418
26456         # make sure we don't crash and fail properly
26457         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26458                 error "parallel dio page allocation failure succeeded"
26459         diff $DIR/$tfile $dio_file
26460         [[ $? != 0 ]] || error "no diff after failed aiocp"
26461 }
26462 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26463
26464 test_398j() { #  LU-13798
26465         # Stripe size > RPC size but less than i/o size tests split across
26466         # stripes and RPCs for individual i/o op
26467         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26468
26469         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26470         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26471         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26472         stack_trap "$LCTL set_param -n $pages_per_rpc"
26473
26474         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26475                 error "parallel dio write failed"
26476         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26477
26478         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26479                 error "parallel dio read failed"
26480         diff $DIR/$tfile $DIR/$tfile.2
26481         [[ $? == 0 ]] || error "file diff after parallel dio read"
26482 }
26483 run_test 398j "test parallel dio where stripe size > rpc_size"
26484
26485 test_398k() { #  LU-13798
26486         wait_delete_completed
26487         wait_mds_ost_sync
26488
26489         # 4 stripe file; we will cause out of space on OST0
26490         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26491
26492         # Fill OST0 (if it's not too large)
26493         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26494                    head -n1)
26495         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26496                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26497         fi
26498         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26499         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26500                 error "dd should fill OST0"
26501         stack_trap "rm -f $DIR/$tfile.1"
26502
26503         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26504         err=$?
26505
26506         ls -la $DIR/$tfile
26507         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26508                 error "file is not 0 bytes in size"
26509
26510         # dd above should not succeed, but don't error until here so we can
26511         # get debug info above
26512         [[ $err != 0 ]] ||
26513                 error "parallel dio write with enospc succeeded"
26514         stack_trap "rm -f $DIR/$tfile"
26515 }
26516 run_test 398k "test enospc on first stripe"
26517
26518 test_398l() { #  LU-13798
26519         wait_delete_completed
26520         wait_mds_ost_sync
26521
26522         # 4 stripe file; we will cause out of space on OST0
26523         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26524         # happens on the second i/o chunk we issue
26525         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26526
26527         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26528         stack_trap "rm -f $DIR/$tfile"
26529
26530         # Fill OST0 (if it's not too large)
26531         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26532                    head -n1)
26533         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26534                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26535         fi
26536         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26537         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26538                 error "dd should fill OST0"
26539         stack_trap "rm -f $DIR/$tfile.1"
26540
26541         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26542         err=$?
26543         stack_trap "rm -f $DIR/$tfile.2"
26544
26545         # Check that short write completed as expected
26546         ls -la $DIR/$tfile.2
26547         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26548                 error "file is not 1M in size"
26549
26550         # dd above should not succeed, but don't error until here so we can
26551         # get debug info above
26552         [[ $err != 0 ]] ||
26553                 error "parallel dio write with enospc succeeded"
26554
26555         # Truncate source file to same length as output file and diff them
26556         $TRUNCATE $DIR/$tfile 1048576
26557         diff $DIR/$tfile $DIR/$tfile.2
26558         [[ $? == 0 ]] || error "data incorrect after short write"
26559 }
26560 run_test 398l "test enospc on intermediate stripe/RPC"
26561
26562 test_398m() { #  LU-13798
26563         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26564
26565         # Set up failure on OST0, the first stripe:
26566         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26567         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26568         # OST0 is on ost1, OST1 is on ost2.
26569         # So this fail_val specifies OST0
26570         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26571         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26572
26573         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26574                 error "parallel dio write with failure on first stripe succeeded"
26575         stack_trap "rm -f $DIR/$tfile"
26576         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26577
26578         # Place data in file for read
26579         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26580                 error "parallel dio write failed"
26581
26582         # Fail read on OST0, first stripe
26583         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26584         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26585         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26586                 error "parallel dio read with error on first stripe succeeded"
26587         rm -f $DIR/$tfile.2
26588         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26589
26590         # Switch to testing on OST1, second stripe
26591         # Clear file contents, maintain striping
26592         echo > $DIR/$tfile
26593         # Set up failure on OST1, second stripe:
26594         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26595         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26596
26597         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26598                 error "parallel dio write with failure on second stripe succeeded"
26599         stack_trap "rm -f $DIR/$tfile"
26600         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26601
26602         # Place data in file for read
26603         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26604                 error "parallel dio write failed"
26605
26606         # Fail read on OST1, second stripe
26607         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26608         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26609         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26610                 error "parallel dio read with error on second stripe succeeded"
26611         rm -f $DIR/$tfile.2
26612         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26613 }
26614 run_test 398m "test RPC failures with parallel dio"
26615
26616 # Parallel submission of DIO should not cause problems for append, but it's
26617 # important to verify.
26618 test_398n() { #  LU-13798
26619         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26620
26621         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26622                 error "dd to create source file failed"
26623         stack_trap "rm -f $DIR/$tfile"
26624
26625         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26626                 error "parallel dio write with failure on second stripe succeeded"
26627         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26628         diff $DIR/$tfile $DIR/$tfile.1
26629         [[ $? == 0 ]] || error "data incorrect after append"
26630
26631 }
26632 run_test 398n "test append with parallel DIO"
26633
26634 test_398o() {
26635         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26636 }
26637 run_test 398o "right kms with DIO"
26638
26639 test_398p()
26640 {
26641         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26642         which aiocp || skip_env "no aiocp installed"
26643
26644         local stripe_size=$((1024 * 1024)) #1 MiB
26645         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26646         local file_size=$((25 * stripe_size))
26647
26648         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26649         stack_trap "rm -f $DIR/$tfile*"
26650         # Just a bit bigger than the largest size in the test set below
26651         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26652                 error "buffered i/o to create file failed"
26653
26654         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26655                 $((stripe_size * 4)); do
26656
26657                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26658
26659                 echo "bs: $bs, file_size $file_size"
26660                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26661                         $DIR/$tfile.1 $DIR/$tfile.2 &
26662                 pid_dio1=$!
26663                 # Buffered I/O with similar but not the same block size
26664                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26665                         conv=notrunc &
26666                 pid_bio2=$!
26667                 wait $pid_dio1
26668                 rc1=$?
26669                 wait $pid_bio2
26670                 rc2=$?
26671                 if (( rc1 != 0 )); then
26672                         error "aio copy 1 w/bsize $bs failed: $rc1"
26673                 fi
26674                 if (( rc2 != 0 )); then
26675                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26676                 fi
26677
26678                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26679                         error "size incorrect"
26680                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26681                         error "files differ, bsize $bs"
26682                 rm -f $DIR/$tfile.2
26683         done
26684 }
26685 run_test 398p "race aio with buffered i/o"
26686
26687 test_398q()
26688 {
26689         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26690
26691         local stripe_size=$((1024 * 1024)) #1 MiB
26692         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26693         local file_size=$((25 * stripe_size))
26694
26695         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26696         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26697
26698         # Just a bit bigger than the largest size in the test set below
26699         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26700                 error "buffered i/o to create file failed"
26701
26702         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26703                 $((stripe_size * 4)); do
26704
26705                 echo "bs: $bs, file_size $file_size"
26706                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26707                         conv=notrunc oflag=direct iflag=direct &
26708                 pid_dio1=$!
26709                 # Buffered I/O with similar but not the same block size
26710                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26711                         conv=notrunc &
26712                 pid_bio2=$!
26713                 wait $pid_dio1
26714                 rc1=$?
26715                 wait $pid_bio2
26716                 rc2=$?
26717                 if (( rc1 != 0 )); then
26718                         error "dio copy 1 w/bsize $bs failed: $rc1"
26719                 fi
26720                 if (( rc2 != 0 )); then
26721                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26722                 fi
26723
26724                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26725                         error "size incorrect"
26726                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26727                         error "files differ, bsize $bs"
26728         done
26729
26730         rm -f $DIR/$tfile*
26731 }
26732 run_test 398q "race dio with buffered i/o"
26733
26734 test_fake_rw() {
26735         local read_write=$1
26736         if [ "$read_write" = "write" ]; then
26737                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26738         elif [ "$read_write" = "read" ]; then
26739                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26740         else
26741                 error "argument error"
26742         fi
26743
26744         # turn off debug for performance testing
26745         local saved_debug=$($LCTL get_param -n debug)
26746         $LCTL set_param debug=0
26747
26748         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26749
26750         # get ost1 size - $FSNAME-OST0000
26751         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26752         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26753         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26754
26755         if [ "$read_write" = "read" ]; then
26756                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26757         fi
26758
26759         local start_time=$(date +%s.%N)
26760         $dd_cmd bs=1M count=$blocks oflag=sync ||
26761                 error "real dd $read_write error"
26762         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26763
26764         if [ "$read_write" = "write" ]; then
26765                 rm -f $DIR/$tfile
26766         fi
26767
26768         # define OBD_FAIL_OST_FAKE_RW           0x238
26769         do_facet ost1 $LCTL set_param fail_loc=0x238
26770
26771         local start_time=$(date +%s.%N)
26772         $dd_cmd bs=1M count=$blocks oflag=sync ||
26773                 error "fake dd $read_write error"
26774         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26775
26776         if [ "$read_write" = "write" ]; then
26777                 # verify file size
26778                 cancel_lru_locks osc
26779                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26780                         error "$tfile size not $blocks MB"
26781         fi
26782         do_facet ost1 $LCTL set_param fail_loc=0
26783
26784         echo "fake $read_write $duration_fake vs. normal $read_write" \
26785                 "$duration in seconds"
26786         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26787                 error_not_in_vm "fake write is slower"
26788
26789         $LCTL set_param -n debug="$saved_debug"
26790         rm -f $DIR/$tfile
26791 }
26792 test_399a() { # LU-7655 for OST fake write
26793         remote_ost_nodsh && skip "remote OST with nodsh"
26794
26795         test_fake_rw write
26796 }
26797 run_test 399a "fake write should not be slower than normal write"
26798
26799 test_399b() { # LU-8726 for OST fake read
26800         remote_ost_nodsh && skip "remote OST with nodsh"
26801         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26802                 skip_env "ldiskfs only test"
26803         fi
26804
26805         test_fake_rw read
26806 }
26807 run_test 399b "fake read should not be slower than normal read"
26808
26809 test_400a() { # LU-1606, was conf-sanity test_74
26810         if ! which $CC > /dev/null 2>&1; then
26811                 skip_env "$CC is not installed"
26812         fi
26813
26814         local extra_flags=''
26815         local out=$TMP/$tfile
26816         local prefix=/usr/include/lustre
26817         local prog
26818
26819         # Oleg removes .c files in his test rig so test if any c files exist
26820         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26821                 skip_env "Needed .c test files are missing"
26822
26823         if ! [[ -d $prefix ]]; then
26824                 # Assume we're running in tree and fixup the include path.
26825                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26826                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26827                 extra_flags+=" -L$LUSTRE/utils/.libs"
26828         fi
26829
26830         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26831                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26832                         error "client api broken"
26833         done
26834         rm -f $out
26835 }
26836 run_test 400a "Lustre client api program can compile and link"
26837
26838 test_400b() { # LU-1606, LU-5011
26839         local header
26840         local out=$TMP/$tfile
26841         local prefix=/usr/include/linux/lustre
26842
26843         # We use a hard coded prefix so that this test will not fail
26844         # when run in tree. There are headers in lustre/include/lustre/
26845         # that are not packaged (like lustre_idl.h) and have more
26846         # complicated include dependencies (like config.h and lnet/types.h).
26847         # Since this test about correct packaging we just skip them when
26848         # they don't exist (see below) rather than try to fixup cppflags.
26849
26850         if ! which $CC > /dev/null 2>&1; then
26851                 skip_env "$CC is not installed"
26852         fi
26853
26854         for header in $prefix/*.h; do
26855                 if ! [[ -f "$header" ]]; then
26856                         continue
26857                 fi
26858
26859                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26860                         continue # lustre_ioctl.h is internal header
26861                 fi
26862
26863                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26864                         error "cannot compile '$header'"
26865         done
26866         rm -f $out
26867 }
26868 run_test 400b "packaged headers can be compiled"
26869
26870 test_401a() { #LU-7437
26871         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26872         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26873
26874         #count the number of parameters by "list_param -R"
26875         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26876         #count the number of parameters by listing proc files
26877         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26878         echo "proc_dirs='$proc_dirs'"
26879         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26880         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26881                       sort -u | wc -l)
26882
26883         [ $params -eq $procs ] ||
26884                 error "found $params parameters vs. $procs proc files"
26885
26886         # test the list_param -D option only returns directories
26887         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26888         #count the number of parameters by listing proc directories
26889         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26890                 sort -u | wc -l)
26891
26892         [ $params -eq $procs ] ||
26893                 error "found $params parameters vs. $procs proc files"
26894 }
26895 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26896
26897 test_401b() {
26898         # jobid_var may not allow arbitrary values, so use jobid_name
26899         # if available
26900         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26901                 local testname=jobid_name tmp='testing%p'
26902         else
26903                 local testname=jobid_var tmp=testing
26904         fi
26905
26906         local save=$($LCTL get_param -n $testname)
26907
26908         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26909                 error "no error returned when setting bad parameters"
26910
26911         local jobid_new=$($LCTL get_param -n foe $testname baz)
26912         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26913
26914         $LCTL set_param -n fog=bam $testname=$save bat=fog
26915         local jobid_old=$($LCTL get_param -n foe $testname bag)
26916         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26917 }
26918 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26919
26920 test_401c() {
26921         # jobid_var may not allow arbitrary values, so use jobid_name
26922         # if available
26923         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26924                 local testname=jobid_name
26925         else
26926                 local testname=jobid_var
26927         fi
26928
26929         local jobid_var_old=$($LCTL get_param -n $testname)
26930         local jobid_var_new
26931
26932         $LCTL set_param $testname= &&
26933                 error "no error returned for 'set_param a='"
26934
26935         jobid_var_new=$($LCTL get_param -n $testname)
26936         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26937                 error "$testname was changed by setting without value"
26938
26939         $LCTL set_param $testname &&
26940                 error "no error returned for 'set_param a'"
26941
26942         jobid_var_new=$($LCTL get_param -n $testname)
26943         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26944                 error "$testname was changed by setting without value"
26945 }
26946 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26947
26948 test_401d() {
26949         # jobid_var may not allow arbitrary values, so use jobid_name
26950         # if available
26951         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26952                 local testname=jobid_name new_value='foo=bar%p'
26953         else
26954                 local testname=jobid_var new_valuie=foo=bar
26955         fi
26956
26957         local jobid_var_old=$($LCTL get_param -n $testname)
26958         local jobid_var_new
26959
26960         $LCTL set_param $testname=$new_value ||
26961                 error "'set_param a=b' did not accept a value containing '='"
26962
26963         jobid_var_new=$($LCTL get_param -n $testname)
26964         [[ "$jobid_var_new" == "$new_value" ]] ||
26965                 error "'set_param a=b' failed on a value containing '='"
26966
26967         # Reset the $testname to test the other format
26968         $LCTL set_param $testname=$jobid_var_old
26969         jobid_var_new=$($LCTL get_param -n $testname)
26970         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26971                 error "failed to reset $testname"
26972
26973         $LCTL set_param $testname $new_value ||
26974                 error "'set_param a b' did not accept a value containing '='"
26975
26976         jobid_var_new=$($LCTL get_param -n $testname)
26977         [[ "$jobid_var_new" == "$new_value" ]] ||
26978                 error "'set_param a b' failed on a value containing '='"
26979
26980         $LCTL set_param $testname $jobid_var_old
26981         jobid_var_new=$($LCTL get_param -n $testname)
26982         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26983                 error "failed to reset $testname"
26984 }
26985 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26986
26987 test_401e() { # LU-14779
26988         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26989                 error "lctl list_param MGC* failed"
26990         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26991         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26992                 error "lctl get_param lru_size failed"
26993 }
26994 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26995
26996 test_402() {
26997         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26998         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26999                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27000         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27001                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27002                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27003         remote_mds_nodsh && skip "remote MDS with nodsh"
27004
27005         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27006 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27007         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27008         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27009                 echo "Touch failed - OK"
27010 }
27011 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27012
27013 test_403() {
27014         local file1=$DIR/$tfile.1
27015         local file2=$DIR/$tfile.2
27016         local tfile=$TMP/$tfile
27017
27018         rm -f $file1 $file2 $tfile
27019
27020         touch $file1
27021         ln $file1 $file2
27022
27023         # 30 sec OBD_TIMEOUT in ll_getattr()
27024         # right before populating st_nlink
27025         $LCTL set_param fail_loc=0x80001409
27026         stat -c %h $file1 > $tfile &
27027
27028         # create an alias, drop all locks and reclaim the dentry
27029         < $file2
27030         cancel_lru_locks mdc
27031         cancel_lru_locks osc
27032         sysctl -w vm.drop_caches=2
27033
27034         wait
27035
27036         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27037
27038         rm -f $tfile $file1 $file2
27039 }
27040 run_test 403 "i_nlink should not drop to zero due to aliasing"
27041
27042 test_404() { # LU-6601
27043         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27044                 skip "Need server version newer than 2.8.52"
27045         remote_mds_nodsh && skip "remote MDS with nodsh"
27046
27047         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27048                 awk '/osp .*-osc-MDT/ { print $4}')
27049
27050         local osp
27051         for osp in $mosps; do
27052                 echo "Deactivate: " $osp
27053                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27054                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27055                         awk -vp=$osp '$4 == p { print $2 }')
27056                 [ $stat = IN ] || {
27057                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27058                         error "deactivate error"
27059                 }
27060                 echo "Activate: " $osp
27061                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27062                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27063                         awk -vp=$osp '$4 == p { print $2 }')
27064                 [ $stat = UP ] || {
27065                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27066                         error "activate error"
27067                 }
27068         done
27069 }
27070 run_test 404 "validate manual {de}activated works properly for OSPs"
27071
27072 test_405() {
27073         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27074         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27075                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27076                         skip "Layout swap lock is not supported"
27077
27078         check_swap_layouts_support
27079         check_swap_layout_no_dom $DIR
27080
27081         test_mkdir $DIR/$tdir
27082         swap_lock_test -d $DIR/$tdir ||
27083                 error "One layout swap locked test failed"
27084 }
27085 run_test 405 "Various layout swap lock tests"
27086
27087 test_406() {
27088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27089         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27090         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27092         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27093                 skip "Need MDS version at least 2.8.50"
27094
27095         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27096         local test_pool=$TESTNAME
27097
27098         pool_add $test_pool || error "pool_add failed"
27099         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27100                 error "pool_add_targets failed"
27101
27102         save_layout_restore_at_exit $MOUNT
27103
27104         # parent set default stripe count only, child will stripe from both
27105         # parent and fs default
27106         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27107                 error "setstripe $MOUNT failed"
27108         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27109         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27110         for i in $(seq 10); do
27111                 local f=$DIR/$tdir/$tfile.$i
27112                 touch $f || error "touch failed"
27113                 local count=$($LFS getstripe -c $f)
27114                 [ $count -eq $OSTCOUNT ] ||
27115                         error "$f stripe count $count != $OSTCOUNT"
27116                 local offset=$($LFS getstripe -i $f)
27117                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27118                 local size=$($LFS getstripe -S $f)
27119                 [ $size -eq $((def_stripe_size * 2)) ] ||
27120                         error "$f stripe size $size != $((def_stripe_size * 2))"
27121                 local pool=$($LFS getstripe -p $f)
27122                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27123         done
27124
27125         # change fs default striping, delete parent default striping, now child
27126         # will stripe from new fs default striping only
27127         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27128                 error "change $MOUNT default stripe failed"
27129         $LFS setstripe -c 0 $DIR/$tdir ||
27130                 error "delete $tdir default stripe failed"
27131         for i in $(seq 11 20); do
27132                 local f=$DIR/$tdir/$tfile.$i
27133                 touch $f || error "touch $f failed"
27134                 local count=$($LFS getstripe -c $f)
27135                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27136                 local offset=$($LFS getstripe -i $f)
27137                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27138                 local size=$($LFS getstripe -S $f)
27139                 [ $size -eq $def_stripe_size ] ||
27140                         error "$f stripe size $size != $def_stripe_size"
27141                 local pool=$($LFS getstripe -p $f)
27142                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27143         done
27144
27145         unlinkmany $DIR/$tdir/$tfile. 1 20
27146
27147         local f=$DIR/$tdir/$tfile
27148         pool_remove_all_targets $test_pool $f
27149         pool_remove $test_pool $f
27150 }
27151 run_test 406 "DNE support fs default striping"
27152
27153 test_407() {
27154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27155         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27156                 skip "Need MDS version at least 2.8.55"
27157         remote_mds_nodsh && skip "remote MDS with nodsh"
27158
27159         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27160                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27161         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27162                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27163         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27164
27165         #define OBD_FAIL_DT_TXN_STOP    0x2019
27166         for idx in $(seq $MDSCOUNT); do
27167                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27168         done
27169         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27170         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27171                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27172         true
27173 }
27174 run_test 407 "transaction fail should cause operation fail"
27175
27176 test_408() {
27177         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27178
27179         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27180         lctl set_param fail_loc=0x8000040a
27181         # let ll_prepare_partial_page() fail
27182         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27183
27184         rm -f $DIR/$tfile
27185
27186         # create at least 100 unused inodes so that
27187         # shrink_icache_memory(0) should not return 0
27188         touch $DIR/$tfile-{0..100}
27189         rm -f $DIR/$tfile-{0..100}
27190         sync
27191
27192         echo 2 > /proc/sys/vm/drop_caches
27193 }
27194 run_test 408 "drop_caches should not hang due to page leaks"
27195
27196 test_409()
27197 {
27198         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27199
27200         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27201         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27202         touch $DIR/$tdir/guard || error "(2) Fail to create"
27203
27204         local PREFIX=$(str_repeat 'A' 128)
27205         echo "Create 1K hard links start at $(date)"
27206         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27207                 error "(3) Fail to hard link"
27208
27209         echo "Links count should be right although linkEA overflow"
27210         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27211         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27212         [ $linkcount -eq 1001 ] ||
27213                 error "(5) Unexpected hard links count: $linkcount"
27214
27215         echo "List all links start at $(date)"
27216         ls -l $DIR/$tdir/foo > /dev/null ||
27217                 error "(6) Fail to list $DIR/$tdir/foo"
27218
27219         echo "Unlink hard links start at $(date)"
27220         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27221                 error "(7) Fail to unlink"
27222         echo "Unlink hard links finished at $(date)"
27223 }
27224 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27225
27226 test_410()
27227 {
27228         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27229                 skip "Need client version at least 2.9.59"
27230         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27231                 skip "Need MODULES build"
27232
27233         # Create a file, and stat it from the kernel
27234         local testfile=$DIR/$tfile
27235         touch $testfile
27236
27237         local run_id=$RANDOM
27238         local my_ino=$(stat --format "%i" $testfile)
27239
27240         # Try to insert the module. This will always fail as the
27241         # module is designed to not be inserted.
27242         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27243             &> /dev/null
27244
27245         # Anything but success is a test failure
27246         dmesg | grep -q \
27247             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27248             error "no inode match"
27249 }
27250 run_test 410 "Test inode number returned from kernel thread"
27251
27252 cleanup_test411_cgroup() {
27253         trap 0
27254         rmdir "$1"
27255 }
27256
27257 test_411() {
27258         local cg_basedir=/sys/fs/cgroup/memory
27259         # LU-9966
27260         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27261                 skip "no setup for cgroup"
27262
27263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27264                 error "test file creation failed"
27265         cancel_lru_locks osc
27266
27267         # Create a very small memory cgroup to force a slab allocation error
27268         local cgdir=$cg_basedir/osc_slab_alloc
27269         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27270         trap "cleanup_test411_cgroup $cgdir" EXIT
27271         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27272         echo 1M > $cgdir/memory.limit_in_bytes
27273
27274         # Should not LBUG, just be killed by oom-killer
27275         # dd will return 0 even allocation failure in some environment.
27276         # So don't check return value
27277         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27278         cleanup_test411_cgroup $cgdir
27279
27280         return 0
27281 }
27282 run_test 411 "Slab allocation error with cgroup does not LBUG"
27283
27284 test_412() {
27285         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27286         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27287                 skip "Need server version at least 2.10.55"
27288
27289         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27290                 error "mkdir failed"
27291         $LFS getdirstripe $DIR/$tdir
27292         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27293         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27294                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27295         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27296         [ $stripe_count -eq 2 ] ||
27297                 error "expect 2 get $stripe_count"
27298
27299         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27300
27301         local index
27302         local index2
27303
27304         # subdirs should be on the same MDT as parent
27305         for i in $(seq 0 $((MDSCOUNT - 1))); do
27306                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27307                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27308                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27309                 (( index == i )) || error "mdt$i/sub on MDT$index"
27310         done
27311
27312         # stripe offset -1, ditto
27313         for i in {1..10}; do
27314                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27315                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27316                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27317                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27318                 (( index == index2 )) ||
27319                         error "qos$i on MDT$index, sub on MDT$index2"
27320         done
27321
27322         local testdir=$DIR/$tdir/inherit
27323
27324         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27325         # inherit 2 levels
27326         for i in 1 2; do
27327                 testdir=$testdir/s$i
27328                 mkdir $testdir || error "mkdir $testdir failed"
27329                 index=$($LFS getstripe -m $testdir)
27330                 (( index == 1 )) ||
27331                         error "$testdir on MDT$index"
27332         done
27333
27334         # not inherit any more
27335         testdir=$testdir/s3
27336         mkdir $testdir || error "mkdir $testdir failed"
27337         getfattr -d -m dmv $testdir | grep dmv &&
27338                 error "default LMV set on $testdir" || true
27339 }
27340 run_test 412 "mkdir on specific MDTs"
27341
27342 TEST413_COUNT=${TEST413_COUNT:-200}
27343
27344 #
27345 # set_maxage() is used by test_413 only.
27346 # This is a helper function to set maxage. Does not return any value.
27347 # Input: maxage to set
27348 #
27349 set_maxage() {
27350         local lmv_qos_maxage
27351         local lod_qos_maxage
27352         local new_maxage=$1
27353
27354         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27355         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27356         stack_trap "$LCTL set_param \
27357                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27358         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27359                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27360         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27361                 lod.*.mdt_qos_maxage=$new_maxage
27362         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27363                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27364 }
27365
27366 generate_uneven_mdts() {
27367         local threshold=$1
27368         local ffree
27369         local bavail
27370         local max
27371         local min
27372         local max_index
27373         local min_index
27374         local tmp
27375         local i
27376
27377         echo
27378         echo "Check for uneven MDTs: "
27379
27380         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27381         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27382         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27383
27384         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27385         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27386         max_index=0
27387         min_index=0
27388         for ((i = 1; i < ${#ffree[@]}; i++)); do
27389                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27390                 if [ $tmp -gt $max ]; then
27391                         max=$tmp
27392                         max_index=$i
27393                 fi
27394                 if [ $tmp -lt $min ]; then
27395                         min=$tmp
27396                         min_index=$i
27397                 fi
27398         done
27399
27400         (( min > 0 )) || skip "low space on MDT$min_index"
27401         (( ${ffree[min_index]} > 0 )) ||
27402                 skip "no free files on MDT$min_index"
27403         (( ${ffree[min_index]} < 10000000 )) ||
27404                 skip "too many free files on MDT$min_index"
27405
27406         # Check if we need to generate uneven MDTs
27407         local diff=$(((max - min) * 100 / min))
27408         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27409         local testdir # individual folder within $testdirp
27410         local start
27411         local cmd
27412
27413         # fallocate is faster to consume space on MDT, if available
27414         if check_fallocate_supported mds$((min_index + 1)); then
27415                 cmd="fallocate -l 128K "
27416         else
27417                 cmd="dd if=/dev/zero bs=128K count=1 of="
27418         fi
27419
27420         echo "using cmd $cmd"
27421         for (( i = 0; diff < threshold; i++ )); do
27422                 testdir=${testdirp}/$i
27423                 [ -d $testdir ] && continue
27424
27425                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27426
27427                 mkdir -p $testdirp
27428                 # generate uneven MDTs, create till $threshold% diff
27429                 echo -n "weight diff=$diff% must be > $threshold% ..."
27430                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27431                 $LFS mkdir -i $min_index $testdir ||
27432                         error "mkdir $testdir failed"
27433                 $LFS setstripe -E 1M -L mdt $testdir ||
27434                         error "setstripe $testdir failed"
27435                 start=$SECONDS
27436                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27437                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27438                 done
27439                 sync; sleep 1; sync
27440
27441                 # wait for QOS to update
27442                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27443
27444                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27445                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27446                 max=$(((${ffree[max_index]} >> 8) *
27447                         (${bavail[max_index]} * bsize >> 16)))
27448                 min=$(((${ffree[min_index]} >> 8) *
27449                         (${bavail[min_index]} * bsize >> 16)))
27450                 (( min > 0 )) || skip "low space on MDT$min_index"
27451                 diff=$(((max - min) * 100 / min))
27452         done
27453
27454         echo "MDT filesfree available: ${ffree[*]}"
27455         echo "MDT blocks available: ${bavail[*]}"
27456         echo "weight diff=$diff%"
27457 }
27458
27459 test_qos_mkdir() {
27460         local mkdir_cmd=$1
27461         local stripe_count=$2
27462         local mdts=$(comma_list $(mdts_nodes))
27463
27464         local testdir
27465         local lmv_qos_prio_free
27466         local lmv_qos_threshold_rr
27467         local lod_qos_prio_free
27468         local lod_qos_threshold_rr
27469         local total
27470         local count
27471         local i
27472
27473         # @total is total directories created if it's testing plain
27474         # directories, otherwise it's total stripe object count for
27475         # striped directories test.
27476         # remote/striped directory unlinking is slow on zfs and may
27477         # timeout, test with fewer directories
27478         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27479
27480         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27481         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27482         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27483                 head -n1)
27484         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27485         stack_trap "$LCTL set_param \
27486                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27487         stack_trap "$LCTL set_param \
27488                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27489
27490         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27491                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27492         lod_qos_prio_free=${lod_qos_prio_free%%%}
27493         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27494                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27495         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27496         stack_trap "do_nodes $mdts $LCTL set_param \
27497                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27498         stack_trap "do_nodes $mdts $LCTL set_param \
27499                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27500
27501         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27502         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27503
27504         testdir=$DIR/$tdir-s$stripe_count/rr
27505
27506         local stripe_index=$($LFS getstripe -m $testdir)
27507         local test_mkdir_rr=true
27508
27509         getfattr -d -m dmv -e hex $testdir | grep dmv
27510         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27511                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27512                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27513                         test_mkdir_rr=false
27514         fi
27515
27516         echo
27517         $test_mkdir_rr &&
27518                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27519                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27520
27521         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27522         for (( i = 0; i < total / stripe_count; i++ )); do
27523                 eval $mkdir_cmd $testdir/subdir$i ||
27524                         error "$mkdir_cmd subdir$i failed"
27525         done
27526
27527         for (( i = 0; i < $MDSCOUNT; i++ )); do
27528                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27529                 echo "$count directories created on MDT$i"
27530                 if $test_mkdir_rr; then
27531                         (( count == total / stripe_count / MDSCOUNT )) ||
27532                                 error "subdirs are not evenly distributed"
27533                 elif (( i == stripe_index )); then
27534                         (( count == total / stripe_count )) ||
27535                                 error "$count subdirs created on MDT$i"
27536                 else
27537                         (( count == 0 )) ||
27538                                 error "$count subdirs created on MDT$i"
27539                 fi
27540
27541                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27542                         count=$($LFS getdirstripe $testdir/* |
27543                                 grep -c -P "^\s+$i\t")
27544                         echo "$count stripes created on MDT$i"
27545                         # deviation should < 5% of average
27546                         delta=$((count - total / MDSCOUNT))
27547                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27548                                 error "stripes are not evenly distributed"
27549                 fi
27550         done
27551
27552         echo
27553         echo "Check for uneven MDTs: "
27554
27555         local ffree
27556         local bavail
27557         local max
27558         local min
27559         local max_index
27560         local min_index
27561         local tmp
27562
27563         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27564         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27565         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27566
27567         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27568         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27569         max_index=0
27570         min_index=0
27571         for ((i = 1; i < ${#ffree[@]}; i++)); do
27572                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27573                 if [ $tmp -gt $max ]; then
27574                         max=$tmp
27575                         max_index=$i
27576                 fi
27577                 if [ $tmp -lt $min ]; then
27578                         min=$tmp
27579                         min_index=$i
27580                 fi
27581         done
27582         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27583
27584         (( min > 0 )) || skip "low space on MDT$min_index"
27585         (( ${ffree[min_index]} < 10000000 )) ||
27586                 skip "too many free files on MDT$min_index"
27587
27588         generate_uneven_mdts 120
27589
27590         echo "MDT filesfree available: ${ffree[*]}"
27591         echo "MDT blocks available: ${bavail[*]}"
27592         echo "weight diff=$(((max - min) * 100 / min))%"
27593         echo
27594         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27595
27596         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27597         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27598         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27599         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27600         # decrease statfs age, so that it can be updated in time
27601         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27602         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27603
27604         sleep 1
27605
27606         testdir=$DIR/$tdir-s$stripe_count/qos
27607
27608         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27609         for (( i = 0; i < total / stripe_count; i++ )); do
27610                 eval $mkdir_cmd $testdir/subdir$i ||
27611                         error "$mkdir_cmd subdir$i failed"
27612         done
27613
27614         max=0
27615         for (( i = 0; i < $MDSCOUNT; i++ )); do
27616                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27617                 (( count > max )) && max=$count
27618                 echo "$count directories created on MDT$i : curmax=$max"
27619         done
27620
27621         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27622
27623         # D-value should > 10% of average
27624         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27625                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27626
27627         # ditto for stripes
27628         if (( stripe_count > 1 )); then
27629                 max=0
27630                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27631                         count=$($LFS getdirstripe $testdir/* |
27632                                 grep -c -P "^\s+$i\t")
27633                         (( count > max )) && max=$count
27634                         echo "$count stripes created on MDT$i"
27635                 done
27636
27637                 min=$($LFS getdirstripe $testdir/* |
27638                         grep -c -P "^\s+$min_index\t")
27639                 (( max - min > total / MDSCOUNT / 10 )) ||
27640                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27641         fi
27642 }
27643
27644 most_full_mdt() {
27645         local ffree
27646         local bavail
27647         local bsize
27648         local min
27649         local min_index
27650         local tmp
27651
27652         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27653         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27654         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27655
27656         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27657         min_index=0
27658         for ((i = 1; i < ${#ffree[@]}; i++)); do
27659                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27660                 (( tmp < min )) && min=$tmp && min_index=$i
27661         done
27662
27663         echo -n $min_index
27664 }
27665
27666 test_413a() {
27667         [ $MDSCOUNT -lt 2 ] &&
27668                 skip "We need at least 2 MDTs for this test"
27669
27670         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27671                 skip "Need server version at least 2.12.52"
27672
27673         local stripe_max=$((MDSCOUNT - 1))
27674         local stripe_count
27675
27676         # let caller set maxage for latest result
27677         set_maxage 1
27678
27679         # fill MDT unevenly
27680         generate_uneven_mdts 120
27681
27682         # test 4-stripe directory at most, otherwise it's too slow
27683         # We are being very defensive. Although Autotest uses 4 MDTs.
27684         # We make sure stripe_max does not go over 4.
27685         (( stripe_max > 4 )) && stripe_max=4
27686         # unlinking striped directory is slow on zfs, and may timeout, only test
27687         # plain directory
27688         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27689         for stripe_count in $(seq 1 $stripe_max); do
27690                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27691                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27692                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27693                         error "mkdir failed"
27694                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27695         done
27696 }
27697 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27698
27699 test_413b() {
27700         [ $MDSCOUNT -lt 2 ] &&
27701                 skip "We need at least 2 MDTs for this test"
27702
27703         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27704                 skip "Need server version at least 2.12.52"
27705
27706         local stripe_max=$((MDSCOUNT - 1))
27707         local testdir
27708         local stripe_count
27709
27710         # let caller set maxage for latest result
27711         set_maxage 1
27712
27713         # fill MDT unevenly
27714         generate_uneven_mdts 120
27715
27716         # test 4-stripe directory at most, otherwise it's too slow
27717         # We are being very defensive. Although Autotest uses 4 MDTs.
27718         # We make sure stripe_max does not go over 4.
27719         (( stripe_max > 4 )) && stripe_max=4
27720         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27721         for stripe_count in $(seq 1 $stripe_max); do
27722                 testdir=$DIR/$tdir-s$stripe_count
27723                 mkdir $testdir || error "mkdir $testdir failed"
27724                 mkdir $testdir/rr || error "mkdir rr failed"
27725                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27726                         error "mkdir qos failed"
27727                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27728                         $testdir/rr || error "setdirstripe rr failed"
27729                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27730                         error "setdirstripe failed"
27731                 test_qos_mkdir "mkdir" $stripe_count
27732         done
27733 }
27734 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27735
27736 test_413c() {
27737         (( $MDSCOUNT >= 2 )) ||
27738                 skip "We need at least 2 MDTs for this test"
27739
27740         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27741                 skip "Need server version at least 2.14.51"
27742
27743         local testdir
27744         local inherit
27745         local inherit_rr
27746         local lmv_qos_maxage
27747         local lod_qos_maxage
27748
27749         # let caller set maxage for latest result
27750         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27751         $LCTL set_param lmv.*.qos_maxage=1
27752         stack_trap "$LCTL set_param \
27753                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27754         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27755                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27756         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27757                 lod.*.mdt_qos_maxage=1
27758         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27759                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27760
27761         # fill MDT unevenly
27762         generate_uneven_mdts 120
27763
27764         testdir=$DIR/${tdir}-s1
27765         mkdir $testdir || error "mkdir $testdir failed"
27766         mkdir $testdir/rr || error "mkdir rr failed"
27767         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27768         # default max_inherit is -1, default max_inherit_rr is 0
27769         $LFS setdirstripe -D -c 1 $testdir/rr ||
27770                 error "setdirstripe rr failed"
27771         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27772                 error "setdirstripe qos failed"
27773         test_qos_mkdir "mkdir" 1
27774
27775         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27776         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27777         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27778         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27779         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27780
27781         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27782         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27783         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27784         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27785         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27786         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27787         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27788                 error "level2 shouldn't have default LMV" || true
27789 }
27790 run_test 413c "mkdir with default LMV max inherit rr"
27791
27792 test_413d() {
27793         (( MDSCOUNT >= 2 )) ||
27794                 skip "We need at least 2 MDTs for this test"
27795
27796         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27797                 skip "Need server version at least 2.14.51"
27798
27799         local lmv_qos_threshold_rr
27800
27801         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27802                 head -n1)
27803         stack_trap "$LCTL set_param \
27804                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27805
27806         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27807         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27808         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27809                 error "$tdir shouldn't have default LMV"
27810         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27811                 error "mkdir sub failed"
27812
27813         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27814
27815         (( count == 100 )) || error "$count subdirs on MDT0"
27816 }
27817 run_test 413d "inherit ROOT default LMV"
27818
27819 test_413e() {
27820         (( MDSCOUNT >= 2 )) ||
27821                 skip "We need at least 2 MDTs for this test"
27822         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27823                 skip "Need server version at least 2.14.55"
27824
27825         local testdir=$DIR/$tdir
27826         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27827         local max_inherit
27828         local sub_max_inherit
27829
27830         mkdir -p $testdir || error "failed to create $testdir"
27831
27832         # set default max-inherit to -1 if stripe count is 0 or 1
27833         $LFS setdirstripe -D -c 1 $testdir ||
27834                 error "failed to set default LMV"
27835         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27836         (( max_inherit == -1 )) ||
27837                 error "wrong max_inherit value $max_inherit"
27838
27839         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27840         $LFS setdirstripe -D -c -1 $testdir ||
27841                 error "failed to set default LMV"
27842         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27843         (( max_inherit > 0 )) ||
27844                 error "wrong max_inherit value $max_inherit"
27845
27846         # and the subdir will decrease the max_inherit by 1
27847         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27848         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27849         (( sub_max_inherit == max_inherit - 1)) ||
27850                 error "wrong max-inherit of subdir $sub_max_inherit"
27851
27852         # check specified --max-inherit and warning message
27853         stack_trap "rm -f $tmpfile"
27854         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27855                 error "failed to set default LMV"
27856         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27857         (( max_inherit == -1 )) ||
27858                 error "wrong max_inherit value $max_inherit"
27859
27860         # check the warning messages
27861         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27862                 error "failed to detect warning string"
27863         fi
27864 }
27865 run_test 413e "check default max-inherit value"
27866
27867 test_fs_dmv_inherit()
27868 {
27869         local testdir=$DIR/$tdir
27870
27871         local count
27872         local inherit
27873         local inherit_rr
27874
27875         for i in 1 2; do
27876                 mkdir $testdir || error "mkdir $testdir failed"
27877                 count=$($LFS getdirstripe -D -c $testdir)
27878                 (( count == 1 )) ||
27879                         error "$testdir default LMV count mismatch $count != 1"
27880                 inherit=$($LFS getdirstripe -D -X $testdir)
27881                 (( inherit == 3 - i )) ||
27882                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27883                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27884                 (( inherit_rr == 3 - i )) ||
27885                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27886                 testdir=$testdir/sub
27887         done
27888
27889         mkdir $testdir || error "mkdir $testdir failed"
27890         count=$($LFS getdirstripe -D -c $testdir)
27891         (( count == 0 )) ||
27892                 error "$testdir default LMV count not zero: $count"
27893 }
27894
27895 test_413f() {
27896         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27897
27898         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27899                 skip "Need server version at least 2.14.55"
27900
27901         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27902                 error "dump $DIR default LMV failed"
27903         stack_trap "setfattr --restore=$TMP/dmv.ea"
27904
27905         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27906                 error "set $DIR default LMV failed"
27907
27908         test_fs_dmv_inherit
27909 }
27910 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27911
27912 test_413g() {
27913         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27914
27915         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27916         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27917                 error "dump $DIR default LMV failed"
27918         stack_trap "setfattr --restore=$TMP/dmv.ea"
27919
27920         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27921                 error "set $DIR default LMV failed"
27922
27923         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27924                 error "mount $MOUNT2 failed"
27925         stack_trap "umount_client $MOUNT2"
27926
27927         local saved_DIR=$DIR
27928
27929         export DIR=$MOUNT2
27930
27931         stack_trap "export DIR=$saved_DIR"
27932
27933         # first check filesystem-wide default LMV inheritance
27934         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27935
27936         # then check subdirs are spread to all MDTs
27937         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27938
27939         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27940
27941         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27942 }
27943 run_test 413g "enforce ROOT default LMV on subdir mount"
27944
27945 test_413h() {
27946         (( MDSCOUNT >= 2 )) ||
27947                 skip "We need at least 2 MDTs for this test"
27948
27949         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27950                 skip "Need server version at least 2.15.50.6"
27951
27952         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27953
27954         stack_trap "$LCTL set_param \
27955                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27956         $LCTL set_param lmv.*.qos_maxage=1
27957
27958         local depth=5
27959         local rr_depth=4
27960         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27961         local count=$((MDSCOUNT * 20))
27962
27963         generate_uneven_mdts 50
27964
27965         mkdir -p $dir || error "mkdir $dir failed"
27966         stack_trap "rm -rf $dir"
27967         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27968                 --max-inherit-rr=$rr_depth $dir
27969
27970         for ((d=0; d < depth + 2; d++)); do
27971                 log "dir=$dir:"
27972                 for ((sub=0; sub < count; sub++)); do
27973                         mkdir $dir/d$sub
27974                 done
27975                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27976                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27977                 # subdirs within $rr_depth should be created round-robin
27978                 if (( d < rr_depth )); then
27979                         (( ${num[0]} != count )) ||
27980                                 error "all objects created on MDT ${num[1]}"
27981                 fi
27982
27983                 dir=$dir/d0
27984         done
27985 }
27986 run_test 413h "don't stick to parent for round-robin dirs"
27987
27988 test_413i() {
27989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27990
27991         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27992                 skip "Need server version at least 2.14.55"
27993
27994         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27995                 error "dump $DIR default LMV failed"
27996         stack_trap "setfattr --restore=$TMP/dmv.ea"
27997
27998         local testdir=$DIR/$tdir
27999         local def_max_rr=1
28000         local def_max=3
28001         local count
28002
28003         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28004                 --max-inherit-rr=$def_max_rr $DIR ||
28005                 error "set $DIR default LMV failed"
28006
28007         for i in $(seq 2 3); do
28008                 def_max=$((def_max - 1))
28009                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28010
28011                 mkdir $testdir
28012                 # RR is decremented and keeps zeroed once exhausted
28013                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28014                 (( count == def_max_rr )) ||
28015                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28016
28017                 # max-inherit is decremented
28018                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28019                 (( count == def_max )) ||
28020                         error_noexit "$testdir: max-inherit $count != $def_max"
28021
28022                 testdir=$testdir/d$i
28023         done
28024
28025         # d3 is the last inherited from ROOT, no inheritance anymore
28026         # i.e. no the default layout anymore
28027         mkdir -p $testdir/d4/d5
28028         count=$($LFS getdirstripe -D --max-inherit $testdir)
28029         (( count == -1 )) ||
28030                 error_noexit "$testdir: max-inherit $count != -1"
28031
28032         local p_count=$($LFS getdirstripe -i $testdir)
28033
28034         for i in $(seq 4 5); do
28035                 testdir=$testdir/d$i
28036
28037                 # the root default layout is not applied once exhausted
28038                 count=$($LFS getdirstripe -i $testdir)
28039                 (( count == p_count )) ||
28040                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28041         done
28042
28043         $LFS setdirstripe -i 0 $DIR/d2
28044         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28045         (( count == -1 )) ||
28046                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28047 }
28048 run_test 413i "check default layout inheritance"
28049
28050 test_413z() {
28051         local pids=""
28052         local subdir
28053         local pid
28054
28055         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28056                 unlinkmany $subdir/f. $TEST413_COUNT &
28057                 pids="$pids $!"
28058         done
28059
28060         for pid in $pids; do
28061                 wait $pid
28062         done
28063
28064         true
28065 }
28066 run_test 413z "413 test cleanup"
28067
28068 test_414() {
28069 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28070         $LCTL set_param fail_loc=0x80000521
28071         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28072         rm -f $DIR/$tfile
28073 }
28074 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28075
28076 test_415() {
28077         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28078         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28079                 skip "Need server version at least 2.11.52"
28080
28081         # LU-11102
28082         local total=500
28083         local max=120
28084
28085         # this test may be slow on ZFS
28086         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28087
28088         # though this test is designed for striped directory, let's test normal
28089         # directory too since lock is always saved as CoS lock.
28090         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28091         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28092         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28093         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28094         wait_delete_completed_mds
28095
28096         # run a loop without concurrent touch to measure rename duration.
28097         # only for test debug/robustness, NOT part of COS functional test.
28098         local start_time=$SECONDS
28099         for ((i = 0; i < total; i++)); do
28100                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28101                         > /dev/null
28102         done
28103         local baseline=$((SECONDS - start_time))
28104         echo "rename $total files without 'touch' took $baseline sec"
28105
28106         (
28107                 while true; do
28108                         touch $DIR/$tdir
28109                 done
28110         ) &
28111         local setattr_pid=$!
28112
28113         # rename files back to original name so unlinkmany works
28114         start_time=$SECONDS
28115         for ((i = 0; i < total; i++)); do
28116                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28117                         > /dev/null
28118         done
28119         local duration=$((SECONDS - start_time))
28120
28121         kill -9 $setattr_pid
28122
28123         echo "rename $total files with 'touch' took $duration sec"
28124         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28125         (( duration <= max )) ||
28126                 error_not_in_vm "rename took $duration > $max sec"
28127 }
28128 run_test 415 "lock revoke is not missing"
28129
28130 test_416() {
28131         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28132                 skip "Need server version at least 2.11.55"
28133
28134         # define OBD_FAIL_OSD_TXN_START    0x19a
28135         do_facet mds1 lctl set_param fail_loc=0x19a
28136
28137         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28138
28139         true
28140 }
28141 run_test 416 "transaction start failure won't cause system hung"
28142
28143 cleanup_417() {
28144         trap 0
28145         do_nodes $(comma_list $(mdts_nodes)) \
28146                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28147         do_nodes $(comma_list $(mdts_nodes)) \
28148                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28149         do_nodes $(comma_list $(mdts_nodes)) \
28150                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28151 }
28152
28153 test_417() {
28154         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28155         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28156                 skip "Need MDS version at least 2.11.56"
28157
28158         trap cleanup_417 RETURN EXIT
28159
28160         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28161         do_nodes $(comma_list $(mdts_nodes)) \
28162                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28163         $LFS migrate -m 0 $DIR/$tdir.1 &&
28164                 error "migrate dir $tdir.1 should fail"
28165
28166         do_nodes $(comma_list $(mdts_nodes)) \
28167                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28168         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28169                 error "create remote dir $tdir.2 should fail"
28170
28171         do_nodes $(comma_list $(mdts_nodes)) \
28172                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28173         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28174                 error "create striped dir $tdir.3 should fail"
28175         true
28176 }
28177 run_test 417 "disable remote dir, striped dir and dir migration"
28178
28179 # Checks that the outputs of df [-i] and lfs df [-i] match
28180 #
28181 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28182 check_lfs_df() {
28183         local dir=$2
28184         local inodes
28185         local df_out
28186         local lfs_df_out
28187         local count
28188         local passed=false
28189
28190         # blocks or inodes
28191         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28192
28193         for count in {1..100}; do
28194                 do_nodes "$CLIENTS" \
28195                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28196                 sync; sleep 0.2
28197
28198                 # read the lines of interest
28199                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28200                         error "df $inodes $dir | tail -n +2 failed"
28201                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28202                         error "lfs df $inodes $dir | grep summary: failed"
28203
28204                 # skip first substrings of each output as they are different
28205                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28206                 # compare the two outputs
28207                 passed=true
28208                 #  skip "available" on MDT until LU-13997 is fixed.
28209                 #for i in {1..5}; do
28210                 for i in 1 2 4 5; do
28211                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28212                 done
28213                 $passed && break
28214         done
28215
28216         if ! $passed; then
28217                 df -P $inodes $dir
28218                 echo
28219                 lfs df $inodes $dir
28220                 error "df and lfs df $1 output mismatch: "      \
28221                       "df ${inodes}: ${df_out[*]}, "            \
28222                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28223         fi
28224 }
28225
28226 test_418() {
28227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28228
28229         local dir=$DIR/$tdir
28230         local numfiles=$((RANDOM % 4096 + 2))
28231         local numblocks=$((RANDOM % 256 + 1))
28232
28233         wait_delete_completed
28234         test_mkdir $dir
28235
28236         # check block output
28237         check_lfs_df blocks $dir
28238         # check inode output
28239         check_lfs_df inodes $dir
28240
28241         # create a single file and retest
28242         echo "Creating a single file and testing"
28243         createmany -o $dir/$tfile- 1 &>/dev/null ||
28244                 error "creating 1 file in $dir failed"
28245         check_lfs_df blocks $dir
28246         check_lfs_df inodes $dir
28247
28248         # create a random number of files
28249         echo "Creating $((numfiles - 1)) files and testing"
28250         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28251                 error "creating $((numfiles - 1)) files in $dir failed"
28252
28253         # write a random number of blocks to the first test file
28254         echo "Writing $numblocks 4K blocks and testing"
28255         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28256                 count=$numblocks &>/dev/null ||
28257                 error "dd to $dir/${tfile}-0 failed"
28258
28259         # retest
28260         check_lfs_df blocks $dir
28261         check_lfs_df inodes $dir
28262
28263         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28264                 error "unlinking $numfiles files in $dir failed"
28265 }
28266 run_test 418 "df and lfs df outputs match"
28267
28268 test_419()
28269 {
28270         local dir=$DIR/$tdir
28271
28272         mkdir -p $dir
28273         touch $dir/file
28274
28275         cancel_lru_locks mdc
28276
28277         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28278         $LCTL set_param fail_loc=0x1410
28279         cat $dir/file
28280         $LCTL set_param fail_loc=0
28281         rm -rf $dir
28282 }
28283 run_test 419 "Verify open file by name doesn't crash kernel"
28284
28285 test_420()
28286 {
28287         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28288                 skip "Need MDS version at least 2.12.53"
28289
28290         local SAVE_UMASK=$(umask)
28291         local dir=$DIR/$tdir
28292         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28293
28294         mkdir -p $dir
28295         umask 0000
28296         mkdir -m03777 $dir/testdir
28297         ls -dn $dir/testdir
28298         # Need to remove trailing '.' when SELinux is enabled
28299         local dirperms=$(ls -dn $dir/testdir |
28300                          awk '{ sub(/\.$/, "", $1); print $1}')
28301         [ $dirperms == "drwxrwsrwt" ] ||
28302                 error "incorrect perms on $dir/testdir"
28303
28304         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28305                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28306         ls -n $dir/testdir/testfile
28307         local fileperms=$(ls -n $dir/testdir/testfile |
28308                           awk '{ sub(/\.$/, "", $1); print $1}')
28309         [ $fileperms == "-rwxr-xr-x" ] ||
28310                 error "incorrect perms on $dir/testdir/testfile"
28311
28312         umask $SAVE_UMASK
28313 }
28314 run_test 420 "clear SGID bit on non-directories for non-members"
28315
28316 test_421a() {
28317         local cnt
28318         local fid1
28319         local fid2
28320
28321         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28322                 skip "Need MDS version at least 2.12.54"
28323
28324         test_mkdir $DIR/$tdir
28325         createmany -o $DIR/$tdir/f 3
28326         cnt=$(ls -1 $DIR/$tdir | wc -l)
28327         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28328
28329         fid1=$(lfs path2fid $DIR/$tdir/f1)
28330         fid2=$(lfs path2fid $DIR/$tdir/f2)
28331         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28332
28333         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28334         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28335
28336         cnt=$(ls -1 $DIR/$tdir | wc -l)
28337         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28338
28339         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28340         createmany -o $DIR/$tdir/f 3
28341         cnt=$(ls -1 $DIR/$tdir | wc -l)
28342         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28343
28344         fid1=$(lfs path2fid $DIR/$tdir/f1)
28345         fid2=$(lfs path2fid $DIR/$tdir/f2)
28346         echo "remove using fsname $FSNAME"
28347         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28348
28349         cnt=$(ls -1 $DIR/$tdir | wc -l)
28350         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28351 }
28352 run_test 421a "simple rm by fid"
28353
28354 test_421b() {
28355         local cnt
28356         local FID1
28357         local FID2
28358
28359         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28360                 skip "Need MDS version at least 2.12.54"
28361
28362         test_mkdir $DIR/$tdir
28363         createmany -o $DIR/$tdir/f 3
28364         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28365         MULTIPID=$!
28366
28367         FID1=$(lfs path2fid $DIR/$tdir/f1)
28368         FID2=$(lfs path2fid $DIR/$tdir/f2)
28369         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28370
28371         kill -USR1 $MULTIPID
28372         wait
28373
28374         cnt=$(ls $DIR/$tdir | wc -l)
28375         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28376 }
28377 run_test 421b "rm by fid on open file"
28378
28379 test_421c() {
28380         local cnt
28381         local FIDS
28382
28383         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28384                 skip "Need MDS version at least 2.12.54"
28385
28386         test_mkdir $DIR/$tdir
28387         createmany -o $DIR/$tdir/f 3
28388         touch $DIR/$tdir/$tfile
28389         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28390         cnt=$(ls -1 $DIR/$tdir | wc -l)
28391         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28392
28393         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28394         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28395
28396         cnt=$(ls $DIR/$tdir | wc -l)
28397         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28398 }
28399 run_test 421c "rm by fid against hardlinked files"
28400
28401 test_421d() {
28402         local cnt
28403         local FIDS
28404
28405         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28406                 skip "Need MDS version at least 2.12.54"
28407
28408         test_mkdir $DIR/$tdir
28409         createmany -o $DIR/$tdir/f 4097
28410         cnt=$(ls -1 $DIR/$tdir | wc -l)
28411         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28412
28413         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28414         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28415
28416         cnt=$(ls $DIR/$tdir | wc -l)
28417         rm -rf $DIR/$tdir
28418         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28419 }
28420 run_test 421d "rmfid en masse"
28421
28422 test_421e() {
28423         local cnt
28424         local FID
28425
28426         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28427         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28428                 skip "Need MDS version at least 2.12.54"
28429
28430         mkdir -p $DIR/$tdir
28431         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28432         createmany -o $DIR/$tdir/striped_dir/f 512
28433         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28434         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28435
28436         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28437                 sed "s/[/][^:]*://g")
28438         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28439
28440         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28441         rm -rf $DIR/$tdir
28442         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28443 }
28444 run_test 421e "rmfid in DNE"
28445
28446 test_421f() {
28447         local cnt
28448         local FID
28449
28450         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28451                 skip "Need MDS version at least 2.12.54"
28452
28453         test_mkdir $DIR/$tdir
28454         touch $DIR/$tdir/f
28455         cnt=$(ls -1 $DIR/$tdir | wc -l)
28456         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28457
28458         FID=$(lfs path2fid $DIR/$tdir/f)
28459         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28460         # rmfid should fail
28461         cnt=$(ls -1 $DIR/$tdir | wc -l)
28462         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28463
28464         chmod a+rw $DIR/$tdir
28465         ls -la $DIR/$tdir
28466         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28467         # rmfid should fail
28468         cnt=$(ls -1 $DIR/$tdir | wc -l)
28469         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28470
28471         rm -f $DIR/$tdir/f
28472         $RUNAS touch $DIR/$tdir/f
28473         FID=$(lfs path2fid $DIR/$tdir/f)
28474         echo "rmfid as root"
28475         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28476         cnt=$(ls -1 $DIR/$tdir | wc -l)
28477         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28478
28479         rm -f $DIR/$tdir/f
28480         $RUNAS touch $DIR/$tdir/f
28481         cnt=$(ls -1 $DIR/$tdir | wc -l)
28482         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28483         FID=$(lfs path2fid $DIR/$tdir/f)
28484         # rmfid w/o user_fid2path mount option should fail
28485         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28486         cnt=$(ls -1 $DIR/$tdir | wc -l)
28487         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28488
28489         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28490         stack_trap "rmdir $tmpdir"
28491         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28492                 error "failed to mount client'"
28493         stack_trap "umount_client $tmpdir"
28494
28495         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28496         # rmfid should succeed
28497         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28498         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28499
28500         # rmfid shouldn't allow to remove files due to dir's permission
28501         chmod a+rwx $tmpdir/$tdir
28502         touch $tmpdir/$tdir/f
28503         ls -la $tmpdir/$tdir
28504         FID=$(lfs path2fid $tmpdir/$tdir/f)
28505         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28506         return 0
28507 }
28508 run_test 421f "rmfid checks permissions"
28509
28510 test_421g() {
28511         local cnt
28512         local FIDS
28513
28514         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28515         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28516                 skip "Need MDS version at least 2.12.54"
28517
28518         mkdir -p $DIR/$tdir
28519         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28520         createmany -o $DIR/$tdir/striped_dir/f 512
28521         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28522         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28523
28524         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28525                 sed "s/[/][^:]*://g")
28526
28527         rm -f $DIR/$tdir/striped_dir/f1*
28528         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28529         removed=$((512 - cnt))
28530
28531         # few files have been just removed, so we expect
28532         # rmfid to fail on their fids
28533         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28534         [ $removed != $errors ] && error "$errors != $removed"
28535
28536         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28537         rm -rf $DIR/$tdir
28538         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28539 }
28540 run_test 421g "rmfid to return errors properly"
28541
28542 test_421h() {
28543         local mount_other
28544         local mount_ret
28545         local rmfid_ret
28546         local old_fid
28547         local fidA
28548         local fidB
28549         local fidC
28550         local fidD
28551
28552         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28553                 skip "Need MDS version at least 2.15.53"
28554
28555         test_mkdir $DIR/$tdir
28556         test_mkdir $DIR/$tdir/subdir
28557         touch $DIR/$tdir/subdir/file0
28558         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28559         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28560         rm -f $DIR/$tdir/subdir/file0
28561         touch $DIR/$tdir/subdir/fileA
28562         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28563         echo File $DIR/$tdir/subdir/fileA FID $fidA
28564         touch $DIR/$tdir/subdir/fileB
28565         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28566         echo File $DIR/$tdir/subdir/fileB FID $fidB
28567         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28568         touch $DIR/$tdir/subdir/fileC
28569         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28570         echo File $DIR/$tdir/subdir/fileC FID $fidC
28571         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28572         touch $DIR/$tdir/fileD
28573         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28574         echo File $DIR/$tdir/fileD FID $fidD
28575
28576         # mount another client mount point with subdirectory mount
28577         export FILESET=/$tdir/subdir
28578         mount_other=${MOUNT}_other
28579         mount_client $mount_other ${MOUNT_OPTS}
28580         mount_ret=$?
28581         export FILESET=""
28582         (( mount_ret == 0 )) || error "mount $mount_other failed"
28583
28584         echo Removing FIDs:
28585         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28586         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28587         rmfid_ret=$?
28588
28589         umount_client $mount_other || error "umount $mount_other failed"
28590
28591         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28592
28593         # fileA should have been deleted
28594         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28595
28596         # fileB should have been deleted
28597         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28598
28599         # fileC should not have been deleted, fid also exists outside of fileset
28600         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28601
28602         # fileD should not have been deleted, it exists outside of fileset
28603         stat $DIR/$tdir/fileD || error "fileD deleted"
28604 }
28605 run_test 421h "rmfid with fileset mount"
28606
28607 test_422() {
28608         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28609         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28610         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28611         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28612         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28613
28614         local amc=$(at_max_get client)
28615         local amo=$(at_max_get mds1)
28616         local timeout=`lctl get_param -n timeout`
28617
28618         at_max_set 0 client
28619         at_max_set 0 mds1
28620
28621 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28622         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28623                         fail_val=$(((2*timeout + 10)*1000))
28624         touch $DIR/$tdir/d3/file &
28625         sleep 2
28626 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28627         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28628                         fail_val=$((2*timeout + 5))
28629         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28630         local pid=$!
28631         sleep 1
28632         kill -9 $pid
28633         sleep $((2 * timeout))
28634         echo kill $pid
28635         kill -9 $pid
28636         lctl mark touch
28637         touch $DIR/$tdir/d2/file3
28638         touch $DIR/$tdir/d2/file4
28639         touch $DIR/$tdir/d2/file5
28640
28641         wait
28642         at_max_set $amc client
28643         at_max_set $amo mds1
28644
28645         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28646         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28647                 error "Watchdog is always throttled"
28648 }
28649 run_test 422 "kill a process with RPC in progress"
28650
28651 stat_test() {
28652     df -h $MOUNT &
28653     df -h $MOUNT &
28654     df -h $MOUNT &
28655     df -h $MOUNT &
28656     df -h $MOUNT &
28657     df -h $MOUNT &
28658 }
28659
28660 test_423() {
28661     local _stats
28662     # ensure statfs cache is expired
28663     sleep 2;
28664
28665     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28666     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28667
28668     return 0
28669 }
28670 run_test 423 "statfs should return a right data"
28671
28672 test_424() {
28673 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28674         $LCTL set_param fail_loc=0x80000522
28675         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28676         rm -f $DIR/$tfile
28677 }
28678 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28679
28680 test_425() {
28681         test_mkdir -c -1 $DIR/$tdir
28682         $LFS setstripe -c -1 $DIR/$tdir
28683
28684         lru_resize_disable "" 100
28685         stack_trap "lru_resize_enable" EXIT
28686
28687         sleep 5
28688
28689         for i in $(seq $((MDSCOUNT * 125))); do
28690                 local t=$DIR/$tdir/$tfile_$i
28691
28692                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28693                         error_noexit "Create file $t"
28694         done
28695         stack_trap "rm -rf $DIR/$tdir" EXIT
28696
28697         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28698                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28699                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28700
28701                 [ $lock_count -le $lru_size ] ||
28702                         error "osc lock count $lock_count > lru size $lru_size"
28703         done
28704
28705         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28706                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28707                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28708
28709                 [ $lock_count -le $lru_size ] ||
28710                         error "mdc lock count $lock_count > lru size $lru_size"
28711         done
28712 }
28713 run_test 425 "lock count should not exceed lru size"
28714
28715 test_426() {
28716         splice-test -r $DIR/$tfile
28717         splice-test -rd $DIR/$tfile
28718         splice-test $DIR/$tfile
28719         splice-test -d $DIR/$tfile
28720 }
28721 run_test 426 "splice test on Lustre"
28722
28723 test_427() {
28724         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28725         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28726                 skip "Need MDS version at least 2.12.4"
28727         local log
28728
28729         mkdir $DIR/$tdir
28730         mkdir $DIR/$tdir/1
28731         mkdir $DIR/$tdir/2
28732         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28733         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28734
28735         $LFS getdirstripe $DIR/$tdir/1/dir
28736
28737         #first setfattr for creating updatelog
28738         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28739
28740 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28741         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28742         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28743         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28744
28745         sleep 2
28746         fail mds2
28747         wait_recovery_complete mds2 $((2*TIMEOUT))
28748
28749         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28750         echo $log | grep "get update log failed" &&
28751                 error "update log corruption is detected" || true
28752 }
28753 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28754
28755 test_428() {
28756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28757         local cache_limit=$CACHE_MAX
28758
28759         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28760         $LCTL set_param -n llite.*.max_cached_mb=64
28761
28762         mkdir $DIR/$tdir
28763         $LFS setstripe -c 1 $DIR/$tdir
28764         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28765         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28766         #test write
28767         for f in $(seq 4); do
28768                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28769         done
28770         wait
28771
28772         cancel_lru_locks osc
28773         # Test read
28774         for f in $(seq 4); do
28775                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28776         done
28777         wait
28778 }
28779 run_test 428 "large block size IO should not hang"
28780
28781 test_429() { # LU-7915 / LU-10948
28782         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28783         local testfile=$DIR/$tfile
28784         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28785         local new_flag=1
28786         local first_rpc
28787         local second_rpc
28788         local third_rpc
28789
28790         $LCTL get_param $ll_opencache_threshold_count ||
28791                 skip "client does not have opencache parameter"
28792
28793         set_opencache $new_flag
28794         stack_trap "restore_opencache"
28795         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28796                 error "enable opencache failed"
28797         touch $testfile
28798         # drop MDC DLM locks
28799         cancel_lru_locks mdc
28800         # clear MDC RPC stats counters
28801         $LCTL set_param $mdc_rpcstats=clear
28802
28803         # According to the current implementation, we need to run 3 times
28804         # open & close file to verify if opencache is enabled correctly.
28805         # 1st, RPCs are sent for lookup/open and open handle is released on
28806         #      close finally.
28807         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28808         #      so open handle won't be released thereafter.
28809         # 3rd, No RPC is sent out.
28810         $MULTIOP $testfile oc || error "multiop failed"
28811         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28812         echo "1st: $first_rpc RPCs in flight"
28813
28814         $MULTIOP $testfile oc || error "multiop failed"
28815         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28816         echo "2nd: $second_rpc RPCs in flight"
28817
28818         $MULTIOP $testfile oc || error "multiop failed"
28819         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28820         echo "3rd: $third_rpc RPCs in flight"
28821
28822         #verify no MDC RPC is sent
28823         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28824 }
28825 run_test 429 "verify if opencache flag on client side does work"
28826
28827 lseek_test_430() {
28828         local offset
28829         local file=$1
28830
28831         # data at [200K, 400K)
28832         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28833                 error "256K->512K dd fails"
28834         # data at [2M, 3M)
28835         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28836                 error "2M->3M dd fails"
28837         # data at [4M, 5M)
28838         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28839                 error "4M->5M dd fails"
28840         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28841         # start at first component hole #1
28842         printf "Seeking hole from 1000 ... "
28843         offset=$(lseek_test -l 1000 $file)
28844         echo $offset
28845         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28846         printf "Seeking data from 1000 ... "
28847         offset=$(lseek_test -d 1000 $file)
28848         echo $offset
28849         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28850
28851         # start at first component data block
28852         printf "Seeking hole from 300000 ... "
28853         offset=$(lseek_test -l 300000 $file)
28854         echo $offset
28855         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28856         printf "Seeking data from 300000 ... "
28857         offset=$(lseek_test -d 300000 $file)
28858         echo $offset
28859         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28860
28861         # start at the first component but beyond end of object size
28862         printf "Seeking hole from 1000000 ... "
28863         offset=$(lseek_test -l 1000000 $file)
28864         echo $offset
28865         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28866         printf "Seeking data from 1000000 ... "
28867         offset=$(lseek_test -d 1000000 $file)
28868         echo $offset
28869         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28870
28871         # start at second component stripe 2 (empty file)
28872         printf "Seeking hole from 1500000 ... "
28873         offset=$(lseek_test -l 1500000 $file)
28874         echo $offset
28875         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28876         printf "Seeking data from 1500000 ... "
28877         offset=$(lseek_test -d 1500000 $file)
28878         echo $offset
28879         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28880
28881         # start at second component stripe 1 (all data)
28882         printf "Seeking hole from 3000000 ... "
28883         offset=$(lseek_test -l 3000000 $file)
28884         echo $offset
28885         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28886         printf "Seeking data from 3000000 ... "
28887         offset=$(lseek_test -d 3000000 $file)
28888         echo $offset
28889         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28890
28891         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28892                 error "2nd dd fails"
28893         echo "Add data block at 640K...1280K"
28894
28895         # start at before new data block, in hole
28896         printf "Seeking hole from 600000 ... "
28897         offset=$(lseek_test -l 600000 $file)
28898         echo $offset
28899         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28900         printf "Seeking data from 600000 ... "
28901         offset=$(lseek_test -d 600000 $file)
28902         echo $offset
28903         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28904
28905         # start at the first component new data block
28906         printf "Seeking hole from 1000000 ... "
28907         offset=$(lseek_test -l 1000000 $file)
28908         echo $offset
28909         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28910         printf "Seeking data from 1000000 ... "
28911         offset=$(lseek_test -d 1000000 $file)
28912         echo $offset
28913         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28914
28915         # start at second component stripe 2, new data
28916         printf "Seeking hole from 1200000 ... "
28917         offset=$(lseek_test -l 1200000 $file)
28918         echo $offset
28919         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28920         printf "Seeking data from 1200000 ... "
28921         offset=$(lseek_test -d 1200000 $file)
28922         echo $offset
28923         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28924
28925         # start beyond file end
28926         printf "Using offset > filesize ... "
28927         lseek_test -l 4000000 $file && error "lseek should fail"
28928         printf "Using offset > filesize ... "
28929         lseek_test -d 4000000 $file && error "lseek should fail"
28930
28931         printf "Done\n\n"
28932 }
28933
28934 test_430a() {
28935         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28936                 skip "MDT does not support SEEK_HOLE"
28937
28938         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28939                 skip "OST does not support SEEK_HOLE"
28940
28941         local file=$DIR/$tdir/$tfile
28942
28943         mkdir -p $DIR/$tdir
28944
28945         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28946         # OST stripe #1 will have continuous data at [1M, 3M)
28947         # OST stripe #2 is empty
28948         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28949         lseek_test_430 $file
28950         rm $file
28951         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28952         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28953         lseek_test_430 $file
28954         rm $file
28955         $LFS setstripe -c2 -S 512K $file
28956         echo "Two stripes, stripe size 512K"
28957         lseek_test_430 $file
28958         rm $file
28959         # FLR with stale mirror
28960         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28961                        -N -c2 -S 1M $file
28962         echo "Mirrored file:"
28963         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28964         echo "Plain 2 stripes 1M"
28965         lseek_test_430 $file
28966         rm $file
28967 }
28968 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28969
28970 test_430b() {
28971         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28972                 skip "OST does not support SEEK_HOLE"
28973
28974         local offset
28975         local file=$DIR/$tdir/$tfile
28976
28977         mkdir -p $DIR/$tdir
28978         # Empty layout lseek should fail
28979         $MCREATE $file
28980         # seek from 0
28981         printf "Seeking hole from 0 ... "
28982         lseek_test -l 0 $file && error "lseek should fail"
28983         printf "Seeking data from 0 ... "
28984         lseek_test -d 0 $file && error "lseek should fail"
28985         rm $file
28986
28987         # 1M-hole file
28988         $LFS setstripe -E 1M -c2 -E eof $file
28989         $TRUNCATE $file 1048576
28990         printf "Seeking hole from 1000000 ... "
28991         offset=$(lseek_test -l 1000000 $file)
28992         echo $offset
28993         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28994         printf "Seeking data from 1000000 ... "
28995         lseek_test -d 1000000 $file && error "lseek should fail"
28996         rm $file
28997
28998         # full component followed by non-inited one
28999         $LFS setstripe -E 1M -c2 -E eof $file
29000         dd if=/dev/urandom of=$file bs=1M count=1
29001         printf "Seeking hole from 1000000 ... "
29002         offset=$(lseek_test -l 1000000 $file)
29003         echo $offset
29004         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29005         printf "Seeking hole from 1048576 ... "
29006         lseek_test -l 1048576 $file && error "lseek should fail"
29007         # init second component and truncate back
29008         echo "123" >> $file
29009         $TRUNCATE $file 1048576
29010         printf "Seeking hole from 1000000 ... "
29011         offset=$(lseek_test -l 1000000 $file)
29012         echo $offset
29013         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29014         printf "Seeking hole from 1048576 ... "
29015         lseek_test -l 1048576 $file && error "lseek should fail"
29016         # boundary checks for big values
29017         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29018         offset=$(lseek_test -d 0 $file.10g)
29019         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29020         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29021         offset=$(lseek_test -d 0 $file.100g)
29022         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29023         return 0
29024 }
29025 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29026
29027 test_430c() {
29028         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29029                 skip "OST does not support SEEK_HOLE"
29030
29031         local file=$DIR/$tdir/$tfile
29032         local start
29033
29034         mkdir -p $DIR/$tdir
29035         stack_trap "rm -f $file $file.tmp"
29036         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29037
29038         # cp version 8.33+ prefers lseek over fiemap
29039         local ver=$(cp --version | awk '{ print $4; exit; }')
29040
29041         echo "cp $ver installed"
29042         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29043                 start=$SECONDS
29044                 time cp -v $file $file.tmp || error "cp $file failed"
29045                 (( SECONDS - start < 5 )) || {
29046                         strace cp $file $file.tmp |&
29047                                 grep -E "open|read|seek|FIEMAP" |
29048                                 grep -A 100 $file
29049                         error "cp: too long runtime $((SECONDS - start))"
29050                 }
29051         else
29052                 echo "cp test skipped due to $ver < 8.33"
29053         fi
29054
29055         # tar version 1.29+ supports SEEK_HOLE/DATA
29056         ver=$(tar --version | awk '{ print $4; exit; }')
29057         echo "tar $ver installed"
29058         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29059                 start=$SECONDS
29060                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29061                 (( SECONDS - start < 5 )) || {
29062                         strace tar cf $file.tmp --sparse $file |&
29063                                 grep -E "open|read|seek|FIEMAP" |
29064                                 grep -A 100 $file
29065                         error "tar: too long runtime $((SECONDS - start))"
29066                 }
29067         else
29068                 echo "tar test skipped due to $ver < 1.29"
29069         fi
29070 }
29071 run_test 430c "lseek: external tools check"
29072
29073 test_431() { # LU-14187
29074         local file=$DIR/$tdir/$tfile
29075
29076         mkdir -p $DIR/$tdir
29077         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29078         dd if=/dev/urandom of=$file bs=4k count=1
29079         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29080         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29081         #define OBD_FAIL_OST_RESTART_IO 0x251
29082         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29083         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29084         cp $file $file.0
29085         cancel_lru_locks
29086         sync_all_data
29087         echo 3 > /proc/sys/vm/drop_caches
29088         diff  $file $file.0 || error "data diff"
29089 }
29090 run_test 431 "Restart transaction for IO"
29091
29092 cleanup_test_432() {
29093         do_facet mgs $LCTL nodemap_activate 0
29094         wait_nm_sync active
29095 }
29096
29097 test_432() {
29098         local tmpdir=$TMP/dir432
29099
29100         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29101                 skip "Need MDS version at least 2.14.52"
29102
29103         stack_trap cleanup_test_432 EXIT
29104         mkdir $DIR/$tdir
29105         mkdir $tmpdir
29106
29107         do_facet mgs $LCTL nodemap_activate 1
29108         wait_nm_sync active
29109         do_facet mgs $LCTL nodemap_modify --name default \
29110                 --property admin --value 1
29111         do_facet mgs $LCTL nodemap_modify --name default \
29112                 --property trusted --value 1
29113         cancel_lru_locks mdc
29114         wait_nm_sync default admin_nodemap
29115         wait_nm_sync default trusted_nodemap
29116
29117         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29118                grep -ci "Operation not permitted") -ne 0 ]; then
29119                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29120         fi
29121 }
29122 run_test 432 "mv dir from outside Lustre"
29123
29124 test_433() {
29125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29126
29127         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29128                 skip "inode cache not supported"
29129
29130         $LCTL set_param llite.*.inode_cache=0
29131         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29132
29133         local count=256
29134         local before
29135         local after
29136
29137         cancel_lru_locks mdc
29138         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29139         createmany -m $DIR/$tdir/f $count
29140         createmany -d $DIR/$tdir/d $count
29141         ls -l $DIR/$tdir > /dev/null
29142         stack_trap "rm -rf $DIR/$tdir"
29143
29144         before=$(num_objects)
29145         cancel_lru_locks mdc
29146         after=$(num_objects)
29147
29148         # sometimes even @before is less than 2 * count
29149         while (( before - after < count )); do
29150                 sleep 1
29151                 after=$(num_objects)
29152                 wait=$((wait + 1))
29153                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29154                 if (( wait > 60 )); then
29155                         error "inode slab grew from $before to $after"
29156                 fi
29157         done
29158
29159         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29160 }
29161 run_test 433 "ldlm lock cancel releases dentries and inodes"
29162
29163 test_434() {
29164         local file
29165         local getxattr_count
29166         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29167         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29168
29169         [[ $(getenforce) == "Disabled" ]] ||
29170                 skip "lsm selinux module have to be disabled for this test"
29171
29172         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29173                 error "fail to create $DIR/$tdir/ on MDT0000"
29174
29175         touch $DIR/$tdir/$tfile-{001..100}
29176
29177         # disable the xattr cache
29178         save_lustre_params client "llite.*.xattr_cache" > $p
29179         lctl set_param llite.*.xattr_cache=0
29180         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29181
29182         # clear clients mdc stats
29183         clear_stats $mdc_stat_param ||
29184                 error "fail to clear stats on mdc MDT0000"
29185
29186         for file in $DIR/$tdir/$tfile-{001..100}; do
29187                 getfattr -n security.selinux $file |&
29188                         grep -q "Operation not supported" ||
29189                         error "getxattr on security.selinux should return EOPNOTSUPP"
29190         done
29191
29192         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29193         (( getxattr_count < 100 )) ||
29194                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29195 }
29196 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29197
29198 test_440() {
29199         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29200                 source $LUSTRE/scripts/bash-completion/lustre
29201         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29202                 source /usr/share/bash-completion/completions/lustre
29203         else
29204                 skip "bash completion scripts not found"
29205         fi
29206
29207         local lctl_completions
29208         local lfs_completions
29209
29210         lctl_completions=$(_lustre_cmds lctl)
29211         if [[ ! $lctl_completions =~ "get_param" ]]; then
29212                 error "lctl bash completion failed"
29213         fi
29214
29215         lfs_completions=$(_lustre_cmds lfs)
29216         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29217                 error "lfs bash completion failed"
29218         fi
29219 }
29220 run_test 440 "bash completion for lfs, lctl"
29221
29222 prep_801() {
29223         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29224         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29225                 skip "Need server version at least 2.9.55"
29226
29227         start_full_debug_logging
29228 }
29229
29230 post_801() {
29231         stop_full_debug_logging
29232 }
29233
29234 barrier_stat() {
29235         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29236                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29237                            awk '/The barrier for/ { print $7 }')
29238                 echo $st
29239         else
29240                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29241                 echo \'$st\'
29242         fi
29243 }
29244
29245 barrier_expired() {
29246         local expired
29247
29248         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29249                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29250                           awk '/will be expired/ { print $7 }')
29251         else
29252                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29253         fi
29254
29255         echo $expired
29256 }
29257
29258 test_801a() {
29259         prep_801
29260
29261         echo "Start barrier_freeze at: $(date)"
29262         #define OBD_FAIL_BARRIER_DELAY          0x2202
29263         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29264         # Do not reduce barrier time - See LU-11873
29265         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29266
29267         sleep 2
29268         local b_status=$(barrier_stat)
29269         echo "Got barrier status at: $(date)"
29270         [ "$b_status" = "'freezing_p1'" ] ||
29271                 error "(1) unexpected barrier status $b_status"
29272
29273         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29274         wait
29275         b_status=$(barrier_stat)
29276         [ "$b_status" = "'frozen'" ] ||
29277                 error "(2) unexpected barrier status $b_status"
29278
29279         local expired=$(barrier_expired)
29280         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29281         sleep $((expired + 3))
29282
29283         b_status=$(barrier_stat)
29284         [ "$b_status" = "'expired'" ] ||
29285                 error "(3) unexpected barrier status $b_status"
29286
29287         # Do not reduce barrier time - See LU-11873
29288         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29289                 error "(4) fail to freeze barrier"
29290
29291         b_status=$(barrier_stat)
29292         [ "$b_status" = "'frozen'" ] ||
29293                 error "(5) unexpected barrier status $b_status"
29294
29295         echo "Start barrier_thaw at: $(date)"
29296         #define OBD_FAIL_BARRIER_DELAY          0x2202
29297         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29298         do_facet mgs $LCTL barrier_thaw $FSNAME &
29299
29300         sleep 2
29301         b_status=$(barrier_stat)
29302         echo "Got barrier status at: $(date)"
29303         [ "$b_status" = "'thawing'" ] ||
29304                 error "(6) unexpected barrier status $b_status"
29305
29306         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29307         wait
29308         b_status=$(barrier_stat)
29309         [ "$b_status" = "'thawed'" ] ||
29310                 error "(7) unexpected barrier status $b_status"
29311
29312         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29313         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29314         do_facet mgs $LCTL barrier_freeze $FSNAME
29315
29316         b_status=$(barrier_stat)
29317         [ "$b_status" = "'failed'" ] ||
29318                 error "(8) unexpected barrier status $b_status"
29319
29320         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29321         do_facet mgs $LCTL barrier_thaw $FSNAME
29322
29323         post_801
29324 }
29325 run_test 801a "write barrier user interfaces and stat machine"
29326
29327 test_801b() {
29328         prep_801
29329
29330         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29331         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29332         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29333         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29334         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29335
29336         cancel_lru_locks mdc
29337
29338         # 180 seconds should be long enough
29339         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29340
29341         local b_status=$(barrier_stat)
29342         [ "$b_status" = "'frozen'" ] ||
29343                 error "(6) unexpected barrier status $b_status"
29344
29345         mkdir $DIR/$tdir/d0/d10 &
29346         mkdir_pid=$!
29347
29348         touch $DIR/$tdir/d1/f13 &
29349         touch_pid=$!
29350
29351         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29352         ln_pid=$!
29353
29354         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29355         mv_pid=$!
29356
29357         rm -f $DIR/$tdir/d4/f12 &
29358         rm_pid=$!
29359
29360         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29361
29362         # To guarantee taht the 'stat' is not blocked
29363         b_status=$(barrier_stat)
29364         [ "$b_status" = "'frozen'" ] ||
29365                 error "(8) unexpected barrier status $b_status"
29366
29367         # let above commands to run at background
29368         sleep 5
29369
29370         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29371         ps -p $touch_pid || error "(10) touch should be blocked"
29372         ps -p $ln_pid || error "(11) link should be blocked"
29373         ps -p $mv_pid || error "(12) rename should be blocked"
29374         ps -p $rm_pid || error "(13) unlink should be blocked"
29375
29376         b_status=$(barrier_stat)
29377         [ "$b_status" = "'frozen'" ] ||
29378                 error "(14) unexpected barrier status $b_status"
29379
29380         do_facet mgs $LCTL barrier_thaw $FSNAME
29381         b_status=$(barrier_stat)
29382         [ "$b_status" = "'thawed'" ] ||
29383                 error "(15) unexpected barrier status $b_status"
29384
29385         wait $mkdir_pid || error "(16) mkdir should succeed"
29386         wait $touch_pid || error "(17) touch should succeed"
29387         wait $ln_pid || error "(18) link should succeed"
29388         wait $mv_pid || error "(19) rename should succeed"
29389         wait $rm_pid || error "(20) unlink should succeed"
29390
29391         post_801
29392 }
29393 run_test 801b "modification will be blocked by write barrier"
29394
29395 test_801c() {
29396         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29397
29398         prep_801
29399
29400         stop mds2 || error "(1) Fail to stop mds2"
29401
29402         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29403
29404         local b_status=$(barrier_stat)
29405         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29406                 do_facet mgs $LCTL barrier_thaw $FSNAME
29407                 error "(2) unexpected barrier status $b_status"
29408         }
29409
29410         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29411                 error "(3) Fail to rescan barrier bitmap"
29412
29413         # Do not reduce barrier time - See LU-11873
29414         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29415
29416         b_status=$(barrier_stat)
29417         [ "$b_status" = "'frozen'" ] ||
29418                 error "(4) unexpected barrier status $b_status"
29419
29420         do_facet mgs $LCTL barrier_thaw $FSNAME
29421         b_status=$(barrier_stat)
29422         [ "$b_status" = "'thawed'" ] ||
29423                 error "(5) unexpected barrier status $b_status"
29424
29425         local devname=$(mdsdevname 2)
29426
29427         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29428
29429         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29430                 error "(7) Fail to rescan barrier bitmap"
29431
29432         post_801
29433 }
29434 run_test 801c "rescan barrier bitmap"
29435
29436 test_802b() {
29437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29438         remote_mds_nodsh && skip "remote MDS with nodsh"
29439
29440         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29441                 skip "readonly option not available"
29442
29443         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29444
29445         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29446                 error "(2) Fail to copy"
29447
29448         # write back all cached data before setting MDT to readonly
29449         cancel_lru_locks
29450         sync_all_data
29451
29452         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29453         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29454
29455         echo "Modify should be refused"
29456         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29457
29458         echo "Read should be allowed"
29459         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29460                 error "(7) Read should succeed under ro mode"
29461
29462         # disable readonly
29463         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29464 }
29465 run_test 802b "be able to set MDTs to readonly"
29466
29467 test_803a() {
29468         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29469         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29470                 skip "MDS needs to be newer than 2.10.54"
29471
29472         mkdir_on_mdt0 $DIR/$tdir
29473         # Create some objects on all MDTs to trigger related logs objects
29474         for idx in $(seq $MDSCOUNT); do
29475                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29476                         $DIR/$tdir/dir${idx} ||
29477                         error "Fail to create $DIR/$tdir/dir${idx}"
29478         done
29479
29480         wait_delete_completed # ensure old test cleanups are finished
29481         sleep 3
29482         echo "before create:"
29483         $LFS df -i $MOUNT
29484         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29485
29486         for i in {1..10}; do
29487                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29488                         error "Fail to create $DIR/$tdir/foo$i"
29489         done
29490
29491         # sync ZFS-on-MDS to refresh statfs data
29492         wait_zfs_commit mds1
29493         sleep 3
29494         echo "after create:"
29495         $LFS df -i $MOUNT
29496         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29497
29498         # allow for an llog to be cleaned up during the test
29499         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29500                 error "before ($before_used) + 10 > after ($after_used)"
29501
29502         for i in {1..10}; do
29503                 rm -rf $DIR/$tdir/foo$i ||
29504                         error "Fail to remove $DIR/$tdir/foo$i"
29505         done
29506
29507         # sync ZFS-on-MDS to refresh statfs data
29508         wait_zfs_commit mds1
29509         wait_delete_completed
29510         sleep 3 # avoid MDT return cached statfs
29511         echo "after unlink:"
29512         $LFS df -i $MOUNT
29513         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29514
29515         # allow for an llog to be created during the test
29516         [ $after_used -le $((before_used + 1)) ] ||
29517                 error "after ($after_used) > before ($before_used) + 1"
29518 }
29519 run_test 803a "verify agent object for remote object"
29520
29521 test_803b() {
29522         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29523         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29524                 skip "MDS needs to be newer than 2.13.56"
29525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29526
29527         for i in $(seq 0 $((MDSCOUNT - 1))); do
29528                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29529         done
29530
29531         local before=0
29532         local after=0
29533
29534         local tmp
29535
29536         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29537         for i in $(seq 0 $((MDSCOUNT - 1))); do
29538                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29539                         awk '/getattr/ { print $2 }')
29540                 before=$((before + tmp))
29541         done
29542         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29543         for i in $(seq 0 $((MDSCOUNT - 1))); do
29544                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29545                         awk '/getattr/ { print $2 }')
29546                 after=$((after + tmp))
29547         done
29548
29549         [ $before -eq $after ] || error "getattr count $before != $after"
29550 }
29551 run_test 803b "remote object can getattr from cache"
29552
29553 test_804() {
29554         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29555         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29556                 skip "MDS needs to be newer than 2.10.54"
29557         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29558
29559         mkdir -p $DIR/$tdir
29560         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29561                 error "Fail to create $DIR/$tdir/dir0"
29562
29563         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29564         local dev=$(mdsdevname 2)
29565
29566         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29567                 grep ${fid} || error "NOT found agent entry for dir0"
29568
29569         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29570                 error "Fail to create $DIR/$tdir/dir1"
29571
29572         touch $DIR/$tdir/dir1/foo0 ||
29573                 error "Fail to create $DIR/$tdir/dir1/foo0"
29574         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29575         local rc=0
29576
29577         for idx in $(seq $MDSCOUNT); do
29578                 dev=$(mdsdevname $idx)
29579                 do_facet mds${idx} \
29580                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29581                         grep ${fid} && rc=$idx
29582         done
29583
29584         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29585                 error "Fail to rename foo0 to foo1"
29586         if [ $rc -eq 0 ]; then
29587                 for idx in $(seq $MDSCOUNT); do
29588                         dev=$(mdsdevname $idx)
29589                         do_facet mds${idx} \
29590                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29591                         grep ${fid} && rc=$idx
29592                 done
29593         fi
29594
29595         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29596                 error "Fail to rename foo1 to foo2"
29597         if [ $rc -eq 0 ]; then
29598                 for idx in $(seq $MDSCOUNT); do
29599                         dev=$(mdsdevname $idx)
29600                         do_facet mds${idx} \
29601                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29602                         grep ${fid} && rc=$idx
29603                 done
29604         fi
29605
29606         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29607
29608         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29609                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29610         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29611                 error "Fail to rename foo2 to foo0"
29612         unlink $DIR/$tdir/dir1/foo0 ||
29613                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29614         rm -rf $DIR/$tdir/dir0 ||
29615                 error "Fail to rm $DIR/$tdir/dir0"
29616
29617         for idx in $(seq $MDSCOUNT); do
29618                 rc=0
29619
29620                 stop mds${idx}
29621                 dev=$(mdsdevname $idx)
29622                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29623                         rc=$?
29624                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29625                         error "mount mds$idx failed"
29626                 df $MOUNT > /dev/null 2>&1
29627
29628                 # e2fsck should not return error
29629                 [ $rc -eq 0 ] ||
29630                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29631         done
29632 }
29633 run_test 804 "verify agent entry for remote entry"
29634
29635 cleanup_805() {
29636         do_facet $SINGLEMDS zfs set quota=$old $fsset
29637         unlinkmany $DIR/$tdir/f- 1000000
29638         trap 0
29639 }
29640
29641 test_805() {
29642         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29643         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29644         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29645                 skip "netfree not implemented before 0.7"
29646         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29647                 skip "Need MDS version at least 2.10.57"
29648
29649         local fsset
29650         local freekb
29651         local usedkb
29652         local old
29653         local quota
29654         local pref="osd-zfs.$FSNAME-MDT0000."
29655
29656         # limit available space on MDS dataset to meet nospace issue
29657         # quickly. then ZFS 0.7.2 can use reserved space if asked
29658         # properly (using netfree flag in osd_declare_destroy()
29659         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29660         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29661                 gawk '{print $3}')
29662         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29663         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29664         let "usedkb=usedkb-freekb"
29665         let "freekb=freekb/2"
29666         if let "freekb > 5000"; then
29667                 let "freekb=5000"
29668         fi
29669         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29670         trap cleanup_805 EXIT
29671         mkdir_on_mdt0 $DIR/$tdir
29672         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29673                 error "Can't set PFL layout"
29674         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29675         rm -rf $DIR/$tdir || error "not able to remove"
29676         do_facet $SINGLEMDS zfs set quota=$old $fsset
29677         trap 0
29678 }
29679 run_test 805 "ZFS can remove from full fs"
29680
29681 # Size-on-MDS test
29682 check_lsom_data()
29683 {
29684         local file=$1
29685         local expect=$(stat -c %s $file)
29686
29687         check_lsom_size $1 $expect
29688
29689         local blocks=$($LFS getsom -b $file)
29690         expect=$(stat -c %b $file)
29691         [[ $blocks == $expect ]] ||
29692                 error "$file expected blocks: $expect, got: $blocks"
29693 }
29694
29695 check_lsom_size()
29696 {
29697         local size
29698         local expect=$2
29699
29700         cancel_lru_locks mdc
29701
29702         size=$($LFS getsom -s $1)
29703         [[ $size == $expect ]] ||
29704                 error "$file expected size: $expect, got: $size"
29705 }
29706
29707 test_806() {
29708         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29709                 skip "Need MDS version at least 2.11.52"
29710
29711         local bs=1048576
29712
29713         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29714
29715         disable_opencache
29716         stack_trap "restore_opencache"
29717
29718         # single-threaded write
29719         echo "Test SOM for single-threaded write"
29720         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29721                 error "write $tfile failed"
29722         check_lsom_size $DIR/$tfile $bs
29723
29724         local num=32
29725         local size=$(($num * $bs))
29726         local offset=0
29727         local i
29728
29729         echo "Test SOM for single client multi-threaded($num) write"
29730         $TRUNCATE $DIR/$tfile 0
29731         for ((i = 0; i < $num; i++)); do
29732                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29733                 local pids[$i]=$!
29734                 offset=$((offset + $bs))
29735         done
29736         for (( i=0; i < $num; i++ )); do
29737                 wait ${pids[$i]}
29738         done
29739         check_lsom_size $DIR/$tfile $size
29740
29741         $TRUNCATE $DIR/$tfile 0
29742         for ((i = 0; i < $num; i++)); do
29743                 offset=$((offset - $bs))
29744                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29745                 local pids[$i]=$!
29746         done
29747         for (( i=0; i < $num; i++ )); do
29748                 wait ${pids[$i]}
29749         done
29750         check_lsom_size $DIR/$tfile $size
29751
29752         # multi-client writes
29753         num=$(get_node_count ${CLIENTS//,/ })
29754         size=$(($num * $bs))
29755         offset=0
29756         i=0
29757
29758         echo "Test SOM for multi-client ($num) writes"
29759         $TRUNCATE $DIR/$tfile 0
29760         for client in ${CLIENTS//,/ }; do
29761                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29762                 local pids[$i]=$!
29763                 i=$((i + 1))
29764                 offset=$((offset + $bs))
29765         done
29766         for (( i=0; i < $num; i++ )); do
29767                 wait ${pids[$i]}
29768         done
29769         check_lsom_size $DIR/$tfile $offset
29770
29771         i=0
29772         $TRUNCATE $DIR/$tfile 0
29773         for client in ${CLIENTS//,/ }; do
29774                 offset=$((offset - $bs))
29775                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29776                 local pids[$i]=$!
29777                 i=$((i + 1))
29778         done
29779         for (( i=0; i < $num; i++ )); do
29780                 wait ${pids[$i]}
29781         done
29782         check_lsom_size $DIR/$tfile $size
29783
29784         # verify SOM blocks count
29785         echo "Verify SOM block count"
29786         $TRUNCATE $DIR/$tfile 0
29787         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29788                 error "failed to write file $tfile with fdatasync and fstat"
29789         check_lsom_data $DIR/$tfile
29790
29791         $TRUNCATE $DIR/$tfile 0
29792         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29793                 error "failed to write file $tfile with fdatasync"
29794         check_lsom_data $DIR/$tfile
29795
29796         $TRUNCATE $DIR/$tfile 0
29797         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29798                 error "failed to write file $tfile with sync IO"
29799         check_lsom_data $DIR/$tfile
29800
29801         # verify truncate
29802         echo "Test SOM for truncate"
29803         # use ftruncate to sync blocks on close request
29804         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29805         check_lsom_size $DIR/$tfile 16384
29806         check_lsom_data $DIR/$tfile
29807
29808         $TRUNCATE $DIR/$tfile 1234
29809         check_lsom_size $DIR/$tfile 1234
29810         # sync blocks on the MDT
29811         $MULTIOP $DIR/$tfile oc
29812         check_lsom_data $DIR/$tfile
29813 }
29814 run_test 806 "Verify Lazy Size on MDS"
29815
29816 test_807() {
29817         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29818         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29819                 skip "Need MDS version at least 2.11.52"
29820
29821         # Registration step
29822         changelog_register || error "changelog_register failed"
29823         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29824         changelog_users $SINGLEMDS | grep -q $cl_user ||
29825                 error "User $cl_user not found in changelog_users"
29826
29827         rm -rf $DIR/$tdir || error "rm $tdir failed"
29828         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29829         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29830         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29831         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29832                 error "truncate $tdir/trunc failed"
29833
29834         local bs=1048576
29835         echo "Test SOM for single-threaded write with fsync"
29836         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29837                 error "write $tfile failed"
29838         sync;sync;sync
29839
29840         # multi-client wirtes
29841         local num=$(get_node_count ${CLIENTS//,/ })
29842         local offset=0
29843         local i=0
29844
29845         echo "Test SOM for multi-client ($num) writes"
29846         touch $DIR/$tfile || error "touch $tfile failed"
29847         $TRUNCATE $DIR/$tfile 0
29848         for client in ${CLIENTS//,/ }; do
29849                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29850                 local pids[$i]=$!
29851                 i=$((i + 1))
29852                 offset=$((offset + $bs))
29853         done
29854         for (( i=0; i < $num; i++ )); do
29855                 wait ${pids[$i]}
29856         done
29857
29858         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29859         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29860         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29861         check_lsom_data $DIR/$tdir/trunc
29862         check_lsom_data $DIR/$tdir/single_dd
29863         check_lsom_data $DIR/$tfile
29864
29865         rm -rf $DIR/$tdir
29866         # Deregistration step
29867         changelog_deregister || error "changelog_deregister failed"
29868 }
29869 run_test 807 "verify LSOM syncing tool"
29870
29871 check_som_nologged()
29872 {
29873         local lines=$($LFS changelog $FSNAME-MDT0000 |
29874                 grep 'x=trusted.som' | wc -l)
29875         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29876 }
29877
29878 test_808() {
29879         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29880                 skip "Need MDS version at least 2.11.55"
29881
29882         # Registration step
29883         changelog_register || error "changelog_register failed"
29884
29885         touch $DIR/$tfile || error "touch $tfile failed"
29886         check_som_nologged
29887
29888         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29889                 error "write $tfile failed"
29890         check_som_nologged
29891
29892         $TRUNCATE $DIR/$tfile 1234
29893         check_som_nologged
29894
29895         $TRUNCATE $DIR/$tfile 1048576
29896         check_som_nologged
29897
29898         # Deregistration step
29899         changelog_deregister || error "changelog_deregister failed"
29900 }
29901 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29902
29903 check_som_nodata()
29904 {
29905         $LFS getsom $1
29906         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29907 }
29908
29909 test_809() {
29910         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29911                 skip "Need MDS version at least 2.11.56"
29912
29913         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29914                 error "failed to create DoM-only file $DIR/$tfile"
29915         touch $DIR/$tfile || error "touch $tfile failed"
29916         check_som_nodata $DIR/$tfile
29917
29918         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29919                 error "write $tfile failed"
29920         check_som_nodata $DIR/$tfile
29921
29922         $TRUNCATE $DIR/$tfile 1234
29923         check_som_nodata $DIR/$tfile
29924
29925         $TRUNCATE $DIR/$tfile 4097
29926         check_som_nodata $DIR/$file
29927 }
29928 run_test 809 "Verify no SOM xattr store for DoM-only files"
29929
29930 test_810() {
29931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29932         $GSS && skip_env "could not run with gss"
29933         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29934                 skip "OST < 2.12.58 doesn't align checksum"
29935
29936         set_checksums 1
29937         stack_trap "set_checksums $ORIG_CSUM" EXIT
29938         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29939
29940         local csum
29941         local before
29942         local after
29943         for csum in $CKSUM_TYPES; do
29944                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29945                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29946                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29947                         eval set -- $i
29948                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29949                         before=$(md5sum $DIR/$tfile)
29950                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29951                         after=$(md5sum $DIR/$tfile)
29952                         [ "$before" == "$after" ] ||
29953                                 error "$csum: $before != $after bs=$1 seek=$2"
29954                 done
29955         done
29956 }
29957 run_test 810 "partial page writes on ZFS (LU-11663)"
29958
29959 test_812a() {
29960         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29961                 skip "OST < 2.12.51 doesn't support this fail_loc"
29962
29963         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29964         # ensure ost1 is connected
29965         stat $DIR/$tfile >/dev/null || error "can't stat"
29966         wait_osc_import_state client ost1 FULL
29967         # no locks, no reqs to let the connection idle
29968         cancel_lru_locks osc
29969
29970         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29971 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29972         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29973         wait_osc_import_state client ost1 CONNECTING
29974         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29975
29976         stat $DIR/$tfile >/dev/null || error "can't stat file"
29977 }
29978 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29979
29980 test_812b() { # LU-12378
29981         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29982                 skip "OST < 2.12.51 doesn't support this fail_loc"
29983
29984         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29985         # ensure ost1 is connected
29986         stat $DIR/$tfile >/dev/null || error "can't stat"
29987         wait_osc_import_state client ost1 FULL
29988         # no locks, no reqs to let the connection idle
29989         cancel_lru_locks osc
29990
29991         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29992 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29993         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29994         wait_osc_import_state client ost1 CONNECTING
29995         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29996
29997         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29998         wait_osc_import_state client ost1 IDLE
29999 }
30000 run_test 812b "do not drop no resend request for idle connect"
30001
30002 test_812c() {
30003         local old
30004
30005         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30006
30007         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30008         $LFS getstripe $DIR/$tfile
30009         $LCTL set_param osc.*.idle_timeout=10
30010         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30011         # ensure ost1 is connected
30012         stat $DIR/$tfile >/dev/null || error "can't stat"
30013         wait_osc_import_state client ost1 FULL
30014         # no locks, no reqs to let the connection idle
30015         cancel_lru_locks osc
30016
30017 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30018         $LCTL set_param fail_loc=0x80000533
30019         sleep 15
30020         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30021 }
30022 run_test 812c "idle import vs lock enqueue race"
30023
30024 test_813() {
30025         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30026         [ -z "$file_heat_sav" ] && skip "no file heat support"
30027
30028         local readsample
30029         local writesample
30030         local readbyte
30031         local writebyte
30032         local readsample1
30033         local writesample1
30034         local readbyte1
30035         local writebyte1
30036
30037         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30038         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30039
30040         $LCTL set_param -n llite.*.file_heat=1
30041         echo "Turn on file heat"
30042         echo "Period second: $period_second, Decay percentage: $decay_pct"
30043
30044         echo "QQQQ" > $DIR/$tfile
30045         echo "QQQQ" > $DIR/$tfile
30046         echo "QQQQ" > $DIR/$tfile
30047         cat $DIR/$tfile > /dev/null
30048         cat $DIR/$tfile > /dev/null
30049         cat $DIR/$tfile > /dev/null
30050         cat $DIR/$tfile > /dev/null
30051
30052         local out=$($LFS heat_get $DIR/$tfile)
30053
30054         $LFS heat_get $DIR/$tfile
30055         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30056         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30057         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30058         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30059
30060         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30061         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30062         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30063         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30064
30065         sleep $((period_second + 3))
30066         echo "Sleep $((period_second + 3)) seconds..."
30067         # The recursion formula to calculate the heat of the file f is as
30068         # follow:
30069         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30070         # Where Hi is the heat value in the period between time points i*I and
30071         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30072         # to the weight of Ci.
30073         out=$($LFS heat_get $DIR/$tfile)
30074         $LFS heat_get $DIR/$tfile
30075         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30076         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30077         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30078         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30079
30080         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30081                 error "read sample ($readsample) is wrong"
30082         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30083                 error "write sample ($writesample) is wrong"
30084         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30085                 error "read bytes ($readbyte) is wrong"
30086         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30087                 error "write bytes ($writebyte) is wrong"
30088
30089         echo "QQQQ" > $DIR/$tfile
30090         echo "QQQQ" > $DIR/$tfile
30091         echo "QQQQ" > $DIR/$tfile
30092         cat $DIR/$tfile > /dev/null
30093         cat $DIR/$tfile > /dev/null
30094         cat $DIR/$tfile > /dev/null
30095         cat $DIR/$tfile > /dev/null
30096
30097         sleep $((period_second + 3))
30098         echo "Sleep $((period_second + 3)) seconds..."
30099
30100         out=$($LFS heat_get $DIR/$tfile)
30101         $LFS heat_get $DIR/$tfile
30102         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30103         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30104         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30105         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30106
30107         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30108                 4 * $decay_pct) / 100") -eq 1 ] ||
30109                 error "read sample ($readsample1) is wrong"
30110         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30111                 3 * $decay_pct) / 100") -eq 1 ] ||
30112                 error "write sample ($writesample1) is wrong"
30113         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30114                 20 * $decay_pct) / 100") -eq 1 ] ||
30115                 error "read bytes ($readbyte1) is wrong"
30116         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30117                 15 * $decay_pct) / 100") -eq 1 ] ||
30118                 error "write bytes ($writebyte1) is wrong"
30119
30120         echo "Turn off file heat for the file $DIR/$tfile"
30121         $LFS heat_set -o $DIR/$tfile
30122
30123         echo "QQQQ" > $DIR/$tfile
30124         echo "QQQQ" > $DIR/$tfile
30125         echo "QQQQ" > $DIR/$tfile
30126         cat $DIR/$tfile > /dev/null
30127         cat $DIR/$tfile > /dev/null
30128         cat $DIR/$tfile > /dev/null
30129         cat $DIR/$tfile > /dev/null
30130
30131         out=$($LFS heat_get $DIR/$tfile)
30132         $LFS heat_get $DIR/$tfile
30133         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30134         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30135         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30136         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30137
30138         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30139         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30140         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30141         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30142
30143         echo "Trun on file heat for the file $DIR/$tfile"
30144         $LFS heat_set -O $DIR/$tfile
30145
30146         echo "QQQQ" > $DIR/$tfile
30147         echo "QQQQ" > $DIR/$tfile
30148         echo "QQQQ" > $DIR/$tfile
30149         cat $DIR/$tfile > /dev/null
30150         cat $DIR/$tfile > /dev/null
30151         cat $DIR/$tfile > /dev/null
30152         cat $DIR/$tfile > /dev/null
30153
30154         out=$($LFS heat_get $DIR/$tfile)
30155         $LFS heat_get $DIR/$tfile
30156         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30157         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30158         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30159         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30160
30161         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30162         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30163         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30164         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30165
30166         $LFS heat_set -c $DIR/$tfile
30167         $LCTL set_param -n llite.*.file_heat=0
30168         echo "Turn off file heat support for the Lustre filesystem"
30169
30170         echo "QQQQ" > $DIR/$tfile
30171         echo "QQQQ" > $DIR/$tfile
30172         echo "QQQQ" > $DIR/$tfile
30173         cat $DIR/$tfile > /dev/null
30174         cat $DIR/$tfile > /dev/null
30175         cat $DIR/$tfile > /dev/null
30176         cat $DIR/$tfile > /dev/null
30177
30178         out=$($LFS heat_get $DIR/$tfile)
30179         $LFS heat_get $DIR/$tfile
30180         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30181         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30182         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30183         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30184
30185         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30186         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30187         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30188         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30189
30190         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30191         rm -f $DIR/$tfile
30192 }
30193 run_test 813 "File heat verfication"
30194
30195 test_814()
30196 {
30197         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30198         echo -n y >> $DIR/$tfile
30199         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30200         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30201 }
30202 run_test 814 "sparse cp works as expected (LU-12361)"
30203
30204 test_815()
30205 {
30206         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30207         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30208 }
30209 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30210
30211 test_816() {
30212         local ost1_imp=$(get_osc_import_name client ost1)
30213         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30214                          cut -d'.' -f2)
30215
30216         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30217         # ensure ost1 is connected
30218
30219         stat $DIR/$tfile >/dev/null || error "can't stat"
30220         wait_osc_import_state client ost1 FULL
30221         # no locks, no reqs to let the connection idle
30222         cancel_lru_locks osc
30223         lru_resize_disable osc
30224         local before
30225         local now
30226         before=$($LCTL get_param -n \
30227                  ldlm.namespaces.$imp_name.lru_size)
30228
30229         wait_osc_import_state client ost1 IDLE
30230         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30231         now=$($LCTL get_param -n \
30232               ldlm.namespaces.$imp_name.lru_size)
30233         [ $before == $now ] || error "lru_size changed $before != $now"
30234 }
30235 run_test 816 "do not reset lru_resize on idle reconnect"
30236
30237 cleanup_817() {
30238         umount $tmpdir
30239         exportfs -u localhost:$DIR/nfsexp
30240         rm -rf $DIR/nfsexp
30241 }
30242
30243 test_817() {
30244         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30245
30246         mkdir -p $DIR/nfsexp
30247         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30248                 error "failed to export nfs"
30249
30250         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30251         stack_trap cleanup_817 EXIT
30252
30253         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30254                 error "failed to mount nfs to $tmpdir"
30255
30256         cp /bin/true $tmpdir
30257         $DIR/nfsexp/true || error "failed to execute 'true' command"
30258 }
30259 run_test 817 "nfsd won't cache write lock for exec file"
30260
30261 test_818() {
30262         test_mkdir -i0 -c1 $DIR/$tdir
30263         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30264         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30265         stop $SINGLEMDS
30266
30267         # restore osp-syn threads
30268         stack_trap "fail $SINGLEMDS"
30269
30270         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30271         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30272         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30273                 error "start $SINGLEMDS failed"
30274         rm -rf $DIR/$tdir
30275
30276         local testid=$(echo $TESTNAME | tr '_' ' ')
30277
30278         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30279                 grep "run LFSCK" || error "run LFSCK is not suggested"
30280 }
30281 run_test 818 "unlink with failed llog"
30282
30283 test_819a() {
30284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30285         cancel_lru_locks osc
30286         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30287         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30288         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30289         rm -f $TDIR/$tfile
30290 }
30291 run_test 819a "too big niobuf in read"
30292
30293 test_819b() {
30294         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30295         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30297         cancel_lru_locks osc
30298         sleep 1
30299         rm -f $TDIR/$tfile
30300 }
30301 run_test 819b "too big niobuf in write"
30302
30303
30304 function test_820_start_ost() {
30305         sleep 5
30306
30307         for num in $(seq $OSTCOUNT); do
30308                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30309         done
30310 }
30311
30312 test_820() {
30313         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30314
30315         mkdir $DIR/$tdir
30316         umount_client $MOUNT || error "umount failed"
30317         for num in $(seq $OSTCOUNT); do
30318                 stop ost$num
30319         done
30320
30321         # mount client with no active OSTs
30322         # so that the client can't initialize max LOV EA size
30323         # from OSC notifications
30324         mount_client $MOUNT || error "mount failed"
30325         # delay OST starting to keep this 0 max EA size for a while
30326         test_820_start_ost &
30327
30328         # create a directory on MDS2
30329         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30330                 error "Failed to create directory"
30331         # open intent should update default EA size
30332         # see mdc_update_max_ea_from_body()
30333         # notice this is the very first RPC to MDS2
30334         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30335         ret=$?
30336         echo $out
30337         # With SSK, this situation can lead to -EPERM being returned.
30338         # In that case, simply retry.
30339         if [ $ret -ne 0 ] && $SHARED_KEY; then
30340                 if echo "$out" | grep -q "not permitted"; then
30341                         cp /etc/services $DIR/$tdir/mds2
30342                         ret=$?
30343                 fi
30344         fi
30345         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30346 }
30347 run_test 820 "update max EA from open intent"
30348
30349 test_823() {
30350         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30351         local OST_MAX_PRECREATE=20000
30352
30353         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30354                 skip "Need MDS version at least 2.14.56"
30355
30356         save_lustre_params mds1 \
30357                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30358         do_facet $SINGLEMDS "$LCTL set_param -n \
30359                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30360         do_facet $SINGLEMDS "$LCTL set_param -n \
30361                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30362
30363         stack_trap "restore_lustre_params < $p; rm $p"
30364
30365         do_facet $SINGLEMDS "$LCTL set_param -n \
30366                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30367
30368         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30369                       osp.$FSNAME-OST0000*MDT0000.create_count")
30370         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30371                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30372         local expect_count=$(((($max/2)/256) * 256))
30373
30374         log "setting create_count to 100200:"
30375         log " -result- count: $count with max: $max, expecting: $expect_count"
30376
30377         [[ $count -eq expect_count ]] ||
30378                 error "Create count not set to max precreate."
30379 }
30380 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30381
30382 test_831() {
30383         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30384                 skip "Need MDS version 2.14.56"
30385
30386         local sync_changes=$(do_facet $SINGLEMDS \
30387                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30388
30389         [ "$sync_changes" -gt 100 ] &&
30390                 skip "Sync changes $sync_changes > 100 already"
30391
30392         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30393
30394         $LFS mkdir -i 0 $DIR/$tdir
30395         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30396
30397         save_lustre_params mds1 \
30398                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30399         save_lustre_params mds1 \
30400                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30401
30402         do_facet mds1 "$LCTL set_param -n \
30403                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30404                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30405         stack_trap "restore_lustre_params < $p" EXIT
30406
30407         createmany -o $DIR/$tdir/f- 1000
30408         unlinkmany $DIR/$tdir/f- 1000 &
30409         local UNLINK_PID=$!
30410
30411         while sleep 1; do
30412                 sync_changes=$(do_facet mds1 \
30413                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30414                 # the check in the code is racy, fail the test
30415                 # if the value above the limit by 10.
30416                 [ $sync_changes -gt 110 ] && {
30417                         kill -2 $UNLINK_PID
30418                         wait
30419                         error "osp changes throttling failed, $sync_changes>110"
30420                 }
30421                 kill -0 $UNLINK_PID 2> /dev/null || break
30422         done
30423         wait
30424 }
30425 run_test 831 "throttling unlink/setattr queuing on OSP"
30426
30427 test_832() {
30428         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30429         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30430                 skip "Need MDS version 2.15.52+"
30431         is_rmentry_supported || skip "rm_entry not supported"
30432
30433         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30434         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30435         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30436                 error "mkdir remote_dir failed"
30437         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30438                 error "mkdir striped_dir failed"
30439         touch $DIR/$tdir/file || error "touch file failed"
30440         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30441         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30442 }
30443 run_test 832 "lfs rm_entry"
30444
30445 test_833() {
30446         local file=$DIR/$tfile
30447
30448         stack_trap "rm -f $file" EXIT
30449         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30450
30451         local wpid
30452         local rpid
30453         local rpid2
30454
30455         # Buffered I/O write
30456         (
30457                 while [ ! -e $DIR/sanity.833.lck ]; do
30458                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30459                                 error "failed to write $file"
30460                         sleep 0.$((RANDOM % 4 + 1))
30461                 done
30462         )&
30463         wpid=$!
30464
30465         # Buffered I/O read
30466         (
30467                 while [ ! -e $DIR/sanity.833.lck ]; do
30468                         dd if=$file of=/dev/null bs=1M count=50 ||
30469                                 error "failed to read $file"
30470                         sleep 0.$((RANDOM % 4 + 1))
30471                 done
30472         )&
30473         rpid=$!
30474
30475         # Direct I/O read
30476         (
30477                 while [ ! -e $DIR/sanity.833.lck ]; do
30478                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30479                                 error "failed to read $file in direct I/O mode"
30480                         sleep 0.$((RANDOM % 4 + 1))
30481                 done
30482         )&
30483         rpid2=$!
30484
30485         sleep 30
30486         touch $DIR/sanity.833.lck
30487         wait $wpid || error "$?: buffered write failed"
30488         wait $rpid || error "$?: buffered read failed"
30489         wait $rpid2 || error "$?: direct read failed"
30490 }
30491 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30492
30493 #
30494 # tests that do cleanup/setup should be run at the end
30495 #
30496
30497 test_900() {
30498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30499         local ls
30500
30501         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30502         $LCTL set_param fail_loc=0x903
30503
30504         cancel_lru_locks MGC
30505
30506         FAIL_ON_ERROR=true cleanup
30507         FAIL_ON_ERROR=true setup
30508 }
30509 run_test 900 "umount should not race with any mgc requeue thread"
30510
30511 # LUS-6253/LU-11185
30512 test_901() {
30513         local old
30514         local count
30515         local oldc
30516         local newc
30517         local olds
30518         local news
30519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30520
30521         # some get_param have a bug to handle dot in param name
30522         cancel_lru_locks MGC
30523         old=$(mount -t lustre | wc -l)
30524         # 1 config+sptlrpc
30525         # 2 params
30526         # 3 nodemap
30527         # 4 IR
30528         old=$((old * 4))
30529         oldc=0
30530         count=0
30531         while [ $old -ne $oldc ]; do
30532                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30533                 sleep 1
30534                 ((count++))
30535                 if [ $count -ge $TIMEOUT ]; then
30536                         error "too large timeout"
30537                 fi
30538         done
30539         umount_client $MOUNT || error "umount failed"
30540         mount_client $MOUNT || error "mount failed"
30541         cancel_lru_locks MGC
30542         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30543
30544         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30545
30546         return 0
30547 }
30548 run_test 901 "don't leak a mgc lock on client umount"
30549
30550 # LU-13377
30551 test_902() {
30552         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30553                 skip "client does not have LU-13377 fix"
30554         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30555         $LCTL set_param fail_loc=0x1415
30556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30557         cancel_lru_locks osc
30558         rm -f $DIR/$tfile
30559 }
30560 run_test 902 "test short write doesn't hang lustre"
30561
30562 # LU-14711
30563 test_903() {
30564         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30565         echo "blah" > $DIR/${tfile}-2
30566         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30567         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30568         $LCTL set_param fail_loc=0x417 fail_val=20
30569
30570         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30571         sleep 1 # To start the destroy
30572         wait_destroy_complete 150 || error "Destroy taking too long"
30573         cat $DIR/$tfile > /dev/null || error "Evicted"
30574 }
30575 run_test 903 "Test long page discard does not cause evictions"
30576
30577 test_904() {
30578         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30579         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30580                 grep -q project || skip "skip project quota not supported"
30581
30582         local testfile="$DIR/$tdir/$tfile"
30583         local xattr="trusted.projid"
30584         local projid
30585         local mdts=$(comma_list $(mdts_nodes))
30586         local saved=$(do_facet mds1 $LCTL get_param -n \
30587                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30588
30589         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30590         stack_trap "do_nodes $mdts $LCTL set_param \
30591                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30592
30593         mkdir -p $DIR/$tdir
30594         touch $testfile
30595         #hide projid xattr on server
30596         $LFS project -p 1 $testfile ||
30597                 error "set $testfile project id failed"
30598         getfattr -m - $testfile | grep $xattr &&
30599                 error "do not show trusted.projid when disabled on server"
30600         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30601         #should be hidden when projid is 0
30602         $LFS project -p 0 $testfile ||
30603                 error "set $testfile project id failed"
30604         getfattr -m - $testfile | grep $xattr &&
30605                 error "do not show trusted.projid with project ID 0"
30606
30607         #still can getxattr explicitly
30608         projid=$(getfattr -n $xattr $testfile |
30609                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30610         [ $projid == "0" ] ||
30611                 error "projid expected 0 not $projid"
30612
30613         #set the projid via setxattr
30614         setfattr -n $xattr -v "1000" $testfile ||
30615                 error "setattr failed with $?"
30616         projid=($($LFS project $testfile))
30617         [ ${projid[0]} == "1000" ] ||
30618                 error "projid expected 1000 not $projid"
30619
30620         #check the new projid via getxattr
30621         $LFS project -p 1001 $testfile ||
30622                 error "set $testfile project id failed"
30623         getfattr -m - $testfile | grep $xattr ||
30624                 error "should show trusted.projid when project ID != 0"
30625         projid=$(getfattr -n $xattr $testfile |
30626                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30627         [ $projid == "1001" ] ||
30628                 error "projid expected 1001 not $projid"
30629
30630         #try to set invalid projid
30631         setfattr -n $xattr -v "4294967295" $testfile &&
30632                 error "set invalid projid should fail"
30633
30634         #remove the xattr means setting projid to 0
30635         setfattr -x $xattr $testfile ||
30636                 error "setfattr failed with $?"
30637         projid=($($LFS project $testfile))
30638         [ ${projid[0]} == "0" ] ||
30639                 error "projid expected 0 not $projid"
30640
30641         #should be hidden when parent has inherit flag and same projid
30642         $LFS project -srp 1002 $DIR/$tdir ||
30643                 error "set $tdir project id failed"
30644         getfattr -m - $testfile | grep $xattr &&
30645                 error "do not show trusted.projid with inherit flag"
30646
30647         #still can getxattr explicitly
30648         projid=$(getfattr -n $xattr $testfile |
30649                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30650         [ $projid == "1002" ] ||
30651                 error "projid expected 1002 not $projid"
30652 }
30653 run_test 904 "virtual project ID xattr"
30654
30655 # LU-8582
30656 test_905() {
30657         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30658                 skip "need OST version >= 2.15.50.220 for fail_loc"
30659
30660         remote_ost_nodsh && skip "remote OST with nodsh"
30661         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30662
30663         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30664
30665         #define OBD_FAIL_OST_OPCODE 0x253
30666         # OST_LADVISE = 21
30667         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30668         $LFS ladvise -a willread $DIR/$tfile &&
30669                 error "unexpected success of ladvise with fault injection"
30670         $LFS ladvise -a willread $DIR/$tfile |&
30671                 grep -q "Operation not supported"
30672         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30673 }
30674 run_test 905 "bad or new opcode should not stuck client"
30675
30676 test_906() {
30677         grep -q io_uring_setup /proc/kallsyms ||
30678                 skip "Client OS does not support io_uring I/O engine"
30679         io_uring_probe || skip "kernel does not support io_uring fully"
30680         which fio || skip_env "no fio installed"
30681         fio --enghelp | grep -q io_uring ||
30682                 skip_env "fio does not support io_uring I/O engine"
30683
30684         local file=$DIR/$tfile
30685         local ioengine="io_uring"
30686         local numjobs=2
30687         local size=50M
30688
30689         fio --name=seqwrite --ioengine=$ioengine        \
30690                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30691                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30692                 error "fio seqwrite $file failed"
30693
30694         fio --name=seqread --ioengine=$ioengine \
30695                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30696                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30697                 error "fio seqread $file failed"
30698
30699         rm -f $file || error "rm -f $file failed"
30700 }
30701 run_test 906 "Simple test for io_uring I/O engine via fio"
30702
30703 complete_test $SECONDS
30704 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30705 check_and_cleanup_lustre
30706 if [ "$I_MOUNTED" != "yes" ]; then
30707         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30708 fi
30709 exit_status