Whamcloud - gitweb
a4861217337c3126592f3e06d99d6cb06ba28d63
[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         # Testing that buffered IO consumes grant on the client
9640
9641         # Delay the RPC on the server so it's guaranteed to not complete even
9642         # if the RPC is sent from the client
9643         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9644         $LCTL set_param fail_loc=0x50a fail_val=3
9645         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9646                 error "error writing to $DIR/$tfile with buffered IO"
9647
9648         check_grants $osc_tgt $((init_grants - grants)) \
9649                 "buffered io, not write rpc"
9650
9651         # Clear the fail loc and do a sync on the client
9652         $LCTL set_param fail_loc=0 fail_val=0
9653         sync
9654
9655         # RPC is now known to have sent
9656         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9657                 "buffered io, one RPC"
9658 }
9659 run_test 64f "check grant consumption (with grant allocation)"
9660
9661 test_64g() {
9662         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9663                 skip "Need MDS version at least 2.14.56"
9664
9665         local mdts=$(comma_list $(mdts_nodes))
9666
9667         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9668                         tr '\n' ' ')
9669         stack_trap "$LCTL set_param $old"
9670
9671         # generate dirty pages and increase dirty granted on MDT
9672         stack_trap "rm -f $DIR/$tfile-*"
9673         for (( i = 0; i < 10; i++)); do
9674                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9675                         error "can't set stripe"
9676                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9677                         error "can't dd"
9678                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9679                         $LFS getstripe $DIR/$tfile-$i
9680                         error "not DoM file"
9681                 }
9682         done
9683
9684         # flush dirty pages
9685         sync
9686
9687         # wait until grant shrink reset grant dirty on MDTs
9688         for ((i = 0; i < 120; i++)); do
9689                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9690                         awk '{sum=sum+$1} END {print sum}')
9691                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9692                 echo "$grant_dirty grants, $vm_dirty pages"
9693                 (( grant_dirty + vm_dirty == 0 )) && break
9694                 (( i == 3 )) && sync &&
9695                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9696                 sleep 1
9697         done
9698
9699         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9700                 awk '{sum=sum+$1} END {print sum}')
9701         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9702 }
9703 run_test 64g "grant shrink on MDT"
9704
9705 test_64h() {
9706         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9707                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9708
9709         local instance=$($LFS getname -i $DIR)
9710         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9711         local num_exps=$(do_facet ost1 \
9712             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9713         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9714         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9715         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9716
9717         # 10MiB is for file to be written, max_brw_size * 16 *
9718         # num_exps is space reserve so that tgt_grant_shrink() decided
9719         # to not shrink
9720         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9721         (( avail * 1024 < expect )) &&
9722                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9723
9724         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9725         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9726         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9727         $LCTL set_param osc.*OST0000*.grant_shrink=1
9728         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9729
9730         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9731         stack_trap "rm -f $DIR/$tfile"
9732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9733
9734         # drop cache so that coming read would do rpc
9735         cancel_lru_locks osc
9736
9737         # shrink interval is set to 10, pause for 7 seconds so that
9738         # grant thread did not wake up yet but coming read entered
9739         # shrink mode for rpc (osc_should_shrink_grant())
9740         sleep 7
9741
9742         declare -a cur_grant_bytes
9743         declare -a tot_granted
9744         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9745         tot_granted[0]=$(do_facet ost1 \
9746             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9747
9748         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9749
9750         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9751         tot_granted[1]=$(do_facet ost1 \
9752             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9753
9754         # grant change should be equal on both sides
9755         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9756                 tot_granted[0] - tot_granted[1])) ||
9757                 error "grant change mismatch, "                                \
9758                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9759                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9760 }
9761 run_test 64h "grant shrink on read"
9762
9763 test_64i() {
9764         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9765                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9766
9767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9768         remote_ost_nodsh && skip "remote OSTs with nodsh"
9769
9770         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9771         stack_trap "rm -f $DIR/$tfile"
9772
9773         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9774
9775         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9776         local instance=$($LFS getname -i $DIR)
9777
9778         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9779         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9780
9781         # shrink grants and simulate rpc loss
9782         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9783         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9784         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9785
9786         fail ost1
9787
9788         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9789
9790         local testid=$(echo $TESTNAME | tr '_' ' ')
9791
9792         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9793                 grep "GRANT, real grant" &&
9794                 error "client has more grants then it owns" || true
9795 }
9796 run_test 64i "shrink on reconnect"
9797
9798 # bug 1414 - set/get directories' stripe info
9799 test_65a() {
9800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9801
9802         test_mkdir $DIR/$tdir
9803         touch $DIR/$tdir/f1
9804         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9805 }
9806 run_test 65a "directory with no stripe info"
9807
9808 test_65b() {
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         test_mkdir $DIR/$tdir
9812         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9813
9814         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9815                                                 error "setstripe"
9816         touch $DIR/$tdir/f2
9817         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9818 }
9819 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9820
9821 test_65c() {
9822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9823         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9824
9825         test_mkdir $DIR/$tdir
9826         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9827
9828         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9829                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9830         touch $DIR/$tdir/f3
9831         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9832 }
9833 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9834
9835 test_65d() {
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837
9838         test_mkdir $DIR/$tdir
9839         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9840         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9841
9842         if [[ $STRIPECOUNT -le 0 ]]; then
9843                 sc=1
9844         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9845                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9846                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9847         else
9848                 sc=$(($STRIPECOUNT - 1))
9849         fi
9850         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9851         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9852         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9853                 error "lverify failed"
9854 }
9855 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9856
9857 test_65e() {
9858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9859
9860         # LU-16904 delete layout when root is set as PFL layout
9861         save_layout_restore_at_exit $MOUNT
9862         $LFS setstripe -d $MOUNT || error "setstripe failed"
9863
9864         test_mkdir $DIR/$tdir
9865
9866         $LFS setstripe $DIR/$tdir || error "setstripe"
9867         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9868                                         error "no stripe info failed"
9869         touch $DIR/$tdir/f6
9870         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9871 }
9872 run_test 65e "directory setstripe defaults"
9873
9874 test_65f() {
9875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9876
9877         test_mkdir $DIR/${tdir}f
9878         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9879                 error "setstripe succeeded" || true
9880 }
9881 run_test 65f "dir setstripe permission (should return error) ==="
9882
9883 test_65g() {
9884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9885
9886         # LU-16904 delete layout when root is set as PFL layout
9887         save_layout_restore_at_exit $MOUNT
9888         $LFS setstripe -d $MOUNT || error "setstripe failed"
9889
9890         test_mkdir $DIR/$tdir
9891         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9892
9893         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9894                 error "setstripe -S failed"
9895         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9896         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9897                 error "delete default stripe failed"
9898 }
9899 run_test 65g "directory setstripe -d"
9900
9901 test_65h() {
9902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9903
9904         test_mkdir $DIR/$tdir
9905         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9906
9907         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9908                 error "setstripe -S failed"
9909         test_mkdir $DIR/$tdir/dd1
9910         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9911                 error "stripe info inherit failed"
9912 }
9913 run_test 65h "directory stripe info inherit ===================="
9914
9915 test_65i() {
9916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9917
9918         save_layout_restore_at_exit $MOUNT
9919
9920         # bug6367: set non-default striping on root directory
9921         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9922
9923         # bug12836: getstripe on -1 default directory striping
9924         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9925
9926         # bug12836: getstripe -v on -1 default directory striping
9927         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9928
9929         # bug12836: new find on -1 default directory striping
9930         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9931 }
9932 run_test 65i "various tests to set root directory striping"
9933
9934 test_65j() { # bug6367
9935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9936
9937         sync; sleep 1
9938
9939         # if we aren't already remounting for each test, do so for this test
9940         if [ "$I_MOUNTED" = "yes" ]; then
9941                 cleanup || error "failed to unmount"
9942                 setup
9943         fi
9944
9945         save_layout_restore_at_exit $MOUNT
9946
9947         $LFS setstripe -d $MOUNT || error "setstripe failed"
9948 }
9949 run_test 65j "set default striping on root directory (bug 6367)="
9950
9951 cleanup_65k() {
9952         rm -rf $DIR/$tdir
9953         wait_delete_completed
9954         do_facet $SINGLEMDS "lctl set_param -n \
9955                 osp.$ost*MDT0000.max_create_count=$max_count"
9956         do_facet $SINGLEMDS "lctl set_param -n \
9957                 osp.$ost*MDT0000.create_count=$count"
9958         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9959         echo $INACTIVE_OSC "is Activate"
9960
9961         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9962 }
9963
9964 test_65k() { # bug11679
9965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9966         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9967         remote_mds_nodsh && skip "remote MDS with nodsh"
9968
9969         local disable_precreate=true
9970         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9971                 disable_precreate=false
9972
9973         echo "Check OST status: "
9974         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9975                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9976
9977         for OSC in $MDS_OSCS; do
9978                 echo $OSC "is active"
9979                 do_facet $SINGLEMDS lctl --device %$OSC activate
9980         done
9981
9982         for INACTIVE_OSC in $MDS_OSCS; do
9983                 local ost=$(osc_to_ost $INACTIVE_OSC)
9984                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9985                                lov.*md*.target_obd |
9986                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9987
9988                 mkdir -p $DIR/$tdir
9989                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9990                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9991
9992                 echo "Deactivate: " $INACTIVE_OSC
9993                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9994
9995                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9996                               osp.$ost*MDT0000.create_count")
9997                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9998                                   osp.$ost*MDT0000.max_create_count")
9999                 $disable_precreate &&
10000                         do_facet $SINGLEMDS "lctl set_param -n \
10001                                 osp.$ost*MDT0000.max_create_count=0"
10002
10003                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10004                         [ -f $DIR/$tdir/$idx ] && continue
10005                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10006                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10007                                 { cleanup_65k;
10008                                   error "setstripe $idx should succeed"; }
10009                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10010                 done
10011                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10012                 rmdir $DIR/$tdir
10013
10014                 do_facet $SINGLEMDS "lctl set_param -n \
10015                         osp.$ost*MDT0000.max_create_count=$max_count"
10016                 do_facet $SINGLEMDS "lctl set_param -n \
10017                         osp.$ost*MDT0000.create_count=$count"
10018                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10019                 echo $INACTIVE_OSC "is Activate"
10020
10021                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10022         done
10023 }
10024 run_test 65k "validate manual striping works properly with deactivated OSCs"
10025
10026 test_65l() { # bug 12836
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028
10029         test_mkdir -p $DIR/$tdir/test_dir
10030         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10031         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10032 }
10033 run_test 65l "lfs find on -1 stripe dir ========================"
10034
10035 test_65m() {
10036         local layout=$(save_layout $MOUNT)
10037         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10038                 restore_layout $MOUNT $layout
10039                 error "setstripe should fail by non-root users"
10040         }
10041         true
10042 }
10043 run_test 65m "normal user can't set filesystem default stripe"
10044
10045 test_65n() {
10046         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10047         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10048                 skip "Need MDS version at least 2.12.50"
10049         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10050
10051         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10052         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10053         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10054
10055         save_layout_restore_at_exit $MOUNT
10056
10057         # new subdirectory under root directory should not inherit
10058         # the default layout from root
10059         # LU-16904 check if the root is set as PFL layout
10060         local numcomp=$($LFS getstripe --component-count $MOUNT)
10061
10062         if [[ $numcomp -eq 0 ]]; then
10063                 local dir1=$MOUNT/$tdir-1
10064                 mkdir $dir1 || error "mkdir $dir1 failed"
10065                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10066                         error "$dir1 shouldn't have LOV EA"
10067         fi
10068
10069         # delete the default layout on root directory
10070         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10071
10072         local dir2=$MOUNT/$tdir-2
10073         mkdir $dir2 || error "mkdir $dir2 failed"
10074         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10075                 error "$dir2 shouldn't have LOV EA"
10076
10077         # set a new striping pattern on root directory
10078         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10079         local new_def_stripe_size=$((def_stripe_size * 2))
10080         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10081                 error "set stripe size on $MOUNT failed"
10082
10083         # new file created in $dir2 should inherit the new stripe size from
10084         # the filesystem default
10085         local file2=$dir2/$tfile-2
10086         touch $file2 || error "touch $file2 failed"
10087
10088         local file2_stripe_size=$($LFS getstripe -S $file2)
10089         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10090         {
10091                 echo "file2_stripe_size: '$file2_stripe_size'"
10092                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10093                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10094         }
10095
10096         local dir3=$MOUNT/$tdir-3
10097         mkdir $dir3 || error "mkdir $dir3 failed"
10098         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10099         # the root layout, which is the actual default layout that will be used
10100         # when new files are created in $dir3.
10101         local dir3_layout=$(get_layout_param $dir3)
10102         local root_dir_layout=$(get_layout_param $MOUNT)
10103         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10104         {
10105                 echo "dir3_layout: '$dir3_layout'"
10106                 echo "root_dir_layout: '$root_dir_layout'"
10107                 error "$dir3 should show the default layout from $MOUNT"
10108         }
10109
10110         # set OST pool on root directory
10111         local pool=$TESTNAME
10112         pool_add $pool || error "add $pool failed"
10113         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10114                 error "add targets to $pool failed"
10115
10116         $LFS setstripe -p $pool $MOUNT ||
10117                 error "set OST pool on $MOUNT failed"
10118
10119         # new file created in $dir3 should inherit the pool from
10120         # the filesystem default
10121         local file3=$dir3/$tfile-3
10122         touch $file3 || error "touch $file3 failed"
10123
10124         local file3_pool=$($LFS getstripe -p $file3)
10125         [[ "$file3_pool" = "$pool" ]] ||
10126                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10127
10128         local dir4=$MOUNT/$tdir-4
10129         mkdir $dir4 || error "mkdir $dir4 failed"
10130         local dir4_layout=$(get_layout_param $dir4)
10131         root_dir_layout=$(get_layout_param $MOUNT)
10132         echo "$LFS getstripe -d $dir4"
10133         $LFS getstripe -d $dir4
10134         echo "$LFS getstripe -d $MOUNT"
10135         $LFS getstripe -d $MOUNT
10136         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10137         {
10138                 echo "dir4_layout: '$dir4_layout'"
10139                 echo "root_dir_layout: '$root_dir_layout'"
10140                 error "$dir4 should show the default layout from $MOUNT"
10141         }
10142
10143         # new file created in $dir4 should inherit the pool from
10144         # the filesystem default
10145         local file4=$dir4/$tfile-4
10146         touch $file4 || error "touch $file4 failed"
10147
10148         local file4_pool=$($LFS getstripe -p $file4)
10149         [[ "$file4_pool" = "$pool" ]] ||
10150                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10151
10152         # new subdirectory under non-root directory should inherit
10153         # the default layout from its parent directory
10154         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10155                 error "set directory layout on $dir4 failed"
10156
10157         local dir5=$dir4/$tdir-5
10158         mkdir $dir5 || error "mkdir $dir5 failed"
10159
10160         dir4_layout=$(get_layout_param $dir4)
10161         local dir5_layout=$(get_layout_param $dir5)
10162         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10163         {
10164                 echo "dir4_layout: '$dir4_layout'"
10165                 echo "dir5_layout: '$dir5_layout'"
10166                 error "$dir5 should inherit the default layout from $dir4"
10167         }
10168
10169         # though subdir under ROOT doesn't inherit default layout, but
10170         # its sub dir/file should be created with default layout.
10171         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10172         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10173                 skip "Need MDS version at least 2.12.59"
10174
10175         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10176         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10177         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10178
10179         if [ $default_lmv_hash == "none" ]; then
10180                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10181         else
10182                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10183                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10184         fi
10185
10186         $LFS setdirstripe -D -c 2 $MOUNT ||
10187                 error "setdirstripe -D -c 2 failed"
10188         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10189         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10190         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10191
10192         # $dir4 layout includes pool
10193         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10194         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10195                 error "pool lost on setstripe"
10196         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10197         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10198                 error "pool lost on compound layout setstripe"
10199 }
10200 run_test 65n "don't inherit default layout from root for new subdirectories"
10201
10202 test_65o() {
10203         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10204                 skip "need MDS version at least 2.14.57"
10205
10206         # set OST pool on root directory
10207         local pool=$TESTNAME
10208
10209         pool_add $pool || error "add $pool failed"
10210         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10211                 error "add targets to $pool failed"
10212
10213         local dir1=$MOUNT/$tdir
10214
10215         mkdir $dir1 || error "mkdir $dir1 failed"
10216
10217         # set a new striping pattern on root directory
10218         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10219
10220         $LFS setstripe -p $pool $dir1 ||
10221                 error "set directory layout on $dir1 failed"
10222
10223         # $dir1 layout includes pool
10224         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10225         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10226                 error "pool lost on setstripe"
10227         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10228         $LFS getstripe $dir1
10229         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10230                 error "pool lost on compound layout setstripe"
10231
10232         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10233                 error "setdirstripe failed on sub-dir with inherited pool"
10234         $LFS getstripe $dir1/dir2
10235         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10236                 error "pool lost on compound layout setdirstripe"
10237
10238         $LFS setstripe -E -1 -c 1 $dir1
10239         $LFS getstripe -d $dir1
10240         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10241                 error "pool lost on setstripe"
10242 }
10243 run_test 65o "pool inheritance for mdt component"
10244
10245 test_65p () { # LU-16152
10246         local src_dir=$DIR/$tdir/src_dir
10247         local dst_dir=$DIR/$tdir/dst_dir
10248         local yaml_file=$DIR/$tdir/layout.yaml
10249         local border
10250
10251         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10252                 skip "Need at least version 2.15.51"
10253
10254         test_mkdir -p $src_dir
10255         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10256                 error "failed to setstripe"
10257         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10258                 error "failed to getstripe"
10259
10260         test_mkdir -p $dst_dir
10261         $LFS setstripe --yaml $yaml_file $dst_dir ||
10262                 error "failed to setstripe with yaml file"
10263         border=$($LFS getstripe -d $dst_dir |
10264                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10265                 error "failed to getstripe"
10266
10267         # 2048M is 0x80000000, or 2147483648
10268         (( $border == 2147483648 )) ||
10269                 error "failed to handle huge number in yaml layout"
10270 }
10271 run_test 65p "setstripe with yaml file and huge number"
10272
10273 # bug 2543 - update blocks count on client
10274 test_66() {
10275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10276
10277         local COUNT=${COUNT:-8}
10278         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10279         sync; sync_all_data; sync; sync_all_data
10280         cancel_lru_locks osc
10281         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10282         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10283 }
10284 run_test 66 "update inode blocks count on client ==============="
10285
10286 meminfo() {
10287         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10288 }
10289
10290 swap_used() {
10291         swapon -s | awk '($1 == "'$1'") { print $4 }'
10292 }
10293
10294 # bug5265, obdfilter oa2dentry return -ENOENT
10295 # #define OBD_FAIL_SRV_ENOENT 0x217
10296 test_69() {
10297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10298         remote_ost_nodsh && skip "remote OST with nodsh"
10299
10300         f="$DIR/$tfile"
10301         $LFS setstripe -c 1 -i 0 $f
10302         stack_trap "rm -f $f ${f}.2"
10303
10304         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10305
10306         do_facet ost1 lctl set_param fail_loc=0x217
10307         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10308         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10309
10310         do_facet ost1 lctl set_param fail_loc=0
10311         $DIRECTIO write $f 0 2 || error "write error"
10312
10313         cancel_lru_locks osc
10314         $DIRECTIO read $f 0 1 || error "read error"
10315
10316         do_facet ost1 lctl set_param fail_loc=0x217
10317         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10318
10319         do_facet ost1 lctl set_param fail_loc=0
10320 }
10321 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10322
10323 test_71() {
10324         test_mkdir $DIR/$tdir
10325         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10326         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10327 }
10328 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10329
10330 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332         [ "$RUNAS_ID" = "$UID" ] &&
10333                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10334         # Check that testing environment is properly set up. Skip if not
10335         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10336                 skip_env "User $RUNAS_ID does not exist - skipping"
10337
10338         touch $DIR/$tfile
10339         chmod 777 $DIR/$tfile
10340         chmod ug+s $DIR/$tfile
10341         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10342                 error "$RUNAS dd $DIR/$tfile failed"
10343         # See if we are still setuid/sgid
10344         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10345                 error "S/gid is not dropped on write"
10346         # Now test that MDS is updated too
10347         cancel_lru_locks mdc
10348         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10349                 error "S/gid is not dropped on MDS"
10350         rm -f $DIR/$tfile
10351 }
10352 run_test 72a "Test that remove suid works properly (bug5695) ===="
10353
10354 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10355         local perm
10356
10357         [ "$RUNAS_ID" = "$UID" ] &&
10358                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10359         [ "$RUNAS_ID" -eq 0 ] &&
10360                 skip_env "RUNAS_ID = 0 -- skipping"
10361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10362         # Check that testing environment is properly set up. Skip if not
10363         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10364                 skip_env "User $RUNAS_ID does not exist - skipping"
10365
10366         touch $DIR/${tfile}-f{g,u}
10367         test_mkdir $DIR/${tfile}-dg
10368         test_mkdir $DIR/${tfile}-du
10369         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10370         chmod g+s $DIR/${tfile}-{f,d}g
10371         chmod u+s $DIR/${tfile}-{f,d}u
10372         for perm in 777 2777 4777; do
10373                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10374                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10375                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10376                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10377         done
10378         true
10379 }
10380 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10381
10382 # bug 3462 - multiple simultaneous MDC requests
10383 test_73() {
10384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10385
10386         test_mkdir $DIR/d73-1
10387         test_mkdir $DIR/d73-2
10388         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10389         pid1=$!
10390
10391         lctl set_param fail_loc=0x80000129
10392         $MULTIOP $DIR/d73-1/f73-2 Oc &
10393         sleep 1
10394         lctl set_param fail_loc=0
10395
10396         $MULTIOP $DIR/d73-2/f73-3 Oc &
10397         pid3=$!
10398
10399         kill -USR1 $pid1
10400         wait $pid1 || return 1
10401
10402         sleep 25
10403
10404         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10405         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10406         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10407
10408         rm -rf $DIR/d73-*
10409 }
10410 run_test 73 "multiple MDC requests (should not deadlock)"
10411
10412 test_74a() { # bug 6149, 6184
10413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10414
10415         touch $DIR/f74a
10416         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10417         #
10418         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10419         # will spin in a tight reconnection loop
10420         $LCTL set_param fail_loc=0x8000030e
10421         # get any lock that won't be difficult - lookup works.
10422         ls $DIR/f74a
10423         $LCTL set_param fail_loc=0
10424         rm -f $DIR/f74a
10425         true
10426 }
10427 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10428
10429 test_74b() { # bug 13310
10430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10431
10432         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10433         #
10434         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10435         # will spin in a tight reconnection loop
10436         $LCTL set_param fail_loc=0x8000030e
10437         # get a "difficult" lock
10438         touch $DIR/f74b
10439         $LCTL set_param fail_loc=0
10440         rm -f $DIR/f74b
10441         true
10442 }
10443 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10444
10445 test_74c() {
10446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10447
10448         #define OBD_FAIL_LDLM_NEW_LOCK
10449         $LCTL set_param fail_loc=0x319
10450         touch $DIR/$tfile && error "touch successful"
10451         $LCTL set_param fail_loc=0
10452         true
10453 }
10454 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10455
10456 slab_lic=/sys/kernel/slab/lustre_inode_cache
10457 num_objects() {
10458         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10459         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10460                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10461 }
10462
10463 test_76a() { # Now for b=20433, added originally in b=1443
10464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10465
10466         cancel_lru_locks osc
10467         # there may be some slab objects cached per core
10468         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10469         local before=$(num_objects)
10470         local count=$((512 * cpus))
10471         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10472         local margin=$((count / 10))
10473         if [[ -f $slab_lic/aliases ]]; then
10474                 local aliases=$(cat $slab_lic/aliases)
10475                 (( aliases > 0 )) && margin=$((margin * aliases))
10476         fi
10477
10478         echo "before slab objects: $before"
10479         for i in $(seq $count); do
10480                 touch $DIR/$tfile
10481                 rm -f $DIR/$tfile
10482         done
10483         cancel_lru_locks osc
10484         local after=$(num_objects)
10485         echo "created: $count, after slab objects: $after"
10486         # shared slab counts are not very accurate, allow significant margin
10487         # the main goal is that the cache growth is not permanently > $count
10488         while (( after > before + margin )); do
10489                 sleep 1
10490                 after=$(num_objects)
10491                 wait=$((wait + 1))
10492                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10493                 if (( wait > 60 )); then
10494                         error "inode slab grew from $before+$margin to $after"
10495                 fi
10496         done
10497 }
10498 run_test 76a "confirm clients recycle inodes properly ===="
10499
10500 test_76b() {
10501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10502         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10503
10504         local count=512
10505         local before=$(num_objects)
10506
10507         for i in $(seq $count); do
10508                 mkdir $DIR/$tdir
10509                 rmdir $DIR/$tdir
10510         done
10511
10512         local after=$(num_objects)
10513         local wait=0
10514
10515         while (( after > before )); do
10516                 sleep 1
10517                 after=$(num_objects)
10518                 wait=$((wait + 1))
10519                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10520                 if (( wait > 60 )); then
10521                         error "inode slab grew from $before to $after"
10522                 fi
10523         done
10524
10525         echo "slab objects before: $before, after: $after"
10526 }
10527 run_test 76b "confirm clients recycle directory inodes properly ===="
10528
10529 export ORIG_CSUM=""
10530 set_checksums()
10531 {
10532         # Note: in sptlrpc modes which enable its own bulk checksum, the
10533         # original crc32_le bulk checksum will be automatically disabled,
10534         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10535         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10536         # In this case set_checksums() will not be no-op, because sptlrpc
10537         # bulk checksum will be enabled all through the test.
10538
10539         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10540         lctl set_param -n osc.*.checksums $1
10541         return 0
10542 }
10543
10544 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10545                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10546 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10547                              tr -d [] | head -n1)}
10548 set_checksum_type()
10549 {
10550         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10551         rc=$?
10552         log "set checksum type to $1, rc = $rc"
10553         return $rc
10554 }
10555
10556 get_osc_checksum_type()
10557 {
10558         # arugment 1: OST name, like OST0000
10559         ost=$1
10560         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10561                         sed 's/.*\[\(.*\)\].*/\1/g')
10562         rc=$?
10563         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10564         echo $checksum_type
10565 }
10566
10567 F77_TMP=$TMP/f77-temp
10568 F77SZ=8
10569 setup_f77() {
10570         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10571                 error "error writing to $F77_TMP"
10572 }
10573
10574 test_77a() { # bug 10889
10575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10576         $GSS && skip_env "could not run with gss"
10577
10578         [ ! -f $F77_TMP ] && setup_f77
10579         set_checksums 1
10580         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10581         set_checksums 0
10582         rm -f $DIR/$tfile
10583 }
10584 run_test 77a "normal checksum read/write operation"
10585
10586 test_77b() { # bug 10889
10587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10588         $GSS && skip_env "could not run with gss"
10589
10590         [ ! -f $F77_TMP ] && setup_f77
10591         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10592         $LCTL set_param fail_loc=0x80000409
10593         set_checksums 1
10594
10595         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10596                 error "dd error: $?"
10597         $LCTL set_param fail_loc=0
10598
10599         for algo in $CKSUM_TYPES; do
10600                 cancel_lru_locks osc
10601                 set_checksum_type $algo
10602                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10603                 $LCTL set_param fail_loc=0x80000408
10604                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10605                 $LCTL set_param fail_loc=0
10606         done
10607         set_checksums 0
10608         set_checksum_type $ORIG_CSUM_TYPE
10609         rm -f $DIR/$tfile
10610 }
10611 run_test 77b "checksum error on client write, read"
10612
10613 cleanup_77c() {
10614         trap 0
10615         set_checksums 0
10616         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10617         $check_ost &&
10618                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10619         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10620         $check_ost && [ -n "$ost_file_prefix" ] &&
10621                 do_facet ost1 rm -f ${ost_file_prefix}\*
10622 }
10623
10624 test_77c() {
10625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10626         $GSS && skip_env "could not run with gss"
10627         remote_ost_nodsh && skip "remote OST with nodsh"
10628
10629         local bad1
10630         local osc_file_prefix
10631         local osc_file
10632         local check_ost=false
10633         local ost_file_prefix
10634         local ost_file
10635         local orig_cksum
10636         local dump_cksum
10637         local fid
10638
10639         # ensure corruption will occur on first OSS/OST
10640         $LFS setstripe -i 0 $DIR/$tfile
10641
10642         [ ! -f $F77_TMP ] && setup_f77
10643         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10644                 error "dd write error: $?"
10645         fid=$($LFS path2fid $DIR/$tfile)
10646
10647         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10648         then
10649                 check_ost=true
10650                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10651                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10652         else
10653                 echo "OSS do not support bulk pages dump upon error"
10654         fi
10655
10656         osc_file_prefix=$($LCTL get_param -n debug_path)
10657         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10658
10659         trap cleanup_77c EXIT
10660
10661         set_checksums 1
10662         # enable bulk pages dump upon error on Client
10663         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10664         # enable bulk pages dump upon error on OSS
10665         $check_ost &&
10666                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10667
10668         # flush Client cache to allow next read to reach OSS
10669         cancel_lru_locks osc
10670
10671         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10672         $LCTL set_param fail_loc=0x80000408
10673         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10674         $LCTL set_param fail_loc=0
10675
10676         rm -f $DIR/$tfile
10677
10678         # check cksum dump on Client
10679         osc_file=$(ls ${osc_file_prefix}*)
10680         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10681         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10682         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10683         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10684         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10685                      cksum)
10686         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10687         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10688                 error "dump content does not match on Client"
10689
10690         $check_ost || skip "No need to check cksum dump on OSS"
10691
10692         # check cksum dump on OSS
10693         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10694         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10695         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10696         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10697         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10698                 error "dump content does not match on OSS"
10699
10700         cleanup_77c
10701 }
10702 run_test 77c "checksum error on client read with debug"
10703
10704 test_77d() { # bug 10889
10705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10706         $GSS && skip_env "could not run with gss"
10707
10708         stack_trap "rm -f $DIR/$tfile"
10709         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10710         $LCTL set_param fail_loc=0x80000409
10711         set_checksums 1
10712         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10713                 error "direct write: rc=$?"
10714         $LCTL set_param fail_loc=0
10715         set_checksums 0
10716
10717         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10718         $LCTL set_param fail_loc=0x80000408
10719         set_checksums 1
10720         cancel_lru_locks osc
10721         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10722                 error "direct read: rc=$?"
10723         $LCTL set_param fail_loc=0
10724         set_checksums 0
10725 }
10726 run_test 77d "checksum error on OST direct write, read"
10727
10728 test_77f() { # bug 10889
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730         $GSS && skip_env "could not run with gss"
10731
10732         set_checksums 1
10733         stack_trap "rm -f $DIR/$tfile"
10734         for algo in $CKSUM_TYPES; do
10735                 cancel_lru_locks osc
10736                 set_checksum_type $algo
10737                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10738                 $LCTL set_param fail_loc=0x409
10739                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10740                         error "direct write succeeded"
10741                 $LCTL set_param fail_loc=0
10742         done
10743         set_checksum_type $ORIG_CSUM_TYPE
10744         set_checksums 0
10745 }
10746 run_test 77f "repeat checksum error on write (expect error)"
10747
10748 test_77g() { # bug 10889
10749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10750         $GSS && skip_env "could not run with gss"
10751         remote_ost_nodsh && skip "remote OST with nodsh"
10752
10753         [ ! -f $F77_TMP ] && setup_f77
10754
10755         local file=$DIR/$tfile
10756         stack_trap "rm -f $file" EXIT
10757
10758         $LFS setstripe -c 1 -i 0 $file
10759         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10760         do_facet ost1 lctl set_param fail_loc=0x8000021a
10761         set_checksums 1
10762         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10763                 error "write error: rc=$?"
10764         do_facet ost1 lctl set_param fail_loc=0
10765         set_checksums 0
10766
10767         cancel_lru_locks osc
10768         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10769         do_facet ost1 lctl set_param fail_loc=0x8000021b
10770         set_checksums 1
10771         cmp $F77_TMP $file || error "file compare failed"
10772         do_facet ost1 lctl set_param fail_loc=0
10773         set_checksums 0
10774 }
10775 run_test 77g "checksum error on OST write, read"
10776
10777 test_77k() { # LU-10906
10778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10779         $GSS && skip_env "could not run with gss"
10780
10781         local cksum_param="osc.$FSNAME*.checksums"
10782         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10783         local checksum
10784         local i
10785
10786         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10787         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10788         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10789
10790         for i in 0 1; do
10791                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10792                         error "failed to set checksum=$i on MGS"
10793                 wait_update $HOSTNAME "$get_checksum" $i
10794                 #remount
10795                 echo "remount client, checksum should be $i"
10796                 remount_client $MOUNT || error "failed to remount client"
10797                 checksum=$(eval $get_checksum)
10798                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10799         done
10800         # remove persistent param to avoid races with checksum mountopt below
10801         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10802                 error "failed to delete checksum on MGS"
10803
10804         for opt in "checksum" "nochecksum"; do
10805                 #remount with mount option
10806                 echo "remount client with option $opt, checksum should be $i"
10807                 umount_client $MOUNT || error "failed to umount client"
10808                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10809                         error "failed to mount client with option '$opt'"
10810                 checksum=$(eval $get_checksum)
10811                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10812                 i=$((i - 1))
10813         done
10814
10815         remount_client $MOUNT || error "failed to remount client"
10816 }
10817 run_test 77k "enable/disable checksum correctly"
10818
10819 test_77l() {
10820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10821         $GSS && skip_env "could not run with gss"
10822
10823         set_checksums 1
10824         stack_trap "set_checksums $ORIG_CSUM" EXIT
10825         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10826
10827         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10828
10829         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10830         for algo in $CKSUM_TYPES; do
10831                 set_checksum_type $algo || error "fail to set checksum type $algo"
10832                 osc_algo=$(get_osc_checksum_type OST0000)
10833                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10834
10835                 # no locks, no reqs to let the connection idle
10836                 cancel_lru_locks osc
10837                 lru_resize_disable osc
10838                 wait_osc_import_state client ost1 IDLE
10839
10840                 # ensure ost1 is connected
10841                 stat $DIR/$tfile >/dev/null || error "can't stat"
10842                 wait_osc_import_state client ost1 FULL
10843
10844                 osc_algo=$(get_osc_checksum_type OST0000)
10845                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10846         done
10847         return 0
10848 }
10849 run_test 77l "preferred checksum type is remembered after reconnected"
10850
10851 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10852 rm -f $F77_TMP
10853 unset F77_TMP
10854
10855 test_77m() {
10856         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10857                 skip "Need at least version 2.14.52"
10858         local param=checksum_speed
10859
10860         $LCTL get_param $param || error "reading $param failed"
10861
10862         csum_speeds=$($LCTL get_param -n $param)
10863
10864         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10865                 error "known checksum types are missing"
10866 }
10867 run_test 77m "Verify checksum_speed is correctly read"
10868
10869 check_filefrag_77n() {
10870         local nr_ext=0
10871         local starts=()
10872         local ends=()
10873
10874         while read extidx a b start end rest; do
10875                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10876                         nr_ext=$(( $nr_ext + 1 ))
10877                         starts+=( ${start%..} )
10878                         ends+=( ${end%:} )
10879                 fi
10880         done < <( filefrag -sv $1 )
10881
10882         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10883         return 1
10884 }
10885
10886 test_77n() {
10887         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10888
10889         touch $DIR/$tfile
10890         $TRUNCATE $DIR/$tfile 0
10891         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10892         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10893         check_filefrag_77n $DIR/$tfile ||
10894                 skip "$tfile blocks not contiguous around hole"
10895
10896         set_checksums 1
10897         stack_trap "set_checksums $ORIG_CSUM" EXIT
10898         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10899         stack_trap "rm -f $DIR/$tfile"
10900
10901         for algo in $CKSUM_TYPES; do
10902                 if [[ "$algo" =~ ^t10 ]]; then
10903                         set_checksum_type $algo ||
10904                                 error "fail to set checksum type $algo"
10905                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10906                                 error "fail to read $tfile with $algo"
10907                 fi
10908         done
10909         rm -f $DIR/$tfile
10910         return 0
10911 }
10912 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10913
10914 test_77o() {
10915         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10916                 skip "Need MDS version at least 2.14.55"
10917         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10918                 skip "Need OST version at least 2.14.55"
10919         local ofd=obdfilter
10920         local mdt=mdt
10921
10922         # print OST checksum_type
10923         echo "$ofd.$FSNAME-*.checksum_type:"
10924         do_nodes $(comma_list $(osts_nodes)) \
10925                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10926
10927         # print MDT checksum_type
10928         echo "$mdt.$FSNAME-*.checksum_type:"
10929         do_nodes $(comma_list $(mdts_nodes)) \
10930                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10931
10932         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10933                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10934
10935         (( $o_count == $OSTCOUNT )) ||
10936                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10937
10938         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10939                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10940
10941         (( $m_count == $MDSCOUNT )) ||
10942                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10943 }
10944 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10945
10946 cleanup_test_78() {
10947         trap 0
10948         rm -f $DIR/$tfile
10949 }
10950
10951 test_78() { # bug 10901
10952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10953         remote_ost || skip_env "local OST"
10954
10955         NSEQ=5
10956         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10957         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10958         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10959         echo "MemTotal: $MEMTOTAL"
10960
10961         # reserve 256MB of memory for the kernel and other running processes,
10962         # and then take 1/2 of the remaining memory for the read/write buffers.
10963         if [ $MEMTOTAL -gt 512 ] ;then
10964                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10965         else
10966                 # for those poor memory-starved high-end clusters...
10967                 MEMTOTAL=$((MEMTOTAL / 2))
10968         fi
10969         echo "Mem to use for directio: $MEMTOTAL"
10970
10971         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10972         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10973         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10974         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10975                 head -n1)
10976         echo "Smallest OST: $SMALLESTOST"
10977         [[ $SMALLESTOST -lt 10240 ]] &&
10978                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10979
10980         trap cleanup_test_78 EXIT
10981
10982         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10983                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10984
10985         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10986         echo "File size: $F78SIZE"
10987         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10988         for i in $(seq 1 $NSEQ); do
10989                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10990                 echo directIO rdwr round $i of $NSEQ
10991                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10992         done
10993
10994         cleanup_test_78
10995 }
10996 run_test 78 "handle large O_DIRECT writes correctly ============"
10997
10998 test_79() { # bug 12743
10999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11000
11001         wait_delete_completed
11002
11003         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11004         BKFREE=$(calc_osc_kbytes kbytesfree)
11005         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11006
11007         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11008         DFTOTAL=`echo $STRING | cut -d, -f1`
11009         DFUSED=`echo $STRING  | cut -d, -f2`
11010         DFAVAIL=`echo $STRING | cut -d, -f3`
11011         DFFREE=$(($DFTOTAL - $DFUSED))
11012
11013         ALLOWANCE=$((64 * $OSTCOUNT))
11014
11015         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11016            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11017                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11018         fi
11019         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11020            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11021                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11022         fi
11023         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11024            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11025                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11026         fi
11027 }
11028 run_test 79 "df report consistency check ======================="
11029
11030 test_80() { # bug 10718
11031         remote_ost_nodsh && skip "remote OST with nodsh"
11032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11033
11034         # relax strong synchronous semantics for slow backends like ZFS
11035         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11036                 local soc="obdfilter.*.sync_lock_cancel"
11037                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11038
11039                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11040                 if [ -z "$save" ]; then
11041                         soc="obdfilter.*.sync_on_lock_cancel"
11042                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11043                 fi
11044
11045                 if [ "$save" != "never" ]; then
11046                         local hosts=$(comma_list $(osts_nodes))
11047
11048                         do_nodes $hosts $LCTL set_param $soc=never
11049                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11050                 fi
11051         fi
11052
11053         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11054         sync; sleep 1; sync
11055         local before=$(date +%s)
11056         cancel_lru_locks osc
11057         local after=$(date +%s)
11058         local diff=$((after - before))
11059         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11060
11061         rm -f $DIR/$tfile
11062 }
11063 run_test 80 "Page eviction is equally fast at high offsets too"
11064
11065 test_81a() { # LU-456
11066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11067         remote_ost_nodsh && skip "remote OST with nodsh"
11068
11069         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11070         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11071         do_facet ost1 lctl set_param fail_loc=0x80000228
11072
11073         # write should trigger a retry and success
11074         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11075         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11076         RC=$?
11077         if [ $RC -ne 0 ] ; then
11078                 error "write should success, but failed for $RC"
11079         fi
11080 }
11081 run_test 81a "OST should retry write when get -ENOSPC ==============="
11082
11083 test_81b() { # LU-456
11084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11085         remote_ost_nodsh && skip "remote OST with nodsh"
11086
11087         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11088         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11089         do_facet ost1 lctl set_param fail_loc=0x228
11090
11091         # write should retry several times and return -ENOSPC finally
11092         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11093         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11094         RC=$?
11095         ENOSPC=28
11096         if [ $RC -ne $ENOSPC ] ; then
11097                 error "dd should fail for -ENOSPC, but succeed."
11098         fi
11099 }
11100 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11101
11102 test_99() {
11103         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11104
11105         test_mkdir $DIR/$tdir.cvsroot
11106         chown $RUNAS_ID $DIR/$tdir.cvsroot
11107
11108         cd $TMP
11109         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11110
11111         cd /etc/init.d
11112         # some versions of cvs import exit(1) when asked to import links or
11113         # files they can't read.  ignore those files.
11114         local toignore=$(find . -type l -printf '-I %f\n' -o \
11115                          ! -perm /4 -printf '-I %f\n')
11116         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11117                 $tdir.reposname vtag rtag
11118
11119         cd $DIR
11120         test_mkdir $DIR/$tdir.reposname
11121         chown $RUNAS_ID $DIR/$tdir.reposname
11122         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11123
11124         cd $DIR/$tdir.reposname
11125         $RUNAS touch foo99
11126         $RUNAS cvs add -m 'addmsg' foo99
11127         $RUNAS cvs update
11128         $RUNAS cvs commit -m 'nomsg' foo99
11129         rm -fr $DIR/$tdir.cvsroot
11130 }
11131 run_test 99 "cvs strange file/directory operations"
11132
11133 test_100() {
11134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11135         [[ "$NETTYPE" =~ tcp ]] ||
11136                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11137         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11138         remote_ost_nodsh && skip "remote OST with nodsh"
11139         remote_mds_nodsh && skip "remote MDS with nodsh"
11140         remote_servers || skip "useless for local single node setup"
11141
11142         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11143                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11144
11145                 rc=0
11146                 if (( ${LOCAL/*:/} >= 1024 )); then
11147                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11148                         ss -tna
11149                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11150                 fi
11151         done
11152         (( $rc == 0 )) || error "privileged port not found" )
11153 }
11154 run_test 100 "check local port using privileged port"
11155
11156 function get_named_value()
11157 {
11158     local tag=$1
11159
11160     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11161 }
11162
11163 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11164                    awk '/^max_cached_mb/ { print $2 }')
11165
11166 cleanup_101a() {
11167         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11168         trap 0
11169 }
11170
11171 test_101a() {
11172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11173
11174         local s
11175         local discard
11176         local nreads=10000
11177         local cache_limit=32
11178
11179         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11180         trap cleanup_101a EXIT
11181         $LCTL set_param -n llite.*.read_ahead_stats=0
11182         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11183
11184         #
11185         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11186         #
11187         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11188         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11189
11190         discard=0
11191         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11192                    get_named_value 'read.but.discarded'); do
11193                         discard=$(($discard + $s))
11194         done
11195         cleanup_101a
11196
11197         $LCTL get_param osc.*-osc*.rpc_stats
11198         $LCTL get_param llite.*.read_ahead_stats
11199
11200         # Discard is generally zero, but sometimes a few random reads line up
11201         # and trigger larger readahead, which is wasted & leads to discards.
11202         if [[ $(($discard)) -gt $nreads ]]; then
11203                 error "too many ($discard) discarded pages"
11204         fi
11205         rm -f $DIR/$tfile || true
11206 }
11207 run_test 101a "check read-ahead for random reads"
11208
11209 setup_test101bc() {
11210         test_mkdir $DIR/$tdir
11211         local ssize=$1
11212         local FILE_LENGTH=$2
11213         STRIPE_OFFSET=0
11214
11215         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11216
11217         local list=$(comma_list $(osts_nodes))
11218         set_osd_param $list '' read_cache_enable 0
11219         set_osd_param $list '' writethrough_cache_enable 0
11220
11221         trap cleanup_test101bc EXIT
11222         # prepare the read-ahead file
11223         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11224
11225         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11226                                 count=$FILE_SIZE_MB 2> /dev/null
11227
11228 }
11229
11230 cleanup_test101bc() {
11231         trap 0
11232         rm -rf $DIR/$tdir
11233         rm -f $DIR/$tfile
11234
11235         local list=$(comma_list $(osts_nodes))
11236         set_osd_param $list '' read_cache_enable 1
11237         set_osd_param $list '' writethrough_cache_enable 1
11238 }
11239
11240 calc_total() {
11241         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11242 }
11243
11244 ra_check_101() {
11245         local read_size=$1
11246         local stripe_size=$2
11247         local stride_length=$((stripe_size / read_size))
11248         local stride_width=$((stride_length * OSTCOUNT))
11249         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11250                                 (stride_width - stride_length) ))
11251         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11252                   get_named_value 'read.but.discarded' | calc_total)
11253
11254         if [[ $discard -gt $discard_limit ]]; then
11255                 $LCTL get_param llite.*.read_ahead_stats
11256                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11257         else
11258                 echo "Read-ahead success for size ${read_size}"
11259         fi
11260 }
11261
11262 test_101b() {
11263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11265
11266         local STRIPE_SIZE=1048576
11267         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11268
11269         if [ $SLOW == "yes" ]; then
11270                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11271         else
11272                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11273         fi
11274
11275         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11276
11277         # prepare the read-ahead file
11278         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11279         cancel_lru_locks osc
11280         for BIDX in 2 4 8 16 32 64 128 256
11281         do
11282                 local BSIZE=$((BIDX*4096))
11283                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11284                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11285                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11286                 $LCTL set_param -n llite.*.read_ahead_stats=0
11287                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11288                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11289                 cancel_lru_locks osc
11290                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11291         done
11292         cleanup_test101bc
11293         true
11294 }
11295 run_test 101b "check stride-io mode read-ahead ================="
11296
11297 test_101c() {
11298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11299
11300         local STRIPE_SIZE=1048576
11301         local FILE_LENGTH=$((STRIPE_SIZE*100))
11302         local nreads=10000
11303         local rsize=65536
11304         local osc_rpc_stats
11305
11306         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11307
11308         cancel_lru_locks osc
11309         $LCTL set_param osc.*.rpc_stats=0
11310         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11311         $LCTL get_param osc.*.rpc_stats
11312         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11313                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11314                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11315                 local size
11316
11317                 if [ $lines -le 20 ]; then
11318                         echo "continue debug"
11319                         continue
11320                 fi
11321                 for size in 1 2 4 8; do
11322                         local rpc=$(echo "$stats" |
11323                                     awk '($1 == "'$size':") {print $2; exit; }')
11324                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11325                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11326                 done
11327                 echo "$osc_rpc_stats check passed!"
11328         done
11329         cleanup_test101bc
11330         true
11331 }
11332 run_test 101c "check stripe_size aligned read-ahead"
11333
11334 test_101d() {
11335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11336
11337         local file=$DIR/$tfile
11338         local sz_MB=${FILESIZE_101d:-80}
11339         local ra_MB=${READAHEAD_MB:-40}
11340
11341         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11342         [ $free_MB -lt $sz_MB ] &&
11343                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11344
11345         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11346         $LFS setstripe -c -1 $file || error "setstripe failed"
11347
11348         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11349         echo Cancel LRU locks on lustre client to flush the client cache
11350         cancel_lru_locks osc
11351
11352         echo Disable read-ahead
11353         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11354         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11355         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11356         $LCTL get_param -n llite.*.max_read_ahead_mb
11357
11358         echo "Reading the test file $file with read-ahead disabled"
11359         local sz_KB=$((sz_MB * 1024 / 4))
11360         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11361         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11362         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11363                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11364
11365         echo "Cancel LRU locks on lustre client to flush the client cache"
11366         cancel_lru_locks osc
11367         echo Enable read-ahead with ${ra_MB}MB
11368         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11369
11370         echo "Reading the test file $file with read-ahead enabled"
11371         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11372                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11373
11374         echo "read-ahead disabled time read $raOFF"
11375         echo "read-ahead enabled time read $raON"
11376
11377         rm -f $file
11378         wait_delete_completed
11379
11380         # use awk for this check instead of bash because it handles decimals
11381         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11382                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11383 }
11384 run_test 101d "file read with and without read-ahead enabled"
11385
11386 test_101e() {
11387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11388
11389         local file=$DIR/$tfile
11390         local size_KB=500  #KB
11391         local count=100
11392         local bsize=1024
11393
11394         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11395         local need_KB=$((count * size_KB))
11396         [[ $free_KB -le $need_KB ]] &&
11397                 skip_env "Need free space $need_KB, have $free_KB"
11398
11399         echo "Creating $count ${size_KB}K test files"
11400         for ((i = 0; i < $count; i++)); do
11401                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11402         done
11403
11404         echo "Cancel LRU locks on lustre client to flush the client cache"
11405         cancel_lru_locks $OSC
11406
11407         echo "Reset readahead stats"
11408         $LCTL set_param -n llite.*.read_ahead_stats=0
11409
11410         for ((i = 0; i < $count; i++)); do
11411                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11412         done
11413
11414         $LCTL get_param llite.*.max_cached_mb
11415         $LCTL get_param llite.*.read_ahead_stats
11416         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11417                      get_named_value 'misses' | calc_total)
11418
11419         for ((i = 0; i < $count; i++)); do
11420                 rm -rf $file.$i 2>/dev/null
11421         done
11422
11423         #10000 means 20% reads are missing in readahead
11424         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11425 }
11426 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11427
11428 test_101f() {
11429         which iozone || skip_env "no iozone installed"
11430
11431         local old_debug=$($LCTL get_param debug)
11432         old_debug=${old_debug#*=}
11433         $LCTL set_param debug="reada mmap"
11434
11435         # create a test file
11436         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11437
11438         echo Cancel LRU locks on lustre client to flush the client cache
11439         cancel_lru_locks osc
11440
11441         echo Reset readahead stats
11442         $LCTL set_param -n llite.*.read_ahead_stats=0
11443
11444         echo mmap read the file with small block size
11445         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11446                 > /dev/null 2>&1
11447
11448         echo checking missing pages
11449         $LCTL get_param llite.*.read_ahead_stats
11450         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11451                         get_named_value 'misses' | calc_total)
11452
11453         $LCTL set_param debug="$old_debug"
11454         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11455         rm -f $DIR/$tfile
11456 }
11457 run_test 101f "check mmap read performance"
11458
11459 test_101g_brw_size_test() {
11460         local mb=$1
11461         local pages=$((mb * 1048576 / PAGE_SIZE))
11462         local file=$DIR/$tfile
11463
11464         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11465                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11466         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11467                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11468                         return 2
11469         done
11470
11471         stack_trap "rm -f $file" EXIT
11472         $LCTL set_param -n osc.*.rpc_stats=0
11473
11474         # 10 RPCs should be enough for the test
11475         local count=10
11476         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11477                 { error "dd write ${mb} MB blocks failed"; return 3; }
11478         cancel_lru_locks osc
11479         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11480                 { error "dd write ${mb} MB blocks failed"; return 4; }
11481
11482         # calculate number of full-sized read and write RPCs
11483         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11484                 sed -n '/pages per rpc/,/^$/p' |
11485                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11486                 END { print reads,writes }'))
11487         # allow one extra full-sized read RPC for async readahead
11488         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11489                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11490         [[ ${rpcs[1]} == $count ]] ||
11491                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11492 }
11493
11494 test_101g() {
11495         remote_ost_nodsh && skip "remote OST with nodsh"
11496
11497         local rpcs
11498         local osts=$(get_facets OST)
11499         local list=$(comma_list $(osts_nodes))
11500         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11501         local brw_size="obdfilter.*.brw_size"
11502
11503         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11504
11505         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11506
11507         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11508                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11509                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11510            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11511                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11512                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11513
11514                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11515                         suffix="M"
11516
11517                 if [[ $orig_mb -lt 16 ]]; then
11518                         save_lustre_params $osts "$brw_size" > $p
11519                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11520                                 error "set 16MB RPC size failed"
11521
11522                         echo "remount client to enable new RPC size"
11523                         remount_client $MOUNT || error "remount_client failed"
11524                 fi
11525
11526                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11527                 # should be able to set brw_size=12, but no rpc_stats for that
11528                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11529         fi
11530
11531         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11532
11533         if [[ $orig_mb -lt 16 ]]; then
11534                 restore_lustre_params < $p
11535                 remount_client $MOUNT || error "remount_client restore failed"
11536         fi
11537
11538         rm -f $p $DIR/$tfile
11539 }
11540 run_test 101g "Big bulk(4/16 MiB) readahead"
11541
11542 test_101h() {
11543         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11544
11545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11546                 error "dd 70M file failed"
11547         echo Cancel LRU locks on lustre client to flush the client cache
11548         cancel_lru_locks osc
11549
11550         echo "Reset readahead stats"
11551         $LCTL set_param -n llite.*.read_ahead_stats 0
11552
11553         echo "Read 10M of data but cross 64M bundary"
11554         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11555         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11556                      get_named_value 'misses' | calc_total)
11557         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11558         rm -f $p $DIR/$tfile
11559 }
11560 run_test 101h "Readahead should cover current read window"
11561
11562 test_101i() {
11563         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11564                 error "dd 10M file failed"
11565
11566         local max_per_file_mb=$($LCTL get_param -n \
11567                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11568         cancel_lru_locks osc
11569         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11570         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11571                 error "set max_read_ahead_per_file_mb to 1 failed"
11572
11573         echo "Reset readahead stats"
11574         $LCTL set_param llite.*.read_ahead_stats=0
11575
11576         dd if=$DIR/$tfile of=/dev/null bs=2M
11577
11578         $LCTL get_param llite.*.read_ahead_stats
11579         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11580                      awk '/misses/ { print $2 }')
11581         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11582         rm -f $DIR/$tfile
11583 }
11584 run_test 101i "allow current readahead to exceed reservation"
11585
11586 test_101j() {
11587         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11588                 error "setstripe $DIR/$tfile failed"
11589         local file_size=$((1048576 * 16))
11590         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11591         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11592
11593         echo Disable read-ahead
11594         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11595
11596         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11597         for blk in $PAGE_SIZE 1048576 $file_size; do
11598                 cancel_lru_locks osc
11599                 echo "Reset readahead stats"
11600                 $LCTL set_param -n llite.*.read_ahead_stats=0
11601                 local count=$(($file_size / $blk))
11602                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11603                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11604                              get_named_value 'failed.to.fast.read' | calc_total)
11605                 $LCTL get_param -n llite.*.read_ahead_stats
11606                 [ $miss -eq $count ] || error "expected $count got $miss"
11607         done
11608
11609         rm -f $p $DIR/$tfile
11610 }
11611 run_test 101j "A complete read block should be submitted when no RA"
11612
11613 test_readahead_base() {
11614         local file=$DIR/$tfile
11615         local size=$1
11616         local iosz
11617         local ramax
11618         local ranum
11619
11620         $LCTL set_param -n llite.*.read_ahead_stats=0
11621         # The first page is not accounted into readahead
11622         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11623         iosz=$(((size + 1048575) / 1048576 * 1048576))
11624         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11625
11626         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11627         fallocate -l $size $file || error "failed to fallocate $file"
11628         cancel_lru_locks osc
11629         $MULTIOP $file or${iosz}c || error "failed to read $file"
11630         $LCTL get_param -n llite.*.read_ahead_stats
11631         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11632                 awk '/readahead.pages/ { print $7 }' | calc_total)
11633         (( $ranum <= $ramax )) ||
11634                 error "read-ahead pages is $ranum more than $ramax"
11635         rm -rf $file || error "failed to remove $file"
11636 }
11637
11638 test_101m()
11639 {
11640         local file=$DIR/$tfile
11641         local ramax
11642         local ranum
11643         local size
11644         local iosz
11645
11646         check_set_fallocate_or_skip
11647         stack_trap "rm -f $file" EXIT
11648
11649         test_readahead_base 4096
11650
11651         # file size: 16K = 16384
11652         test_readahead_base 16384
11653         test_readahead_base 16385
11654         test_readahead_base 16383
11655
11656         # file size: 1M + 1 = 1048576 + 1
11657         test_readahead_base 1048577
11658         # file size: 1M + 16K
11659         test_readahead_base $((1048576 + 16384))
11660
11661         # file size: stripe_size * (stripe_count - 1) + 16K
11662         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11663         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11664         # file size: stripe_size * stripe_count + 16K
11665         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11666         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11667         # file size: 2 * stripe_size * stripe_count + 16K
11668         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11669         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11670 }
11671 run_test 101m "read ahead for small file and last stripe of the file"
11672
11673 setup_test102() {
11674         test_mkdir $DIR/$tdir
11675         chown $RUNAS_ID $DIR/$tdir
11676         STRIPE_SIZE=65536
11677         STRIPE_OFFSET=1
11678         STRIPE_COUNT=$OSTCOUNT
11679         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11680
11681         trap cleanup_test102 EXIT
11682         cd $DIR
11683         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11684         cd $DIR/$tdir
11685         for num in 1 2 3 4; do
11686                 for count in $(seq 1 $STRIPE_COUNT); do
11687                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11688                                 local size=`expr $STRIPE_SIZE \* $num`
11689                                 local file=file"$num-$idx-$count"
11690                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11691                         done
11692                 done
11693         done
11694
11695         cd $DIR
11696         $1 tar cf $TMP/f102.tar $tdir --xattrs
11697 }
11698
11699 cleanup_test102() {
11700         trap 0
11701         rm -f $TMP/f102.tar
11702         rm -rf $DIR/d0.sanity/d102
11703 }
11704
11705 test_102a() {
11706         [ "$UID" != 0 ] && skip "must run as root"
11707         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11708                 skip_env "must have user_xattr"
11709
11710         [ -z "$(which setfattr 2>/dev/null)" ] &&
11711                 skip_env "could not find setfattr"
11712
11713         local testfile=$DIR/$tfile
11714
11715         touch $testfile
11716         echo "set/get xattr..."
11717         setfattr -n trusted.name1 -v value1 $testfile ||
11718                 error "setfattr -n trusted.name1=value1 $testfile failed"
11719         getfattr -n trusted.name1 $testfile 2> /dev/null |
11720           grep "trusted.name1=.value1" ||
11721                 error "$testfile missing trusted.name1=value1"
11722
11723         setfattr -n user.author1 -v author1 $testfile ||
11724                 error "setfattr -n user.author1=author1 $testfile failed"
11725         getfattr -n user.author1 $testfile 2> /dev/null |
11726           grep "user.author1=.author1" ||
11727                 error "$testfile missing trusted.author1=author1"
11728
11729         echo "listxattr..."
11730         setfattr -n trusted.name2 -v value2 $testfile ||
11731                 error "$testfile unable to set trusted.name2"
11732         setfattr -n trusted.name3 -v value3 $testfile ||
11733                 error "$testfile unable to set trusted.name3"
11734         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11735             grep "trusted.name" | wc -l) -eq 3 ] ||
11736                 error "$testfile missing 3 trusted.name xattrs"
11737
11738         setfattr -n user.author2 -v author2 $testfile ||
11739                 error "$testfile unable to set user.author2"
11740         setfattr -n user.author3 -v author3 $testfile ||
11741                 error "$testfile unable to set user.author3"
11742         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11743             grep "user.author" | wc -l) -eq 3 ] ||
11744                 error "$testfile missing 3 user.author xattrs"
11745
11746         echo "remove xattr..."
11747         setfattr -x trusted.name1 $testfile ||
11748                 error "$testfile error deleting trusted.name1"
11749         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11750                 error "$testfile did not delete trusted.name1 xattr"
11751
11752         setfattr -x user.author1 $testfile ||
11753                 error "$testfile error deleting user.author1"
11754         echo "set lustre special xattr ..."
11755         $LFS setstripe -c1 $testfile
11756         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11757                 awk -F "=" '/trusted.lov/ { print $2 }' )
11758         setfattr -n "trusted.lov" -v $lovea $testfile ||
11759                 error "$testfile doesn't ignore setting trusted.lov again"
11760         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11761                 error "$testfile allow setting invalid trusted.lov"
11762         rm -f $testfile
11763 }
11764 run_test 102a "user xattr test =================================="
11765
11766 check_102b_layout() {
11767         local layout="$*"
11768         local testfile=$DIR/$tfile
11769
11770         echo "test layout '$layout'"
11771         $LFS setstripe $layout $testfile || error "setstripe failed"
11772         $LFS getstripe -y $testfile
11773
11774         echo "get/set/list trusted.lov xattr ..." # b=10930
11775         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11776         [[ "$value" =~ "trusted.lov" ]] ||
11777                 error "can't get trusted.lov from $testfile"
11778         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11779                 error "getstripe failed"
11780
11781         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11782
11783         value=$(cut -d= -f2 <<<$value)
11784         # LU-13168: truncated xattr should fail if short lov_user_md header
11785         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11786                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11787         for len in $lens; do
11788                 echo "setfattr $len $testfile.2"
11789                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11790                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11791         done
11792         local stripe_size=$($LFS getstripe -S $testfile.2)
11793         local stripe_count=$($LFS getstripe -c $testfile.2)
11794         [[ $stripe_size -eq 65536 ]] ||
11795                 error "stripe size $stripe_size != 65536"
11796         [[ $stripe_count -eq $stripe_count_orig ]] ||
11797                 error "stripe count $stripe_count != $stripe_count_orig"
11798         rm $testfile $testfile.2
11799 }
11800
11801 test_102b() {
11802         [ -z "$(which setfattr 2>/dev/null)" ] &&
11803                 skip_env "could not find setfattr"
11804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11805
11806         # check plain layout
11807         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11808
11809         # and also check composite layout
11810         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11811
11812 }
11813 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11814
11815 test_102c() {
11816         [ -z "$(which setfattr 2>/dev/null)" ] &&
11817                 skip_env "could not find setfattr"
11818         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11819
11820         # b10930: get/set/list lustre.lov xattr
11821         echo "get/set/list lustre.lov xattr ..."
11822         test_mkdir $DIR/$tdir
11823         chown $RUNAS_ID $DIR/$tdir
11824         local testfile=$DIR/$tdir/$tfile
11825         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11826                 error "setstripe failed"
11827         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11828                 error "getstripe failed"
11829         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11830         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11831
11832         local testfile2=${testfile}2
11833         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11834                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11835
11836         $RUNAS $MCREATE $testfile2
11837         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11838         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11839         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11840         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11841         [ $stripe_count -eq $STRIPECOUNT ] ||
11842                 error "stripe count $stripe_count != $STRIPECOUNT"
11843 }
11844 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11845
11846 compare_stripe_info1() {
11847         local stripe_index_all_zero=true
11848
11849         for num in 1 2 3 4; do
11850                 for count in $(seq 1 $STRIPE_COUNT); do
11851                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11852                                 local size=$((STRIPE_SIZE * num))
11853                                 local file=file"$num-$offset-$count"
11854                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11855                                 [[ $stripe_size -ne $size ]] &&
11856                                     error "$file: size $stripe_size != $size"
11857                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11858                                 # allow fewer stripes to be created, ORI-601
11859                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11860                                     error "$file: count $stripe_count != $count"
11861                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11862                                 [[ $stripe_index -ne 0 ]] &&
11863                                         stripe_index_all_zero=false
11864                         done
11865                 done
11866         done
11867         $stripe_index_all_zero &&
11868                 error "all files are being extracted starting from OST index 0"
11869         return 0
11870 }
11871
11872 have_xattrs_include() {
11873         tar --help | grep -q xattrs-include &&
11874                 echo --xattrs-include="lustre.*"
11875 }
11876
11877 test_102d() {
11878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11880
11881         XINC=$(have_xattrs_include)
11882         setup_test102
11883         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11884         cd $DIR/$tdir/$tdir
11885         compare_stripe_info1
11886 }
11887 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11888
11889 test_102f() {
11890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11891         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11892
11893         XINC=$(have_xattrs_include)
11894         setup_test102
11895         test_mkdir $DIR/$tdir.restore
11896         cd $DIR
11897         tar cf - --xattrs $tdir | tar xf - \
11898                 -C $DIR/$tdir.restore --xattrs $XINC
11899         cd $DIR/$tdir.restore/$tdir
11900         compare_stripe_info1
11901 }
11902 run_test 102f "tar copy files, not keep osts"
11903
11904 grow_xattr() {
11905         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11906                 skip "must have user_xattr"
11907         [ -z "$(which setfattr 2>/dev/null)" ] &&
11908                 skip_env "could not find setfattr"
11909         [ -z "$(which getfattr 2>/dev/null)" ] &&
11910                 skip_env "could not find getfattr"
11911
11912         local xsize=${1:-1024}  # in bytes
11913         local file=$DIR/$tfile
11914         local value="$(generate_string $xsize)"
11915         local xbig=trusted.big
11916         local toobig=$2
11917
11918         touch $file
11919         log "save $xbig on $file"
11920         if [ -z "$toobig" ]
11921         then
11922                 setfattr -n $xbig -v $value $file ||
11923                         error "saving $xbig on $file failed"
11924         else
11925                 setfattr -n $xbig -v $value $file &&
11926                         error "saving $xbig on $file succeeded"
11927                 return 0
11928         fi
11929
11930         local orig=$(get_xattr_value $xbig $file)
11931         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11932
11933         local xsml=trusted.sml
11934         log "save $xsml on $file"
11935         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11936
11937         local new=$(get_xattr_value $xbig $file)
11938         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11939
11940         log "grow $xsml on $file"
11941         setfattr -n $xsml -v "$value" $file ||
11942                 error "growing $xsml on $file failed"
11943
11944         new=$(get_xattr_value $xbig $file)
11945         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11946         log "$xbig still valid after growing $xsml"
11947
11948         rm -f $file
11949 }
11950
11951 test_102h() { # bug 15777
11952         grow_xattr 1024
11953 }
11954 run_test 102h "grow xattr from inside inode to external block"
11955
11956 test_102ha() {
11957         large_xattr_enabled || skip_env "ea_inode feature disabled"
11958
11959         echo "setting xattr of max xattr size: $(max_xattr_size)"
11960         grow_xattr $(max_xattr_size)
11961
11962         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11963         echo "This should fail:"
11964         grow_xattr $(($(max_xattr_size) + 10)) 1
11965 }
11966 run_test 102ha "grow xattr from inside inode to external inode"
11967
11968 test_102i() { # bug 17038
11969         [ -z "$(which getfattr 2>/dev/null)" ] &&
11970                 skip "could not find getfattr"
11971
11972         touch $DIR/$tfile
11973         ln -s $DIR/$tfile $DIR/${tfile}link
11974         getfattr -n trusted.lov $DIR/$tfile ||
11975                 error "lgetxattr on $DIR/$tfile failed"
11976         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11977                 grep -i "no such attr" ||
11978                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11979         rm -f $DIR/$tfile $DIR/${tfile}link
11980 }
11981 run_test 102i "lgetxattr test on symbolic link ============"
11982
11983 test_102j() {
11984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11985         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11986
11987         XINC=$(have_xattrs_include)
11988         setup_test102 "$RUNAS"
11989         chown $RUNAS_ID $DIR/$tdir
11990         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11991         cd $DIR/$tdir/$tdir
11992         compare_stripe_info1 "$RUNAS"
11993 }
11994 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11995
11996 test_102k() {
11997         [ -z "$(which setfattr 2>/dev/null)" ] &&
11998                 skip "could not find setfattr"
11999
12000         touch $DIR/$tfile
12001         # b22187 just check that does not crash for regular file.
12002         setfattr -n trusted.lov $DIR/$tfile
12003         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12004         local test_kdir=$DIR/$tdir
12005         test_mkdir $test_kdir
12006         local default_size=$($LFS getstripe -S $test_kdir)
12007         local default_count=$($LFS getstripe -c $test_kdir)
12008         local default_offset=$($LFS getstripe -i $test_kdir)
12009         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12010                 error 'dir setstripe failed'
12011         setfattr -n trusted.lov $test_kdir
12012         local stripe_size=$($LFS getstripe -S $test_kdir)
12013         local stripe_count=$($LFS getstripe -c $test_kdir)
12014         local stripe_offset=$($LFS getstripe -i $test_kdir)
12015         [ $stripe_size -eq $default_size ] ||
12016                 error "stripe size $stripe_size != $default_size"
12017         [ $stripe_count -eq $default_count ] ||
12018                 error "stripe count $stripe_count != $default_count"
12019         [ $stripe_offset -eq $default_offset ] ||
12020                 error "stripe offset $stripe_offset != $default_offset"
12021         rm -rf $DIR/$tfile $test_kdir
12022 }
12023 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12024
12025 test_102l() {
12026         [ -z "$(which getfattr 2>/dev/null)" ] &&
12027                 skip "could not find getfattr"
12028
12029         # LU-532 trusted. xattr is invisible to non-root
12030         local testfile=$DIR/$tfile
12031
12032         touch $testfile
12033
12034         echo "listxattr as user..."
12035         chown $RUNAS_ID $testfile
12036         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12037             grep -q "trusted" &&
12038                 error "$testfile trusted xattrs are user visible"
12039
12040         return 0;
12041 }
12042 run_test 102l "listxattr size test =================================="
12043
12044 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12045         local path=$DIR/$tfile
12046         touch $path
12047
12048         listxattr_size_check $path || error "listattr_size_check $path failed"
12049 }
12050 run_test 102m "Ensure listxattr fails on small bufffer ========"
12051
12052 cleanup_test102
12053
12054 getxattr() { # getxattr path name
12055         # Return the base64 encoding of the value of xattr name on path.
12056         local path=$1
12057         local name=$2
12058
12059         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12060         # file: $path
12061         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12062         #
12063         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12064
12065         getfattr --absolute-names --encoding=base64 --name=$name $path |
12066                 awk -F= -v name=$name '$1 == name {
12067                         print substr($0, index($0, "=") + 1);
12068         }'
12069 }
12070
12071 test_102n() { # LU-4101 mdt: protect internal xattrs
12072         [ -z "$(which setfattr 2>/dev/null)" ] &&
12073                 skip "could not find setfattr"
12074         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12075         then
12076                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12077         fi
12078
12079         local file0=$DIR/$tfile.0
12080         local file1=$DIR/$tfile.1
12081         local xattr0=$TMP/$tfile.0
12082         local xattr1=$TMP/$tfile.1
12083         local namelist="lov lma lmv link fid version som hsm"
12084         local name
12085         local value
12086
12087         rm -rf $file0 $file1 $xattr0 $xattr1
12088         touch $file0 $file1
12089
12090         # Get 'before' xattrs of $file1.
12091         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12092
12093         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12094                 namelist+=" lfsck_namespace"
12095         for name in $namelist; do
12096                 # Try to copy xattr from $file0 to $file1.
12097                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12098
12099                 setfattr --name=trusted.$name --value="$value" $file1 ||
12100                         error "setxattr 'trusted.$name' failed"
12101
12102                 # Try to set a garbage xattr.
12103                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12104
12105                 if [[ x$name == "xlov" ]]; then
12106                         setfattr --name=trusted.lov --value="$value" $file1 &&
12107                         error "setxattr invalid 'trusted.lov' success"
12108                 else
12109                         setfattr --name=trusted.$name --value="$value" $file1 ||
12110                                 error "setxattr invalid 'trusted.$name' failed"
12111                 fi
12112
12113                 # Try to remove the xattr from $file1. We don't care if this
12114                 # appears to succeed or fail, we just don't want there to be
12115                 # any changes or crashes.
12116                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12117         done
12118
12119         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12120         then
12121                 name="lfsck_ns"
12122                 # Try to copy xattr from $file0 to $file1.
12123                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12124
12125                 setfattr --name=trusted.$name --value="$value" $file1 ||
12126                         error "setxattr 'trusted.$name' failed"
12127
12128                 # Try to set a garbage xattr.
12129                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12130
12131                 setfattr --name=trusted.$name --value="$value" $file1 ||
12132                         error "setxattr 'trusted.$name' failed"
12133
12134                 # Try to remove the xattr from $file1. We don't care if this
12135                 # appears to succeed or fail, we just don't want there to be
12136                 # any changes or crashes.
12137                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12138         fi
12139
12140         # Get 'after' xattrs of file1.
12141         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12142
12143         if ! diff $xattr0 $xattr1; then
12144                 error "before and after xattrs of '$file1' differ"
12145         fi
12146
12147         rm -rf $file0 $file1 $xattr0 $xattr1
12148
12149         return 0
12150 }
12151 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12152
12153 test_102p() { # LU-4703 setxattr did not check ownership
12154         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12155                 skip "MDS needs to be at least 2.5.56"
12156
12157         local testfile=$DIR/$tfile
12158
12159         touch $testfile
12160
12161         echo "setfacl as user..."
12162         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12163         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12164
12165         echo "setfattr as user..."
12166         setfacl -m "u:$RUNAS_ID:---" $testfile
12167         $RUNAS setfattr -x system.posix_acl_access $testfile
12168         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12169 }
12170 run_test 102p "check setxattr(2) correctly fails without permission"
12171
12172 test_102q() {
12173         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12174                 skip "MDS needs to be at least 2.6.92"
12175
12176         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12177 }
12178 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12179
12180 test_102r() {
12181         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12182                 skip "MDS needs to be at least 2.6.93"
12183
12184         touch $DIR/$tfile || error "touch"
12185         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12186         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12187         rm $DIR/$tfile || error "rm"
12188
12189         #normal directory
12190         mkdir -p $DIR/$tdir || error "mkdir"
12191         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12192         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12193         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12194                 error "$testfile error deleting user.author1"
12195         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12196                 grep "user.$(basename $tdir)" &&
12197                 error "$tdir did not delete user.$(basename $tdir)"
12198         rmdir $DIR/$tdir || error "rmdir"
12199
12200         #striped directory
12201         test_mkdir $DIR/$tdir
12202         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12203         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12204         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12205                 error "$testfile error deleting user.author1"
12206         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12207                 grep "user.$(basename $tdir)" &&
12208                 error "$tdir did not delete user.$(basename $tdir)"
12209         rmdir $DIR/$tdir || error "rm striped dir"
12210 }
12211 run_test 102r "set EAs with empty values"
12212
12213 test_102s() {
12214         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12215                 skip "MDS needs to be at least 2.11.52"
12216
12217         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12218
12219         save_lustre_params client "llite.*.xattr_cache" > $save
12220
12221         for cache in 0 1; do
12222                 lctl set_param llite.*.xattr_cache=$cache
12223
12224                 rm -f $DIR/$tfile
12225                 touch $DIR/$tfile || error "touch"
12226                 for prefix in lustre security system trusted user; do
12227                         # Note getxattr() may fail with 'Operation not
12228                         # supported' or 'No such attribute' depending
12229                         # on prefix and cache.
12230                         getfattr -n $prefix.n102s $DIR/$tfile &&
12231                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12232                 done
12233         done
12234
12235         restore_lustre_params < $save
12236 }
12237 run_test 102s "getting nonexistent xattrs should fail"
12238
12239 test_102t() {
12240         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12241                 skip "MDS needs to be at least 2.11.52"
12242
12243         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12244
12245         save_lustre_params client "llite.*.xattr_cache" > $save
12246
12247         for cache in 0 1; do
12248                 lctl set_param llite.*.xattr_cache=$cache
12249
12250                 for buf_size in 0 256; do
12251                         rm -f $DIR/$tfile
12252                         touch $DIR/$tfile || error "touch"
12253                         setfattr -n user.multiop $DIR/$tfile
12254                         $MULTIOP $DIR/$tfile oa$buf_size ||
12255                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12256                 done
12257         done
12258
12259         restore_lustre_params < $save
12260 }
12261 run_test 102t "zero length xattr values handled correctly"
12262
12263 run_acl_subtest()
12264 {
12265         local test=$LUSTRE/tests/acl/$1.test
12266         local tmp=$(mktemp -t $1-XXXXXX).test
12267         local bin=$2
12268         local dmn=$3
12269         local grp=$4
12270         local nbd=$5
12271         export LANG=C
12272
12273
12274         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12275         local sedgroups="-e s/:users/:$grp/g"
12276         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12277
12278         sed $sedusers $sedgroups < $test > $tmp
12279         stack_trap "rm -f $tmp"
12280         [[ -s $tmp ]] || error "sed failed to create test script"
12281
12282         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12283         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12284 }
12285
12286 test_103a() {
12287         [ "$UID" != 0 ] && skip "must run as root"
12288         $GSS && skip_env "could not run under gss"
12289         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12290                 skip_env "must have acl enabled"
12291         which setfacl || skip_env "could not find setfacl"
12292         remote_mds_nodsh && skip "remote MDS with nodsh"
12293
12294         local mdts=$(comma_list $(mdts_nodes))
12295         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12296
12297         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12298         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12299
12300         ACLBIN=${ACLBIN:-"bin"}
12301         ACLDMN=${ACLDMN:-"daemon"}
12302         ACLGRP=${ACLGRP:-"users"}
12303         ACLNBD=${ACLNBD:-"nobody"}
12304
12305         if ! id $ACLBIN ||
12306            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12307                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12308                 ACLBIN=$USER0
12309                 if ! id $ACLBIN ; then
12310                         cat /etc/passwd
12311                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12312                 fi
12313         fi
12314         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12315            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12316                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12317                 ACLDMN=$USER1
12318                 if ! id $ACLDMN ; then
12319                         cat /etc/passwd
12320                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12321                 fi
12322         fi
12323         if ! getent group $ACLGRP; then
12324                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12325                 ACLGRP="$TSTUSR"
12326                 if ! getent group $ACLGRP; then
12327                         echo "cannot find group '$ACLGRP', adding it"
12328                         cat /etc/group
12329                         add_group 60000 $ACLGRP
12330                 fi
12331         fi
12332
12333         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12334         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12335         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12336
12337         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12338                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12339                 ACLGRP="$TSTUSR"
12340                 if ! getent group $ACLGRP; then
12341                         echo "cannot find group '$ACLGRP', adding it"
12342                         cat /etc/group
12343                         add_group 60000 $ACLGRP
12344                 fi
12345                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12346                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12347                         cat /etc/group
12348                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12349                 fi
12350         fi
12351
12352         gpasswd -a $ACLDMN $ACLBIN ||
12353                 error "setting client group failed"             # LU-5641
12354         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12355                 error "setting MDS group failed"                # LU-5641
12356
12357         declare -a identity_old
12358
12359         for num in $(seq $MDSCOUNT); do
12360                 switch_identity $num true || identity_old[$num]=$?
12361         done
12362
12363         SAVE_UMASK=$(umask)
12364         umask 0022
12365         mkdir -p $DIR/$tdir
12366         cd $DIR/$tdir
12367
12368         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12369         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12370         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12371         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12372         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12373         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12374         if ! id -u $ACLNBD ||
12375            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12376                 ACLNBD="nfsnobody"
12377                 if ! id -u $ACLNBD; then
12378                         ACLNBD=""
12379                 fi
12380         fi
12381         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12382                 add_group $(id -u $ACLNBD) $ACLNBD
12383                 if ! getent group $ACLNBD; then
12384                         ACLNBD=""
12385                 fi
12386         fi
12387         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12388            [[ -n "$ACLNBD" ]] && which setfattr; then
12389                 run_acl_subtest permissions_xattr \
12390                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12391         elif [[ -z "$ACLNBD" ]]; then
12392                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12393         else
12394                 echo "skip 'permission_xattr' test - missing setfattr command"
12395         fi
12396         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12397
12398         # inheritance test got from HP
12399         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12400         chmod +x make-tree || error "chmod +x failed"
12401         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12402         rm -f make-tree
12403
12404         echo "LU-974 ignore umask when acl is enabled..."
12405         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12406         if [ $MDSCOUNT -ge 2 ]; then
12407                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12408         fi
12409
12410         echo "LU-2561 newly created file is same size as directory..."
12411         if [ "$mds1_FSTYPE" != "zfs" ]; then
12412                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12413         else
12414                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12415         fi
12416
12417         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12418
12419         cd $SAVE_PWD
12420         umask $SAVE_UMASK
12421
12422         for num in $(seq $MDSCOUNT); do
12423                 if [ "${identity_old[$num]}" = 1 ]; then
12424                         switch_identity $num false || identity_old[$num]=$?
12425                 fi
12426         done
12427 }
12428 run_test 103a "acl test"
12429
12430 test_103b() {
12431         declare -a pids
12432         local U
12433
12434         stack_trap "rm -f $DIR/$tfile.*"
12435         for U in {0..511}; do
12436                 {
12437                 local O=$(printf "%04o" $U)
12438
12439                 umask $(printf "%04o" $((511 ^ $O)))
12440                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12441                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12442
12443                 (( $S == ($O & 0666) )) ||
12444                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12445
12446                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12447                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12448                 (( $S == ($O & 0666) )) ||
12449                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12450
12451                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12452                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12453                 (( $S == ($O & 0666) )) ||
12454                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12455                 rm -f $DIR/$tfile.[smp]$0
12456                 } &
12457                 local pid=$!
12458
12459                 # limit the concurrently running threads to 64. LU-11878
12460                 local idx=$((U % 64))
12461                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12462                 pids[idx]=$pid
12463         done
12464         wait
12465 }
12466 run_test 103b "umask lfs setstripe"
12467
12468 test_103c() {
12469         mkdir -p $DIR/$tdir
12470         cp -rp $DIR/$tdir $DIR/$tdir.bak
12471
12472         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12473                 error "$DIR/$tdir shouldn't contain default ACL"
12474         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12475                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12476         true
12477 }
12478 run_test 103c "'cp -rp' won't set empty acl"
12479
12480 test_103e() {
12481         local numacl
12482         local fileacl
12483         local saved_debug=$($LCTL get_param -n debug)
12484
12485         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12486                 skip "MDS needs to be at least 2.14.52"
12487
12488         large_xattr_enabled || skip_env "ea_inode feature disabled"
12489
12490         mkdir -p $DIR/$tdir
12491         # add big LOV EA to cause reply buffer overflow earlier
12492         $LFS setstripe -C 1000 $DIR/$tdir
12493         lctl set_param mdc.*-mdc*.stats=clear
12494
12495         $LCTL set_param debug=0
12496         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12497         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12498
12499         # add a large number of default ACLs (expect 8000+ for 2.13+)
12500         for U in {2..7000}; do
12501                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12502                         error "Able to add just $U default ACLs"
12503         done
12504         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12505         echo "$numacl default ACLs created"
12506
12507         stat $DIR/$tdir || error "Cannot stat directory"
12508         # check file creation
12509         touch $DIR/$tdir/$tfile ||
12510                 error "failed to create $tfile with $numacl default ACLs"
12511         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12512         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12513         echo "$fileacl ACLs were inherited"
12514         (( $fileacl == $numacl )) ||
12515                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12516         # check that new ACLs creation adds new ACLs to inherited ACLs
12517         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12518                 error "Cannot set new ACL"
12519         numacl=$((numacl + 1))
12520         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12521         (( $fileacl == $numacl )) ||
12522                 error "failed to add new ACL: $fileacl != $numacl as expected"
12523         # adds more ACLs to a file to reach their maximum at 8000+
12524         numacl=0
12525         for U in {20000..25000}; do
12526                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12527                 numacl=$((numacl + 1))
12528         done
12529         echo "Added $numacl more ACLs to the file"
12530         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12531         echo "Total $fileacl ACLs in file"
12532         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12533         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12534         rmdir $DIR/$tdir || error "Cannot remove directory"
12535 }
12536 run_test 103e "inheritance of big amount of default ACLs"
12537
12538 test_103f() {
12539         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12540                 skip "MDS needs to be at least 2.14.51"
12541
12542         large_xattr_enabled || skip_env "ea_inode feature disabled"
12543
12544         # enable changelog to consume more internal MDD buffers
12545         changelog_register
12546
12547         mkdir -p $DIR/$tdir
12548         # add big LOV EA
12549         $LFS setstripe -C 1000 $DIR/$tdir
12550         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12551         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12552         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12553         rmdir $DIR/$tdir || error "Cannot remove directory"
12554 }
12555 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12556
12557 test_104a() {
12558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12559
12560         touch $DIR/$tfile
12561         lfs df || error "lfs df failed"
12562         lfs df -ih || error "lfs df -ih failed"
12563         lfs df -h $DIR || error "lfs df -h $DIR failed"
12564         lfs df -i $DIR || error "lfs df -i $DIR failed"
12565         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12566         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12567
12568         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12569         lctl --device %$OSC deactivate
12570         lfs df || error "lfs df with deactivated OSC failed"
12571         lctl --device %$OSC activate
12572         # wait the osc back to normal
12573         wait_osc_import_ready client ost
12574
12575         lfs df || error "lfs df with reactivated OSC failed"
12576         rm -f $DIR/$tfile
12577 }
12578 run_test 104a "lfs df [-ih] [path] test ========================="
12579
12580 test_104b() {
12581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12582         [ $RUNAS_ID -eq $UID ] &&
12583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12584
12585         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12586                         grep "Permission denied" | wc -l)))
12587         if [ $denied_cnt -ne 0 ]; then
12588                 error "lfs check servers test failed"
12589         fi
12590 }
12591 run_test 104b "$RUNAS lfs check servers test ===================="
12592
12593 #
12594 # Verify $1 is within range of $2.
12595 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12596 # $1 is <= 2% of $2. Else Fail.
12597 #
12598 value_in_range() {
12599         # Strip all units (M, G, T)
12600         actual=$(echo $1 | tr -d A-Z)
12601         expect=$(echo $2 | tr -d A-Z)
12602
12603         expect_lo=$(($expect * 98 / 100)) # 2% below
12604         expect_hi=$(($expect * 102 / 100)) # 2% above
12605
12606         # permit 2% drift above and below
12607         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12608 }
12609
12610 test_104c() {
12611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12612         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12613
12614         local ost_param="osd-zfs.$FSNAME-OST0000."
12615         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12616         local ofacets=$(get_facets OST)
12617         local mfacets=$(get_facets MDS)
12618         local saved_ost_blocks=
12619         local saved_mdt_blocks=
12620
12621         echo "Before recordsize change"
12622         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12623         df=($(df -h | grep "$MOUNT"$))
12624
12625         # For checking.
12626         echo "lfs output : ${lfs_df[*]}"
12627         echo "df  output : ${df[*]}"
12628
12629         for facet in ${ofacets//,/ }; do
12630                 if [ -z $saved_ost_blocks ]; then
12631                         saved_ost_blocks=$(do_facet $facet \
12632                                 lctl get_param -n $ost_param.blocksize)
12633                         echo "OST Blocksize: $saved_ost_blocks"
12634                 fi
12635                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12636                 do_facet $facet zfs set recordsize=32768 $ost
12637         done
12638
12639         # BS too small. Sufficient for functional testing.
12640         for facet in ${mfacets//,/ }; do
12641                 if [ -z $saved_mdt_blocks ]; then
12642                         saved_mdt_blocks=$(do_facet $facet \
12643                                 lctl get_param -n $mdt_param.blocksize)
12644                         echo "MDT Blocksize: $saved_mdt_blocks"
12645                 fi
12646                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12647                 do_facet $facet zfs set recordsize=32768 $mdt
12648         done
12649
12650         # Give new values chance to reflect change
12651         sleep 2
12652
12653         echo "After recordsize change"
12654         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12655         df_after=($(df -h | grep "$MOUNT"$))
12656
12657         # For checking.
12658         echo "lfs output : ${lfs_df_after[*]}"
12659         echo "df  output : ${df_after[*]}"
12660
12661         # Verify lfs df
12662         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12663                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12664         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12665                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12666         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12667                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12668
12669         # Verify df
12670         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12671                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12672         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12673                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12674         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12675                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12676
12677         # Restore MDT recordize back to original
12678         for facet in ${mfacets//,/ }; do
12679                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12680                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12681         done
12682
12683         # Restore OST recordize back to original
12684         for facet in ${ofacets//,/ }; do
12685                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12686                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12687         done
12688
12689         return 0
12690 }
12691 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12692
12693 test_104d() {
12694         (( $RUNAS_ID != $UID )) ||
12695                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12696
12697         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12698                 skip "lustre version doesn't support lctl dl with non-root"
12699
12700         # debugfs only allows root users to access files, so the
12701         # previous move of the "devices" file to debugfs broke
12702         # "lctl dl" for non-root users. The LU-9680 Netlink
12703         # interface again allows non-root users to list devices.
12704         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12705                 error "lctl dl doesn't work for non root"
12706
12707         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12708         [ "$ost_count" -eq $OSTCOUNT ]  ||
12709                 error "lctl dl reports wrong number of OST devices"
12710
12711         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12712         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12713                 error "lctl dl reports wrong number of MDT devices"
12714 }
12715 run_test 104d "$RUNAS lctl dl test"
12716
12717 test_105a() {
12718         # doesn't work on 2.4 kernels
12719         touch $DIR/$tfile
12720         if $(flock_is_enabled); then
12721                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12722         else
12723                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12724         fi
12725         rm -f $DIR/$tfile
12726 }
12727 run_test 105a "flock when mounted without -o flock test ========"
12728
12729 test_105b() {
12730         touch $DIR/$tfile
12731         if $(flock_is_enabled); then
12732                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12733         else
12734                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12735         fi
12736         rm -f $DIR/$tfile
12737 }
12738 run_test 105b "fcntl when mounted without -o flock test ========"
12739
12740 test_105c() {
12741         touch $DIR/$tfile
12742         if $(flock_is_enabled); then
12743                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12744         else
12745                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12746         fi
12747         rm -f $DIR/$tfile
12748 }
12749 run_test 105c "lockf when mounted without -o flock test"
12750
12751 test_105d() { # bug 15924
12752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12753
12754         test_mkdir $DIR/$tdir
12755         flock_is_enabled || skip_env "mount w/o flock enabled"
12756         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12757         $LCTL set_param fail_loc=0x80000315
12758         flocks_test 2 $DIR/$tdir
12759 }
12760 run_test 105d "flock race (should not freeze) ========"
12761
12762 test_105e() { # bug 22660 && 22040
12763         flock_is_enabled || skip_env "mount w/o flock enabled"
12764
12765         touch $DIR/$tfile
12766         flocks_test 3 $DIR/$tfile
12767 }
12768 run_test 105e "Two conflicting flocks from same process"
12769
12770 test_106() { #bug 10921
12771         test_mkdir $DIR/$tdir
12772         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12773         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12774 }
12775 run_test 106 "attempt exec of dir followed by chown of that dir"
12776
12777 test_107() {
12778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12779
12780         CDIR=`pwd`
12781         local file=core
12782
12783         cd $DIR
12784         rm -f $file
12785
12786         local save_pattern=$(sysctl -n kernel.core_pattern)
12787         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12788         sysctl -w kernel.core_pattern=$file
12789         sysctl -w kernel.core_uses_pid=0
12790
12791         ulimit -c unlimited
12792         sleep 60 &
12793         SLEEPPID=$!
12794
12795         sleep 1
12796
12797         kill -s 11 $SLEEPPID
12798         wait $SLEEPPID
12799         if [ -e $file ]; then
12800                 size=`stat -c%s $file`
12801                 [ $size -eq 0 ] && error "Fail to create core file $file"
12802         else
12803                 error "Fail to create core file $file"
12804         fi
12805         rm -f $file
12806         sysctl -w kernel.core_pattern=$save_pattern
12807         sysctl -w kernel.core_uses_pid=$save_uses_pid
12808         cd $CDIR
12809 }
12810 run_test 107 "Coredump on SIG"
12811
12812 test_110() {
12813         test_mkdir $DIR/$tdir
12814         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12815         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12816                 error "mkdir with 256 char should fail, but did not"
12817         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12818                 error "create with 255 char failed"
12819         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12820                 error "create with 256 char should fail, but did not"
12821
12822         ls -l $DIR/$tdir
12823         rm -rf $DIR/$tdir
12824 }
12825 run_test 110 "filename length checking"
12826
12827 test_116a() { # was previously test_116()
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12830         remote_mds_nodsh && skip "remote MDS with nodsh"
12831
12832         echo -n "Free space priority "
12833         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12834                 head -n1
12835         declare -a AVAIL
12836         free_min_max
12837
12838         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12839         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12840         stack_trap simple_cleanup_common
12841
12842         # Check if we need to generate uneven OSTs
12843         test_mkdir -p $DIR/$tdir/OST${MINI}
12844         local FILL=$((MINV / 4))
12845         local DIFF=$((MAXV - MINV))
12846         local DIFF2=$((DIFF * 100 / MINV))
12847
12848         local threshold=$(do_facet $SINGLEMDS \
12849                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12850         threshold=${threshold%%%}
12851         echo -n "Check for uneven OSTs: "
12852         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12853
12854         if [[ $DIFF2 -gt $threshold ]]; then
12855                 echo "ok"
12856                 echo "Don't need to fill OST$MINI"
12857         else
12858                 # generate uneven OSTs. Write 2% over the QOS threshold value
12859                 echo "no"
12860                 DIFF=$((threshold - DIFF2 + 2))
12861                 DIFF2=$((MINV * DIFF / 100))
12862                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12863                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12864                         error "setstripe failed"
12865                 DIFF=$((DIFF2 / 2048))
12866                 i=0
12867                 while [ $i -lt $DIFF ]; do
12868                         i=$((i + 1))
12869                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12870                                 bs=2M count=1 2>/dev/null
12871                         echo -n .
12872                 done
12873                 echo .
12874                 sync
12875                 sleep_maxage
12876                 free_min_max
12877         fi
12878
12879         DIFF=$((MAXV - MINV))
12880         DIFF2=$((DIFF * 100 / MINV))
12881         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12882         if [ $DIFF2 -gt $threshold ]; then
12883                 echo "ok"
12884         else
12885                 skip "QOS imbalance criteria not met"
12886         fi
12887
12888         MINI1=$MINI
12889         MINV1=$MINV
12890         MAXI1=$MAXI
12891         MAXV1=$MAXV
12892
12893         # now fill using QOS
12894         $LFS setstripe -c 1 $DIR/$tdir
12895         FILL=$((FILL / 200))
12896         if [ $FILL -gt 600 ]; then
12897                 FILL=600
12898         fi
12899         echo "writing $FILL files to QOS-assigned OSTs"
12900         i=0
12901         while [ $i -lt $FILL ]; do
12902                 i=$((i + 1))
12903                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12904                         count=1 2>/dev/null
12905                 echo -n .
12906         done
12907         echo "wrote $i 200k files"
12908         sync
12909         sleep_maxage
12910
12911         echo "Note: free space may not be updated, so measurements might be off"
12912         free_min_max
12913         DIFF2=$((MAXV - MINV))
12914         echo "free space delta: orig $DIFF final $DIFF2"
12915         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12916         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12917         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12918         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12919         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12920         if [[ $DIFF -gt 0 ]]; then
12921                 FILL=$((DIFF2 * 100 / DIFF - 100))
12922                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12923         fi
12924
12925         # Figure out which files were written where
12926         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12927                awk '/'$MINI1': / {print $2; exit}')
12928         echo $UUID
12929         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12930         echo "$MINC files created on smaller OST $MINI1"
12931         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12932                awk '/'$MAXI1': / {print $2; exit}')
12933         echo $UUID
12934         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12935         echo "$MAXC files created on larger OST $MAXI1"
12936         if [[ $MINC -gt 0 ]]; then
12937                 FILL=$((MAXC * 100 / MINC - 100))
12938                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12939         fi
12940         [[ $MAXC -gt $MINC ]] ||
12941                 error_ignore LU-9 "stripe QOS didn't balance free space"
12942 }
12943 run_test 116a "stripe QOS: free space balance ==================="
12944
12945 test_116b() { # LU-2093
12946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12947         remote_mds_nodsh && skip "remote MDS with nodsh"
12948
12949 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12950         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12951                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12952         [ -z "$old_rr" ] && skip "no QOS"
12953         do_facet $SINGLEMDS lctl set_param \
12954                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12955         mkdir -p $DIR/$tdir
12956         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12957         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12958         do_facet $SINGLEMDS lctl set_param fail_loc=0
12959         rm -rf $DIR/$tdir
12960         do_facet $SINGLEMDS lctl set_param \
12961                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12962 }
12963 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12964
12965 test_117() # bug 10891
12966 {
12967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12968
12969         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12970         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12971         lctl set_param fail_loc=0x21e
12972         > $DIR/$tfile || error "truncate failed"
12973         lctl set_param fail_loc=0
12974         echo "Truncate succeeded."
12975         rm -f $DIR/$tfile
12976 }
12977 run_test 117 "verify osd extend =========="
12978
12979 NO_SLOW_RESENDCOUNT=4
12980 export OLD_RESENDCOUNT=""
12981 set_resend_count () {
12982         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12983         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12984         lctl set_param -n $PROC_RESENDCOUNT $1
12985         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12986 }
12987
12988 # for reduce test_118* time (b=14842)
12989 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12990
12991 # Reset async IO behavior after error case
12992 reset_async() {
12993         FILE=$DIR/reset_async
12994
12995         # Ensure all OSCs are cleared
12996         $LFS setstripe -c -1 $FILE
12997         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12998         sync
12999         rm $FILE
13000 }
13001
13002 test_118a() #bug 11710
13003 {
13004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13005
13006         reset_async
13007
13008         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13009         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13010         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13011
13012         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13013                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13014                 return 1;
13015         fi
13016         rm -f $DIR/$tfile
13017 }
13018 run_test 118a "verify O_SYNC works =========="
13019
13020 test_118b()
13021 {
13022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13023         remote_ost_nodsh && skip "remote OST with nodsh"
13024
13025         reset_async
13026
13027         #define OBD_FAIL_SRV_ENOENT 0x217
13028         set_nodes_failloc "$(osts_nodes)" 0x217
13029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13030         RC=$?
13031         set_nodes_failloc "$(osts_nodes)" 0
13032         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13033         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13034                     grep -c writeback)
13035
13036         if [[ $RC -eq 0 ]]; then
13037                 error "Must return error due to dropped pages, rc=$RC"
13038                 return 1;
13039         fi
13040
13041         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13042                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13043                 return 1;
13044         fi
13045
13046         echo "Dirty pages not leaked on ENOENT"
13047
13048         # Due to the above error the OSC will issue all RPCs syncronously
13049         # until a subsequent RPC completes successfully without error.
13050         $MULTIOP $DIR/$tfile Ow4096yc
13051         rm -f $DIR/$tfile
13052
13053         return 0
13054 }
13055 run_test 118b "Reclaim dirty pages on fatal error =========="
13056
13057 test_118c()
13058 {
13059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13060
13061         # for 118c, restore the original resend count, LU-1940
13062         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13063                                 set_resend_count $OLD_RESENDCOUNT
13064         remote_ost_nodsh && skip "remote OST with nodsh"
13065
13066         reset_async
13067
13068         #define OBD_FAIL_OST_EROFS               0x216
13069         set_nodes_failloc "$(osts_nodes)" 0x216
13070
13071         # multiop should block due to fsync until pages are written
13072         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13073         MULTIPID=$!
13074         sleep 1
13075
13076         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13077                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13078         fi
13079
13080         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13081                     grep -c writeback)
13082         if [[ $WRITEBACK -eq 0 ]]; then
13083                 error "No page in writeback, writeback=$WRITEBACK"
13084         fi
13085
13086         set_nodes_failloc "$(osts_nodes)" 0
13087         wait $MULTIPID
13088         RC=$?
13089         if [[ $RC -ne 0 ]]; then
13090                 error "Multiop fsync failed, rc=$RC"
13091         fi
13092
13093         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13094         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13095                     grep -c writeback)
13096         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13097                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13098         fi
13099
13100         rm -f $DIR/$tfile
13101         echo "Dirty pages flushed via fsync on EROFS"
13102         return 0
13103 }
13104 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13105
13106 # continue to use small resend count to reduce test_118* time (b=14842)
13107 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13108
13109 test_118d()
13110 {
13111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13112         remote_ost_nodsh && skip "remote OST with nodsh"
13113
13114         reset_async
13115
13116         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13117         set_nodes_failloc "$(osts_nodes)" 0x214
13118         # multiop should block due to fsync until pages are written
13119         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13120         MULTIPID=$!
13121         sleep 1
13122
13123         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13124                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13125         fi
13126
13127         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13128                     grep -c writeback)
13129         if [[ $WRITEBACK -eq 0 ]]; then
13130                 error "No page in writeback, writeback=$WRITEBACK"
13131         fi
13132
13133         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13134         set_nodes_failloc "$(osts_nodes)" 0
13135
13136         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13137         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13138                     grep -c writeback)
13139         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13140                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13141         fi
13142
13143         rm -f $DIR/$tfile
13144         echo "Dirty pages gaurenteed flushed via fsync"
13145         return 0
13146 }
13147 run_test 118d "Fsync validation inject a delay of the bulk =========="
13148
13149 test_118f() {
13150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13151
13152         reset_async
13153
13154         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13155         lctl set_param fail_loc=0x8000040a
13156
13157         # Should simulate EINVAL error which is fatal
13158         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13159         RC=$?
13160         if [[ $RC -eq 0 ]]; then
13161                 error "Must return error due to dropped pages, rc=$RC"
13162         fi
13163
13164         lctl set_param fail_loc=0x0
13165
13166         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13167         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13168         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13169                     grep -c writeback)
13170         if [[ $LOCKED -ne 0 ]]; then
13171                 error "Locked pages remain in cache, locked=$LOCKED"
13172         fi
13173
13174         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13175                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13176         fi
13177
13178         rm -f $DIR/$tfile
13179         echo "No pages locked after fsync"
13180
13181         reset_async
13182         return 0
13183 }
13184 run_test 118f "Simulate unrecoverable OSC side error =========="
13185
13186 test_118g() {
13187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13188
13189         reset_async
13190
13191         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13192         lctl set_param fail_loc=0x406
13193
13194         # simulate local -ENOMEM
13195         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13196         RC=$?
13197
13198         lctl set_param fail_loc=0
13199         if [[ $RC -eq 0 ]]; then
13200                 error "Must return error due to dropped pages, rc=$RC"
13201         fi
13202
13203         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13204         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13205         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13206                         grep -c writeback)
13207         if [[ $LOCKED -ne 0 ]]; then
13208                 error "Locked pages remain in cache, locked=$LOCKED"
13209         fi
13210
13211         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13212                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13213         fi
13214
13215         rm -f $DIR/$tfile
13216         echo "No pages locked after fsync"
13217
13218         reset_async
13219         return 0
13220 }
13221 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13222
13223 test_118h() {
13224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13225         remote_ost_nodsh && skip "remote OST with nodsh"
13226
13227         reset_async
13228
13229         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13230         set_nodes_failloc "$(osts_nodes)" 0x20e
13231         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13232         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13233         RC=$?
13234
13235         set_nodes_failloc "$(osts_nodes)" 0
13236         if [[ $RC -eq 0 ]]; then
13237                 error "Must return error due to dropped pages, rc=$RC"
13238         fi
13239
13240         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13241         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13242         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13243                     grep -c writeback)
13244         if [[ $LOCKED -ne 0 ]]; then
13245                 error "Locked pages remain in cache, locked=$LOCKED"
13246         fi
13247
13248         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13249                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13250         fi
13251
13252         rm -f $DIR/$tfile
13253         echo "No pages locked after fsync"
13254
13255         return 0
13256 }
13257 run_test 118h "Verify timeout in handling recoverables errors  =========="
13258
13259 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13260
13261 test_118i() {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263         remote_ost_nodsh && skip "remote OST with nodsh"
13264
13265         reset_async
13266
13267         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13268         set_nodes_failloc "$(osts_nodes)" 0x20e
13269
13270         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13271         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13272         PID=$!
13273         sleep 5
13274         set_nodes_failloc "$(osts_nodes)" 0
13275
13276         wait $PID
13277         RC=$?
13278         if [[ $RC -ne 0 ]]; then
13279                 error "got error, but should be not, rc=$RC"
13280         fi
13281
13282         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13283         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13284         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13285         if [[ $LOCKED -ne 0 ]]; then
13286                 error "Locked pages remain in cache, locked=$LOCKED"
13287         fi
13288
13289         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13290                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13291         fi
13292
13293         rm -f $DIR/$tfile
13294         echo "No pages locked after fsync"
13295
13296         return 0
13297 }
13298 run_test 118i "Fix error before timeout in recoverable error  =========="
13299
13300 [ "$SLOW" = "no" ] && set_resend_count 4
13301
13302 test_118j() {
13303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13304         remote_ost_nodsh && skip "remote OST with nodsh"
13305
13306         reset_async
13307
13308         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13309         set_nodes_failloc "$(osts_nodes)" 0x220
13310
13311         # return -EIO from OST
13312         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13313         RC=$?
13314         set_nodes_failloc "$(osts_nodes)" 0x0
13315         if [[ $RC -eq 0 ]]; then
13316                 error "Must return error due to dropped pages, rc=$RC"
13317         fi
13318
13319         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13320         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13321         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13322         if [[ $LOCKED -ne 0 ]]; then
13323                 error "Locked pages remain in cache, locked=$LOCKED"
13324         fi
13325
13326         # in recoverable error on OST we want resend and stay until it finished
13327         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13328                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13329         fi
13330
13331         rm -f $DIR/$tfile
13332         echo "No pages locked after fsync"
13333
13334         return 0
13335 }
13336 run_test 118j "Simulate unrecoverable OST side error =========="
13337
13338 test_118k()
13339 {
13340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13341         remote_ost_nodsh && skip "remote OSTs with nodsh"
13342
13343         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13344         set_nodes_failloc "$(osts_nodes)" 0x20e
13345         test_mkdir $DIR/$tdir
13346
13347         for ((i=0;i<10;i++)); do
13348                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13349                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13350                 SLEEPPID=$!
13351                 sleep 0.500s
13352                 kill $SLEEPPID
13353                 wait $SLEEPPID
13354         done
13355
13356         set_nodes_failloc "$(osts_nodes)" 0
13357         rm -rf $DIR/$tdir
13358 }
13359 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13360
13361 test_118l() # LU-646
13362 {
13363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13364
13365         test_mkdir $DIR/$tdir
13366         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13367         rm -rf $DIR/$tdir
13368 }
13369 run_test 118l "fsync dir"
13370
13371 test_118m() # LU-3066
13372 {
13373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13374
13375         test_mkdir $DIR/$tdir
13376         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13377         rm -rf $DIR/$tdir
13378 }
13379 run_test 118m "fdatasync dir ========="
13380
13381 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13382
13383 test_118n()
13384 {
13385         local begin
13386         local end
13387
13388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13389         remote_ost_nodsh && skip "remote OSTs with nodsh"
13390
13391         # Sleep to avoid a cached response.
13392         #define OBD_STATFS_CACHE_SECONDS 1
13393         sleep 2
13394
13395         # Inject a 10 second delay in the OST_STATFS handler.
13396         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13397         set_nodes_failloc "$(osts_nodes)" 0x242
13398
13399         begin=$SECONDS
13400         stat --file-system $MOUNT > /dev/null
13401         end=$SECONDS
13402
13403         set_nodes_failloc "$(osts_nodes)" 0
13404
13405         if ((end - begin > 20)); then
13406             error "statfs took $((end - begin)) seconds, expected 10"
13407         fi
13408 }
13409 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13410
13411 test_119a() # bug 11737
13412 {
13413         BSIZE=$((512 * 1024))
13414         directio write $DIR/$tfile 0 1 $BSIZE
13415         # We ask to read two blocks, which is more than a file size.
13416         # directio will indicate an error when requested and actual
13417         # sizes aren't equeal (a normal situation in this case) and
13418         # print actual read amount.
13419         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13420         if [ "$NOB" != "$BSIZE" ]; then
13421                 error "read $NOB bytes instead of $BSIZE"
13422         fi
13423         rm -f $DIR/$tfile
13424 }
13425 run_test 119a "Short directIO read must return actual read amount"
13426
13427 test_119b() # bug 11737
13428 {
13429         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13430
13431         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13432         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13433         sync
13434         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13435                 error "direct read failed"
13436         rm -f $DIR/$tfile
13437 }
13438 run_test 119b "Sparse directIO read must return actual read amount"
13439
13440 test_119c() # bug 13099
13441 {
13442         BSIZE=1048576
13443         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13444         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13445         rm -f $DIR/$tfile
13446 }
13447 run_test 119c "Testing for direct read hitting hole"
13448
13449 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13450 # Maloo test history
13451
13452 test_119e()
13453 {
13454         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13455
13456         local stripe_size=$((1024 * 1024)) #1 MiB
13457         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13458         local file_size=$((25 * stripe_size))
13459         local bsizes
13460
13461         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13462         stack_trap "rm -f $DIR/$tfile*"
13463
13464         # Just a bit bigger than the largest size in the test set below
13465         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13466                 error "buffered i/o to create file failed"
13467
13468         if zfs_or_rotational; then
13469                 # DIO on ZFS can take up to 2 seconds per IO
13470                 # rotational is better, but still slow.
13471                 # Limit testing on those media to larger sizes
13472                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13473         else
13474                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13475                         $((stripe_size * 4))"
13476         fi
13477
13478         for bs in $bsizes; do
13479                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13480                 echo "Read/write with DIO at size $bs"
13481                 # Read and write with DIO from source to dest
13482                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13483                         iflag=direct oflag=direct ||
13484                         error "dio failed"
13485
13486                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13487                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13488                         error "size incorrect, file copy read/write bsize: $bs"
13489                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13490                         error "files differ, bsize $bs"
13491                 rm -f $DIR/$tfile.2
13492         done
13493 }
13494 run_test 119e "Basic tests of dio read and write at various sizes"
13495
13496 test_119f()
13497 {
13498         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13499
13500         local stripe_size=$((1024 * 1024)) #1 MiB
13501         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13502         local file_size=$((25 * stripe_size))
13503         local bsizes
13504
13505         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13506         stack_trap "rm -f $DIR/$tfile*"
13507
13508         # Just a bit bigger than the largest size in the test set below
13509         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13510                 error "buffered i/o to create file failed"
13511
13512         if zfs_or_rotational; then
13513                 # DIO on ZFS can take up to 2 seconds per IO
13514                 # rotational is better, but still slow.
13515                 # Limit testing on those media to larger sizes
13516                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13517         else
13518                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13519                         $((stripe_size * 4))"
13520         fi
13521
13522         for bs in $bsizes; do
13523                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13524                 # Read and write with DIO from source to dest in two
13525                 # threads - should give correct copy of file
13526
13527                 echo "bs: $bs"
13528                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13529                         oflag=direct conv=notrunc &
13530                 pid_dio1=$!
13531                 # Note block size is different here for a more interesting race
13532                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13533                         iflag=direct oflag=direct conv=notrunc &
13534                 pid_dio2=$!
13535                 wait $pid_dio1
13536                 rc1=$?
13537                 wait $pid_dio2
13538                 rc2=$?
13539                 if (( rc1 != 0 )); then
13540                         error "dio copy 1 w/bsize $bs failed: $rc1"
13541                 fi
13542                 if (( rc2 != 0 )); then
13543                         error "dio copy 2 w/bsize $bs failed: $rc2"
13544                 fi
13545
13546
13547                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13548                         error "size incorrect, file copy read/write bsize: $bs"
13549                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13550                         error "files differ, bsize $bs"
13551                 rm -f $DIR/$tfile.2
13552         done
13553 }
13554 run_test 119f "dio vs dio race"
13555
13556 test_119g()
13557 {
13558         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13559
13560         local stripe_size=$((1024 * 1024)) #1 MiB
13561         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13562         local file_size=$((25 * stripe_size))
13563         local bsizes
13564
13565         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13566         stack_trap "rm -f $DIR/$tfile*"
13567
13568         # Just a bit bigger than the largest size in the test set below
13569         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13570                 error "buffered i/o to create file failed"
13571
13572         if zfs_or_rotational; then
13573                 # DIO on ZFS can take up to 2 seconds per IO
13574                 # rotational is better, but still slow.
13575                 # Limit testing on those media to larger sizes
13576                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13577         else
13578                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13579                         $((stripe_size * 4))"
13580         fi
13581
13582         for bs in $bsizes; do
13583                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13584                 echo "bs: $bs"
13585                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13586                         oflag=direct conv=notrunc &
13587                 pid_dio1=$!
13588                 # Buffered I/O with similar but not the same block size
13589                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13590                 pid_bio2=$!
13591                 wait $pid_dio1
13592                 rc1=$?
13593                 wait $pid_bio2
13594                 rc2=$?
13595                 if (( rc1 != 0 )); then
13596                         error "dio copy 1 w/bsize $bs failed: $rc1"
13597                 fi
13598                 if (( rc2 != 0 )); then
13599                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13600                 fi
13601
13602                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13603                         error "size incorrect"
13604                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13605                         error "files differ, bsize $bs"
13606                 rm -f $DIR/$tfile.2
13607         done
13608 }
13609 run_test 119g "dio vs buffered I/O race"
13610
13611 test_120a() {
13612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13613         remote_mds_nodsh && skip "remote MDS with nodsh"
13614         test_mkdir -i0 -c1 $DIR/$tdir
13615         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13616                 skip_env "no early lock cancel on server"
13617
13618         lru_resize_disable mdc
13619         lru_resize_disable osc
13620         cancel_lru_locks mdc
13621         # asynchronous object destroy at MDT could cause bl ast to client
13622         cancel_lru_locks osc
13623
13624         stat $DIR/$tdir > /dev/null
13625         can1=$(do_facet mds1 \
13626                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13627                awk '/ldlm_cancel/ {print $2}')
13628         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13629                awk '/ldlm_bl_callback/ {print $2}')
13630         test_mkdir -i0 -c1 $DIR/$tdir/d1
13631         can2=$(do_facet mds1 \
13632                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13633                awk '/ldlm_cancel/ {print $2}')
13634         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13635                awk '/ldlm_bl_callback/ {print $2}')
13636         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13637         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13638         lru_resize_enable mdc
13639         lru_resize_enable osc
13640 }
13641 run_test 120a "Early Lock Cancel: mkdir test"
13642
13643 test_120b() {
13644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13645         remote_mds_nodsh && skip "remote MDS with nodsh"
13646         test_mkdir $DIR/$tdir
13647         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13648                 skip_env "no early lock cancel on server"
13649
13650         lru_resize_disable mdc
13651         lru_resize_disable osc
13652         cancel_lru_locks mdc
13653         stat $DIR/$tdir > /dev/null
13654         can1=$(do_facet $SINGLEMDS \
13655                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13656                awk '/ldlm_cancel/ {print $2}')
13657         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13658                awk '/ldlm_bl_callback/ {print $2}')
13659         touch $DIR/$tdir/f1
13660         can2=$(do_facet $SINGLEMDS \
13661                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13662                awk '/ldlm_cancel/ {print $2}')
13663         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13664                awk '/ldlm_bl_callback/ {print $2}')
13665         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13666         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13667         lru_resize_enable mdc
13668         lru_resize_enable osc
13669 }
13670 run_test 120b "Early Lock Cancel: create test"
13671
13672 test_120c() {
13673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13674         remote_mds_nodsh && skip "remote MDS with nodsh"
13675         test_mkdir -i0 -c1 $DIR/$tdir
13676         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13677                 skip "no early lock cancel on server"
13678
13679         lru_resize_disable mdc
13680         lru_resize_disable osc
13681         test_mkdir -i0 -c1 $DIR/$tdir/d1
13682         test_mkdir -i0 -c1 $DIR/$tdir/d2
13683         touch $DIR/$tdir/d1/f1
13684         cancel_lru_locks mdc
13685         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13686         can1=$(do_facet mds1 \
13687                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13688                awk '/ldlm_cancel/ {print $2}')
13689         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13690                awk '/ldlm_bl_callback/ {print $2}')
13691         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13692         can2=$(do_facet mds1 \
13693                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13694                awk '/ldlm_cancel/ {print $2}')
13695         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13696                awk '/ldlm_bl_callback/ {print $2}')
13697         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13698         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13699         lru_resize_enable mdc
13700         lru_resize_enable osc
13701 }
13702 run_test 120c "Early Lock Cancel: link test"
13703
13704 test_120d() {
13705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13706         remote_mds_nodsh && skip "remote MDS with nodsh"
13707         test_mkdir -i0 -c1 $DIR/$tdir
13708         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13709                 skip_env "no early lock cancel on server"
13710
13711         lru_resize_disable mdc
13712         lru_resize_disable osc
13713         touch $DIR/$tdir
13714         cancel_lru_locks mdc
13715         stat $DIR/$tdir > /dev/null
13716         can1=$(do_facet mds1 \
13717                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13718                awk '/ldlm_cancel/ {print $2}')
13719         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13720                awk '/ldlm_bl_callback/ {print $2}')
13721         chmod a+x $DIR/$tdir
13722         can2=$(do_facet mds1 \
13723                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13724                awk '/ldlm_cancel/ {print $2}')
13725         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13726                awk '/ldlm_bl_callback/ {print $2}')
13727         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13728         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13729         lru_resize_enable mdc
13730         lru_resize_enable osc
13731 }
13732 run_test 120d "Early Lock Cancel: setattr test"
13733
13734 test_120e() {
13735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13736         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13737                 skip_env "no early lock cancel on server"
13738         remote_mds_nodsh && skip "remote MDS with nodsh"
13739
13740         local dlmtrace_set=false
13741
13742         test_mkdir -i0 -c1 $DIR/$tdir
13743         lru_resize_disable mdc
13744         lru_resize_disable osc
13745         ! $LCTL get_param debug | grep -q dlmtrace &&
13746                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13747         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13748         cancel_lru_locks mdc
13749         cancel_lru_locks osc
13750         dd if=$DIR/$tdir/f1 of=/dev/null
13751         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13752         # XXX client can not do early lock cancel of OST lock
13753         # during unlink (LU-4206), so cancel osc lock now.
13754         sleep 2
13755         cancel_lru_locks osc
13756         can1=$(do_facet mds1 \
13757                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13758                awk '/ldlm_cancel/ {print $2}')
13759         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13760                awk '/ldlm_bl_callback/ {print $2}')
13761         unlink $DIR/$tdir/f1
13762         sleep 5
13763         can2=$(do_facet mds1 \
13764                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13765                awk '/ldlm_cancel/ {print $2}')
13766         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13767                awk '/ldlm_bl_callback/ {print $2}')
13768         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13769                 $LCTL dk $TMP/cancel.debug.txt
13770         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13771                 $LCTL dk $TMP/blocking.debug.txt
13772         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13773         lru_resize_enable mdc
13774         lru_resize_enable osc
13775 }
13776 run_test 120e "Early Lock Cancel: unlink test"
13777
13778 test_120f() {
13779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13780         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13781                 skip_env "no early lock cancel on server"
13782         remote_mds_nodsh && skip "remote MDS with nodsh"
13783
13784         test_mkdir -i0 -c1 $DIR/$tdir
13785         lru_resize_disable mdc
13786         lru_resize_disable osc
13787         test_mkdir -i0 -c1 $DIR/$tdir/d1
13788         test_mkdir -i0 -c1 $DIR/$tdir/d2
13789         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13790         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13791         cancel_lru_locks mdc
13792         cancel_lru_locks osc
13793         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13794         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13795         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13796         # XXX client can not do early lock cancel of OST lock
13797         # during rename (LU-4206), so cancel osc lock now.
13798         sleep 2
13799         cancel_lru_locks osc
13800         can1=$(do_facet mds1 \
13801                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13802                awk '/ldlm_cancel/ {print $2}')
13803         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13804                awk '/ldlm_bl_callback/ {print $2}')
13805         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13806         sleep 5
13807         can2=$(do_facet mds1 \
13808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13809                awk '/ldlm_cancel/ {print $2}')
13810         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13811                awk '/ldlm_bl_callback/ {print $2}')
13812         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13813         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13814         lru_resize_enable mdc
13815         lru_resize_enable osc
13816 }
13817 run_test 120f "Early Lock Cancel: rename test"
13818
13819 test_120g() {
13820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13821         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13822                 skip_env "no early lock cancel on server"
13823         remote_mds_nodsh && skip "remote MDS with nodsh"
13824
13825         lru_resize_disable mdc
13826         lru_resize_disable osc
13827         count=10000
13828         echo create $count files
13829         test_mkdir $DIR/$tdir
13830         cancel_lru_locks mdc
13831         cancel_lru_locks osc
13832         t0=$(date +%s)
13833
13834         can0=$(do_facet $SINGLEMDS \
13835                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13836                awk '/ldlm_cancel/ {print $2}')
13837         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13838                awk '/ldlm_bl_callback/ {print $2}')
13839         createmany -o $DIR/$tdir/f $count
13840         sync
13841         can1=$(do_facet $SINGLEMDS \
13842                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13843                awk '/ldlm_cancel/ {print $2}')
13844         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13845                awk '/ldlm_bl_callback/ {print $2}')
13846         t1=$(date +%s)
13847         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13848         echo rm $count files
13849         rm -r $DIR/$tdir
13850         sync
13851         can2=$(do_facet $SINGLEMDS \
13852                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13853                awk '/ldlm_cancel/ {print $2}')
13854         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13855                awk '/ldlm_bl_callback/ {print $2}')
13856         t2=$(date +%s)
13857         echo total: $count removes in $((t2-t1))
13858         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13859         sleep 2
13860         # wait for commitment of removal
13861         lru_resize_enable mdc
13862         lru_resize_enable osc
13863 }
13864 run_test 120g "Early Lock Cancel: performance test"
13865
13866 test_121() { #bug #10589
13867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13868
13869         rm -rf $DIR/$tfile
13870         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13871 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13872         lctl set_param fail_loc=0x310
13873         cancel_lru_locks osc > /dev/null
13874         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13875         lctl set_param fail_loc=0
13876         [[ $reads -eq $writes ]] ||
13877                 error "read $reads blocks, must be $writes blocks"
13878 }
13879 run_test 121 "read cancel race ========="
13880
13881 test_123a_base() { # was test 123, statahead(bug 11401)
13882         local lsx="$1"
13883
13884         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13885
13886         SLOWOK=0
13887         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13888                 log "testing UP system. Performance may be lower than expected."
13889                 SLOWOK=1
13890         fi
13891         running_in_vm && SLOWOK=1
13892
13893         $LCTL set_param mdc.*.batch_stats=0
13894
13895         rm -rf $DIR/$tdir
13896         test_mkdir $DIR/$tdir
13897         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13898         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13899         MULT=10
13900         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13901                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13902
13903                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13904                 lctl set_param -n llite.*.statahead_max 0
13905                 lctl get_param llite.*.statahead_max
13906                 cancel_lru_locks mdc
13907                 cancel_lru_locks osc
13908                 stime=$(date +%s)
13909                 time $lsx $DIR/$tdir | wc -l
13910                 etime=$(date +%s)
13911                 delta=$((etime - stime))
13912                 log "$lsx $i files without statahead: $delta sec"
13913                 lctl set_param llite.*.statahead_max=$max
13914
13915                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13916                          awk '/statahead.wrong:/ { print $NF }')
13917                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13918                 cancel_lru_locks mdc
13919                 cancel_lru_locks osc
13920                 stime=$(date +%s)
13921                 time $lsx $DIR/$tdir | wc -l
13922                 etime=$(date +%s)
13923                 delta_sa=$((etime - stime))
13924                 log "$lsx $i files with statahead: $delta_sa sec"
13925                 lctl get_param -n llite.*.statahead_stats
13926                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13927                          awk '/statahead.wrong:/ { print $NF }')
13928
13929                 [[ $swrong -lt $ewrong ]] &&
13930                         log "statahead was stopped, maybe too many locks held!"
13931                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13932
13933                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13934                         max=$(lctl get_param -n llite.*.statahead_max |
13935                                 head -n 1)
13936                         lctl set_param -n llite.*.statahead_max 0
13937                         lctl get_param llite.*.statahead_max
13938                         cancel_lru_locks mdc
13939                         cancel_lru_locks osc
13940                         stime=$(date +%s)
13941                         time $lsx $DIR/$tdir | wc -l
13942                         etime=$(date +%s)
13943                         delta=$((etime - stime))
13944                         log "$lsx $i files again without statahead: $delta sec"
13945                         lctl set_param llite.*.statahead_max=$max
13946                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13947                                 if [ $SLOWOK -eq 0 ]; then
13948                                         error "$lsx $i files is slower with statahead!"
13949                                 else
13950                                         log "$lsx $i files is slower with statahead!"
13951                                 fi
13952                                 break
13953                         fi
13954                 fi
13955
13956                 [ $delta -gt 20 ] && break
13957                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13958                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13959         done
13960         log "$lsx done"
13961
13962         stime=$(date +%s)
13963         rm -r $DIR/$tdir
13964         sync
13965         etime=$(date +%s)
13966         delta=$((etime - stime))
13967         log "rm -r $DIR/$tdir/: $delta seconds"
13968         log "rm done"
13969         lctl get_param -n llite.*.statahead_stats
13970         $LCTL get_param mdc.*.batch_stats
13971 }
13972
13973 test_123aa() {
13974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13975
13976         test_123a_base "ls -l"
13977 }
13978 run_test 123aa "verify statahead work"
13979
13980 test_123ab() {
13981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13982
13983         statx_supported || skip_env "Test must be statx() syscall supported"
13984
13985         test_123a_base "$STATX -l"
13986 }
13987 run_test 123ab "verify statahead work by using statx"
13988
13989 test_123ac() {
13990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13991
13992         statx_supported || skip_env "Test must be statx() syscall supported"
13993
13994         local rpcs_before
13995         local rpcs_after
13996         local agl_before
13997         local agl_after
13998
13999         cancel_lru_locks $OSC
14000         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14001         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14002                      awk '/agl.total:/ { print $NF }')
14003         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14004         test_123a_base "$STATX --cached=always -D"
14005         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14006                     awk '/agl.total:/ { print $NF }')
14007         [ $agl_before -eq $agl_after ] ||
14008                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14009         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14010         [ $rpcs_after -eq $rpcs_before ] ||
14011                 error "$STATX should not send glimpse RPCs to $OSC"
14012 }
14013 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14014
14015 test_batch_statahead() {
14016         local max=$1
14017         local batch_max=$2
14018         local num=10000
14019         local batch_rpcs
14020         local unbatch_rpcs
14021         local hit_total
14022
14023         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14024         $LCTL set_param mdc.*.batch_stats=0
14025         $LCTL set_param llite.*.statahead_max=$max
14026         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14027         # Verify that batched statahead is faster than one without statahead
14028         test_123a_base "ls -l"
14029
14030         stack_trap "rm -rf $DIR/$tdir" EXIT
14031         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14032         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14033
14034         # unbatched statahead
14035         $LCTL set_param llite.*.statahead_batch_max=0
14036         $LCTL set_param llite.*.statahead_stats=clear
14037         $LCTL set_param mdc.*.stats=clear
14038         cancel_lru_locks mdc
14039         cancel_lru_locks osc
14040         time ls -l $DIR/$tdir | wc -l
14041         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14042         sleep 2
14043         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14044                     awk '/hit.total:/ { print $NF }')
14045         # hit ratio should be larger than 75% (7500).
14046         (( $hit_total > 7500 )) ||
14047                 error "unbatched statahead hit count ($hit_total) is too low"
14048
14049         # batched statahead
14050         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14051         $LCTL set_param llite.*.statahead_stats=clear
14052         $LCTL set_param mdc.*.batch_stats=clear
14053         $LCTL set_param mdc.*.stats=clear
14054         cancel_lru_locks mdc
14055         cancel_lru_locks osc
14056         time ls -l $DIR/$tdir | wc -l
14057         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14058         # wait for statahead thread to quit and update statahead stats
14059         sleep 2
14060         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14061                     awk '/hit.total:/ { print $NF }')
14062         # hit ratio should be larger than 75% (7500).
14063         (( $hit_total > 7500 )) ||
14064                 error "batched statahead hit count ($hit_total) is too low"
14065
14066         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14067         (( $unbatch_rpcs > $batch_rpcs )) ||
14068                 error "batched statahead does not reduce RPC count"
14069         $LCTL get_param mdc.*.batch_stats
14070 }
14071
14072 test_123ad() {
14073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14074
14075         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14076                 skip "Need server version at least 2.15.53"
14077
14078         local max
14079         local batch_max
14080
14081         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14082         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14083
14084         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14085         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14086
14087         test_batch_statahead 32 32
14088         test_batch_statahead 2048 256
14089 }
14090 run_test 123ad "Verify batching statahead works correctly"
14091
14092 test_123b () { # statahead(bug 15027)
14093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14094
14095         test_mkdir $DIR/$tdir
14096         createmany -o $DIR/$tdir/$tfile-%d 1000
14097
14098         cancel_lru_locks mdc
14099         cancel_lru_locks osc
14100
14101 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14102         lctl set_param fail_loc=0x80000803
14103         ls -lR $DIR/$tdir > /dev/null
14104         log "ls done"
14105         lctl set_param fail_loc=0x0
14106         lctl get_param -n llite.*.statahead_stats
14107         rm -r $DIR/$tdir
14108         sync
14109
14110 }
14111 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14112
14113 test_123c() {
14114         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14115
14116         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14117         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14118         touch $DIR/$tdir.1/{1..3}
14119         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14120
14121         remount_client $MOUNT
14122
14123         $MULTIOP $DIR/$tdir.0 Q
14124
14125         # let statahead to complete
14126         ls -l $DIR/$tdir.0 > /dev/null
14127
14128         testid=$(echo $TESTNAME | tr '_' ' ')
14129         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14130                 error "statahead warning" || true
14131 }
14132 run_test 123c "Can not initialize inode warning on DNE statahead"
14133
14134 test_123d() {
14135         local num=100
14136         local swrong
14137         local ewrong
14138
14139         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14140         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14141                 error "setdirstripe $DIR/$tdir failed"
14142         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14143         remount_client $MOUNT
14144         $LCTL get_param llite.*.statahead_max
14145         $LCTL set_param llite.*.statahead_stats=0 ||
14146                 error "clear statahead_stats failed"
14147         swrong=$(lctl get_param -n llite.*.statahead_stats |
14148                  awk '/statahead.wrong:/ { print $NF }')
14149         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14150         # wait for statahead thread finished to update hit/miss stats.
14151         sleep 1
14152         $LCTL get_param -n llite.*.statahead_stats
14153         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14154                  awk '/statahead.wrong:/ { print $NF }')
14155         (( $swrong == $ewrong )) ||
14156                 log "statahead was stopped, maybe too many locks held!"
14157 }
14158 run_test 123d "Statahead on striped directories works correctly"
14159
14160 test_123e() {
14161         local max
14162         local batch_max
14163         local dir=$DIR/$tdir
14164
14165         mkdir $dir || error "mkdir $dir failed"
14166         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14167         stack_trap "rm -rf $dir"
14168
14169         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14170
14171         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14172         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14173         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14174         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14175
14176         $LCTL set_param llite.*.statahead_max=2048
14177         $LCTL set_param llite.*.statahead_batch_max=1024
14178
14179         ls -l $dir
14180         $LCTL get_param mdc.*.batch_stats
14181         $LCTL get_param llite.*.statahead_*
14182 }
14183 run_test 123e "statahead with large wide striping"
14184
14185 test_123f() {
14186         local max
14187         local batch_max
14188         local dir=$DIR/$tdir
14189
14190         mkdir $dir || error "mkdir $dir failed"
14191         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14192         stack_trap "rm -rf $dir"
14193
14194         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14195
14196         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14197         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14198
14199         $LCTL set_param llite.*.statahead_max=64
14200         $LCTL set_param llite.*.statahead_batch_max=64
14201
14202         ls -l $dir
14203         lctl get_param mdc.*.batch_stats
14204         lctl get_param llite.*.statahead_*
14205
14206         $LCTL set_param llite.*.statahead_max=$max
14207         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14208 }
14209 run_test 123f "Retry mechanism with large wide striping files"
14210
14211 test_124a() {
14212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14213         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14214                 skip_env "no lru resize on server"
14215
14216         local NR=2000
14217
14218         test_mkdir $DIR/$tdir
14219
14220         log "create $NR files at $DIR/$tdir"
14221         createmany -o $DIR/$tdir/f $NR ||
14222                 error "failed to create $NR files in $DIR/$tdir"
14223
14224         cancel_lru_locks mdc
14225         ls -l $DIR/$tdir > /dev/null
14226
14227         local NSDIR=""
14228         local LRU_SIZE=0
14229         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14230                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14231                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14232                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14233                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14234                         log "NSDIR=$NSDIR"
14235                         log "NS=$(basename $NSDIR)"
14236                         break
14237                 fi
14238         done
14239
14240         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14241                 skip "Not enough cached locks created!"
14242         fi
14243         log "LRU=$LRU_SIZE"
14244
14245         local SLEEP=30
14246
14247         # We know that lru resize allows one client to hold $LIMIT locks
14248         # for 10h. After that locks begin to be killed by client.
14249         local MAX_HRS=10
14250         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14251         log "LIMIT=$LIMIT"
14252         if [ $LIMIT -lt $LRU_SIZE ]; then
14253                 skip "Limit is too small $LIMIT"
14254         fi
14255
14256         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14257         # killing locks. Some time was spent for creating locks. This means
14258         # that up to the moment of sleep finish we must have killed some of
14259         # them (10-100 locks). This depends on how fast ther were created.
14260         # Many of them were touched in almost the same moment and thus will
14261         # be killed in groups.
14262         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14263
14264         # Use $LRU_SIZE_B here to take into account real number of locks
14265         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14266         local LRU_SIZE_B=$LRU_SIZE
14267         log "LVF=$LVF"
14268         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14269         log "OLD_LVF=$OLD_LVF"
14270         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14271
14272         # Let's make sure that we really have some margin. Client checks
14273         # cached locks every 10 sec.
14274         SLEEP=$((SLEEP+20))
14275         log "Sleep ${SLEEP} sec"
14276         local SEC=0
14277         while ((SEC<$SLEEP)); do
14278                 echo -n "..."
14279                 sleep 5
14280                 SEC=$((SEC+5))
14281                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14282                 echo -n "$LRU_SIZE"
14283         done
14284         echo ""
14285         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14286         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14287
14288         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14289                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14290                 unlinkmany $DIR/$tdir/f $NR
14291                 return
14292         }
14293
14294         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14295         log "unlink $NR files at $DIR/$tdir"
14296         unlinkmany $DIR/$tdir/f $NR
14297 }
14298 run_test 124a "lru resize ======================================="
14299
14300 get_max_pool_limit()
14301 {
14302         local limit=$($LCTL get_param \
14303                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14304         local max=0
14305         for l in $limit; do
14306                 if [[ $l -gt $max ]]; then
14307                         max=$l
14308                 fi
14309         done
14310         echo $max
14311 }
14312
14313 test_124b() {
14314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14315         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14316                 skip_env "no lru resize on server"
14317
14318         LIMIT=$(get_max_pool_limit)
14319
14320         NR=$(($(default_lru_size)*20))
14321         if [[ $NR -gt $LIMIT ]]; then
14322                 log "Limit lock number by $LIMIT locks"
14323                 NR=$LIMIT
14324         fi
14325
14326         IFree=$(mdsrate_inodes_available)
14327         if [ $IFree -lt $NR ]; then
14328                 log "Limit lock number by $IFree inodes"
14329                 NR=$IFree
14330         fi
14331
14332         lru_resize_disable mdc
14333         test_mkdir -p $DIR/$tdir/disable_lru_resize
14334
14335         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14336         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14337         cancel_lru_locks mdc
14338         stime=`date +%s`
14339         PID=""
14340         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14341         PID="$PID $!"
14342         sleep 2
14343         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14344         PID="$PID $!"
14345         sleep 2
14346         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14347         PID="$PID $!"
14348         wait $PID
14349         etime=`date +%s`
14350         nolruresize_delta=$((etime-stime))
14351         log "ls -la time: $nolruresize_delta seconds"
14352         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14353         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14354
14355         lru_resize_enable mdc
14356         test_mkdir -p $DIR/$tdir/enable_lru_resize
14357
14358         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14359         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14360         cancel_lru_locks mdc
14361         stime=`date +%s`
14362         PID=""
14363         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14364         PID="$PID $!"
14365         sleep 2
14366         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14367         PID="$PID $!"
14368         sleep 2
14369         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14370         PID="$PID $!"
14371         wait $PID
14372         etime=`date +%s`
14373         lruresize_delta=$((etime-stime))
14374         log "ls -la time: $lruresize_delta seconds"
14375         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14376
14377         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14378                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14379         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14380                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14381         else
14382                 log "lru resize performs the same with no lru resize"
14383         fi
14384         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14385 }
14386 run_test 124b "lru resize (performance test) ======================="
14387
14388 test_124c() {
14389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14390         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14391                 skip_env "no lru resize on server"
14392
14393         # cache ununsed locks on client
14394         local nr=100
14395         cancel_lru_locks mdc
14396         test_mkdir $DIR/$tdir
14397         createmany -o $DIR/$tdir/f $nr ||
14398                 error "failed to create $nr files in $DIR/$tdir"
14399         ls -l $DIR/$tdir > /dev/null
14400
14401         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14402         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14403         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14404         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14405         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14406
14407         # set lru_max_age to 1 sec
14408         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14409         echo "sleep $((recalc_p * 2)) seconds..."
14410         sleep $((recalc_p * 2))
14411
14412         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14413         # restore lru_max_age
14414         $LCTL set_param -n $nsdir.lru_max_age $max_age
14415         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14416         unlinkmany $DIR/$tdir/f $nr
14417 }
14418 run_test 124c "LRUR cancel very aged locks"
14419
14420 test_124d() {
14421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14422         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14423                 skip_env "no lru resize on server"
14424
14425         # cache ununsed locks on client
14426         local nr=100
14427
14428         lru_resize_disable mdc
14429         stack_trap "lru_resize_enable mdc" EXIT
14430
14431         cancel_lru_locks mdc
14432
14433         # asynchronous object destroy at MDT could cause bl ast to client
14434         test_mkdir $DIR/$tdir
14435         createmany -o $DIR/$tdir/f $nr ||
14436                 error "failed to create $nr files in $DIR/$tdir"
14437         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14438
14439         ls -l $DIR/$tdir > /dev/null
14440
14441         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14442         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14443         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14444         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14445
14446         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14447
14448         # set lru_max_age to 1 sec
14449         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14450         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14451
14452         echo "sleep $((recalc_p * 2)) seconds..."
14453         sleep $((recalc_p * 2))
14454
14455         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14456
14457         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14458 }
14459 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14460
14461 test_125() { # 13358
14462         $LCTL get_param -n llite.*.client_type | grep -q local ||
14463                 skip "must run as local client"
14464         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14465                 skip_env "must have acl enabled"
14466         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14467         id $USER0 || skip_env "missing user $USER0"
14468
14469         test_mkdir $DIR/$tdir
14470         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14471         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14472                 error "setfacl $DIR/$tdir failed"
14473         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14474 }
14475 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14476
14477 test_126() { # bug 12829/13455
14478         $GSS && skip_env "must run as gss disabled"
14479         $LCTL get_param -n llite.*.client_type | grep -q local ||
14480                 skip "must run as local client"
14481         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14482
14483         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14484         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14485         rm -f $DIR/$tfile
14486         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14487 }
14488 run_test 126 "check that the fsgid provided by the client is taken into account"
14489
14490 test_127a() { # bug 15521
14491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14492         local name count samp unit min max sum sumsq
14493         local tmpfile=$TMP/$tfile.tmp
14494
14495         # enable stats header if it is disabled
14496         $LCTL set_param enable_stats_header=1
14497
14498         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14499         echo "stats before reset"
14500         stack_trap "rm -f $tmpfile"
14501         local now=$(date +%s)
14502
14503         $LCTL get_param osc.*.stats | tee $tmpfile
14504
14505         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14506         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14507         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14508         local uptime=$(awk '{ print $1 }' /proc/uptime)
14509
14510         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14511         (( ${snapshot_time%\.*} >= $now - 5 &&
14512            ${snapshot_time%\.*} <= $now + 5 )) ||
14513                 error "snapshot_time=$snapshot_time != now=$now"
14514         # elapsed _should_ be from mount, but at least less than uptime
14515         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14516                 error "elapsed=$elapsed > uptime=$uptime"
14517         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14518            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14519                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14520
14521         $LCTL set_param osc.*.stats=0
14522         local reset=$(date +%s)
14523         local fsize=$((2048 * 1024))
14524
14525         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14526         cancel_lru_locks osc
14527         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14528
14529         now=$(date +%s)
14530         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14531         while read name count samp unit min max sum sumsq; do
14532                 [[ "$samp" == "samples" ]] || continue
14533
14534                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14535                 [ ! $min ] && error "Missing min value for $name proc entry"
14536                 eval $name=$count || error "Wrong proc format"
14537
14538                 case $name in
14539                 read_bytes|write_bytes)
14540                         [[ "$unit" =~ "bytes" ]] ||
14541                                 error "unit is not 'bytes': $unit"
14542                         (( $min >= 4096 )) || error "min is too small: $min"
14543                         (( $min <= $fsize )) || error "min is too big: $min"
14544                         (( $max >= 4096 )) || error "max is too small: $max"
14545                         (( $max <= $fsize )) || error "max is too big: $max"
14546                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14547                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14548                                 error "sumsquare is too small: $sumsq"
14549                         (( $sumsq <= $fsize * $fsize )) ||
14550                                 error "sumsquare is too big: $sumsq"
14551                         ;;
14552                 ost_read|ost_write)
14553                         [[ "$unit" =~ "usec" ]] ||
14554                                 error "unit is not 'usec': $unit"
14555                         ;;
14556                 *)      ;;
14557                 esac
14558         done < $tmpfile
14559
14560         #check that we actually got some stats
14561         [ "$read_bytes" ] || error "Missing read_bytes stats"
14562         [ "$write_bytes" ] || error "Missing write_bytes stats"
14563         [ "$read_bytes" != 0 ] || error "no read done"
14564         [ "$write_bytes" != 0 ] || error "no write done"
14565
14566         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14567         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14568         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14569
14570         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14571         (( ${snapshot_time%\.*} >= $now - 5 &&
14572            ${snapshot_time%\.*} <= $now + 5 )) ||
14573                 error "reset snapshot_time=$snapshot_time != now=$now"
14574         # elapsed should be from time of stats reset
14575         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14576            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14577                 error "reset elapsed=$elapsed > $now - $reset"
14578         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14579            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14580                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14581 }
14582 run_test 127a "verify the client stats are sane"
14583
14584 test_127b() { # bug LU-333
14585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14586         local name count samp unit min max sum sumsq
14587
14588         echo "stats before reset"
14589         $LCTL get_param llite.*.stats
14590         $LCTL set_param llite.*.stats=0
14591
14592         # perform 2 reads and writes so MAX is different from SUM.
14593         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14594         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14595         cancel_lru_locks osc
14596         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14597         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14598
14599         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14600         stack_trap "rm -f $TMP/$tfile.tmp"
14601         while read name count samp unit min max sum sumsq; do
14602                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14603                 eval $name=$count || error "Wrong proc format"
14604
14605                 case $name in
14606                 read_bytes|write_bytes)
14607                         [[ "$unit" =~ "bytes" ]] ||
14608                                 error "unit is not 'bytes': $unit"
14609                         (( $count == 2 )) || error "count is not 2: $count"
14610                         (( $min == $PAGE_SIZE )) ||
14611                                 error "min is not $PAGE_SIZE: $min"
14612                         (( $max == $PAGE_SIZE )) ||
14613                                 error "max is not $PAGE_SIZE: $max"
14614                         (( $sum == $PAGE_SIZE * 2 )) ||
14615                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14616                         ;;
14617                 read|write)
14618                         [[ "$unit" =~ "usec" ]] ||
14619                                 error "unit is not 'usec': $unit"
14620                         ;;
14621                 *)      ;;
14622                 esac
14623         done < $TMP/$tfile.tmp
14624
14625         #check that we actually got some stats
14626         [ "$read_bytes" ] || error "Missing read_bytes stats"
14627         [ "$write_bytes" ] || error "Missing write_bytes stats"
14628         [ "$read_bytes" != 0 ] || error "no read done"
14629         [ "$write_bytes" != 0 ] || error "no write done"
14630 }
14631 run_test 127b "verify the llite client stats are sane"
14632
14633 test_127c() { # LU-12394
14634         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14635         local size
14636         local bsize
14637         local reads
14638         local writes
14639         local count
14640
14641         $LCTL set_param llite.*.extents_stats=1
14642         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14643
14644         # Use two stripes so there is enough space in default config
14645         $LFS setstripe -c 2 $DIR/$tfile
14646
14647         # Extent stats start at 0-4K and go in power of two buckets
14648         # LL_HIST_START = 12 --> 2^12 = 4K
14649         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14650         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14651         # small configs
14652         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14653                 do
14654                 # Write and read, 2x each, second time at a non-zero offset
14655                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14656                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14657                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14658                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14659                 rm -f $DIR/$tfile
14660         done
14661
14662         $LCTL get_param llite.*.extents_stats
14663
14664         count=2
14665         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14666                 do
14667                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14668                                 grep -m 1 $bsize)
14669                 reads=$(echo $bucket | awk '{print $5}')
14670                 writes=$(echo $bucket | awk '{print $9}')
14671                 [ "$reads" -eq $count ] ||
14672                         error "$reads reads in < $bsize bucket, expect $count"
14673                 [ "$writes" -eq $count ] ||
14674                         error "$writes writes in < $bsize bucket, expect $count"
14675         done
14676
14677         # Test mmap write and read
14678         $LCTL set_param llite.*.extents_stats=c
14679         size=512
14680         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14681         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14682         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14683
14684         $LCTL get_param llite.*.extents_stats
14685
14686         count=$(((size*1024) / PAGE_SIZE))
14687
14688         bsize=$((2 * PAGE_SIZE / 1024))K
14689
14690         bucket=$($LCTL get_param -n llite.*.extents_stats |
14691                         grep -m 1 $bsize)
14692         reads=$(echo $bucket | awk '{print $5}')
14693         writes=$(echo $bucket | awk '{print $9}')
14694         # mmap writes fault in the page first, creating an additonal read
14695         [ "$reads" -eq $((2 * count)) ] ||
14696                 error "$reads reads in < $bsize bucket, expect $count"
14697         [ "$writes" -eq $count ] ||
14698                 error "$writes writes in < $bsize bucket, expect $count"
14699 }
14700 run_test 127c "test llite extent stats with regular & mmap i/o"
14701
14702 test_128() { # bug 15212
14703         touch $DIR/$tfile
14704         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14705                 find $DIR/$tfile
14706                 find $DIR/$tfile
14707         EOF
14708
14709         result=$(grep error $TMP/$tfile.log)
14710         rm -f $DIR/$tfile $TMP/$tfile.log
14711         [ -z "$result" ] ||
14712                 error "consecutive find's under interactive lfs failed"
14713 }
14714 run_test 128 "interactive lfs for 2 consecutive find's"
14715
14716 set_dir_limits () {
14717         local mntdev
14718         local canondev
14719         local node
14720
14721         local ldproc=/proc/fs/ldiskfs
14722         local facets=$(get_facets MDS)
14723
14724         for facet in ${facets//,/ }; do
14725                 canondev=$(ldiskfs_canon \
14726                            *.$(convert_facet2label $facet).mntdev $facet)
14727                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14728                         ldproc=/sys/fs/ldiskfs
14729                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14730                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14731         done
14732 }
14733
14734 check_mds_dmesg() {
14735         local facets=$(get_facets MDS)
14736         for facet in ${facets//,/ }; do
14737                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14738         done
14739         return 1
14740 }
14741
14742 test_129() {
14743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14744         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14745                 skip "Need MDS version with at least 2.5.56"
14746         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14747                 skip_env "ldiskfs only test"
14748         fi
14749         remote_mds_nodsh && skip "remote MDS with nodsh"
14750
14751         local ENOSPC=28
14752         local has_warning=false
14753
14754         rm -rf $DIR/$tdir
14755         mkdir -p $DIR/$tdir
14756
14757         # block size of mds1
14758         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14759         set_dir_limits $maxsize $((maxsize * 6 / 8))
14760         stack_trap "set_dir_limits 0 0"
14761         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14762         local dirsize=$(stat -c%s "$DIR/$tdir")
14763         local nfiles=0
14764         while (( $dirsize <= $maxsize )); do
14765                 $MCREATE $DIR/$tdir/file_base_$nfiles
14766                 rc=$?
14767                 # check two errors:
14768                 # ENOSPC for ext4 max_dir_size, which has been used since
14769                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14770                 if (( rc == ENOSPC )); then
14771                         set_dir_limits 0 0
14772                         echo "rc=$rc returned as expected after $nfiles files"
14773
14774                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14775                                 error "create failed w/o dir size limit"
14776
14777                         # messages may be rate limited if test is run repeatedly
14778                         check_mds_dmesg '"is approaching max"' ||
14779                                 echo "warning message should be output"
14780                         check_mds_dmesg '"has reached max"' ||
14781                                 echo "reached message should be output"
14782
14783                         dirsize=$(stat -c%s "$DIR/$tdir")
14784
14785                         [[ $dirsize -ge $maxsize ]] && return 0
14786                         error "dirsize $dirsize < $maxsize after $nfiles files"
14787                 elif (( rc != 0 )); then
14788                         break
14789                 fi
14790                 nfiles=$((nfiles + 1))
14791                 dirsize=$(stat -c%s "$DIR/$tdir")
14792         done
14793
14794         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14795 }
14796 run_test 129 "test directory size limit ========================"
14797
14798 OLDIFS="$IFS"
14799 cleanup_130() {
14800         trap 0
14801         IFS="$OLDIFS"
14802         rm -f $DIR/$tfile
14803 }
14804
14805 test_130a() {
14806         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14807         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14808
14809         trap cleanup_130 EXIT RETURN
14810
14811         local fm_file=$DIR/$tfile
14812         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14813         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14814                 error "dd failed for $fm_file"
14815
14816         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14817         filefrag -ves $fm_file
14818         local rc=$?
14819         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14820                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14821         (( $rc == 0 )) || error "filefrag $fm_file failed"
14822
14823         filefrag_op=$(filefrag -ve -k $fm_file |
14824                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14825         local lun=$($LFS getstripe -i $fm_file)
14826
14827         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14828         IFS=$'\n'
14829         local tot_len=0
14830         for line in $filefrag_op; do
14831                 local frag_lun=$(echo $line | cut -d: -f5)
14832                 local ext_len=$(echo $line | cut -d: -f4)
14833
14834                 if (( $frag_lun != $lun )); then
14835                         error "FIEMAP on 1-stripe file($fm_file) failed"
14836                         return
14837                 fi
14838                 (( tot_len += ext_len ))
14839         done
14840
14841         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14842                 error "FIEMAP on 1-stripe file($fm_file) failed"
14843                 return
14844         fi
14845
14846         echo "FIEMAP on single striped file succeeded"
14847 }
14848 run_test 130a "FIEMAP (1-stripe file)"
14849
14850 test_130b() {
14851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14852
14853         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14854         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14855         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14856                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14857
14858         trap cleanup_130 EXIT RETURN
14859
14860         local fm_file=$DIR/$tfile
14861         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14862                 error "setstripe on $fm_file"
14863
14864         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14865                 error "dd failed on $fm_file"
14866
14867         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14868         filefrag_op=$(filefrag -ve -k $fm_file |
14869                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14870
14871         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14872                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14873
14874         IFS=$'\n'
14875         local tot_len=0
14876         local num_luns=1
14877
14878         for line in $filefrag_op; do
14879                 local frag_lun=$(echo $line | cut -d: -f5 |
14880                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14881                 local ext_len=$(echo $line | cut -d: -f4)
14882                 if (( $frag_lun != $last_lun )); then
14883                         if (( tot_len != 1024 )); then
14884                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14885                                 return
14886                         else
14887                                 (( num_luns += 1 ))
14888                                 tot_len=0
14889                         fi
14890                 fi
14891                 (( tot_len += ext_len ))
14892                 last_lun=$frag_lun
14893         done
14894         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14895                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14896                 return
14897         fi
14898
14899         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14900 }
14901 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14902
14903 test_130c() {
14904         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14905
14906         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14907         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14908         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14909                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14910
14911         trap cleanup_130 EXIT RETURN
14912
14913         local fm_file=$DIR/$tfile
14914         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14915
14916         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14917                 error "dd failed on $fm_file"
14918
14919         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14920         filefrag_op=$(filefrag -ve -k $fm_file |
14921                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14922
14923         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14924                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14925
14926         IFS=$'\n'
14927         local tot_len=0
14928         local num_luns=1
14929         for line in $filefrag_op; do
14930                 local frag_lun=$(echo $line | cut -d: -f5 |
14931                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14932                 local ext_len=$(echo $line | cut -d: -f4)
14933                 if (( $frag_lun != $last_lun )); then
14934                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14935                         if (( logical != 512 )); then
14936                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14937                                 return
14938                         fi
14939                         if (( tot_len != 512 )); then
14940                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14941                                 return
14942                         else
14943                                 (( num_luns += 1 ))
14944                                 tot_len=0
14945                         fi
14946                 fi
14947                 (( tot_len += ext_len ))
14948                 last_lun=$frag_lun
14949         done
14950         if (( num_luns != 2 || tot_len != 512 )); then
14951                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14952                 return
14953         fi
14954
14955         echo "FIEMAP on 2-stripe file with hole succeeded"
14956 }
14957 run_test 130c "FIEMAP (2-stripe file with hole)"
14958
14959 test_130d() {
14960         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14961
14962         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14963         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14964         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14965                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14966
14967         trap cleanup_130 EXIT RETURN
14968
14969         local fm_file=$DIR/$tfile
14970         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14971                         error "setstripe on $fm_file"
14972
14973         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14974         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14975                 error "dd failed on $fm_file"
14976
14977         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14978         filefrag_op=$(filefrag -ve -k $fm_file |
14979                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14980
14981         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14982                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14983
14984         IFS=$'\n'
14985         local tot_len=0
14986         local num_luns=1
14987         for line in $filefrag_op; do
14988                 local frag_lun=$(echo $line | cut -d: -f5 |
14989                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14990                 local ext_len=$(echo $line | cut -d: -f4)
14991                 if (( $frag_lun != $last_lun )); then
14992                         if (( tot_len != 1024 )); then
14993                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14994                                 return
14995                         else
14996                                 (( num_luns += 1 ))
14997                                 local tot_len=0
14998                         fi
14999                 fi
15000                 (( tot_len += ext_len ))
15001                 last_lun=$frag_lun
15002         done
15003         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15004                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15005                 return
15006         fi
15007
15008         echo "FIEMAP on N-stripe file succeeded"
15009 }
15010 run_test 130d "FIEMAP (N-stripe file)"
15011
15012 test_130e() {
15013         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15014
15015         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15016         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15017         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15018                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15019
15020         trap cleanup_130 EXIT RETURN
15021
15022         local fm_file=$DIR/$tfile
15023         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15024         stack_trap "rm -f $fm_file"
15025
15026         local num_blks=512
15027         local expected_len=$(( (num_blks / 2) * 64 ))
15028         for ((i = 0; i < $num_blks; i++)); do
15029                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15030                         conv=notrunc > /dev/null 2>&1
15031         done
15032
15033         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15034         filefrag_op=$(filefrag -ve -k $fm_file |
15035                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15036
15037         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15038
15039         IFS=$'\n'
15040         local tot_len=0
15041         local num_luns=1
15042         for line in $filefrag_op; do
15043                 local frag_lun=$(echo $line | cut -d: -f5)
15044                 local ext_len=$(echo $line | cut -d: -f4)
15045                 if (( $frag_lun != $last_lun )); then
15046                         if (( tot_len != $expected_len )); then
15047                                 error "OST$last_lun $tot_len != $expected_len"
15048                         else
15049                                 (( num_luns += 1 ))
15050                                 tot_len=0
15051                         fi
15052                 fi
15053                 (( tot_len += ext_len ))
15054                 last_lun=$frag_lun
15055         done
15056         if (( num_luns != 2 || tot_len != $expected_len )); then
15057                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15058         fi
15059
15060         echo "FIEMAP with continuation calls succeeded"
15061 }
15062 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15063
15064 test_130f() {
15065         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15066         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15067         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15068                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15069
15070         local fm_file=$DIR/$tfile
15071         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15072                 error "multiop create with lov_delay_create on $fm_file"
15073
15074         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15075         filefrag_extents=$(filefrag -vek $fm_file |
15076                            awk '/extents? found/ { print $2 }')
15077         if (( $filefrag_extents != 0 )); then
15078                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15079         fi
15080
15081         rm -f $fm_file
15082 }
15083 run_test 130f "FIEMAP (unstriped file)"
15084
15085 test_130g() {
15086         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15087                 skip "Need MDS version with at least 2.12.53 for overstriping"
15088         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15089         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15090         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15091                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15092
15093         local file=$DIR/$tfile
15094         local nr=$((OSTCOUNT * 100))
15095
15096         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15097
15098         stack_trap "rm -f $file"
15099         dd if=/dev/zero of=$file count=$nr bs=1M
15100         sync
15101         nr=$($LFS getstripe -c $file)
15102
15103         local extents=$(filefrag -v $file |
15104                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15105
15106         echo "filefrag list $extents extents in file with stripecount $nr"
15107         if (( extents < nr )); then
15108                 $LFS getstripe $file
15109                 filefrag -v $file
15110                 error "filefrag printed $extents < $nr extents"
15111         fi
15112 }
15113 run_test 130g "FIEMAP (overstripe file)"
15114
15115 # Test for writev/readv
15116 test_131a() {
15117         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15118                 error "writev test failed"
15119         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15120                 error "readv failed"
15121         rm -f $DIR/$tfile
15122 }
15123 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15124
15125 test_131b() {
15126         local fsize=$((524288 + 1048576 + 1572864))
15127         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15128                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15129                         error "append writev test failed"
15130
15131         ((fsize += 1572864 + 1048576))
15132         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15133                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15134                         error "append writev test failed"
15135         rm -f $DIR/$tfile
15136 }
15137 run_test 131b "test append writev"
15138
15139 test_131c() {
15140         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15141         error "NOT PASS"
15142 }
15143 run_test 131c "test read/write on file w/o objects"
15144
15145 test_131d() {
15146         rwv -f $DIR/$tfile -w -n 1 1572864
15147         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15148         if [ "$NOB" != 1572864 ]; then
15149                 error "Short read filed: read $NOB bytes instead of 1572864"
15150         fi
15151         rm -f $DIR/$tfile
15152 }
15153 run_test 131d "test short read"
15154
15155 test_131e() {
15156         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15157         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15158         error "read hitting hole failed"
15159         rm -f $DIR/$tfile
15160 }
15161 run_test 131e "test read hitting hole"
15162
15163 check_stats() {
15164         local facet=$1
15165         local op=$2
15166         local want=${3:-0}
15167         local res
15168
15169         # open             11 samples [usecs] 468 4793 13658 35791898
15170         case $facet in
15171         mds*) res=($(do_facet $facet \
15172                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15173                  ;;
15174         ost*) res=($(do_facet $facet \
15175                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15176                  ;;
15177         *) error "Wrong facet '$facet'" ;;
15178         esac
15179         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15180         # if $want is zero, it means any stat increment is ok.
15181         if (( $want > 0 )); then
15182                 local count=${res[1]}
15183
15184                 if (( $count != $want )); then
15185                         if [[ $facet =~ "mds" ]]; then
15186                                 do_nodes $(comma_list $(mdts_nodes)) \
15187                                         $LCTL get_param mdt.*.md_stats
15188                         else
15189                                 do_nodes $(comma_list $(osts-nodes)) \
15190                                         $LCTL get_param obdfilter.*.stats
15191                         fi
15192                         error "The $op counter on $facet is $count, not $want"
15193                 fi
15194         fi
15195 }
15196
15197 test_133a() {
15198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15199         remote_ost_nodsh && skip "remote OST with nodsh"
15200         remote_mds_nodsh && skip "remote MDS with nodsh"
15201         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15202                 skip_env "MDS doesn't support rename stats"
15203
15204         local testdir=$DIR/${tdir}/stats_testdir
15205
15206         mkdir -p $DIR/${tdir}
15207
15208         # clear stats.
15209         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15210         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15211
15212         # verify mdt stats first.
15213         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15214         check_stats $SINGLEMDS "mkdir" 1
15215
15216         # clear "open" from "lfs mkdir" above
15217         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15218         touch ${testdir}/${tfile} || error "touch failed"
15219         check_stats $SINGLEMDS "open" 1
15220         check_stats $SINGLEMDS "close" 1
15221         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15222                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15223                 check_stats $SINGLEMDS "mknod" 2
15224         }
15225         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15226         check_stats $SINGLEMDS "unlink" 1
15227         rm -f ${testdir}/${tfile} || error "file remove failed"
15228         check_stats $SINGLEMDS "unlink" 2
15229
15230         # remove working dir and check mdt stats again.
15231         rmdir ${testdir} || error "rmdir failed"
15232         check_stats $SINGLEMDS "rmdir" 1
15233
15234         local testdir1=$DIR/${tdir}/stats_testdir1
15235         mkdir_on_mdt0 -p ${testdir}
15236         mkdir_on_mdt0 -p ${testdir1}
15237         touch ${testdir1}/test1
15238         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15239         check_stats $SINGLEMDS "crossdir_rename" 1
15240
15241         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15242         check_stats $SINGLEMDS "samedir_rename" 1
15243
15244         rm -rf $DIR/${tdir}
15245 }
15246 run_test 133a "Verifying MDT stats ========================================"
15247
15248 test_133b() {
15249         local res
15250
15251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15252         remote_ost_nodsh && skip "remote OST with nodsh"
15253         remote_mds_nodsh && skip "remote MDS with nodsh"
15254
15255         local testdir=$DIR/${tdir}/stats_testdir
15256
15257         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15258         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15259         touch ${testdir}/${tfile} || error "touch failed"
15260         cancel_lru_locks mdc
15261
15262         # clear stats.
15263         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15264         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15265
15266         # extra mdt stats verification.
15267         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15268         check_stats $SINGLEMDS "setattr" 1
15269         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15270         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15271         then            # LU-1740
15272                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15273                 check_stats $SINGLEMDS "getattr" 1
15274         fi
15275         rm -rf $DIR/${tdir}
15276
15277         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15278         # so the check below is not reliable
15279         [ $MDSCOUNT -eq 1 ] || return 0
15280
15281         # Sleep to avoid a cached response.
15282         #define OBD_STATFS_CACHE_SECONDS 1
15283         sleep 2
15284         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15285         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15286         $LFS df || error "lfs failed"
15287         check_stats $SINGLEMDS "statfs" 1
15288
15289         # check aggregated statfs (LU-10018)
15290         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15291                 return 0
15292         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15293                 return 0
15294         sleep 2
15295         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15296         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15297         df $DIR
15298         check_stats $SINGLEMDS "statfs" 1
15299
15300         # We want to check that the client didn't send OST_STATFS to
15301         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15302         # extra care is needed here.
15303         if remote_mds; then
15304                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15305                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15306
15307                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15308                 [ "$res" ] && error "OST got STATFS"
15309         fi
15310
15311         return 0
15312 }
15313 run_test 133b "Verifying extra MDT stats =================================="
15314
15315 test_133c() {
15316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15317         remote_ost_nodsh && skip "remote OST with nodsh"
15318         remote_mds_nodsh && skip "remote MDS with nodsh"
15319
15320         local testdir=$DIR/$tdir/stats_testdir
15321
15322         test_mkdir -p $testdir
15323
15324         # verify obdfilter stats.
15325         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15326         sync
15327         cancel_lru_locks osc
15328         wait_delete_completed
15329
15330         # clear stats.
15331         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15332         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15333
15334         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15335                 error "dd failed"
15336         sync
15337         cancel_lru_locks osc
15338         check_stats ost1 "write" 1
15339
15340         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15341         check_stats ost1 "read" 1
15342
15343         > $testdir/$tfile || error "truncate failed"
15344         check_stats ost1 "punch" 1
15345
15346         rm -f $testdir/$tfile || error "file remove failed"
15347         wait_delete_completed
15348         check_stats ost1 "destroy" 1
15349
15350         rm -rf $DIR/$tdir
15351 }
15352 run_test 133c "Verifying OST stats ========================================"
15353
15354 order_2() {
15355         local value=$1
15356         local orig=$value
15357         local order=1
15358
15359         while [ $value -ge 2 ]; do
15360                 order=$((order*2))
15361                 value=$((value/2))
15362         done
15363
15364         if [ $orig -gt $order ]; then
15365                 order=$((order*2))
15366         fi
15367         echo $order
15368 }
15369
15370 size_in_KMGT() {
15371     local value=$1
15372     local size=('K' 'M' 'G' 'T');
15373     local i=0
15374     local size_string=$value
15375
15376     while [ $value -ge 1024 ]; do
15377         if [ $i -gt 3 ]; then
15378             #T is the biggest unit we get here, if that is bigger,
15379             #just return XXXT
15380             size_string=${value}T
15381             break
15382         fi
15383         value=$((value >> 10))
15384         if [ $value -lt 1024 ]; then
15385             size_string=${value}${size[$i]}
15386             break
15387         fi
15388         i=$((i + 1))
15389     done
15390
15391     echo $size_string
15392 }
15393
15394 get_rename_size() {
15395         local size=$1
15396         local context=${2:-.}
15397         local sample=$(do_facet $SINGLEMDS $LCTL \
15398                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15399                 grep -A1 $context |
15400                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15401         echo $sample
15402 }
15403
15404 test_133d() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         remote_ost_nodsh && skip "remote OST with nodsh"
15407         remote_mds_nodsh && skip "remote MDS with nodsh"
15408         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15409                 skip_env "MDS doesn't support rename stats"
15410
15411         local testdir1=$DIR/${tdir}/stats_testdir1
15412         local testdir2=$DIR/${tdir}/stats_testdir2
15413         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15414
15415         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15416
15417         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15418         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15419
15420         createmany -o $testdir1/test 512 || error "createmany failed"
15421
15422         # check samedir rename size
15423         mv ${testdir1}/test0 ${testdir1}/test_0
15424
15425         local testdir1_size=$(ls -l $DIR/${tdir} |
15426                 awk '/stats_testdir1/ {print $5}')
15427         local testdir2_size=$(ls -l $DIR/${tdir} |
15428                 awk '/stats_testdir2/ {print $5}')
15429
15430         testdir1_size=$(order_2 $testdir1_size)
15431         testdir2_size=$(order_2 $testdir2_size)
15432
15433         testdir1_size=$(size_in_KMGT $testdir1_size)
15434         testdir2_size=$(size_in_KMGT $testdir2_size)
15435
15436         echo "source rename dir size: ${testdir1_size}"
15437         echo "target rename dir size: ${testdir2_size}"
15438
15439         local cmd="do_facet $SINGLEMDS $LCTL "
15440         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15441
15442         eval $cmd || error "$cmd failed"
15443         local samedir=$($cmd | grep 'same_dir')
15444         local same_sample=$(get_rename_size $testdir1_size)
15445         [ -z "$samedir" ] && error "samedir_rename_size count error"
15446         [[ $same_sample -eq 1 ]] ||
15447                 error "samedir_rename_size error $same_sample"
15448         echo "Check same dir rename stats success"
15449
15450         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15451
15452         # check crossdir rename size
15453         mv ${testdir1}/test_0 ${testdir2}/test_0
15454
15455         testdir1_size=$(ls -l $DIR/${tdir} |
15456                 awk '/stats_testdir1/ {print $5}')
15457         testdir2_size=$(ls -l $DIR/${tdir} |
15458                 awk '/stats_testdir2/ {print $5}')
15459
15460         testdir1_size=$(order_2 $testdir1_size)
15461         testdir2_size=$(order_2 $testdir2_size)
15462
15463         testdir1_size=$(size_in_KMGT $testdir1_size)
15464         testdir2_size=$(size_in_KMGT $testdir2_size)
15465
15466         echo "source rename dir size: ${testdir1_size}"
15467         echo "target rename dir size: ${testdir2_size}"
15468
15469         eval $cmd || error "$cmd failed"
15470         local crossdir=$($cmd | grep 'crossdir')
15471         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15472         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15473         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15474         [[ $src_sample -eq 1 ]] ||
15475                 error "crossdir_rename_size error $src_sample"
15476         [[ $tgt_sample -eq 1 ]] ||
15477                 error "crossdir_rename_size error $tgt_sample"
15478         echo "Check cross dir rename stats success"
15479         rm -rf $DIR/${tdir}
15480 }
15481 run_test 133d "Verifying rename_stats ========================================"
15482
15483 test_133e() {
15484         remote_mds_nodsh && skip "remote MDS with nodsh"
15485         remote_ost_nodsh && skip "remote OST with nodsh"
15486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15487
15488         local testdir=$DIR/${tdir}/stats_testdir
15489         local ctr f0 f1 bs=32768 count=42 sum
15490
15491         mkdir -p ${testdir} || error "mkdir failed"
15492
15493         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15494
15495         for ctr in {write,read}_bytes; do
15496                 sync
15497                 cancel_lru_locks osc
15498
15499                 do_facet ost1 $LCTL set_param -n \
15500                         "obdfilter.*.exports.clear=clear"
15501
15502                 if [ $ctr = write_bytes ]; then
15503                         f0=/dev/zero
15504                         f1=${testdir}/${tfile}
15505                 else
15506                         f0=${testdir}/${tfile}
15507                         f1=/dev/null
15508                 fi
15509
15510                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15511                         error "dd failed"
15512                 sync
15513                 cancel_lru_locks osc
15514
15515                 sum=$(do_facet ost1 $LCTL get_param \
15516                         "obdfilter.*.exports.*.stats" |
15517                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15518                                 $1 == ctr { sum += $7 }
15519                                 END { printf("%0.0f", sum) }')
15520
15521                 if ((sum != bs * count)); then
15522                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15523                 fi
15524         done
15525
15526         rm -rf $DIR/${tdir}
15527 }
15528 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15529
15530 test_133f() {
15531         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15532                 skip "too old lustre for get_param -R ($facet_ver)"
15533
15534         # verifying readability.
15535         $LCTL get_param -R '*' &> /dev/null
15536
15537         # Verifing writability with badarea_io.
15538         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15539         local skipped_params='force_lbug|changelog_mask|daemon_file'
15540         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15541                 egrep -v "$skipped_params" |
15542                 xargs -n 1 find $proc_dirs -name |
15543                 xargs -n 1 badarea_io ||
15544                 error "client badarea_io failed"
15545
15546         # remount the FS in case writes/reads /proc break the FS
15547         cleanup || error "failed to unmount"
15548         setup || error "failed to setup"
15549 }
15550 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15551
15552 test_133g() {
15553         remote_mds_nodsh && skip "remote MDS with nodsh"
15554         remote_ost_nodsh && skip "remote OST with nodsh"
15555
15556         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15557         local proc_dirs_str=$(eval echo $proc_dirs)
15558         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15559         local facet
15560         for facet in mds1 ost1; do
15561                 local facet_ver=$(lustre_version_code $facet)
15562                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15563                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15564                 else
15565                         log "$facet: too old lustre for get_param -R"
15566                 fi
15567                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15568                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15569                                 tr -d = | egrep -v $skipped_params |
15570                                 xargs -n 1 find $proc_dirs_str -name |
15571                                 xargs -n 1 badarea_io" ||
15572                                         error "$facet badarea_io failed"
15573                 else
15574                         skip_noexit "$facet: too old lustre for get_param -R"
15575                 fi
15576         done
15577
15578         # remount the FS in case writes/reads /proc break the FS
15579         cleanup || error "failed to unmount"
15580         setup || error "failed to setup"
15581 }
15582 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15583
15584 test_133h() {
15585         remote_mds_nodsh && skip "remote MDS with nodsh"
15586         remote_ost_nodsh && skip "remote OST with nodsh"
15587         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15588                 skip "Need MDS version at least 2.9.54"
15589
15590         local facet
15591         for facet in client mds1 ost1; do
15592                 # Get the list of files that are missing the terminating newline
15593                 local plist=$(do_facet $facet
15594                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15595                 local ent
15596                 for ent in $plist; do
15597                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15598                                 awk -v FS='\v' -v RS='\v\v' \
15599                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15600                                         print FILENAME}'" 2>/dev/null)
15601                         [ -z $missing ] || {
15602                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15603                                 error "file does not end with newline: $facet-$ent"
15604                         }
15605                 done
15606         done
15607 }
15608 run_test 133h "Proc files should end with newlines"
15609
15610 test_134a() {
15611         remote_mds_nodsh && skip "remote MDS with nodsh"
15612         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15613                 skip "Need MDS version at least 2.7.54"
15614
15615         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15616         cancel_lru_locks mdc
15617
15618         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15619         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15620         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15621
15622         local nr=1000
15623         createmany -o $DIR/$tdir/f $nr ||
15624                 error "failed to create $nr files in $DIR/$tdir"
15625         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15626
15627         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15628         do_facet mds1 $LCTL set_param fail_loc=0x327
15629         do_facet mds1 $LCTL set_param fail_val=500
15630         touch $DIR/$tdir/m
15631
15632         echo "sleep 10 seconds ..."
15633         sleep 10
15634         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15635
15636         do_facet mds1 $LCTL set_param fail_loc=0
15637         do_facet mds1 $LCTL set_param fail_val=0
15638         [ $lck_cnt -lt $unused ] ||
15639                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15640
15641         rm $DIR/$tdir/m
15642         unlinkmany $DIR/$tdir/f $nr
15643 }
15644 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15645
15646 test_134b() {
15647         remote_mds_nodsh && skip "remote MDS with nodsh"
15648         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15649                 skip "Need MDS version at least 2.7.54"
15650
15651         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15652         cancel_lru_locks mdc
15653
15654         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15655                         ldlm.lock_reclaim_threshold_mb)
15656         # disable reclaim temporarily
15657         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15658
15659         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15660         do_facet mds1 $LCTL set_param fail_loc=0x328
15661         do_facet mds1 $LCTL set_param fail_val=500
15662
15663         $LCTL set_param debug=+trace
15664
15665         local nr=600
15666         createmany -o $DIR/$tdir/f $nr &
15667         local create_pid=$!
15668
15669         echo "Sleep $TIMEOUT seconds ..."
15670         sleep $TIMEOUT
15671         if ! ps -p $create_pid  > /dev/null 2>&1; then
15672                 do_facet mds1 $LCTL set_param fail_loc=0
15673                 do_facet mds1 $LCTL set_param fail_val=0
15674                 do_facet mds1 $LCTL set_param \
15675                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15676                 error "createmany finished incorrectly!"
15677         fi
15678         do_facet mds1 $LCTL set_param fail_loc=0
15679         do_facet mds1 $LCTL set_param fail_val=0
15680         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15681         wait $create_pid || return 1
15682
15683         unlinkmany $DIR/$tdir/f $nr
15684 }
15685 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15686
15687 test_135() {
15688         remote_mds_nodsh && skip "remote MDS with nodsh"
15689         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15690                 skip "Need MDS version at least 2.13.50"
15691         local fname
15692
15693         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15694
15695 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15696         #set only one record at plain llog
15697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15698
15699         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15700
15701         #fill already existed plain llog each 64767
15702         #wrapping whole catalog
15703         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15704
15705         createmany -o $DIR/$tdir/$tfile_ 64700
15706         for (( i = 0; i < 64700; i = i + 2 ))
15707         do
15708                 rm $DIR/$tdir/$tfile_$i &
15709                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15710                 local pid=$!
15711                 wait $pid
15712         done
15713
15714         #waiting osp synchronization
15715         wait_delete_completed
15716 }
15717 run_test 135 "Race catalog processing"
15718
15719 test_136() {
15720         remote_mds_nodsh && skip "remote MDS with nodsh"
15721         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15722                 skip "Need MDS version at least 2.13.50"
15723         local fname
15724
15725         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15726         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15727         #set only one record at plain llog
15728 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15729         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15730
15731         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15732
15733         #fill already existed 2 plain llogs each 64767
15734         #wrapping whole catalog
15735         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15736         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15737         wait_delete_completed
15738
15739         createmany -o $DIR/$tdir/$tfile_ 10
15740         sleep 25
15741
15742         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15743         for (( i = 0; i < 10; i = i + 3 ))
15744         do
15745                 rm $DIR/$tdir/$tfile_$i &
15746                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15747                 local pid=$!
15748                 wait $pid
15749                 sleep 7
15750                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15751         done
15752
15753         #waiting osp synchronization
15754         wait_delete_completed
15755 }
15756 run_test 136 "Race catalog processing 2"
15757
15758 test_140() { #bug-17379
15759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15760
15761         test_mkdir $DIR/$tdir
15762         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15763         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15764
15765         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15766         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15767         local i=0
15768         while i=$((i + 1)); do
15769                 test_mkdir $i
15770                 cd $i || error "Changing to $i"
15771                 ln -s ../stat stat || error "Creating stat symlink"
15772                 # Read the symlink until ELOOP present,
15773                 # not LBUGing the system is considered success,
15774                 # we didn't overrun the stack.
15775                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15776                 if [ $ret -ne 0 ]; then
15777                         if [ $ret -eq 40 ]; then
15778                                 break  # -ELOOP
15779                         else
15780                                 error "Open stat symlink"
15781                                         return
15782                         fi
15783                 fi
15784         done
15785         i=$((i - 1))
15786         echo "The symlink depth = $i"
15787         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15788                 error "Invalid symlink depth"
15789
15790         # Test recursive symlink
15791         ln -s symlink_self symlink_self
15792         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15793         echo "open symlink_self returns $ret"
15794         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15795 }
15796 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15797
15798 test_150a() {
15799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15800
15801         local TF="$TMP/$tfile"
15802
15803         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15804         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15805         cp $TF $DIR/$tfile
15806         cancel_lru_locks $OSC
15807         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15808         remount_client $MOUNT
15809         df -P $MOUNT
15810         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15811
15812         $TRUNCATE $TF 6000
15813         $TRUNCATE $DIR/$tfile 6000
15814         cancel_lru_locks $OSC
15815         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15816
15817         echo "12345" >>$TF
15818         echo "12345" >>$DIR/$tfile
15819         cancel_lru_locks $OSC
15820         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15821
15822         echo "12345" >>$TF
15823         echo "12345" >>$DIR/$tfile
15824         cancel_lru_locks $OSC
15825         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15826 }
15827 run_test 150a "truncate/append tests"
15828
15829 test_150b() {
15830         check_set_fallocate_or_skip
15831         local out
15832
15833         touch $DIR/$tfile
15834         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15835         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15836                 skip_eopnotsupp "$out|check_fallocate failed"
15837 }
15838 run_test 150b "Verify fallocate (prealloc) functionality"
15839
15840 test_150bb() {
15841         check_set_fallocate_or_skip
15842
15843         touch $DIR/$tfile
15844         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15845         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15846         > $DIR/$tfile
15847         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15848         # precomputed md5sum for 20MB of zeroes
15849         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15850         local sum=($(md5sum $DIR/$tfile))
15851
15852         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15853
15854         check_set_fallocate 1
15855
15856         > $DIR/$tfile
15857         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15858         sum=($(md5sum $DIR/$tfile))
15859
15860         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15861 }
15862 run_test 150bb "Verify fallocate modes both zero space"
15863
15864 test_150c() {
15865         check_set_fallocate_or_skip
15866         local striping="-c2"
15867
15868         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15869         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15870         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15871         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15872         local want=$((OSTCOUNT * 1048576))
15873
15874         # Must allocate all requested space, not more than 5% extra
15875         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15876                 error "bytes $bytes is not $want"
15877
15878         rm -f $DIR/$tfile
15879
15880         echo "verify fallocate on PFL file"
15881
15882         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15883
15884         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15885                 error "Create $DIR/$tfile failed"
15886         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15887         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15888         want=$((512 * 1048576))
15889
15890         # Must allocate all requested space, not more than 5% extra
15891         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15892                 error "bytes $bytes is not $want"
15893 }
15894 run_test 150c "Verify fallocate Size and Blocks"
15895
15896 test_150d() {
15897         check_set_fallocate_or_skip
15898         local striping="-c2"
15899
15900         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15901
15902         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15903         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15904                 error "setstripe failed"
15905         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15906         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15907         local want=$((OSTCOUNT * 1048576))
15908
15909         # Must allocate all requested space, not more than 5% extra
15910         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15911                 error "bytes $bytes is not $want"
15912 }
15913 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15914
15915 test_150e() {
15916         check_set_fallocate_or_skip
15917
15918         echo "df before:"
15919         $LFS df
15920         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15921         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15922                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15923
15924         # Find OST with Minimum Size
15925         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15926                        sort -un | head -1)
15927
15928         # Get 100MB per OST of the available space to reduce run time
15929         # else 60% of the available space if we are running SLOW tests
15930         if [ $SLOW == "no" ]; then
15931                 local space=$((1024 * 100 * OSTCOUNT))
15932         else
15933                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15934         fi
15935
15936         fallocate -l${space}k $DIR/$tfile ||
15937                 error "fallocate ${space}k $DIR/$tfile failed"
15938         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15939
15940         # get size immediately after fallocate. This should be correctly
15941         # updated
15942         local size=$(stat -c '%s' $DIR/$tfile)
15943         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15944
15945         # Sleep for a while for statfs to get updated. And not pull from cache.
15946         sleep 2
15947
15948         echo "df after fallocate:"
15949         $LFS df
15950
15951         (( size / 1024 == space )) || error "size $size != requested $space"
15952         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15953                 error "used $used < space $space"
15954
15955         rm $DIR/$tfile || error "rm failed"
15956         sync
15957         wait_delete_completed
15958
15959         echo "df after unlink:"
15960         $LFS df
15961 }
15962 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15963
15964 test_150f() {
15965         local size
15966         local blocks
15967         local want_size_before=20480 # in bytes
15968         local want_blocks_before=40 # 512 sized blocks
15969         local want_blocks_after=24  # 512 sized blocks
15970         local length=$(((want_blocks_before - want_blocks_after) * 512))
15971
15972         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15973                 skip "need at least 2.14.0 for fallocate punch"
15974
15975         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15976                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15977         fi
15978
15979         check_set_fallocate_or_skip
15980         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15981
15982         [[ "x$DOM" == "xyes" ]] &&
15983                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15984
15985         echo "Verify fallocate punch: Range within the file range"
15986         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15987                 error "dd failed for bs 4096 and count 5"
15988
15989         # Call fallocate with punch range which is within the file range
15990         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15991                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15992         # client must see changes immediately after fallocate
15993         size=$(stat -c '%s' $DIR/$tfile)
15994         blocks=$(stat -c '%b' $DIR/$tfile)
15995
15996         # Verify punch worked.
15997         (( blocks == want_blocks_after )) ||
15998                 error "punch failed: blocks $blocks != $want_blocks_after"
15999
16000         (( size == want_size_before )) ||
16001                 error "punch failed: size $size != $want_size_before"
16002
16003         # Verify there is hole in file
16004         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16005         # precomputed md5sum
16006         local expect="4a9a834a2db02452929c0a348273b4aa"
16007
16008         cksum=($(md5sum $DIR/$tfile))
16009         [[ "${cksum[0]}" == "$expect" ]] ||
16010                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16011
16012         # Start second sub-case for fallocate punch.
16013         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16014         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16015                 error "dd failed for bs 4096 and count 5"
16016
16017         # Punch range less than block size will have no change in block count
16018         want_blocks_after=40  # 512 sized blocks
16019
16020         # Punch overlaps two blocks and less than blocksize
16021         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16022                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16023         size=$(stat -c '%s' $DIR/$tfile)
16024         blocks=$(stat -c '%b' $DIR/$tfile)
16025
16026         # Verify punch worked.
16027         (( blocks == want_blocks_after )) ||
16028                 error "punch failed: blocks $blocks != $want_blocks_after"
16029
16030         (( size == want_size_before )) ||
16031                 error "punch failed: size $size != $want_size_before"
16032
16033         # Verify if range is really zero'ed out. We expect Zeros.
16034         # precomputed md5sum
16035         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16036         cksum=($(md5sum $DIR/$tfile))
16037         [[ "${cksum[0]}" == "$expect" ]] ||
16038                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16039 }
16040 run_test 150f "Verify fallocate punch functionality"
16041
16042 test_150g() {
16043         local space
16044         local size
16045         local blocks
16046         local blocks_after
16047         local size_after
16048         local BS=4096 # Block size in bytes
16049
16050         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16051                 skip "need at least 2.14.0 for fallocate punch"
16052
16053         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16054                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16055         fi
16056
16057         check_set_fallocate_or_skip
16058         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16059
16060         if [[ "x$DOM" == "xyes" ]]; then
16061                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16062                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16063         else
16064                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16065                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16066         fi
16067
16068         # Get 100MB per OST of the available space to reduce run time
16069         # else 60% of the available space if we are running SLOW tests
16070         if [ $SLOW == "no" ]; then
16071                 space=$((1024 * 100 * OSTCOUNT))
16072         else
16073                 # Find OST with Minimum Size
16074                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16075                         sort -un | head -1)
16076                 echo "min size OST: $space"
16077                 space=$(((space * 60)/100 * OSTCOUNT))
16078         fi
16079         # space in 1k units, round to 4k blocks
16080         local blkcount=$((space * 1024 / $BS))
16081
16082         echo "Verify fallocate punch: Very large Range"
16083         fallocate -l${space}k $DIR/$tfile ||
16084                 error "fallocate ${space}k $DIR/$tfile failed"
16085         # write 1M at the end, start and in the middle
16086         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16087                 error "dd failed: bs $BS count 256"
16088         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16089                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16090         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16091                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16092
16093         # Gather stats.
16094         size=$(stat -c '%s' $DIR/$tfile)
16095
16096         # gather punch length.
16097         local punch_size=$((size - (BS * 2)))
16098
16099         echo "punch_size = $punch_size"
16100         echo "size - punch_size: $((size - punch_size))"
16101         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16102
16103         # Call fallocate to punch all except 2 blocks. We leave the
16104         # first and the last block
16105         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16106         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16107                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16108
16109         size_after=$(stat -c '%s' $DIR/$tfile)
16110         blocks_after=$(stat -c '%b' $DIR/$tfile)
16111
16112         # Verify punch worked.
16113         # Size should be kept
16114         (( size == size_after )) ||
16115                 error "punch failed: size $size != $size_after"
16116
16117         # two 4k data blocks to remain plus possible 1 extra extent block
16118         (( blocks_after <= ((BS / 512) * 3) )) ||
16119                 error "too many blocks remains: $blocks_after"
16120
16121         # Verify that file has hole between the first and the last blocks
16122         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16123         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16124
16125         echo "Hole at [$hole_start, $hole_end)"
16126         (( hole_start == BS )) ||
16127                 error "no hole at offset $BS after punch"
16128
16129         (( hole_end == BS + punch_size )) ||
16130                 error "data at offset $hole_end < $((BS + punch_size))"
16131 }
16132 run_test 150g "Verify fallocate punch on large range"
16133
16134 test_150h() {
16135         local file=$DIR/$tfile
16136         local size
16137
16138         check_set_fallocate_or_skip
16139         statx_supported || skip_env "Test must be statx() syscall supported"
16140
16141         # fallocate() does not update the size information on the MDT
16142         fallocate -l 16K $file || error "failed to fallocate $file"
16143         cancel_lru_locks $OSC
16144         # STATX with cached-always mode will not send glimpse RPCs to OST,
16145         # it uses the caching attrs on the client side as much as possible.
16146         size=$($STATX --cached=always -c %s $file)
16147         [ $size == 16384 ] ||
16148                 error "size after fallocate() is $size, expected 16384"
16149 }
16150 run_test 150h "Verify extend fallocate updates the file size"
16151
16152 #LU-2902 roc_hit was not able to read all values from lproc
16153 function roc_hit_init() {
16154         local list=$(comma_list $(osts_nodes))
16155         local dir=$DIR/$tdir-check
16156         local file=$dir/$tfile
16157         local BEFORE
16158         local AFTER
16159         local idx
16160
16161         test_mkdir $dir
16162         #use setstripe to do a write to every ost
16163         for i in $(seq 0 $((OSTCOUNT-1))); do
16164                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16165                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16166                 idx=$(printf %04x $i)
16167                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16168                         awk '$1 == "cache_access" {sum += $7}
16169                                 END { printf("%0.0f", sum) }')
16170
16171                 cancel_lru_locks osc
16172                 cat $file >/dev/null
16173
16174                 AFTER=$(get_osd_param $list *OST*$idx stats |
16175                         awk '$1 == "cache_access" {sum += $7}
16176                                 END { printf("%0.0f", sum) }')
16177
16178                 echo BEFORE:$BEFORE AFTER:$AFTER
16179                 if ! let "AFTER - BEFORE == 4"; then
16180                         rm -rf $dir
16181                         error "roc_hit is not safe to use"
16182                 fi
16183                 rm $file
16184         done
16185
16186         rm -rf $dir
16187 }
16188
16189 function roc_hit() {
16190         local list=$(comma_list $(osts_nodes))
16191         echo $(get_osd_param $list '' stats |
16192                 awk '$1 == "cache_hit" {sum += $7}
16193                         END { printf("%0.0f", sum) }')
16194 }
16195
16196 function set_cache() {
16197         local on=1
16198
16199         if [ "$2" == "off" ]; then
16200                 on=0;
16201         fi
16202         local list=$(comma_list $(osts_nodes))
16203         set_osd_param $list '' $1_cache_enable $on
16204
16205         cancel_lru_locks osc
16206 }
16207
16208 test_151() {
16209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16210         remote_ost_nodsh && skip "remote OST with nodsh"
16211         (( CLIENT_VERSION == OST1_VERSION )) ||
16212                 skip "LU-13081: no interop testing for OSS cache"
16213
16214         local CPAGES=3
16215         local list=$(comma_list $(osts_nodes))
16216
16217         # check whether obdfilter is cache capable at all
16218         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16219                 skip "not cache-capable obdfilter"
16220         fi
16221
16222         # check cache is enabled on all obdfilters
16223         if get_osd_param $list '' read_cache_enable | grep 0; then
16224                 skip "oss cache is disabled"
16225         fi
16226
16227         set_osd_param $list '' writethrough_cache_enable 1
16228
16229         # check write cache is enabled on all obdfilters
16230         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16231                 skip "oss write cache is NOT enabled"
16232         fi
16233
16234         roc_hit_init
16235
16236         #define OBD_FAIL_OBD_NO_LRU  0x609
16237         do_nodes $list $LCTL set_param fail_loc=0x609
16238
16239         # pages should be in the case right after write
16240         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16241                 error "dd failed"
16242
16243         local BEFORE=$(roc_hit)
16244         cancel_lru_locks osc
16245         cat $DIR/$tfile >/dev/null
16246         local AFTER=$(roc_hit)
16247
16248         do_nodes $list $LCTL set_param fail_loc=0
16249
16250         if ! let "AFTER - BEFORE == CPAGES"; then
16251                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16252         fi
16253
16254         cancel_lru_locks osc
16255         # invalidates OST cache
16256         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16257         set_osd_param $list '' read_cache_enable 0
16258         cat $DIR/$tfile >/dev/null
16259
16260         # now data shouldn't be found in the cache
16261         BEFORE=$(roc_hit)
16262         cancel_lru_locks osc
16263         cat $DIR/$tfile >/dev/null
16264         AFTER=$(roc_hit)
16265         if let "AFTER - BEFORE != 0"; then
16266                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16267         fi
16268
16269         set_osd_param $list '' read_cache_enable 1
16270         rm -f $DIR/$tfile
16271 }
16272 run_test 151 "test cache on oss and controls ==============================="
16273
16274 test_152() {
16275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16276
16277         local TF="$TMP/$tfile"
16278
16279         # simulate ENOMEM during write
16280 #define OBD_FAIL_OST_NOMEM      0x226
16281         lctl set_param fail_loc=0x80000226
16282         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16283         cp $TF $DIR/$tfile
16284         sync || error "sync failed"
16285         lctl set_param fail_loc=0
16286
16287         # discard client's cache
16288         cancel_lru_locks osc
16289
16290         # simulate ENOMEM during read
16291         lctl set_param fail_loc=0x80000226
16292         cmp $TF $DIR/$tfile || error "cmp failed"
16293         lctl set_param fail_loc=0
16294
16295         rm -f $TF
16296 }
16297 run_test 152 "test read/write with enomem ============================"
16298
16299 test_153() {
16300         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16301 }
16302 run_test 153 "test if fdatasync does not crash ======================="
16303
16304 dot_lustre_fid_permission_check() {
16305         local fid=$1
16306         local ffid=$MOUNT/.lustre/fid/$fid
16307         local test_dir=$2
16308
16309         echo "stat fid $fid"
16310         stat $ffid || error "stat $ffid failed."
16311         echo "touch fid $fid"
16312         touch $ffid || error "touch $ffid failed."
16313         echo "write to fid $fid"
16314         cat /etc/hosts > $ffid || error "write $ffid failed."
16315         echo "read fid $fid"
16316         diff /etc/hosts $ffid || error "read $ffid failed."
16317         echo "append write to fid $fid"
16318         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16319         echo "rename fid $fid"
16320         mv $ffid $test_dir/$tfile.1 &&
16321                 error "rename $ffid to $tfile.1 should fail."
16322         touch $test_dir/$tfile.1
16323         mv $test_dir/$tfile.1 $ffid &&
16324                 error "rename $tfile.1 to $ffid should fail."
16325         rm -f $test_dir/$tfile.1
16326         echo "truncate fid $fid"
16327         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16328         echo "link fid $fid"
16329         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16330         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16331                 id $USER0 || skip_env "missing user $USER0"
16332                 echo "setfacl fid $fid"
16333                 setfacl -R -m u:$USER0:rwx $ffid ||
16334                         error "setfacl $ffid failed"
16335                 echo "getfacl fid $fid"
16336                 getfacl $ffid || error "getfacl $ffid failed."
16337         fi
16338         echo "unlink fid $fid"
16339         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16340         echo "mknod fid $fid"
16341         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16342
16343         fid=[0xf00000400:0x1:0x0]
16344         ffid=$MOUNT/.lustre/fid/$fid
16345
16346         echo "stat non-exist fid $fid"
16347         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16348         echo "write to non-exist fid $fid"
16349         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16350         echo "link new fid $fid"
16351         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16352
16353         mkdir -p $test_dir/$tdir
16354         touch $test_dir/$tdir/$tfile
16355         fid=$($LFS path2fid $test_dir/$tdir)
16356         rc=$?
16357         [ $rc -ne 0 ] &&
16358                 error "error: could not get fid for $test_dir/$dir/$tfile."
16359
16360         ffid=$MOUNT/.lustre/fid/$fid
16361
16362         echo "ls $fid"
16363         ls $ffid || error "ls $ffid failed."
16364         echo "touch $fid/$tfile.1"
16365         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16366
16367         echo "touch $MOUNT/.lustre/fid/$tfile"
16368         touch $MOUNT/.lustre/fid/$tfile && \
16369                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16370
16371         echo "setxattr to $MOUNT/.lustre/fid"
16372         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16373
16374         echo "listxattr for $MOUNT/.lustre/fid"
16375         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16376
16377         echo "delxattr from $MOUNT/.lustre/fid"
16378         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16379
16380         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16381         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16382                 error "touch invalid fid should fail."
16383
16384         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16385         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16386                 error "touch non-normal fid should fail."
16387
16388         echo "rename $tdir to $MOUNT/.lustre/fid"
16389         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16390                 error "rename to $MOUNT/.lustre/fid should fail."
16391
16392         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16393         then            # LU-3547
16394                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16395                 local new_obf_mode=777
16396
16397                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16398                 chmod $new_obf_mode $DIR/.lustre/fid ||
16399                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16400
16401                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16402                 [ $obf_mode -eq $new_obf_mode ] ||
16403                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16404
16405                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16406                 chmod $old_obf_mode $DIR/.lustre/fid ||
16407                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16408         fi
16409
16410         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16411         fid=$($LFS path2fid $test_dir/$tfile-2)
16412
16413         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16414         then # LU-5424
16415                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16416                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16417                         error "create lov data thru .lustre failed"
16418         fi
16419         echo "cp /etc/passwd $test_dir/$tfile-2"
16420         cp /etc/passwd $test_dir/$tfile-2 ||
16421                 error "copy to $test_dir/$tfile-2 failed."
16422         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16423         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16424                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16425
16426         rm -rf $test_dir/tfile.lnk
16427         rm -rf $test_dir/$tfile-2
16428 }
16429
16430 test_154A() {
16431         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16432                 skip "Need MDS version at least 2.4.1"
16433
16434         local tf=$DIR/$tfile
16435         touch $tf
16436
16437         local fid=$($LFS path2fid $tf)
16438         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16439
16440         # check that we get the same pathname back
16441         local rootpath
16442         local found
16443         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16444                 echo "$rootpath $fid"
16445                 found=$($LFS fid2path $rootpath "$fid")
16446                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16447                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16448         done
16449
16450         # check wrong root path format
16451         rootpath=$MOUNT"_wrong"
16452         found=$($LFS fid2path $rootpath "$fid")
16453         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16454 }
16455 run_test 154A "lfs path2fid and fid2path basic checks"
16456
16457 test_154B() {
16458         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16459                 skip "Need MDS version at least 2.4.1"
16460
16461         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16462         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16463         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16464         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16465
16466         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16467         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16468
16469         # check that we get the same pathname
16470         echo "PFID: $PFID, name: $name"
16471         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16472         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16473         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16474                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16475
16476         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16477 }
16478 run_test 154B "verify the ll_decode_linkea tool"
16479
16480 test_154a() {
16481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16482         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16483         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16484                 skip "Need MDS version at least 2.2.51"
16485         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16486
16487         cp /etc/hosts $DIR/$tfile
16488
16489         fid=$($LFS path2fid $DIR/$tfile)
16490         rc=$?
16491         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16492
16493         dot_lustre_fid_permission_check "$fid" $DIR ||
16494                 error "dot lustre permission check $fid failed"
16495
16496         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16497
16498         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16499
16500         touch $MOUNT/.lustre/file &&
16501                 error "creation is not allowed under .lustre"
16502
16503         mkdir $MOUNT/.lustre/dir &&
16504                 error "mkdir is not allowed under .lustre"
16505
16506         rm -rf $DIR/$tfile
16507 }
16508 run_test 154a "Open-by-FID"
16509
16510 test_154b() {
16511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16512         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16514         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16515                 skip "Need MDS version at least 2.2.51"
16516
16517         local remote_dir=$DIR/$tdir/remote_dir
16518         local MDTIDX=1
16519         local rc=0
16520
16521         mkdir -p $DIR/$tdir
16522         $LFS mkdir -i $MDTIDX $remote_dir ||
16523                 error "create remote directory failed"
16524
16525         cp /etc/hosts $remote_dir/$tfile
16526
16527         fid=$($LFS path2fid $remote_dir/$tfile)
16528         rc=$?
16529         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16530
16531         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16532                 error "dot lustre permission check $fid failed"
16533         rm -rf $DIR/$tdir
16534 }
16535 run_test 154b "Open-by-FID for remote directory"
16536
16537 test_154c() {
16538         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16539                 skip "Need MDS version at least 2.4.1"
16540
16541         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16542         local FID1=$($LFS path2fid $DIR/$tfile.1)
16543         local FID2=$($LFS path2fid $DIR/$tfile.2)
16544         local FID3=$($LFS path2fid $DIR/$tfile.3)
16545
16546         local N=1
16547         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16548                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16549                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16550                 local want=FID$N
16551                 [ "$FID" = "${!want}" ] ||
16552                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16553                 N=$((N + 1))
16554         done
16555
16556         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16557         do
16558                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16559                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16560                 N=$((N + 1))
16561         done
16562 }
16563 run_test 154c "lfs path2fid and fid2path multiple arguments"
16564
16565 test_154d() {
16566         remote_mds_nodsh && skip "remote MDS with nodsh"
16567         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16568                 skip "Need MDS version at least 2.5.53"
16569
16570         if remote_mds; then
16571                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16572         else
16573                 nid="0@lo"
16574         fi
16575         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16576         local fd
16577         local cmd
16578
16579         rm -f $DIR/$tfile
16580         touch $DIR/$tfile
16581
16582         local fid=$($LFS path2fid $DIR/$tfile)
16583         # Open the file
16584         fd=$(free_fd)
16585         cmd="exec $fd<$DIR/$tfile"
16586         eval $cmd
16587         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16588         echo "$fid_list" | grep "$fid"
16589         rc=$?
16590
16591         cmd="exec $fd>/dev/null"
16592         eval $cmd
16593         if [ $rc -ne 0 ]; then
16594                 error "FID $fid not found in open files list $fid_list"
16595         fi
16596 }
16597 run_test 154d "Verify open file fid"
16598
16599 test_154e()
16600 {
16601         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16602                 skip "Need MDS version at least 2.6.50"
16603
16604         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16605                 error ".lustre returned by readdir"
16606         fi
16607 }
16608 run_test 154e ".lustre is not returned by readdir"
16609
16610 test_154f() {
16611         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16612
16613         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16614         mkdir_on_mdt0 $DIR/$tdir
16615         # test dirs inherit from its stripe
16616         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16617         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16618         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16619         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16620         touch $DIR/f
16621
16622         # get fid of parents
16623         local FID0=$($LFS path2fid $DIR/$tdir)
16624         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16625         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16626         local FID3=$($LFS path2fid $DIR)
16627
16628         # check that path2fid --parents returns expected <parent_fid>/name
16629         # 1) test for a directory (single parent)
16630         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16631         [ "$parent" == "$FID0/foo1" ] ||
16632                 error "expected parent: $FID0/foo1, got: $parent"
16633
16634         # 2) test for a file with nlink > 1 (multiple parents)
16635         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16636         echo "$parent" | grep -F "$FID1/$tfile" ||
16637                 error "$FID1/$tfile not returned in parent list"
16638         echo "$parent" | grep -F "$FID2/link" ||
16639                 error "$FID2/link not returned in parent list"
16640
16641         # 3) get parent by fid
16642         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16643         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16644         echo "$parent" | grep -F "$FID1/$tfile" ||
16645                 error "$FID1/$tfile not returned in parent list (by fid)"
16646         echo "$parent" | grep -F "$FID2/link" ||
16647                 error "$FID2/link not returned in parent list (by fid)"
16648
16649         # 4) test for entry in root directory
16650         parent=$($LFS path2fid --parents $DIR/f)
16651         echo "$parent" | grep -F "$FID3/f" ||
16652                 error "$FID3/f not returned in parent list"
16653
16654         # 5) test it on root directory
16655         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16656                 error "$MOUNT should not have parents"
16657
16658         # enable xattr caching and check that linkea is correctly updated
16659         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16660         save_lustre_params client "llite.*.xattr_cache" > $save
16661         lctl set_param llite.*.xattr_cache 1
16662
16663         # 6.1) linkea update on rename
16664         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16665
16666         # get parents by fid
16667         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16668         # foo1 should no longer be returned in parent list
16669         echo "$parent" | grep -F "$FID1" &&
16670                 error "$FID1 should no longer be in parent list"
16671         # the new path should appear
16672         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16673                 error "$FID2/$tfile.moved is not in parent list"
16674
16675         # 6.2) linkea update on unlink
16676         rm -f $DIR/$tdir/foo2/link
16677         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16678         # foo2/link should no longer be returned in parent list
16679         echo "$parent" | grep -F "$FID2/link" &&
16680                 error "$FID2/link should no longer be in parent list"
16681         true
16682
16683         rm -f $DIR/f
16684         restore_lustre_params < $save
16685         rm -f $save
16686 }
16687 run_test 154f "get parent fids by reading link ea"
16688
16689 test_154g()
16690 {
16691         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16692            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16693                 skip "Need MDS version at least 2.6.92"
16694
16695         mkdir_on_mdt0 $DIR/$tdir
16696         llapi_fid_test -d $DIR/$tdir
16697 }
16698 run_test 154g "various llapi FID tests"
16699
16700 test_154h()
16701 {
16702         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16703                 skip "Need client at least version 2.15.55.1"
16704
16705         # Create an empty file
16706         touch $DIR/$tfile
16707
16708         # Get FID (interactive mode) and save under $TMP/$tfile.log
16709         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16710                 path2fid $DIR/$tfile
16711         EOF
16712
16713         fid=$(cat $TMP/$tfile.log)
16714         # $fid should not be empty
16715         [[ ! -z $fid ]] || error "FID is empty"
16716         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16717 }
16718 run_test 154h "Verify interactive path2fid"
16719
16720 test_155_small_load() {
16721     local temp=$TMP/$tfile
16722     local file=$DIR/$tfile
16723
16724     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16725         error "dd of=$temp bs=6096 count=1 failed"
16726     cp $temp $file
16727     cancel_lru_locks $OSC
16728     cmp $temp $file || error "$temp $file differ"
16729
16730     $TRUNCATE $temp 6000
16731     $TRUNCATE $file 6000
16732     cmp $temp $file || error "$temp $file differ (truncate1)"
16733
16734     echo "12345" >>$temp
16735     echo "12345" >>$file
16736     cmp $temp $file || error "$temp $file differ (append1)"
16737
16738     echo "12345" >>$temp
16739     echo "12345" >>$file
16740     cmp $temp $file || error "$temp $file differ (append2)"
16741
16742     rm -f $temp $file
16743     true
16744 }
16745
16746 test_155_big_load() {
16747         remote_ost_nodsh && skip "remote OST with nodsh"
16748
16749         local temp=$TMP/$tfile
16750         local file=$DIR/$tfile
16751
16752         free_min_max
16753         local cache_size=$(do_facet ost$((MAXI+1)) \
16754                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16755
16756         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16757         # pre-set value
16758         if [ -z "$cache_size" ]; then
16759                 cache_size=256
16760         fi
16761         local large_file_size=$((cache_size * 2))
16762
16763         echo "OSS cache size: $cache_size KB"
16764         echo "Large file size: $large_file_size KB"
16765
16766         [ $MAXV -le $large_file_size ] &&
16767                 skip_env "max available OST size needs > $large_file_size KB"
16768
16769         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16770
16771         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16772                 error "dd of=$temp bs=$large_file_size count=1k failed"
16773         cp $temp $file
16774         ls -lh $temp $file
16775         cancel_lru_locks osc
16776         cmp $temp $file || error "$temp $file differ"
16777
16778         rm -f $temp $file
16779         true
16780 }
16781
16782 save_writethrough() {
16783         local facets=$(get_facets OST)
16784
16785         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16786 }
16787
16788 test_155a() {
16789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16790
16791         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16792
16793         save_writethrough $p
16794
16795         set_cache read on
16796         set_cache writethrough on
16797         test_155_small_load
16798         restore_lustre_params < $p
16799         rm -f $p
16800 }
16801 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16802
16803 test_155b() {
16804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16805
16806         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16807
16808         save_writethrough $p
16809
16810         set_cache read on
16811         set_cache writethrough off
16812         test_155_small_load
16813         restore_lustre_params < $p
16814         rm -f $p
16815 }
16816 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16817
16818 test_155c() {
16819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16820
16821         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16822
16823         save_writethrough $p
16824
16825         set_cache read off
16826         set_cache writethrough on
16827         test_155_small_load
16828         restore_lustre_params < $p
16829         rm -f $p
16830 }
16831 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16832
16833 test_155d() {
16834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16835
16836         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16837
16838         save_writethrough $p
16839
16840         set_cache read off
16841         set_cache writethrough off
16842         test_155_small_load
16843         restore_lustre_params < $p
16844         rm -f $p
16845 }
16846 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16847
16848 test_155e() {
16849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16850
16851         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16852
16853         save_writethrough $p
16854
16855         set_cache read on
16856         set_cache writethrough on
16857         test_155_big_load
16858         restore_lustre_params < $p
16859         rm -f $p
16860 }
16861 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16862
16863 test_155f() {
16864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16865
16866         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16867
16868         save_writethrough $p
16869
16870         set_cache read on
16871         set_cache writethrough off
16872         test_155_big_load
16873         restore_lustre_params < $p
16874         rm -f $p
16875 }
16876 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16877
16878 test_155g() {
16879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16880
16881         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16882
16883         save_writethrough $p
16884
16885         set_cache read off
16886         set_cache writethrough on
16887         test_155_big_load
16888         restore_lustre_params < $p
16889         rm -f $p
16890 }
16891 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16892
16893 test_155h() {
16894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16895
16896         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16897
16898         save_writethrough $p
16899
16900         set_cache read off
16901         set_cache writethrough off
16902         test_155_big_load
16903         restore_lustre_params < $p
16904         rm -f $p
16905 }
16906 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16907
16908 test_156() {
16909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16910         remote_ost_nodsh && skip "remote OST with nodsh"
16911         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16912                 skip "stats not implemented on old servers"
16913         [ "$ost1_FSTYPE" = "zfs" ] &&
16914                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16915         (( CLIENT_VERSION == OST1_VERSION )) ||
16916                 skip "LU-13081: no interop testing for OSS cache"
16917
16918         local CPAGES=3
16919         local BEFORE
16920         local AFTER
16921         local file="$DIR/$tfile"
16922         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16923
16924         save_writethrough $p
16925         roc_hit_init
16926
16927         log "Turn on read and write cache"
16928         set_cache read on
16929         set_cache writethrough on
16930
16931         log "Write data and read it back."
16932         log "Read should be satisfied from the cache."
16933         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16934         BEFORE=$(roc_hit)
16935         cancel_lru_locks osc
16936         cat $file >/dev/null
16937         AFTER=$(roc_hit)
16938         if ! let "AFTER - BEFORE == CPAGES"; then
16939                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16940         else
16941                 log "cache hits: before: $BEFORE, after: $AFTER"
16942         fi
16943
16944         log "Read again; it should be satisfied from the cache."
16945         BEFORE=$AFTER
16946         cancel_lru_locks osc
16947         cat $file >/dev/null
16948         AFTER=$(roc_hit)
16949         if ! let "AFTER - BEFORE == CPAGES"; then
16950                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16951         else
16952                 log "cache hits:: before: $BEFORE, after: $AFTER"
16953         fi
16954
16955         log "Turn off the read cache and turn on the write cache"
16956         set_cache read off
16957         set_cache writethrough on
16958
16959         log "Read again; it should be satisfied from the cache."
16960         BEFORE=$(roc_hit)
16961         cancel_lru_locks osc
16962         cat $file >/dev/null
16963         AFTER=$(roc_hit)
16964         if ! let "AFTER - BEFORE == CPAGES"; then
16965                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16966         else
16967                 log "cache hits:: before: $BEFORE, after: $AFTER"
16968         fi
16969
16970         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16971                 # > 2.12.56 uses pagecache if cached
16972                 log "Read again; it should not be satisfied from the cache."
16973                 BEFORE=$AFTER
16974                 cancel_lru_locks osc
16975                 cat $file >/dev/null
16976                 AFTER=$(roc_hit)
16977                 if ! let "AFTER - BEFORE == 0"; then
16978                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16979                 else
16980                         log "cache hits:: before: $BEFORE, after: $AFTER"
16981                 fi
16982         fi
16983
16984         log "Write data and read it back."
16985         log "Read should be satisfied from the cache."
16986         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16987         BEFORE=$(roc_hit)
16988         cancel_lru_locks osc
16989         cat $file >/dev/null
16990         AFTER=$(roc_hit)
16991         if ! let "AFTER - BEFORE == CPAGES"; then
16992                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16993         else
16994                 log "cache hits:: before: $BEFORE, after: $AFTER"
16995         fi
16996
16997         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16998                 # > 2.12.56 uses pagecache if cached
16999                 log "Read again; it should not be satisfied from the cache."
17000                 BEFORE=$AFTER
17001                 cancel_lru_locks osc
17002                 cat $file >/dev/null
17003                 AFTER=$(roc_hit)
17004                 if ! let "AFTER - BEFORE == 0"; then
17005                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17006                 else
17007                         log "cache hits:: before: $BEFORE, after: $AFTER"
17008                 fi
17009         fi
17010
17011         log "Turn off read and write cache"
17012         set_cache read off
17013         set_cache writethrough off
17014
17015         log "Write data and read it back"
17016         log "It should not be satisfied from the cache."
17017         rm -f $file
17018         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17019         cancel_lru_locks osc
17020         BEFORE=$(roc_hit)
17021         cat $file >/dev/null
17022         AFTER=$(roc_hit)
17023         if ! let "AFTER - BEFORE == 0"; then
17024                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17025         else
17026                 log "cache hits:: before: $BEFORE, after: $AFTER"
17027         fi
17028
17029         log "Turn on the read cache and turn off the write cache"
17030         set_cache read on
17031         set_cache writethrough off
17032
17033         log "Write data and read it back"
17034         log "It should not be satisfied from the cache."
17035         rm -f $file
17036         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17037         BEFORE=$(roc_hit)
17038         cancel_lru_locks osc
17039         cat $file >/dev/null
17040         AFTER=$(roc_hit)
17041         if ! let "AFTER - BEFORE == 0"; then
17042                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17043         else
17044                 log "cache hits:: before: $BEFORE, after: $AFTER"
17045         fi
17046
17047         log "Read again; it should be satisfied from the cache."
17048         BEFORE=$(roc_hit)
17049         cancel_lru_locks osc
17050         cat $file >/dev/null
17051         AFTER=$(roc_hit)
17052         if ! let "AFTER - BEFORE == CPAGES"; then
17053                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17054         else
17055                 log "cache hits:: before: $BEFORE, after: $AFTER"
17056         fi
17057
17058         restore_lustre_params < $p
17059         rm -f $p $file
17060 }
17061 run_test 156 "Verification of tunables"
17062
17063 test_160a() {
17064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17065         remote_mds_nodsh && skip "remote MDS with nodsh"
17066         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17067                 skip "Need MDS version at least 2.2.0"
17068
17069         changelog_register || error "changelog_register failed"
17070         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17071         changelog_users $SINGLEMDS | grep -q $cl_user ||
17072                 error "User $cl_user not found in changelog_users"
17073
17074         mkdir_on_mdt0 $DIR/$tdir
17075
17076         # change something
17077         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17078         changelog_clear 0 || error "changelog_clear failed"
17079         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17080         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17081         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17082         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17083         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17084         rm $DIR/$tdir/pics/desktop.jpg
17085
17086         echo "verifying changelog mask"
17087         changelog_chmask "-MKDIR"
17088         changelog_chmask "-CLOSE"
17089
17090         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17091         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17092
17093         changelog_chmask "+MKDIR"
17094         changelog_chmask "+CLOSE"
17095
17096         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17097         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17098
17099         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17100         CLOSES=$(changelog_dump | grep -c "CLOSE")
17101         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17102         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17103
17104         # verify contents
17105         echo "verifying target fid"
17106         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17107         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17108         [ "$fidc" == "$fidf" ] ||
17109                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17110         echo "verifying parent fid"
17111         # The FID returned from the Changelog may be the directory shard on
17112         # a different MDT, and not the FID returned by path2fid on the parent.
17113         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17114         # since this is what will matter when recreating this file in the tree.
17115         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17116         local pathp=$($LFS fid2path $MOUNT "$fidp")
17117         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17118                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17119
17120         echo "getting records for $cl_user"
17121         changelog_users $SINGLEMDS
17122         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17123         local nclr=3
17124         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17125                 error "changelog_clear failed"
17126         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17127         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17128         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17129                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17130
17131         local min0_rec=$(changelog_users $SINGLEMDS |
17132                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17133         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17134                           awk '{ print $1; exit; }')
17135
17136         changelog_dump | tail -n 5
17137         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17138         [ $first_rec == $((min0_rec + 1)) ] ||
17139                 error "first index should be $min0_rec + 1 not $first_rec"
17140
17141         # LU-3446 changelog index reset on MDT restart
17142         local cur_rec1=$(changelog_users $SINGLEMDS |
17143                          awk '/^current.index:/ { print $NF }')
17144         changelog_clear 0 ||
17145                 error "clear all changelog records for $cl_user failed"
17146         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17147         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17148                 error "Fail to start $SINGLEMDS"
17149         local cur_rec2=$(changelog_users $SINGLEMDS |
17150                          awk '/^current.index:/ { print $NF }')
17151         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17152         [ $cur_rec1 == $cur_rec2 ] ||
17153                 error "current index should be $cur_rec1 not $cur_rec2"
17154
17155         echo "verifying users from this test are deregistered"
17156         changelog_deregister || error "changelog_deregister failed"
17157         changelog_users $SINGLEMDS | grep -q $cl_user &&
17158                 error "User '$cl_user' still in changelog_users"
17159
17160         # lctl get_param -n mdd.*.changelog_users
17161         # current_index: 144
17162         # ID    index (idle seconds)
17163         # cl3   144   (2) mask=<list>
17164         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17165                 # this is the normal case where all users were deregistered
17166                 # make sure no new records are added when no users are present
17167                 local last_rec1=$(changelog_users $SINGLEMDS |
17168                                   awk '/^current.index:/ { print $NF }')
17169                 touch $DIR/$tdir/chloe
17170                 local last_rec2=$(changelog_users $SINGLEMDS |
17171                                   awk '/^current.index:/ { print $NF }')
17172                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17173                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17174         else
17175                 # any changelog users must be leftovers from a previous test
17176                 changelog_users $SINGLEMDS
17177                 echo "other changelog users; can't verify off"
17178         fi
17179 }
17180 run_test 160a "changelog sanity"
17181
17182 test_160b() { # LU-3587
17183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17184         remote_mds_nodsh && skip "remote MDS with nodsh"
17185         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17186                 skip "Need MDS version at least 2.2.0"
17187
17188         changelog_register || error "changelog_register failed"
17189         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17190         changelog_users $SINGLEMDS | grep -q $cl_user ||
17191                 error "User '$cl_user' not found in changelog_users"
17192
17193         local longname1=$(str_repeat a 255)
17194         local longname2=$(str_repeat b 255)
17195
17196         cd $DIR
17197         echo "creating very long named file"
17198         touch $longname1 || error "create of '$longname1' failed"
17199         echo "renaming very long named file"
17200         mv $longname1 $longname2
17201
17202         changelog_dump | grep RENME | tail -n 5
17203         rm -f $longname2
17204 }
17205 run_test 160b "Verify that very long rename doesn't crash in changelog"
17206
17207 test_160c() {
17208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17209         remote_mds_nodsh && skip "remote MDS with nodsh"
17210
17211         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17212                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17213                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17214                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17215
17216         local rc=0
17217
17218         # Registration step
17219         changelog_register || error "changelog_register failed"
17220
17221         rm -rf $DIR/$tdir
17222         mkdir -p $DIR/$tdir
17223         $MCREATE $DIR/$tdir/foo_160c
17224         changelog_chmask "-TRUNC"
17225         $TRUNCATE $DIR/$tdir/foo_160c 200
17226         changelog_chmask "+TRUNC"
17227         $TRUNCATE $DIR/$tdir/foo_160c 199
17228         changelog_dump | tail -n 5
17229         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17230         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17231 }
17232 run_test 160c "verify that changelog log catch the truncate event"
17233
17234 test_160d() {
17235         remote_mds_nodsh && skip "remote MDS with nodsh"
17236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17238         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17239                 skip "Need MDS version at least 2.7.60"
17240
17241         # Registration step
17242         changelog_register || error "changelog_register failed"
17243
17244         mkdir -p $DIR/$tdir/migrate_dir
17245         changelog_clear 0 || error "changelog_clear failed"
17246
17247         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17248         changelog_dump | tail -n 5
17249         local migrates=$(changelog_dump | grep -c "MIGRT")
17250         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17251 }
17252 run_test 160d "verify that changelog log catch the migrate event"
17253
17254 test_160e() {
17255         remote_mds_nodsh && skip "remote MDS with nodsh"
17256
17257         # Create a user
17258         changelog_register || error "changelog_register failed"
17259
17260         local MDT0=$(facet_svc $SINGLEMDS)
17261         local rc
17262
17263         # No user (expect fail)
17264         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17265         rc=$?
17266         if [ $rc -eq 0 ]; then
17267                 error "Should fail without user"
17268         elif [ $rc -ne 4 ]; then
17269                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17270         fi
17271
17272         # Delete a future user (expect fail)
17273         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17274         rc=$?
17275         if [ $rc -eq 0 ]; then
17276                 error "Deleted non-existant user cl77"
17277         elif [ $rc -ne 2 ]; then
17278                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17279         fi
17280
17281         # Clear to a bad index (1 billion should be safe)
17282         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17283         rc=$?
17284
17285         if [ $rc -eq 0 ]; then
17286                 error "Successfully cleared to invalid CL index"
17287         elif [ $rc -ne 22 ]; then
17288                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17289         fi
17290 }
17291 run_test 160e "changelog negative testing (should return errors)"
17292
17293 test_160f() {
17294         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17295         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17296                 skip "Need MDS version at least 2.10.56"
17297
17298         local mdts=$(comma_list $(mdts_nodes))
17299
17300         # Create a user
17301         changelog_register || error "first changelog_register failed"
17302         changelog_register || error "second changelog_register failed"
17303         local cl_users
17304         declare -A cl_user1
17305         declare -A cl_user2
17306         local user_rec1
17307         local user_rec2
17308         local i
17309
17310         # generate some changelog records to accumulate on each MDT
17311         # use all_char because created files should be evenly distributed
17312         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17313                 error "test_mkdir $tdir failed"
17314         log "$(date +%s): creating first files"
17315         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17316                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17317                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17318         done
17319
17320         # check changelogs have been generated
17321         local start=$SECONDS
17322         local idle_time=$((MDSCOUNT * 5 + 5))
17323         local nbcl=$(changelog_dump | wc -l)
17324         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17325
17326         for param in "changelog_max_idle_time=$idle_time" \
17327                      "changelog_gc=1" \
17328                      "changelog_min_gc_interval=2" \
17329                      "changelog_min_free_cat_entries=3"; do
17330                 local MDT0=$(facet_svc $SINGLEMDS)
17331                 local var="${param%=*}"
17332                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17333
17334                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17335                 do_nodes $mdts $LCTL set_param mdd.*.$param
17336         done
17337
17338         # force cl_user2 to be idle (1st part), but also cancel the
17339         # cl_user1 records so that it is not evicted later in the test.
17340         local sleep1=$((idle_time / 2))
17341         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17342         sleep $sleep1
17343
17344         # simulate changelog catalog almost full
17345         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17346         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17347
17348         for i in $(seq $MDSCOUNT); do
17349                 cl_users=(${CL_USERS[mds$i]})
17350                 cl_user1[mds$i]="${cl_users[0]}"
17351                 cl_user2[mds$i]="${cl_users[1]}"
17352
17353                 [ -n "${cl_user1[mds$i]}" ] ||
17354                         error "mds$i: no user registered"
17355                 [ -n "${cl_user2[mds$i]}" ] ||
17356                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17357
17358                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17359                 [ -n "$user_rec1" ] ||
17360                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17361                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17362                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17363                 [ -n "$user_rec2" ] ||
17364                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17365                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17366                      "$user_rec1 + 2 == $user_rec2"
17367                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17368                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17369                               "$user_rec1 + 2, but is $user_rec2"
17370                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17371                 [ -n "$user_rec2" ] ||
17372                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17373                 [ $user_rec1 == $user_rec2 ] ||
17374                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17375                               "$user_rec1, but is $user_rec2"
17376         done
17377
17378         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17379         local sleep2=$((idle_time - (SECONDS - start) + 1))
17380         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17381         sleep $sleep2
17382
17383         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17384         # cl_user1 should be OK because it recently processed records.
17385         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17386         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17387                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17388                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17389         done
17390
17391         # ensure gc thread is done
17392         for i in $(mdts_nodes); do
17393                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17394                         error "$i: GC-thread not done"
17395         done
17396
17397         local first_rec
17398         for (( i = 1; i <= MDSCOUNT; i++ )); do
17399                 # check cl_user1 still registered
17400                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17401                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17402                 # check cl_user2 unregistered
17403                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17404                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17405
17406                 # check changelogs are present and starting at $user_rec1 + 1
17407                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17408                 [ -n "$user_rec1" ] ||
17409                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17410                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17411                             awk '{ print $1; exit; }')
17412
17413                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17414                 [ $((user_rec1 + 1)) == $first_rec ] ||
17415                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17416         done
17417 }
17418 run_test 160f "changelog garbage collect (timestamped users)"
17419
17420 test_160g() {
17421         remote_mds_nodsh && skip "remote MDS with nodsh"
17422         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17423                 skip "Need MDS version at least 2.14.55"
17424
17425         local mdts=$(comma_list $(mdts_nodes))
17426
17427         # Create a user
17428         changelog_register || error "first changelog_register failed"
17429         changelog_register || error "second changelog_register failed"
17430         local cl_users
17431         declare -A cl_user1
17432         declare -A cl_user2
17433         local user_rec1
17434         local user_rec2
17435         local i
17436
17437         # generate some changelog records to accumulate on each MDT
17438         # use all_char because created files should be evenly distributed
17439         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17440                 error "test_mkdir $tdir failed"
17441         for ((i = 0; i < MDSCOUNT; i++)); do
17442                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17443                         error "create $DIR/$tdir/d$i.1 failed"
17444         done
17445
17446         # check changelogs have been generated
17447         local nbcl=$(changelog_dump | wc -l)
17448         (( $nbcl > 0 )) || error "no changelogs found"
17449
17450         # reduce the max_idle_indexes value to make sure we exceed it
17451         for param in "changelog_max_idle_indexes=2" \
17452                      "changelog_gc=1" \
17453                      "changelog_min_gc_interval=2"; do
17454                 local MDT0=$(facet_svc $SINGLEMDS)
17455                 local var="${param%=*}"
17456                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17457
17458                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17459                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17460                         error "unable to set mdd.*.$param"
17461         done
17462
17463         local start=$SECONDS
17464         for i in $(seq $MDSCOUNT); do
17465                 cl_users=(${CL_USERS[mds$i]})
17466                 cl_user1[mds$i]="${cl_users[0]}"
17467                 cl_user2[mds$i]="${cl_users[1]}"
17468
17469                 [ -n "${cl_user1[mds$i]}" ] ||
17470                         error "mds$i: user1 is not registered"
17471                 [ -n "${cl_user2[mds$i]}" ] ||
17472                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17473
17474                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17475                 [ -n "$user_rec1" ] ||
17476                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17477                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17478                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17479                 [ -n "$user_rec2" ] ||
17480                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17481                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17482                      "$user_rec1 + 2 == $user_rec2"
17483                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17484                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17485                               "expected $user_rec1 + 2, but is $user_rec2"
17486                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17487                 [ -n "$user_rec2" ] ||
17488                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17489                 [ $user_rec1 == $user_rec2 ] ||
17490                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17491                               "expected $user_rec1, but is $user_rec2"
17492         done
17493
17494         # ensure we are past the previous changelog_min_gc_interval set above
17495         local sleep2=$((start + 2 - SECONDS))
17496         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17497         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17498         # cl_user1 should be OK because it recently processed records.
17499         for ((i = 0; i < MDSCOUNT; i++)); do
17500                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17501                         error "create $DIR/$tdir/d$i.3 failed"
17502         done
17503
17504         # ensure gc thread is done
17505         for i in $(mdts_nodes); do
17506                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17507                         error "$i: GC-thread not done"
17508         done
17509
17510         local first_rec
17511         for (( i = 1; i <= MDSCOUNT; i++ )); do
17512                 # check cl_user1 still registered
17513                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17514                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17515                 # check cl_user2 unregistered
17516                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17517                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17518
17519                 # check changelogs are present and starting at $user_rec1 + 1
17520                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17521                 [ -n "$user_rec1" ] ||
17522                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17523                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17524                             awk '{ print $1; exit; }')
17525
17526                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17527                 [ $((user_rec1 + 1)) == $first_rec ] ||
17528                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17529         done
17530 }
17531 run_test 160g "changelog garbage collect on idle records"
17532
17533 test_160h() {
17534         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17535         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17536                 skip "Need MDS version at least 2.10.56"
17537
17538         local mdts=$(comma_list $(mdts_nodes))
17539
17540         # Create a user
17541         changelog_register || error "first changelog_register failed"
17542         changelog_register || error "second changelog_register failed"
17543         local cl_users
17544         declare -A cl_user1
17545         declare -A cl_user2
17546         local user_rec1
17547         local user_rec2
17548         local i
17549
17550         # generate some changelog records to accumulate on each MDT
17551         # use all_char because created files should be evenly distributed
17552         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17553                 error "test_mkdir $tdir failed"
17554         for ((i = 0; i < MDSCOUNT; i++)); do
17555                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17556                         error "create $DIR/$tdir/d$i.1 failed"
17557         done
17558
17559         # check changelogs have been generated
17560         local nbcl=$(changelog_dump | wc -l)
17561         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17562
17563         for param in "changelog_max_idle_time=10" \
17564                      "changelog_gc=1" \
17565                      "changelog_min_gc_interval=2"; do
17566                 local MDT0=$(facet_svc $SINGLEMDS)
17567                 local var="${param%=*}"
17568                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17569
17570                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17571                 do_nodes $mdts $LCTL set_param mdd.*.$param
17572         done
17573
17574         # force cl_user2 to be idle (1st part)
17575         sleep 9
17576
17577         for i in $(seq $MDSCOUNT); do
17578                 cl_users=(${CL_USERS[mds$i]})
17579                 cl_user1[mds$i]="${cl_users[0]}"
17580                 cl_user2[mds$i]="${cl_users[1]}"
17581
17582                 [ -n "${cl_user1[mds$i]}" ] ||
17583                         error "mds$i: no user registered"
17584                 [ -n "${cl_user2[mds$i]}" ] ||
17585                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17586
17587                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17588                 [ -n "$user_rec1" ] ||
17589                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17590                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17591                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17592                 [ -n "$user_rec2" ] ||
17593                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17594                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17595                      "$user_rec1 + 2 == $user_rec2"
17596                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17597                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17598                               "$user_rec1 + 2, but is $user_rec2"
17599                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17600                 [ -n "$user_rec2" ] ||
17601                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17602                 [ $user_rec1 == $user_rec2 ] ||
17603                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17604                               "$user_rec1, but is $user_rec2"
17605         done
17606
17607         # force cl_user2 to be idle (2nd part) and to reach
17608         # changelog_max_idle_time
17609         sleep 2
17610
17611         # force each GC-thread start and block then
17612         # one per MDT/MDD, set fail_val accordingly
17613         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17614         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17615
17616         # generate more changelogs to trigger fail_loc
17617         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17618                 error "create $DIR/$tdir/${tfile}bis failed"
17619
17620         # stop MDT to stop GC-thread, should be done in back-ground as it will
17621         # block waiting for the thread to be released and exit
17622         declare -A stop_pids
17623         for i in $(seq $MDSCOUNT); do
17624                 stop mds$i &
17625                 stop_pids[mds$i]=$!
17626         done
17627
17628         for i in $(mdts_nodes); do
17629                 local facet
17630                 local nb=0
17631                 local facets=$(facets_up_on_host $i)
17632
17633                 for facet in ${facets//,/ }; do
17634                         if [[ $facet == mds* ]]; then
17635                                 nb=$((nb + 1))
17636                         fi
17637                 done
17638                 # ensure each MDS's gc threads are still present and all in "R"
17639                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17640                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17641                         error "$i: expected $nb GC-thread"
17642                 wait_update $i \
17643                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17644                         "R" 20 ||
17645                         error "$i: GC-thread not found in R-state"
17646                 # check umounts of each MDT on MDS have reached kthread_stop()
17647                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17648                         error "$i: expected $nb umount"
17649                 wait_update $i \
17650                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17651                         error "$i: umount not found in D-state"
17652         done
17653
17654         # release all GC-threads
17655         do_nodes $mdts $LCTL set_param fail_loc=0
17656
17657         # wait for MDT stop to complete
17658         for i in $(seq $MDSCOUNT); do
17659                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17660         done
17661
17662         # XXX
17663         # may try to check if any orphan changelog records are present
17664         # via ldiskfs/zfs and llog_reader...
17665
17666         # re-start/mount MDTs
17667         for i in $(seq $MDSCOUNT); do
17668                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17669                         error "Fail to start mds$i"
17670         done
17671
17672         local first_rec
17673         for i in $(seq $MDSCOUNT); do
17674                 # check cl_user1 still registered
17675                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17677                 # check cl_user2 unregistered
17678                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17679                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17680
17681                 # check changelogs are present and starting at $user_rec1 + 1
17682                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17683                 [ -n "$user_rec1" ] ||
17684                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17685                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17686                             awk '{ print $1; exit; }')
17687
17688                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17689                 [ $((user_rec1 + 1)) == $first_rec ] ||
17690                         error "mds$i: first index should be $user_rec1 + 1, " \
17691                               "but is $first_rec"
17692         done
17693 }
17694 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17695               "during mount"
17696
17697 test_160i() {
17698
17699         local mdts=$(comma_list $(mdts_nodes))
17700
17701         changelog_register || error "first changelog_register failed"
17702
17703         # generate some changelog records to accumulate on each MDT
17704         # use all_char because created files should be evenly distributed
17705         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17706                 error "test_mkdir $tdir failed"
17707         for ((i = 0; i < MDSCOUNT; i++)); do
17708                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17709                         error "create $DIR/$tdir/d$i.1 failed"
17710         done
17711
17712         # check changelogs have been generated
17713         local nbcl=$(changelog_dump | wc -l)
17714         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17715
17716         # simulate race between register and unregister
17717         # XXX as fail_loc is set per-MDS, with DNE configs the race
17718         # simulation will only occur for one MDT per MDS and for the
17719         # others the normal race scenario will take place
17720         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17721         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17722         do_nodes $mdts $LCTL set_param fail_val=1
17723
17724         # unregister 1st user
17725         changelog_deregister &
17726         local pid1=$!
17727         # wait some time for deregister work to reach race rdv
17728         sleep 2
17729         # register 2nd user
17730         changelog_register || error "2nd user register failed"
17731
17732         wait $pid1 || error "1st user deregister failed"
17733
17734         local i
17735         local last_rec
17736         declare -A LAST_REC
17737         for i in $(seq $MDSCOUNT); do
17738                 if changelog_users mds$i | grep "^cl"; then
17739                         # make sure new records are added with one user present
17740                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17741                                           awk '/^current.index:/ { print $NF }')
17742                 else
17743                         error "mds$i has no user registered"
17744                 fi
17745         done
17746
17747         # generate more changelog records to accumulate on each MDT
17748         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17749                 error "create $DIR/$tdir/${tfile}bis failed"
17750
17751         for i in $(seq $MDSCOUNT); do
17752                 last_rec=$(changelog_users $SINGLEMDS |
17753                            awk '/^current.index:/ { print $NF }')
17754                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17755                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17756                         error "changelogs are off on mds$i"
17757         done
17758 }
17759 run_test 160i "changelog user register/unregister race"
17760
17761 test_160j() {
17762         remote_mds_nodsh && skip "remote MDS with nodsh"
17763         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17764                 skip "Need MDS version at least 2.12.56"
17765
17766         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17767         stack_trap "umount $MOUNT2" EXIT
17768
17769         changelog_register || error "first changelog_register failed"
17770         stack_trap "changelog_deregister" EXIT
17771
17772         # generate some changelog
17773         # use all_char because created files should be evenly distributed
17774         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17775                 error "mkdir $tdir failed"
17776         for ((i = 0; i < MDSCOUNT; i++)); do
17777                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17778                         error "create $DIR/$tdir/d$i.1 failed"
17779         done
17780
17781         # open the changelog device
17782         exec 3>/dev/changelog-$FSNAME-MDT0000
17783         stack_trap "exec 3>&-" EXIT
17784         exec 4</dev/changelog-$FSNAME-MDT0000
17785         stack_trap "exec 4<&-" EXIT
17786
17787         # umount the first lustre mount
17788         umount $MOUNT
17789         stack_trap "mount_client $MOUNT" EXIT
17790
17791         # read changelog, which may or may not fail, but should not crash
17792         cat <&4 >/dev/null
17793
17794         # clear changelog
17795         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17796         changelog_users $SINGLEMDS | grep -q $cl_user ||
17797                 error "User $cl_user not found in changelog_users"
17798
17799         printf 'clear:'$cl_user':0' >&3
17800 }
17801 run_test 160j "client can be umounted while its chanangelog is being used"
17802
17803 test_160k() {
17804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17805         remote_mds_nodsh && skip "remote MDS with nodsh"
17806
17807         mkdir -p $DIR/$tdir/1/1
17808
17809         changelog_register || error "changelog_register failed"
17810         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17811
17812         changelog_users $SINGLEMDS | grep -q $cl_user ||
17813                 error "User '$cl_user' not found in changelog_users"
17814 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17815         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17816         rmdir $DIR/$tdir/1/1 & sleep 1
17817         mkdir $DIR/$tdir/2
17818         touch $DIR/$tdir/2/2
17819         rm -rf $DIR/$tdir/2
17820
17821         wait
17822         sleep 4
17823
17824         changelog_dump | grep rmdir || error "rmdir not recorded"
17825 }
17826 run_test 160k "Verify that changelog records are not lost"
17827
17828 # Verifies that a file passed as a parameter has recently had an operation
17829 # performed on it that has generated an MTIME changelog which contains the
17830 # correct parent FID. As files might reside on a different MDT from the
17831 # parent directory in DNE configurations, the FIDs are translated to paths
17832 # before being compared, which should be identical
17833 compare_mtime_changelog() {
17834         local file="${1}"
17835         local mdtidx
17836         local mtime
17837         local cl_fid
17838         local pdir
17839         local dir
17840
17841         mdtidx=$($LFS getstripe --mdt-index $file)
17842         mdtidx=$(printf "%04x" $mdtidx)
17843
17844         # Obtain the parent FID from the MTIME changelog
17845         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17846         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17847
17848         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17849         [ -z "$cl_fid" ] && error "parent FID not present"
17850
17851         # Verify that the path for the parent FID is the same as the path for
17852         # the test directory
17853         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17854
17855         dir=$(dirname $1)
17856
17857         [[ "${pdir%/}" == "$dir" ]] ||
17858                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17859 }
17860
17861 test_160l() {
17862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17863
17864         remote_mds_nodsh && skip "remote MDS with nodsh"
17865         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17866                 skip "Need MDS version at least 2.13.55"
17867
17868         local cl_user
17869
17870         changelog_register || error "changelog_register failed"
17871         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17872
17873         changelog_users $SINGLEMDS | grep -q $cl_user ||
17874                 error "User '$cl_user' not found in changelog_users"
17875
17876         # Clear some types so that MTIME changelogs are generated
17877         changelog_chmask "-CREAT"
17878         changelog_chmask "-CLOSE"
17879
17880         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17881
17882         # Test CL_MTIME during setattr
17883         touch $DIR/$tdir/$tfile
17884         compare_mtime_changelog $DIR/$tdir/$tfile
17885
17886         # Test CL_MTIME during close
17887         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17888         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17889 }
17890 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17891
17892 test_160m() {
17893         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17894         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17895                 skip "Need MDS version at least 2.14.51"
17896         local cl_users
17897         local cl_user1
17898         local cl_user2
17899         local pid1
17900
17901         # Create a user
17902         changelog_register || error "first changelog_register failed"
17903         changelog_register || error "second changelog_register failed"
17904
17905         cl_users=(${CL_USERS[mds1]})
17906         cl_user1="${cl_users[0]}"
17907         cl_user2="${cl_users[1]}"
17908         # generate some changelog records to accumulate on MDT0
17909         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17910         createmany -m $DIR/$tdir/$tfile 50 ||
17911                 error "create $DIR/$tdir/$tfile failed"
17912         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17913         rm -f $DIR/$tdir
17914
17915         # check changelogs have been generated
17916         local nbcl=$(changelog_dump | wc -l)
17917         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17918
17919 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17920         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17921
17922         __changelog_clear mds1 $cl_user1 +10
17923         __changelog_clear mds1 $cl_user2 0 &
17924         pid1=$!
17925         sleep 2
17926         __changelog_clear mds1 $cl_user1 0 ||
17927                 error "fail to cancel record for $cl_user1"
17928         wait $pid1
17929         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17930 }
17931 run_test 160m "Changelog clear race"
17932
17933 test_160n() {
17934         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17935         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17936                 skip "Need MDS version at least 2.14.51"
17937         local cl_users
17938         local cl_user1
17939         local cl_user2
17940         local pid1
17941         local first_rec
17942         local last_rec=0
17943
17944         # Create a user
17945         changelog_register || error "first changelog_register failed"
17946
17947         cl_users=(${CL_USERS[mds1]})
17948         cl_user1="${cl_users[0]}"
17949
17950         # generate some changelog records to accumulate on MDT0
17951         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17952         first_rec=$(changelog_users $SINGLEMDS |
17953                         awk '/^current.index:/ { print $NF }')
17954         while (( last_rec < (( first_rec + 65000)) )); do
17955                 createmany -m $DIR/$tdir/$tfile 10000 ||
17956                         error "create $DIR/$tdir/$tfile failed"
17957
17958                 for i in $(seq 0 10000); do
17959                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17960                                 > /dev/null
17961                 done
17962
17963                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17964                         error "unlinkmany failed unlink"
17965                 last_rec=$(changelog_users $SINGLEMDS |
17966                         awk '/^current.index:/ { print $NF }')
17967                 echo last record $last_rec
17968                 (( last_rec == 0 )) && error "no changelog found"
17969         done
17970
17971 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17972         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17973
17974         __changelog_clear mds1 $cl_user1 0 &
17975         pid1=$!
17976         sleep 2
17977         __changelog_clear mds1 $cl_user1 0 ||
17978                 error "fail to cancel record for $cl_user1"
17979         wait $pid1
17980         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17981 }
17982 run_test 160n "Changelog destroy race"
17983
17984 test_160o() {
17985         local mdt="$(facet_svc $SINGLEMDS)"
17986
17987         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17988         remote_mds_nodsh && skip "remote MDS with nodsh"
17989         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17990                 skip "Need MDS version at least 2.14.52"
17991
17992         changelog_register --user test_160o -m unlnk+close+open ||
17993                 error "changelog_register failed"
17994
17995         do_facet $SINGLEMDS $LCTL --device $mdt \
17996                                 changelog_register -u "Tt3_-#" &&
17997                 error "bad symbols in name should fail"
17998
17999         do_facet $SINGLEMDS $LCTL --device $mdt \
18000                                 changelog_register -u test_160o &&
18001                 error "the same name registration should fail"
18002
18003         do_facet $SINGLEMDS $LCTL --device $mdt \
18004                         changelog_register -u test_160toolongname &&
18005                 error "too long name registration should fail"
18006
18007         changelog_chmask "MARK+HSM"
18008         lctl get_param mdd.*.changelog*mask
18009         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18010         changelog_users $SINGLEMDS | grep -q $cl_user ||
18011                 error "User $cl_user not found in changelog_users"
18012         #verify username
18013         echo $cl_user | grep -q test_160o ||
18014                 error "User $cl_user has no specific name 'test160o'"
18015
18016         # change something
18017         changelog_clear 0 || error "changelog_clear failed"
18018         # generate some changelog records to accumulate on MDT0
18019         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18020         touch $DIR/$tdir/$tfile                 # open 1
18021
18022         OPENS=$(changelog_dump | grep -c "OPEN")
18023         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18024
18025         # must be no MKDIR it wasn't set as user mask
18026         MKDIR=$(changelog_dump | grep -c "MKDIR")
18027         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18028
18029         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18030                                 mdd.$mdt.changelog_current_mask -n)
18031         # register maskless user
18032         changelog_register || error "changelog_register failed"
18033         # effective mask should be not changed because it is not minimal
18034         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18035                                 mdd.$mdt.changelog_current_mask -n)
18036         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18037         # set server mask to minimal value
18038         changelog_chmask "MARK"
18039         # check effective mask again, should be treated as DEFMASK now
18040         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18041                                 mdd.$mdt.changelog_current_mask -n)
18042         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18043
18044         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18045                 # set server mask back to some value
18046                 changelog_chmask "CLOSE,UNLNK"
18047                 # check effective mask again, should not remain as DEFMASK
18048                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18049                                 mdd.$mdt.changelog_current_mask -n)
18050                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18051         fi
18052
18053         do_facet $SINGLEMDS $LCTL --device $mdt \
18054                                 changelog_deregister -u test_160o ||
18055                 error "cannot deregister by name"
18056 }
18057 run_test 160o "changelog user name and mask"
18058
18059 test_160p() {
18060         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18061         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18062                 skip "Need MDS version at least 2.14.51"
18063         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18064         local cl_users
18065         local cl_user1
18066         local entry_count
18067
18068         # Create a user
18069         changelog_register || error "first changelog_register failed"
18070
18071         cl_users=(${CL_USERS[mds1]})
18072         cl_user1="${cl_users[0]}"
18073
18074         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18075         createmany -m $DIR/$tdir/$tfile 50 ||
18076                 error "create $DIR/$tdir/$tfile failed"
18077         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18078         rm -rf $DIR/$tdir
18079
18080         # check changelogs have been generated
18081         entry_count=$(changelog_dump | wc -l)
18082         ((entry_count != 0)) || error "no changelog entries found"
18083
18084         # remove changelog_users and check that orphan entries are removed
18085         stop mds1
18086         local dev=$(mdsdevname 1)
18087         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18088         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18089         entry_count=$(changelog_dump | wc -l)
18090         ((entry_count == 0)) ||
18091                 error "found $entry_count changelog entries, expected none"
18092 }
18093 run_test 160p "Changelog orphan cleanup with no users"
18094
18095 test_160q() {
18096         local mdt="$(facet_svc $SINGLEMDS)"
18097         local clu
18098
18099         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18100         remote_mds_nodsh && skip "remote MDS with nodsh"
18101         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18102                 skip "Need MDS version at least 2.14.54"
18103
18104         # set server mask to minimal value like server init does
18105         changelog_chmask "MARK"
18106         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18107                 error "changelog_register failed"
18108         # check effective mask again, should be treated as DEFMASK now
18109         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18110                                 mdd.$mdt.changelog_current_mask -n)
18111         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18112                 error "changelog_deregister failed"
18113         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18114 }
18115 run_test 160q "changelog effective mask is DEFMASK if not set"
18116
18117 test_160s() {
18118         remote_mds_nodsh && skip "remote MDS with nodsh"
18119         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18120                 skip "Need MDS version at least 2.14.55"
18121
18122         local mdts=$(comma_list $(mdts_nodes))
18123
18124         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18125         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18126                                        fail_val=$((24 * 3600 * 10))
18127
18128         # Create a user which is 10 days old
18129         changelog_register || error "first changelog_register failed"
18130         local cl_users
18131         declare -A cl_user1
18132         local i
18133
18134         # generate some changelog records to accumulate on each MDT
18135         # use all_char because created files should be evenly distributed
18136         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18137                 error "test_mkdir $tdir failed"
18138         for ((i = 0; i < MDSCOUNT; i++)); do
18139                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18140                         error "create $DIR/$tdir/d$i.1 failed"
18141         done
18142
18143         # check changelogs have been generated
18144         local nbcl=$(changelog_dump | wc -l)
18145         (( nbcl > 0 )) || error "no changelogs found"
18146
18147         # reduce the max_idle_indexes value to make sure we exceed it
18148         for param in "changelog_max_idle_indexes=2097446912" \
18149                      "changelog_max_idle_time=2592000" \
18150                      "changelog_gc=1" \
18151                      "changelog_min_gc_interval=2"; do
18152                 local MDT0=$(facet_svc $SINGLEMDS)
18153                 local var="${param%=*}"
18154                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18155
18156                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18157                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18158                         error "unable to set mdd.*.$param"
18159         done
18160
18161         local start=$SECONDS
18162         for i in $(seq $MDSCOUNT); do
18163                 cl_users=(${CL_USERS[mds$i]})
18164                 cl_user1[mds$i]="${cl_users[0]}"
18165
18166                 [[ -n "${cl_user1[mds$i]}" ]] ||
18167                         error "mds$i: no user registered"
18168         done
18169
18170         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18171         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18172
18173         # ensure we are past the previous changelog_min_gc_interval set above
18174         local sleep2=$((start + 2 - SECONDS))
18175         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18176
18177         # Generate one more changelog to trigger GC
18178         for ((i = 0; i < MDSCOUNT; i++)); do
18179                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18180                         error "create $DIR/$tdir/d$i.3 failed"
18181         done
18182
18183         # ensure gc thread is done
18184         for node in $(mdts_nodes); do
18185                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18186                         error "$node: GC-thread not done"
18187         done
18188
18189         do_nodes $mdts $LCTL set_param fail_loc=0
18190
18191         for (( i = 1; i <= MDSCOUNT; i++ )); do
18192                 # check cl_user1 is purged
18193                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18194                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18195         done
18196         return 0
18197 }
18198 run_test 160s "changelog garbage collect on idle records * time"
18199
18200 test_160t() {
18201         remote_mds_nodsh && skip "remote MDS with nodsh"
18202         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18203                 skip "Need MDS version at least 2.15.50"
18204
18205         local MDT0=$(facet_svc $SINGLEMDS)
18206         local cl_users
18207         local cl_user1
18208         local cl_user2
18209         local start
18210
18211         changelog_register --user user1 -m all ||
18212                 error "user1 failed to register"
18213
18214         mkdir_on_mdt0 $DIR/$tdir
18215         # create default overstripe to maximize changelog size
18216         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18217         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18218         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18219
18220         # user2 consumes less records so less space
18221         changelog_register --user user2 || error "user2 failed to register"
18222         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18223         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18224
18225         # check changelogs have been generated
18226         local nbcl=$(changelog_dump | wc -l)
18227         (( nbcl > 0 )) || error "no changelogs found"
18228
18229         # reduce the changelog_min_gc_interval to force check
18230         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18231                 local var="${param%=*}"
18232                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18233
18234                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18235                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18236                         error "unable to set mdd.*.$param"
18237         done
18238
18239         start=$SECONDS
18240         cl_users=(${CL_USERS[mds1]})
18241         cl_user1="${cl_users[0]}"
18242         cl_user2="${cl_users[1]}"
18243
18244         [[ -n $cl_user1 ]] ||
18245                 error "mds1: user #1 isn't registered"
18246         [[ -n $cl_user2 ]] ||
18247                 error "mds1: user #2 isn't registered"
18248
18249         # ensure we are past the previous changelog_min_gc_interval set above
18250         local sleep2=$((start + 2 - SECONDS))
18251         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18252
18253         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18254         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18255                         fail_val=$(((llog_size1 + llog_size2) / 2))
18256
18257         # Generate more changelog to trigger GC
18258         createmany -o $DIR/$tdir/u3_ 4 ||
18259                 error "create failed for more files"
18260
18261         # ensure gc thread is done
18262         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18263                 error "mds1: GC-thread not done"
18264
18265         do_facet mds1 $LCTL set_param fail_loc=0
18266
18267         # check cl_user1 is purged
18268         changelog_users mds1 | grep -q "$cl_user1" &&
18269                 error "User $cl_user1 is registered"
18270         # check cl_user2 is not purged
18271         changelog_users mds1 | grep -q "$cl_user2" ||
18272                 error "User $cl_user2 is not registered"
18273 }
18274 run_test 160t "changelog garbage collect on lack of space"
18275
18276 test_161a() {
18277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18278
18279         test_mkdir -c1 $DIR/$tdir
18280         cp /etc/hosts $DIR/$tdir/$tfile
18281         test_mkdir -c1 $DIR/$tdir/foo1
18282         test_mkdir -c1 $DIR/$tdir/foo2
18283         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18284         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18285         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18286         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18287         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18288         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18289                 $LFS fid2path $DIR $FID
18290                 error "bad link ea"
18291         fi
18292         # middle
18293         rm $DIR/$tdir/foo2/zachary
18294         # last
18295         rm $DIR/$tdir/foo2/thor
18296         # first
18297         rm $DIR/$tdir/$tfile
18298         # rename
18299         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18300         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18301                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18302         rm $DIR/$tdir/foo2/maggie
18303
18304         # overflow the EA
18305         local longname=$tfile.avg_len_is_thirty_two_
18306         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18307                 error_noexit 'failed to unlink many hardlinks'" EXIT
18308         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18309                 error "failed to hardlink many files"
18310         links=$($LFS fid2path $DIR $FID | wc -l)
18311         echo -n "${links}/1000 links in link EA"
18312         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18313 }
18314 run_test 161a "link ea sanity"
18315
18316 test_161b() {
18317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18318         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18319
18320         local MDTIDX=1
18321         local remote_dir=$DIR/$tdir/remote_dir
18322
18323         mkdir -p $DIR/$tdir
18324         $LFS mkdir -i $MDTIDX $remote_dir ||
18325                 error "create remote directory failed"
18326
18327         cp /etc/hosts $remote_dir/$tfile
18328         mkdir -p $remote_dir/foo1
18329         mkdir -p $remote_dir/foo2
18330         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18331         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18332         ln $remote_dir/$tfile $remote_dir/foo1/luna
18333         ln $remote_dir/$tfile $remote_dir/foo2/thor
18334
18335         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18336                      tr -d ']')
18337         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18338                 $LFS fid2path $DIR $FID
18339                 error "bad link ea"
18340         fi
18341         # middle
18342         rm $remote_dir/foo2/zachary
18343         # last
18344         rm $remote_dir/foo2/thor
18345         # first
18346         rm $remote_dir/$tfile
18347         # rename
18348         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18349         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18350         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18351                 $LFS fid2path $DIR $FID
18352                 error "bad link rename"
18353         fi
18354         rm $remote_dir/foo2/maggie
18355
18356         # overflow the EA
18357         local longname=filename_avg_len_is_thirty_two_
18358         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18359                 error "failed to hardlink many files"
18360         links=$($LFS fid2path $DIR $FID | wc -l)
18361         echo -n "${links}/1000 links in link EA"
18362         [[ ${links} -gt 60 ]] ||
18363                 error "expected at least 60 links in link EA"
18364         unlinkmany $remote_dir/foo2/$longname 1000 ||
18365         error "failed to unlink many hardlinks"
18366 }
18367 run_test 161b "link ea sanity under remote directory"
18368
18369 test_161c() {
18370         remote_mds_nodsh && skip "remote MDS with nodsh"
18371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18372         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18373                 skip "Need MDS version at least 2.1.5"
18374
18375         # define CLF_RENAME_LAST 0x0001
18376         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18377         changelog_register || error "changelog_register failed"
18378
18379         rm -rf $DIR/$tdir
18380         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18381         touch $DIR/$tdir/foo_161c
18382         touch $DIR/$tdir/bar_161c
18383         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18384         changelog_dump | grep RENME | tail -n 5
18385         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18386         changelog_clear 0 || error "changelog_clear failed"
18387         if [ x$flags != "x0x1" ]; then
18388                 error "flag $flags is not 0x1"
18389         fi
18390
18391         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18392         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18393         touch $DIR/$tdir/foo_161c
18394         touch $DIR/$tdir/bar_161c
18395         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18396         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18397         changelog_dump | grep RENME | tail -n 5
18398         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18399         changelog_clear 0 || error "changelog_clear failed"
18400         if [ x$flags != "x0x0" ]; then
18401                 error "flag $flags is not 0x0"
18402         fi
18403         echo "rename overwrite a target having nlink > 1," \
18404                 "changelog record has flags of $flags"
18405
18406         # rename doesn't overwrite a target (changelog flag 0x0)
18407         touch $DIR/$tdir/foo_161c
18408         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18409         changelog_dump | grep RENME | tail -n 5
18410         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18411         changelog_clear 0 || error "changelog_clear failed"
18412         if [ x$flags != "x0x0" ]; then
18413                 error "flag $flags is not 0x0"
18414         fi
18415         echo "rename doesn't overwrite a target," \
18416                 "changelog record has flags of $flags"
18417
18418         # define CLF_UNLINK_LAST 0x0001
18419         # unlink a file having nlink = 1 (changelog flag 0x1)
18420         rm -f $DIR/$tdir/foo2_161c
18421         changelog_dump | grep UNLNK | tail -n 5
18422         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18423         changelog_clear 0 || error "changelog_clear failed"
18424         if [ x$flags != "x0x1" ]; then
18425                 error "flag $flags is not 0x1"
18426         fi
18427         echo "unlink a file having nlink = 1," \
18428                 "changelog record has flags of $flags"
18429
18430         # unlink a file having nlink > 1 (changelog flag 0x0)
18431         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18432         rm -f $DIR/$tdir/foobar_161c
18433         changelog_dump | grep UNLNK | tail -n 5
18434         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18435         changelog_clear 0 || error "changelog_clear failed"
18436         if [ x$flags != "x0x0" ]; then
18437                 error "flag $flags is not 0x0"
18438         fi
18439         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18440 }
18441 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18442
18443 test_161d() {
18444         remote_mds_nodsh && skip "remote MDS with nodsh"
18445         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18446
18447         local pid
18448         local fid
18449
18450         changelog_register || error "changelog_register failed"
18451
18452         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18453         # interfer with $MOUNT/.lustre/fid/ access
18454         mkdir $DIR/$tdir
18455         [[ $? -eq 0 ]] || error "mkdir failed"
18456
18457         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18458         $LCTL set_param fail_loc=0x8000140c
18459         # 5s pause
18460         $LCTL set_param fail_val=5
18461
18462         # create file
18463         echo foofoo > $DIR/$tdir/$tfile &
18464         pid=$!
18465
18466         # wait for create to be delayed
18467         sleep 2
18468
18469         ps -p $pid
18470         [[ $? -eq 0 ]] || error "create should be blocked"
18471
18472         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18473         stack_trap "rm -f $tempfile"
18474         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18475         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18476         # some delay may occur during ChangeLog publishing and file read just
18477         # above, that could allow file write to happen finally
18478         [[ -s $tempfile ]] && echo "file should be empty"
18479
18480         $LCTL set_param fail_loc=0
18481
18482         wait $pid
18483         [[ $? -eq 0 ]] || error "create failed"
18484 }
18485 run_test 161d "create with concurrent .lustre/fid access"
18486
18487 check_path() {
18488         local expected="$1"
18489         shift
18490         local fid="$2"
18491
18492         local path
18493         path=$($LFS fid2path "$@")
18494         local rc=$?
18495
18496         if [ $rc -ne 0 ]; then
18497                 error "path looked up of '$expected' failed: rc=$rc"
18498         elif [ "$path" != "$expected" ]; then
18499                 error "path looked up '$path' instead of '$expected'"
18500         else
18501                 echo "FID '$fid' resolves to path '$path' as expected"
18502         fi
18503 }
18504
18505 test_162a() { # was test_162
18506         test_mkdir -p -c1 $DIR/$tdir/d2
18507         touch $DIR/$tdir/d2/$tfile
18508         touch $DIR/$tdir/d2/x1
18509         touch $DIR/$tdir/d2/x2
18510         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18511         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18512         # regular file
18513         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18514         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18515
18516         # softlink
18517         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18518         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18519         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18520
18521         # softlink to wrong file
18522         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18523         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18524         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18525
18526         # hardlink
18527         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18528         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18529         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18530         # fid2path dir/fsname should both work
18531         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18532         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18533
18534         # hardlink count: check that there are 2 links
18535         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18536         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18537
18538         # hardlink indexing: remove the first link
18539         rm $DIR/$tdir/d2/p/q/r/hlink
18540         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18541 }
18542 run_test 162a "path lookup sanity"
18543
18544 test_162b() {
18545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18546         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18547
18548         mkdir $DIR/$tdir
18549         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18550                                 error "create striped dir failed"
18551
18552         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18553                                         tail -n 1 | awk '{print $2}')
18554         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18555
18556         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18557         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18558
18559         # regular file
18560         for ((i=0;i<5;i++)); do
18561                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18562                         error "get fid for f$i failed"
18563                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18564
18565                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18566                         error "get fid for d$i failed"
18567                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18568         done
18569
18570         return 0
18571 }
18572 run_test 162b "striped directory path lookup sanity"
18573
18574 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18575 test_162c() {
18576         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18577                 skip "Need MDS version at least 2.7.51"
18578
18579         local lpath=$tdir.local
18580         local rpath=$tdir.remote
18581
18582         test_mkdir $DIR/$lpath
18583         test_mkdir $DIR/$rpath
18584
18585         for ((i = 0; i <= 101; i++)); do
18586                 lpath="$lpath/$i"
18587                 mkdir $DIR/$lpath
18588                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18589                         error "get fid for local directory $DIR/$lpath failed"
18590                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18591
18592                 rpath="$rpath/$i"
18593                 test_mkdir $DIR/$rpath
18594                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18595                         error "get fid for remote directory $DIR/$rpath failed"
18596                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18597         done
18598
18599         return 0
18600 }
18601 run_test 162c "fid2path works with paths 100 or more directories deep"
18602
18603 oalr_event_count() {
18604         local event="${1}"
18605         local trace="${2}"
18606
18607         awk -v name="${FSNAME}-OST0000" \
18608             -v event="${event}" \
18609             '$1 == "TRACE" && $2 == event && $3 == name' \
18610             "${trace}" |
18611         wc -l
18612 }
18613
18614 oalr_expect_event_count() {
18615         local event="${1}"
18616         local trace="${2}"
18617         local expect="${3}"
18618         local count
18619
18620         count=$(oalr_event_count "${event}" "${trace}")
18621         if ((count == expect)); then
18622                 return 0
18623         fi
18624
18625         error_noexit "${event} event count was '${count}', expected ${expect}"
18626         cat "${trace}" >&2
18627         exit 1
18628 }
18629
18630 cleanup_165() {
18631         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18632         stop ost1
18633         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18634 }
18635
18636 setup_165() {
18637         sync # Flush previous IOs so we can count log entries.
18638         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18639         stack_trap cleanup_165 EXIT
18640 }
18641
18642 test_165a() {
18643         local trace="/tmp/${tfile}.trace"
18644         local rc
18645         local count
18646
18647         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18648                 skip "OFD access log unsupported"
18649
18650         setup_165
18651         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18652         sleep 5
18653
18654         do_facet ost1 ofd_access_log_reader --list
18655         stop ost1
18656
18657         do_facet ost1 killall -TERM ofd_access_log_reader
18658         wait
18659         rc=$?
18660
18661         if ((rc != 0)); then
18662                 error "ofd_access_log_reader exited with rc = '${rc}'"
18663         fi
18664
18665         # Parse trace file for discovery events:
18666         oalr_expect_event_count alr_log_add "${trace}" 1
18667         oalr_expect_event_count alr_log_eof "${trace}" 1
18668         oalr_expect_event_count alr_log_free "${trace}" 1
18669 }
18670 run_test 165a "ofd access log discovery"
18671
18672 test_165b() {
18673         local trace="/tmp/${tfile}.trace"
18674         local file="${DIR}/${tfile}"
18675         local pfid1
18676         local pfid2
18677         local -a entry
18678         local rc
18679         local count
18680         local size
18681         local flags
18682
18683         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18684                 skip "OFD access log unsupported"
18685
18686         setup_165
18687         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18688         sleep 5
18689
18690         do_facet ost1 ofd_access_log_reader --list
18691
18692         lfs setstripe -c 1 -i 0 "${file}"
18693         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18694                 error "cannot create '${file}'"
18695
18696         sleep 5
18697         do_facet ost1 killall -TERM ofd_access_log_reader
18698         wait
18699         rc=$?
18700
18701         if ((rc != 0)); then
18702                 error "ofd_access_log_reader exited with rc = '${rc}'"
18703         fi
18704
18705         oalr_expect_event_count alr_log_entry "${trace}" 1
18706
18707         pfid1=$($LFS path2fid "${file}")
18708
18709         # 1     2             3   4    5     6   7    8    9     10
18710         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18711         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18712
18713         echo "entry = '${entry[*]}'" >&2
18714
18715         pfid2=${entry[4]}
18716         if [[ "${pfid1}" != "${pfid2}" ]]; then
18717                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18718         fi
18719
18720         size=${entry[8]}
18721         if ((size != 1048576)); then
18722                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18723         fi
18724
18725         flags=${entry[10]}
18726         if [[ "${flags}" != "w" ]]; then
18727                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18728         fi
18729
18730         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18731         sleep 5
18732
18733         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18734                 error "cannot read '${file}'"
18735         sleep 5
18736
18737         do_facet ost1 killall -TERM ofd_access_log_reader
18738         wait
18739         rc=$?
18740
18741         if ((rc != 0)); then
18742                 error "ofd_access_log_reader exited with rc = '${rc}'"
18743         fi
18744
18745         oalr_expect_event_count alr_log_entry "${trace}" 1
18746
18747         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18748         echo "entry = '${entry[*]}'" >&2
18749
18750         pfid2=${entry[4]}
18751         if [[ "${pfid1}" != "${pfid2}" ]]; then
18752                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18753         fi
18754
18755         size=${entry[8]}
18756         if ((size != 524288)); then
18757                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18758         fi
18759
18760         flags=${entry[10]}
18761         if [[ "${flags}" != "r" ]]; then
18762                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18763         fi
18764 }
18765 run_test 165b "ofd access log entries are produced and consumed"
18766
18767 test_165c() {
18768         local trace="/tmp/${tfile}.trace"
18769         local file="${DIR}/${tdir}/${tfile}"
18770
18771         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18772                 skip "OFD access log unsupported"
18773
18774         test_mkdir "${DIR}/${tdir}"
18775
18776         setup_165
18777         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18778         sleep 5
18779
18780         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18781
18782         # 4096 / 64 = 64. Create twice as many entries.
18783         for ((i = 0; i < 128; i++)); do
18784                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18785                         error "cannot create file"
18786         done
18787
18788         sync
18789
18790         do_facet ost1 killall -TERM ofd_access_log_reader
18791         wait
18792         rc=$?
18793         if ((rc != 0)); then
18794                 error "ofd_access_log_reader exited with rc = '${rc}'"
18795         fi
18796
18797         unlinkmany  "${file}-%d" 128
18798 }
18799 run_test 165c "full ofd access logs do not block IOs"
18800
18801 oal_get_read_count() {
18802         local stats="$1"
18803
18804         # STATS lustre-OST0001 alr_read_count 1
18805
18806         do_facet ost1 cat "${stats}" |
18807         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18808              END { print count; }'
18809 }
18810
18811 oal_expect_read_count() {
18812         local stats="$1"
18813         local count
18814         local expect="$2"
18815
18816         # Ask ofd_access_log_reader to write stats.
18817         do_facet ost1 killall -USR1 ofd_access_log_reader
18818
18819         # Allow some time for things to happen.
18820         sleep 1
18821
18822         count=$(oal_get_read_count "${stats}")
18823         if ((count == expect)); then
18824                 return 0
18825         fi
18826
18827         error_noexit "bad read count, got ${count}, expected ${expect}"
18828         do_facet ost1 cat "${stats}" >&2
18829         exit 1
18830 }
18831
18832 test_165d() {
18833         local stats="/tmp/${tfile}.stats"
18834         local file="${DIR}/${tdir}/${tfile}"
18835         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18836
18837         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18838                 skip "OFD access log unsupported"
18839
18840         test_mkdir "${DIR}/${tdir}"
18841
18842         setup_165
18843         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18844         sleep 5
18845
18846         lfs setstripe -c 1 -i 0 "${file}"
18847
18848         do_facet ost1 lctl set_param "${param}=rw"
18849         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18850                 error "cannot create '${file}'"
18851         oal_expect_read_count "${stats}" 1
18852
18853         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18854                 error "cannot read '${file}'"
18855         oal_expect_read_count "${stats}" 2
18856
18857         do_facet ost1 lctl set_param "${param}=r"
18858         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18859                 error "cannot create '${file}'"
18860         oal_expect_read_count "${stats}" 2
18861
18862         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18863                 error "cannot read '${file}'"
18864         oal_expect_read_count "${stats}" 3
18865
18866         do_facet ost1 lctl set_param "${param}=w"
18867         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18868                 error "cannot create '${file}'"
18869         oal_expect_read_count "${stats}" 4
18870
18871         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18872                 error "cannot read '${file}'"
18873         oal_expect_read_count "${stats}" 4
18874
18875         do_facet ost1 lctl set_param "${param}=0"
18876         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18877                 error "cannot create '${file}'"
18878         oal_expect_read_count "${stats}" 4
18879
18880         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18881                 error "cannot read '${file}'"
18882         oal_expect_read_count "${stats}" 4
18883
18884         do_facet ost1 killall -TERM ofd_access_log_reader
18885         wait
18886         rc=$?
18887         if ((rc != 0)); then
18888                 error "ofd_access_log_reader exited with rc = '${rc}'"
18889         fi
18890 }
18891 run_test 165d "ofd_access_log mask works"
18892
18893 test_165e() {
18894         local stats="/tmp/${tfile}.stats"
18895         local file0="${DIR}/${tdir}-0/${tfile}"
18896         local file1="${DIR}/${tdir}-1/${tfile}"
18897
18898         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18899                 skip "OFD access log unsupported"
18900
18901         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18902
18903         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18904         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18905
18906         lfs setstripe -c 1 -i 0 "${file0}"
18907         lfs setstripe -c 1 -i 0 "${file1}"
18908
18909         setup_165
18910         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18911         sleep 5
18912
18913         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18914                 error "cannot create '${file0}'"
18915         sync
18916         oal_expect_read_count "${stats}" 0
18917
18918         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18919                 error "cannot create '${file1}'"
18920         sync
18921         oal_expect_read_count "${stats}" 1
18922
18923         do_facet ost1 killall -TERM ofd_access_log_reader
18924         wait
18925         rc=$?
18926         if ((rc != 0)); then
18927                 error "ofd_access_log_reader exited with rc = '${rc}'"
18928         fi
18929 }
18930 run_test 165e "ofd_access_log MDT index filter works"
18931
18932 test_165f() {
18933         local trace="/tmp/${tfile}.trace"
18934         local rc
18935         local count
18936
18937         setup_165
18938         do_facet ost1 timeout 60 ofd_access_log_reader \
18939                 --exit-on-close --debug=- --trace=- > "${trace}" &
18940         sleep 5
18941         stop ost1
18942
18943         wait
18944         rc=$?
18945
18946         if ((rc != 0)); then
18947                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18948                 cat "${trace}"
18949                 exit 1
18950         fi
18951 }
18952 run_test 165f "ofd_access_log_reader --exit-on-close works"
18953
18954 test_169() {
18955         # do directio so as not to populate the page cache
18956         log "creating a 10 Mb file"
18957         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18958                 error "multiop failed while creating a file"
18959         log "starting reads"
18960         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18961         log "truncating the file"
18962         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18963                 error "multiop failed while truncating the file"
18964         log "killing dd"
18965         kill %+ || true # reads might have finished
18966         echo "wait until dd is finished"
18967         wait
18968         log "removing the temporary file"
18969         rm -rf $DIR/$tfile || error "tmp file removal failed"
18970 }
18971 run_test 169 "parallel read and truncate should not deadlock"
18972
18973 test_170() {
18974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18975
18976         $LCTL clear     # bug 18514
18977         $LCTL debug_daemon start $TMP/${tfile}_log_good
18978         touch $DIR/$tfile
18979         $LCTL debug_daemon stop
18980         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18981                 error "sed failed to read log_good"
18982
18983         $LCTL debug_daemon start $TMP/${tfile}_log_good
18984         rm -rf $DIR/$tfile
18985         $LCTL debug_daemon stop
18986
18987         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18988                error "lctl df log_bad failed"
18989
18990         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18991         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18992
18993         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18994         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18995
18996         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18997                 error "bad_line good_line1 good_line2 are empty"
18998
18999         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19000         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19001         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19002
19003         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19004         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19005         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19006
19007         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19008                 error "bad_line_new good_line_new are empty"
19009
19010         local expected_good=$((good_line1 + good_line2*2))
19011
19012         rm -f $TMP/${tfile}*
19013         # LU-231, short malformed line may not be counted into bad lines
19014         if [ $bad_line -ne $bad_line_new ] &&
19015                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19016                 error "expected $bad_line bad lines, but got $bad_line_new"
19017                 return 1
19018         fi
19019
19020         if [ $expected_good -ne $good_line_new ]; then
19021                 error "expected $expected_good good lines, but got $good_line_new"
19022                 return 2
19023         fi
19024         true
19025 }
19026 run_test 170 "test lctl df to handle corrupted log ====================="
19027
19028 test_171() { # bug20592
19029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19030
19031         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19032         $LCTL set_param fail_loc=0x50e
19033         $LCTL set_param fail_val=3000
19034         multiop_bg_pause $DIR/$tfile O_s || true
19035         local MULTIPID=$!
19036         kill -USR1 $MULTIPID
19037         # cause log dump
19038         sleep 3
19039         wait $MULTIPID
19040         if dmesg | grep "recursive fault"; then
19041                 error "caught a recursive fault"
19042         fi
19043         $LCTL set_param fail_loc=0
19044         true
19045 }
19046 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19047
19048 test_172() {
19049
19050         #define OBD_FAIL_OBD_CLEANUP  0x60e
19051         $LCTL set_param fail_loc=0x60e
19052         umount $MOUNT || error "umount $MOUNT failed"
19053         stack_trap "mount_client $MOUNT"
19054
19055         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19056                 error "no client OBDs are remained"
19057
19058         $LCTL dl | while read devno state type name foo; do
19059                 case $type in
19060                 lov|osc|lmv|mdc)
19061                         $LCTL --device $name cleanup
19062                         $LCTL --device $name detach
19063                         ;;
19064                 *)
19065                         # skip server devices
19066                         ;;
19067                 esac
19068         done
19069
19070         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19071                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19072                 error "some client OBDs are still remained"
19073         fi
19074
19075 }
19076 run_test 172 "manual device removal with lctl cleanup/detach ======"
19077
19078 # it would be good to share it with obdfilter-survey/iokit-libecho code
19079 setup_obdecho_osc () {
19080         local rc=0
19081         local ost_nid=$1
19082         local obdfilter_name=$2
19083         echo "Creating new osc for $obdfilter_name on $ost_nid"
19084         # make sure we can find loopback nid
19085         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19086
19087         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19088                            ${obdfilter_name}_osc_UUID || rc=2; }
19089         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19090                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19091         return $rc
19092 }
19093
19094 cleanup_obdecho_osc () {
19095         local obdfilter_name=$1
19096         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19097         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19098         return 0
19099 }
19100
19101 obdecho_test() {
19102         local OBD=$1
19103         local node=$2
19104         local pages=${3:-64}
19105         local rc=0
19106         local id
19107
19108         local count=10
19109         local obd_size=$(get_obd_size $node $OBD)
19110         local page_size=$(get_page_size $node)
19111         if [[ -n "$obd_size" ]]; then
19112                 local new_count=$((obd_size / (pages * page_size / 1024)))
19113                 [[ $new_count -ge $count ]] || count=$new_count
19114         fi
19115
19116         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19117         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19118                            rc=2; }
19119         if [ $rc -eq 0 ]; then
19120             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19121             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19122         fi
19123         echo "New object id is $id"
19124         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19125                            rc=4; }
19126         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19127                            "test_brw $count w v $pages $id" || rc=4; }
19128         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19129                            rc=4; }
19130         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19131                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19132         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19133                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19134         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19135         return $rc
19136 }
19137
19138 test_180a() {
19139         skip "obdecho on osc is no longer supported"
19140 }
19141 run_test 180a "test obdecho on osc"
19142
19143 test_180b() {
19144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19145         remote_ost_nodsh && skip "remote OST with nodsh"
19146
19147         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19148                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19149                 error "failed to load module obdecho"
19150
19151         local target=$(do_facet ost1 $LCTL dl |
19152                        awk '/obdfilter/ { print $4; exit; }')
19153
19154         if [ -n "$target" ]; then
19155                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19156         else
19157                 do_facet ost1 $LCTL dl
19158                 error "there is no obdfilter target on ost1"
19159         fi
19160 }
19161 run_test 180b "test obdecho directly on obdfilter"
19162
19163 test_180c() { # LU-2598
19164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19165         remote_ost_nodsh && skip "remote OST with nodsh"
19166         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19167                 skip "Need MDS version at least 2.4.0"
19168
19169         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19170                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19171                 error "failed to load module obdecho"
19172
19173         local target=$(do_facet ost1 $LCTL dl |
19174                        awk '/obdfilter/ { print $4; exit; }')
19175
19176         if [ -n "$target" ]; then
19177                 local pages=16384 # 64MB bulk I/O RPC size
19178
19179                 obdecho_test "$target" ost1 "$pages" ||
19180                         error "obdecho_test with pages=$pages failed with $?"
19181         else
19182                 do_facet ost1 $LCTL dl
19183                 error "there is no obdfilter target on ost1"
19184         fi
19185 }
19186 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19187
19188 test_181() { # bug 22177
19189         test_mkdir $DIR/$tdir
19190         # create enough files to index the directory
19191         createmany -o $DIR/$tdir/foobar 4000
19192         # print attributes for debug purpose
19193         lsattr -d .
19194         # open dir
19195         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19196         MULTIPID=$!
19197         # remove the files & current working dir
19198         unlinkmany $DIR/$tdir/foobar 4000
19199         rmdir $DIR/$tdir
19200         kill -USR1 $MULTIPID
19201         wait $MULTIPID
19202         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19203         return 0
19204 }
19205 run_test 181 "Test open-unlinked dir ========================"
19206
19207 test_182a() {
19208         local fcount=1000
19209         local tcount=10
19210
19211         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19212
19213         $LCTL set_param mdc.*.rpc_stats=clear
19214
19215         for (( i = 0; i < $tcount; i++ )) ; do
19216                 mkdir $DIR/$tdir/$i
19217         done
19218
19219         for (( i = 0; i < $tcount; i++ )) ; do
19220                 createmany -o $DIR/$tdir/$i/f- $fcount &
19221         done
19222         wait
19223
19224         for (( i = 0; i < $tcount; i++ )) ; do
19225                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19226         done
19227         wait
19228
19229         $LCTL get_param mdc.*.rpc_stats
19230
19231         rm -rf $DIR/$tdir
19232 }
19233 run_test 182a "Test parallel modify metadata operations from mdc"
19234
19235 test_182b() {
19236         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19237         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19238         local dcount=1000
19239         local tcount=10
19240         local stime
19241         local etime
19242         local delta
19243
19244         do_facet mds1 $LCTL list_param \
19245                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19246                 skip "MDS lacks parallel RPC handling"
19247
19248         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19249
19250         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19251                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19252
19253         stime=$(date +%s)
19254         createmany -i 0 -d $DIR/$tdir/t- $tcount
19255
19256         for (( i = 0; i < $tcount; i++ )) ; do
19257                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19258         done
19259         wait
19260         etime=$(date +%s)
19261         delta=$((etime - stime))
19262         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19263
19264         stime=$(date +%s)
19265         for (( i = 0; i < $tcount; i++ )) ; do
19266                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19267         done
19268         wait
19269         etime=$(date +%s)
19270         delta=$((etime - stime))
19271         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19272
19273         rm -rf $DIR/$tdir
19274
19275         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19276
19277         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19278
19279         stime=$(date +%s)
19280         createmany -i 0 -d $DIR/$tdir/t- $tcount
19281
19282         for (( i = 0; i < $tcount; i++ )) ; do
19283                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19284         done
19285         wait
19286         etime=$(date +%s)
19287         delta=$((etime - stime))
19288         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19289
19290         stime=$(date +%s)
19291         for (( i = 0; i < $tcount; i++ )) ; do
19292                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19293         done
19294         wait
19295         etime=$(date +%s)
19296         delta=$((etime - stime))
19297         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19298
19299         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19300 }
19301 run_test 182b "Test parallel modify metadata operations from osp"
19302
19303 test_183() { # LU-2275
19304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19305         remote_mds_nodsh && skip "remote MDS with nodsh"
19306         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19307                 skip "Need MDS version at least 2.3.56"
19308
19309         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19310         echo aaa > $DIR/$tdir/$tfile
19311
19312 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19313         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19314
19315         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19316         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19317
19318         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19319
19320         # Flush negative dentry cache
19321         touch $DIR/$tdir/$tfile
19322
19323         # We are not checking for any leaked references here, they'll
19324         # become evident next time we do cleanup with module unload.
19325         rm -rf $DIR/$tdir
19326 }
19327 run_test 183 "No crash or request leak in case of strange dispositions ========"
19328
19329 # test suite 184 is for LU-2016, LU-2017
19330 test_184a() {
19331         check_swap_layouts_support
19332
19333         dir0=$DIR/$tdir/$testnum
19334         test_mkdir -p -c1 $dir0
19335         ref1=/etc/passwd
19336         ref2=/etc/group
19337         file1=$dir0/f1
19338         file2=$dir0/f2
19339         $LFS setstripe -c1 $file1
19340         cp $ref1 $file1
19341         $LFS setstripe -c2 $file2
19342         cp $ref2 $file2
19343         gen1=$($LFS getstripe -g $file1)
19344         gen2=$($LFS getstripe -g $file2)
19345
19346         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19347         gen=$($LFS getstripe -g $file1)
19348         [[ $gen1 != $gen ]] ||
19349                 error "Layout generation on $file1 does not change"
19350         gen=$($LFS getstripe -g $file2)
19351         [[ $gen2 != $gen ]] ||
19352                 error "Layout generation on $file2 does not change"
19353
19354         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19355         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19356
19357         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19358 }
19359 run_test 184a "Basic layout swap"
19360
19361 test_184b() {
19362         check_swap_layouts_support
19363
19364         dir0=$DIR/$tdir/$testnum
19365         mkdir -p $dir0 || error "creating dir $dir0"
19366         file1=$dir0/f1
19367         file2=$dir0/f2
19368         file3=$dir0/f3
19369         dir1=$dir0/d1
19370         dir2=$dir0/d2
19371         mkdir $dir1 $dir2
19372         $LFS setstripe -c1 $file1
19373         $LFS setstripe -c2 $file2
19374         $LFS setstripe -c1 $file3
19375         chown $RUNAS_ID $file3
19376         gen1=$($LFS getstripe -g $file1)
19377         gen2=$($LFS getstripe -g $file2)
19378
19379         $LFS swap_layouts $dir1 $dir2 &&
19380                 error "swap of directories layouts should fail"
19381         $LFS swap_layouts $dir1 $file1 &&
19382                 error "swap of directory and file layouts should fail"
19383         $RUNAS $LFS swap_layouts $file1 $file2 &&
19384                 error "swap of file we cannot write should fail"
19385         $LFS swap_layouts $file1 $file3 &&
19386                 error "swap of file with different owner should fail"
19387         /bin/true # to clear error code
19388 }
19389 run_test 184b "Forbidden layout swap (will generate errors)"
19390
19391 test_184c() {
19392         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19393         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19394         check_swap_layouts_support
19395         check_swap_layout_no_dom $DIR
19396
19397         local dir0=$DIR/$tdir/$testnum
19398         mkdir -p $dir0 || error "creating dir $dir0"
19399
19400         local ref1=$dir0/ref1
19401         local ref2=$dir0/ref2
19402         local file1=$dir0/file1
19403         local file2=$dir0/file2
19404         # create a file large enough for the concurrent test
19405         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19406         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19407         echo "ref file size: ref1($(stat -c %s $ref1))," \
19408              "ref2($(stat -c %s $ref2))"
19409
19410         cp $ref2 $file2
19411         dd if=$ref1 of=$file1 bs=16k &
19412         local DD_PID=$!
19413
19414         # Make sure dd starts to copy file, but wait at most 5 seconds
19415         local loops=0
19416         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19417
19418         $LFS swap_layouts $file1 $file2
19419         local rc=$?
19420         wait $DD_PID
19421         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19422         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19423
19424         # how many bytes copied before swapping layout
19425         local copied=$(stat -c %s $file2)
19426         local remaining=$(stat -c %s $ref1)
19427         remaining=$((remaining - copied))
19428         echo "Copied $copied bytes before swapping layout..."
19429
19430         cmp -n $copied $file1 $ref2 | grep differ &&
19431                 error "Content mismatch [0, $copied) of ref2 and file1"
19432         cmp -n $copied $file2 $ref1 ||
19433                 error "Content mismatch [0, $copied) of ref1 and file2"
19434         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19435                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19436
19437         # clean up
19438         rm -f $ref1 $ref2 $file1 $file2
19439 }
19440 run_test 184c "Concurrent write and layout swap"
19441
19442 test_184d() {
19443         check_swap_layouts_support
19444         check_swap_layout_no_dom $DIR
19445         [ -z "$(which getfattr 2>/dev/null)" ] &&
19446                 skip_env "no getfattr command"
19447
19448         local file1=$DIR/$tdir/$tfile-1
19449         local file2=$DIR/$tdir/$tfile-2
19450         local file3=$DIR/$tdir/$tfile-3
19451         local lovea1
19452         local lovea2
19453
19454         mkdir -p $DIR/$tdir
19455         touch $file1 || error "create $file1 failed"
19456         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19457                 error "create $file2 failed"
19458         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19459                 error "create $file3 failed"
19460         lovea1=$(get_layout_param $file1)
19461
19462         $LFS swap_layouts $file2 $file3 ||
19463                 error "swap $file2 $file3 layouts failed"
19464         $LFS swap_layouts $file1 $file2 ||
19465                 error "swap $file1 $file2 layouts failed"
19466
19467         lovea2=$(get_layout_param $file2)
19468         echo "$lovea1"
19469         echo "$lovea2"
19470         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19471
19472         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19473         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19474 }
19475 run_test 184d "allow stripeless layouts swap"
19476
19477 test_184e() {
19478         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19479                 skip "Need MDS version at least 2.6.94"
19480         check_swap_layouts_support
19481         check_swap_layout_no_dom $DIR
19482         [ -z "$(which getfattr 2>/dev/null)" ] &&
19483                 skip_env "no getfattr command"
19484
19485         local file1=$DIR/$tdir/$tfile-1
19486         local file2=$DIR/$tdir/$tfile-2
19487         local file3=$DIR/$tdir/$tfile-3
19488         local lovea
19489
19490         mkdir -p $DIR/$tdir
19491         touch $file1 || error "create $file1 failed"
19492         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19493                 error "create $file2 failed"
19494         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19495                 error "create $file3 failed"
19496
19497         $LFS swap_layouts $file1 $file2 ||
19498                 error "swap $file1 $file2 layouts failed"
19499
19500         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19501         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19502
19503         echo 123 > $file1 || error "Should be able to write into $file1"
19504
19505         $LFS swap_layouts $file1 $file3 ||
19506                 error "swap $file1 $file3 layouts failed"
19507
19508         echo 123 > $file1 || error "Should be able to write into $file1"
19509
19510         rm -rf $file1 $file2 $file3
19511 }
19512 run_test 184e "Recreate layout after stripeless layout swaps"
19513
19514 test_184f() {
19515         # Create a file with name longer than sizeof(struct stat) ==
19516         # 144 to see if we can get chars from the file name to appear
19517         # in the returned striping. Note that 'f' == 0x66.
19518         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19519
19520         mkdir -p $DIR/$tdir
19521         mcreate $DIR/$tdir/$file
19522         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19523                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19524         fi
19525 }
19526 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19527
19528 test_185() { # LU-2441
19529         # LU-3553 - no volatile file support in old servers
19530         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19531                 skip "Need MDS version at least 2.3.60"
19532
19533         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19534         touch $DIR/$tdir/spoo
19535         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19536         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19537                 error "cannot create/write a volatile file"
19538         [ "$FILESET" == "" ] &&
19539         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19540                 error "FID is still valid after close"
19541
19542         multiop_bg_pause $DIR/$tdir Vw4096_c
19543         local multi_pid=$!
19544
19545         local OLD_IFS=$IFS
19546         IFS=":"
19547         local fidv=($fid)
19548         IFS=$OLD_IFS
19549         # assume that the next FID for this client is sequential, since stdout
19550         # is unfortunately eaten by multiop_bg_pause
19551         local n=$((${fidv[1]} + 1))
19552         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19553         if [ "$FILESET" == "" ]; then
19554                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19555                         error "FID is missing before close"
19556         fi
19557         kill -USR1 $multi_pid
19558         # 1 second delay, so if mtime change we will see it
19559         sleep 1
19560         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19561         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19562 }
19563 run_test 185 "Volatile file support"
19564
19565 function create_check_volatile() {
19566         local idx=$1
19567         local tgt
19568
19569         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19570         local PID=$!
19571         sleep 1
19572         local FID=$(cat /tmp/${tfile}.fid)
19573         [ "$FID" == "" ] && error "can't get FID for volatile"
19574         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19575         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19576         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19577         kill -USR1 $PID
19578         wait
19579         sleep 1
19580         cancel_lru_locks mdc # flush opencache
19581         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19582         return 0
19583 }
19584
19585 test_185a(){
19586         # LU-12516 - volatile creation via .lustre
19587         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19588                 skip "Need MDS version at least 2.3.55"
19589
19590         create_check_volatile 0
19591         [ $MDSCOUNT -lt 2 ] && return 0
19592
19593         # DNE case
19594         create_check_volatile 1
19595
19596         return 0
19597 }
19598 run_test 185a "Volatile file creation in .lustre/fid/"
19599
19600 test_187a() {
19601         remote_mds_nodsh && skip "remote MDS with nodsh"
19602         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19603                 skip "Need MDS version at least 2.3.0"
19604
19605         local dir0=$DIR/$tdir/$testnum
19606         mkdir -p $dir0 || error "creating dir $dir0"
19607
19608         local file=$dir0/file1
19609         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19610         stack_trap "rm -f $file"
19611         local dv1=$($LFS data_version $file)
19612         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19613         local dv2=$($LFS data_version $file)
19614         [[ $dv1 != $dv2 ]] ||
19615                 error "data version did not change on write $dv1 == $dv2"
19616 }
19617 run_test 187a "Test data version change"
19618
19619 test_187b() {
19620         remote_mds_nodsh && skip "remote MDS with nodsh"
19621         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19622                 skip "Need MDS version at least 2.3.0"
19623
19624         local dir0=$DIR/$tdir/$testnum
19625         mkdir -p $dir0 || error "creating dir $dir0"
19626
19627         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19628         [[ ${DV[0]} != ${DV[1]} ]] ||
19629                 error "data version did not change on write"\
19630                       " ${DV[0]} == ${DV[1]}"
19631
19632         # clean up
19633         rm -f $file1
19634 }
19635 run_test 187b "Test data version change on volatile file"
19636
19637 test_200() {
19638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19639         remote_mgs_nodsh && skip "remote MGS with nodsh"
19640         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19641
19642         local POOL=${POOL:-cea1}
19643         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19644         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19645         # Pool OST targets
19646         local first_ost=0
19647         local last_ost=$(($OSTCOUNT - 1))
19648         local ost_step=2
19649         local ost_list=$(seq $first_ost $ost_step $last_ost)
19650         local ost_range="$first_ost $last_ost $ost_step"
19651         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19652         local file_dir=$POOL_ROOT/file_tst
19653         local subdir=$test_path/subdir
19654         local rc=0
19655
19656         while : ; do
19657                 # former test_200a test_200b
19658                 pool_add $POOL                          || { rc=$? ; break; }
19659                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19660                 # former test_200c test_200d
19661                 mkdir -p $test_path
19662                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19663                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19664                 mkdir -p $subdir
19665                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19666                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19667                                                         || { rc=$? ; break; }
19668                 # former test_200e test_200f
19669                 local files=$((OSTCOUNT*3))
19670                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19671                                                         || { rc=$? ; break; }
19672                 pool_create_files $POOL $file_dir $files "$ost_list" \
19673                                                         || { rc=$? ; break; }
19674                 # former test_200g test_200h
19675                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19676                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19677
19678                 # former test_201a test_201b test_201c
19679                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19680
19681                 local f=$test_path/$tfile
19682                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19683                 pool_remove $POOL $f                    || { rc=$? ; break; }
19684                 break
19685         done
19686
19687         destroy_test_pools
19688
19689         return $rc
19690 }
19691 run_test 200 "OST pools"
19692
19693 # usage: default_attr <count | size | offset>
19694 default_attr() {
19695         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19696 }
19697
19698 # usage: check_default_stripe_attr
19699 check_default_stripe_attr() {
19700         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19701         case $1 in
19702         --stripe-count|-c)
19703                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19704         --stripe-size|-S)
19705                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19706         --stripe-index|-i)
19707                 EXPECTED=-1;;
19708         *)
19709                 error "unknown getstripe attr '$1'"
19710         esac
19711
19712         [ $ACTUAL == $EXPECTED ] ||
19713                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19714 }
19715
19716 test_204a() {
19717         test_mkdir $DIR/$tdir
19718         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19719
19720         check_default_stripe_attr --stripe-count
19721         check_default_stripe_attr --stripe-size
19722         check_default_stripe_attr --stripe-index
19723 }
19724 run_test 204a "Print default stripe attributes"
19725
19726 test_204b() {
19727         test_mkdir $DIR/$tdir
19728         $LFS setstripe --stripe-count 1 $DIR/$tdir
19729
19730         check_default_stripe_attr --stripe-size
19731         check_default_stripe_attr --stripe-index
19732 }
19733 run_test 204b "Print default stripe size and offset"
19734
19735 test_204c() {
19736         test_mkdir $DIR/$tdir
19737         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19738
19739         check_default_stripe_attr --stripe-count
19740         check_default_stripe_attr --stripe-index
19741 }
19742 run_test 204c "Print default stripe count and offset"
19743
19744 test_204d() {
19745         test_mkdir $DIR/$tdir
19746         $LFS setstripe --stripe-index 0 $DIR/$tdir
19747
19748         check_default_stripe_attr --stripe-count
19749         check_default_stripe_attr --stripe-size
19750 }
19751 run_test 204d "Print default stripe count and size"
19752
19753 test_204e() {
19754         test_mkdir $DIR/$tdir
19755         $LFS setstripe -d $DIR/$tdir
19756
19757         # LU-16904 check if root is set as PFL layout
19758         local numcomp=$($LFS getstripe --component-count $MOUNT)
19759
19760         if [[ $numcomp -gt 0 ]]; then
19761                 check_default_stripe_attr --stripe-count
19762         else
19763                 check_default_stripe_attr --stripe-count --raw
19764         fi
19765         check_default_stripe_attr --stripe-size --raw
19766         check_default_stripe_attr --stripe-index --raw
19767 }
19768 run_test 204e "Print raw stripe attributes"
19769
19770 test_204f() {
19771         test_mkdir $DIR/$tdir
19772         $LFS setstripe --stripe-count 1 $DIR/$tdir
19773
19774         check_default_stripe_attr --stripe-size --raw
19775         check_default_stripe_attr --stripe-index --raw
19776 }
19777 run_test 204f "Print raw stripe size and offset"
19778
19779 test_204g() {
19780         test_mkdir $DIR/$tdir
19781         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19782
19783         check_default_stripe_attr --stripe-count --raw
19784         check_default_stripe_attr --stripe-index --raw
19785 }
19786 run_test 204g "Print raw stripe count and offset"
19787
19788 test_204h() {
19789         test_mkdir $DIR/$tdir
19790         $LFS setstripe --stripe-index 0 $DIR/$tdir
19791
19792         check_default_stripe_attr --stripe-count --raw
19793         check_default_stripe_attr --stripe-size --raw
19794 }
19795 run_test 204h "Print raw stripe count and size"
19796
19797 # Figure out which job scheduler is being used, if any,
19798 # or use a fake one
19799 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19800         JOBENV=SLURM_JOB_ID
19801 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19802         JOBENV=LSB_JOBID
19803 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19804         JOBENV=PBS_JOBID
19805 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19806         JOBENV=LOADL_STEP_ID
19807 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19808         JOBENV=JOB_ID
19809 else
19810         $LCTL list_param jobid_name > /dev/null 2>&1
19811         if [ $? -eq 0 ]; then
19812                 JOBENV=nodelocal
19813         else
19814                 JOBENV=FAKE_JOBID
19815         fi
19816 fi
19817 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19818
19819 verify_jobstats() {
19820         local cmd=($1)
19821         shift
19822         local facets="$@"
19823
19824 # we don't really need to clear the stats for this test to work, since each
19825 # command has a unique jobid, but it makes debugging easier if needed.
19826 #       for facet in $facets; do
19827 #               local dev=$(convert_facet2label $facet)
19828 #               # clear old jobstats
19829 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19830 #       done
19831
19832         # use a new JobID for each test, or we might see an old one
19833         [ "$JOBENV" = "FAKE_JOBID" ] &&
19834                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19835
19836         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19837
19838         [ "$JOBENV" = "nodelocal" ] && {
19839                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19840                 $LCTL set_param jobid_name=$FAKE_JOBID
19841                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19842         }
19843
19844         log "Test: ${cmd[*]}"
19845         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19846
19847         if [ $JOBENV = "FAKE_JOBID" ]; then
19848                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19849         else
19850                 ${cmd[*]}
19851         fi
19852
19853         # all files are created on OST0000
19854         for facet in $facets; do
19855                 local stats="*.$(convert_facet2label $facet).job_stats"
19856
19857                 # strip out libtool wrappers for in-tree executables
19858                 if (( $(do_facet $facet lctl get_param $stats |
19859                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19860                         do_facet $facet lctl get_param $stats
19861                         error "No jobstats for $JOBVAL found on $facet::$stats"
19862                 fi
19863         done
19864 }
19865
19866 jobstats_set() {
19867         local new_jobenv=$1
19868
19869         set_persistent_param_and_check client "jobid_var" \
19870                 "$FSNAME.sys.jobid_var" $new_jobenv
19871 }
19872
19873 test_205a() { # Job stats
19874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19875         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19876                 skip "Need MDS version with at least 2.7.1"
19877         remote_mgs_nodsh && skip "remote MGS with nodsh"
19878         remote_mds_nodsh && skip "remote MDS with nodsh"
19879         remote_ost_nodsh && skip "remote OST with nodsh"
19880         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19881                 skip "Server doesn't support jobstats"
19882         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19883
19884         local old_jobenv=$($LCTL get_param -n jobid_var)
19885         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19886         stack_trap "jobstats_set $old_jobenv" EXIT
19887
19888         changelog_register
19889
19890         local old_jobid_name=$($LCTL get_param jobid_name)
19891         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19892
19893         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19894                                 mdt.*.job_cleanup_interval | head -n 1)
19895         local new_interval=5
19896         do_facet $SINGLEMDS \
19897                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19898         stack_trap "do_facet $SINGLEMDS \
19899                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19900         local start=$SECONDS
19901
19902         local cmd
19903         # mkdir
19904         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19905         verify_jobstats "$cmd" "$SINGLEMDS"
19906         # rmdir
19907         cmd="rmdir $DIR/$tdir"
19908         verify_jobstats "$cmd" "$SINGLEMDS"
19909         # mkdir on secondary MDT
19910         if [ $MDSCOUNT -gt 1 ]; then
19911                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19912                 verify_jobstats "$cmd" "mds2"
19913         fi
19914         # mknod
19915         cmd="mknod $DIR/$tfile c 1 3"
19916         verify_jobstats "$cmd" "$SINGLEMDS"
19917         # unlink
19918         cmd="rm -f $DIR/$tfile"
19919         verify_jobstats "$cmd" "$SINGLEMDS"
19920         # create all files on OST0000 so verify_jobstats can find OST stats
19921         # open & close
19922         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19923         verify_jobstats "$cmd" "$SINGLEMDS"
19924         # setattr
19925         cmd="touch $DIR/$tfile"
19926         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19927         # write
19928         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19929         verify_jobstats "$cmd" "ost1"
19930         # read
19931         cancel_lru_locks osc
19932         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19933         verify_jobstats "$cmd" "ost1"
19934         # truncate
19935         cmd="$TRUNCATE $DIR/$tfile 0"
19936         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19937         # rename
19938         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19939         verify_jobstats "$cmd" "$SINGLEMDS"
19940         # jobstats expiry - sleep until old stats should be expired
19941         local left=$((new_interval + 5 - (SECONDS - start)))
19942         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19943                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19944                         "0" $left
19945         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19946         verify_jobstats "$cmd" "$SINGLEMDS"
19947         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19948             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19949
19950         # Ensure that jobid are present in changelog (if supported by MDS)
19951         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19952                 changelog_dump | tail -10
19953                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19954                 [ $jobids -eq 9 ] ||
19955                         error "Wrong changelog jobid count $jobids != 9"
19956
19957                 # LU-5862
19958                 JOBENV="disable"
19959                 jobstats_set $JOBENV
19960                 touch $DIR/$tfile
19961                 changelog_dump | grep $tfile
19962                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19963                 [ $jobids -eq 0 ] ||
19964                         error "Unexpected jobids when jobid_var=$JOBENV"
19965         fi
19966
19967         # test '%j' access to environment variable - if supported
19968         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19969                 JOBENV="JOBCOMPLEX"
19970                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19971
19972                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19973         fi
19974
19975         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19976                 JOBENV="JOBCOMPLEX"
19977                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19978
19979                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19980         fi
19981
19982         # test '%j' access to per-session jobid - if supported
19983         if lctl list_param jobid_this_session > /dev/null 2>&1
19984         then
19985                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19986                 lctl set_param jobid_this_session=$USER
19987
19988                 JOBENV="JOBCOMPLEX"
19989                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19990
19991                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19992         fi
19993 }
19994 run_test 205a "Verify job stats"
19995
19996 # LU-13117, LU-13597, LU-16599
19997 test_205b() {
19998         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19999                 skip "Need MDS version at least 2.13.54.91"
20000
20001         local job_stats="mdt.*.job_stats"
20002         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20003
20004         do_facet mds1 $LCTL set_param $job_stats=clear
20005
20006         # Setting jobid_var to USER might not be supported
20007         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20008         $LCTL set_param jobid_var=USER || true
20009         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20010         $LCTL set_param jobid_name="%j.%e.%u"
20011
20012         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20013         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20014                 { do_facet mds1 $LCTL get_param $job_stats;
20015                   error "Unexpected jobid found"; }
20016         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20017                 { do_facet mds1 $LCTL get_param $job_stats;
20018                   error "wrong job_stats format found"; }
20019
20020         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20021                 echo "MDS does not yet escape jobid" && return 0
20022
20023         mkdir_on_mdt0 $DIR/$tdir
20024         $LCTL set_param jobid_var=TEST205b
20025         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20026         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20027                       awk '/has\\x20sp/ {print $3}')
20028         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20029                   error "jobid not escaped"; }
20030
20031         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20032                 # need to run such a command on mds1:
20033                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20034                 #
20035                 # there might be multiple MDTs on single mds server, so need to
20036                 # specifiy MDT0000. Or the command will fail due to other MDTs
20037                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20038                         error "cannot clear escaped jobid in job_stats";
20039         else
20040                 echo "MDS does not support clearing escaped jobid"
20041         fi
20042 }
20043 run_test 205b "Verify job stats jobid and output format"
20044
20045 # LU-13733
20046 test_205c() {
20047         $LCTL set_param llite.*.stats=0
20048         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20049         $LCTL get_param llite.*.stats
20050         $LCTL get_param llite.*.stats | grep \
20051                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20052                         error "wrong client stats format found"
20053 }
20054 run_test 205c "Verify client stats format"
20055
20056 test_205d() {
20057         local file=$DIR/$tdir/$tfile
20058
20059         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20060                 skip "need lustre >= 2.15.53 for lljobstat"
20061         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20062                 skip "need lustre >= 2.15.53 for lljobstat"
20063         verify_yaml_available || skip_env "YAML verification not installed"
20064
20065         test_mkdir -i 0 $DIR/$tdir
20066         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20067         stack_trap "rm -rf $DIR/$tdir"
20068
20069         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20070                 error "failed to write data to $file"
20071         mv $file $file.2
20072
20073         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20074         echo -n 'verify rename_stats...'
20075         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20076                 verify_yaml || error "rename_stats is not valid YAML"
20077         echo " OK"
20078
20079         echo -n 'verify mdt job_stats...'
20080         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20081                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20082         echo " OK"
20083
20084         echo -n 'verify ost job_stats...'
20085         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20086                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20087         echo " OK"
20088 }
20089 run_test 205d "verify the format of some stats files"
20090
20091 test_205e() {
20092         local ops_comma
20093         local file=$DIR/$tdir/$tfile
20094         local -a cli_params
20095
20096         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20097                 skip "need lustre >= 2.15.53 for lljobstat"
20098         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20099                 skip "need lustre >= 2.15.53 for lljobstat"
20100         verify_yaml_available || skip_env "YAML verification not installed"
20101
20102         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20103         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20104         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20105
20106         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20107         stack_trap "rm -rf $DIR/$tdir"
20108
20109         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20110                 error "failed to create $file on ost1"
20111         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20112                 error "failed to write data to $file"
20113
20114         do_facet mds1 "$LCTL get_param *.*.job_stats"
20115         do_facet ost1 "$LCTL get_param *.*.job_stats"
20116
20117         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20118         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20119                 error "The output of lljobstat is not an valid YAML"
20120
20121         # verify that job dd.0 does exist and has some ops on ost1
20122         # typically this line is like:
20123         # - 205e.dd.0:            {ops: 20, ...}
20124         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20125                     awk '$2=="205e.dd.0:" {print $4}')
20126
20127         (( ${ops_comma%,} >= 10 )) ||
20128                 error "cannot find job 205e.dd.0 with ops >= 10"
20129 }
20130 run_test 205e "verify the output of lljobstat"
20131
20132 test_205f() {
20133         verify_yaml_available || skip_env "YAML verification not installed"
20134
20135         # check both qos_ost_weights and qos_mdt_weights
20136         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20137         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20138                 error "qos_ost_weights is not valid YAML"
20139 }
20140 run_test 205f "verify qos_ost_weights YAML format "
20141
20142 __test_205_jobstats_dump() {
20143         local -a pids
20144         local nbr_instance=$1
20145
20146         while true; do
20147                 if (( ${#pids[@]} >= nbr_instance )); then
20148                         wait ${pids[@]}
20149                         pids=()
20150                 fi
20151
20152                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20153                 pids+=( $! )
20154         done
20155 }
20156
20157 __test_205_cleanup() {
20158         kill $@
20159         # Clear all job entries
20160         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20161 }
20162
20163 test_205g() {
20164         local -a mds1_params
20165         local -a cli_params
20166         local pids
20167         local interval=5
20168
20169         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20170         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20171         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20172
20173         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20174         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20175         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20176
20177         # start jobs loop
20178         export TEST205G_ID=205g
20179         stack_trap "unset TEST205G_ID" EXIT
20180         while true; do
20181                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20182         done & pids="$! "
20183
20184         __test_205_jobstats_dump 4 & pids+="$! "
20185         stack_trap "__test_205_cleanup $pids" EXIT INT
20186
20187         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20188 }
20189 run_test 205g "stress test for job_stats procfile"
20190
20191 test_205h() {
20192         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20193
20194         local dir=$DIR/$tdir
20195         local f=$dir/$tfile
20196         local f2=$dir/$tfile-2
20197         local f3=$dir/$tfile-3
20198         local subdir=$DIR/dir
20199         local val
20200
20201         local mdts=$(comma_list $(mdts_nodes))
20202         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20203         local client_saved=$($LCTL get_param -n jobid_var)
20204
20205         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20206         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20207
20208         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20209                 error "failed to set job_xattr parameter to user.job"
20210         $LCTL set_param jobid_var=procname.uid ||
20211                 error "failed to set jobid_var parameter"
20212
20213         test_mkdir $dir
20214
20215         touch $f
20216         val=$(getfattr -n user.job $f | grep user.job)
20217         [[ $val = user.job=\"touch.0\" ]] ||
20218                 error "expected user.job=\"touch.0\", got '$val'"
20219
20220         mkdir $subdir
20221         val=$(getfattr -n user.job $subdir | grep user.job)
20222         [[ $val = user.job=\"mkdir.0\" ]] ||
20223                 error "expected user.job=\"mkdir.0\", got '$val'"
20224
20225         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20226                 error "failed to set job_xattr parameter to NONE"
20227
20228         touch $f2
20229         val=$(getfattr -d $f2)
20230         [[ -z $val ]] ||
20231                 error "expected no user xattr, got '$val'"
20232
20233         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20234                 error "failed to set job_xattr parameter to trusted.job"
20235
20236         touch $f3
20237         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20238         [[ $val = trusted.job=\"touch.0\" ]] ||
20239                 error "expected trusted.job=\"touch.0\", got '$val'"
20240 }
20241 run_test 205h "check jobid xattr is stored correctly"
20242
20243 test_205i() {
20244         local mdts=$(comma_list $(mdts_nodes))
20245         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20246
20247         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20248
20249         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20250                 error "failed to set mdt.*.job_xattr to user.1234567"
20251
20252         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20253                 error "failed to reject too long job_xattr name"
20254
20255         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20256                 error "failed to reject job_xattr name in bad format"
20257
20258         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20259                 error "failed to reject job_xattr name with invalid character"
20260
20261         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20262                         xargs $LCTL set_param" &&
20263                 error "failed to reject job_xattr name with non-ascii character"
20264
20265         return 0
20266 }
20267 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20268
20269 # LU-1480, LU-1773 and LU-1657
20270 test_206() {
20271         mkdir -p $DIR/$tdir
20272         $LFS setstripe -c -1 $DIR/$tdir
20273 #define OBD_FAIL_LOV_INIT 0x1403
20274         $LCTL set_param fail_loc=0xa0001403
20275         $LCTL set_param fail_val=1
20276         touch $DIR/$tdir/$tfile || true
20277 }
20278 run_test 206 "fail lov_init_raid0() doesn't lbug"
20279
20280 test_207a() {
20281         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20282         local fsz=`stat -c %s $DIR/$tfile`
20283         cancel_lru_locks mdc
20284
20285         # do not return layout in getattr intent
20286 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20287         $LCTL set_param fail_loc=0x170
20288         local sz=`stat -c %s $DIR/$tfile`
20289
20290         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20291
20292         rm -rf $DIR/$tfile
20293 }
20294 run_test 207a "can refresh layout at glimpse"
20295
20296 test_207b() {
20297         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20298         local cksum=`md5sum $DIR/$tfile`
20299         local fsz=`stat -c %s $DIR/$tfile`
20300         cancel_lru_locks mdc
20301         cancel_lru_locks osc
20302
20303         # do not return layout in getattr intent
20304 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20305         $LCTL set_param fail_loc=0x171
20306
20307         # it will refresh layout after the file is opened but before read issues
20308         echo checksum is "$cksum"
20309         echo "$cksum" |md5sum -c --quiet || error "file differs"
20310
20311         rm -rf $DIR/$tfile
20312 }
20313 run_test 207b "can refresh layout at open"
20314
20315 test_208() {
20316         # FIXME: in this test suite, only RD lease is used. This is okay
20317         # for now as only exclusive open is supported. After generic lease
20318         # is done, this test suite should be revised. - Jinshan
20319
20320         remote_mds_nodsh && skip "remote MDS with nodsh"
20321         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20322                 skip "Need MDS version at least 2.4.52"
20323
20324         echo "==== test 1: verify get lease work"
20325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20326
20327         echo "==== test 2: verify lease can be broken by upcoming open"
20328         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20329         local PID=$!
20330         sleep 2
20331
20332         $MULTIOP $DIR/$tfile oO_RDWR:c
20333         kill -USR1 $PID && wait $PID || error "break lease error"
20334
20335         echo "==== test 3: verify lease can't be granted if an open already exists"
20336         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20337         local PID=$!
20338         sleep 2
20339
20340         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20341         kill -USR1 $PID && wait $PID || error "open file error"
20342
20343         echo "==== test 4: lease can sustain over recovery"
20344         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20345         PID=$!
20346         sleep 2
20347
20348         fail mds1
20349
20350         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20351
20352         echo "==== test 5: lease broken can't be regained by replay"
20353         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20354         PID=$!
20355         sleep 2
20356
20357         # open file to break lease and then recovery
20358         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20359         fail mds1
20360
20361         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20362
20363         rm -f $DIR/$tfile
20364 }
20365 run_test 208 "Exclusive open"
20366
20367 test_209() {
20368         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20369                 skip_env "must have disp_stripe"
20370
20371         touch $DIR/$tfile
20372         sync; sleep 5; sync;
20373
20374         echo 3 > /proc/sys/vm/drop_caches
20375         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20376                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20377         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20378
20379         # open/close 500 times
20380         for i in $(seq 500); do
20381                 cat $DIR/$tfile
20382         done
20383
20384         echo 3 > /proc/sys/vm/drop_caches
20385         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20386                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20387         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20388
20389         echo "before: $req_before, after: $req_after"
20390         [ $((req_after - req_before)) -ge 300 ] &&
20391                 error "open/close requests are not freed"
20392         return 0
20393 }
20394 run_test 209 "read-only open/close requests should be freed promptly"
20395
20396 test_210() {
20397         local pid
20398
20399         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_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         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20408         pid=$!
20409         sleep 1
20410
20411         $LFS getstripe $DIR/$tfile
20412         kill -USR1 $pid
20413         wait $pid || error "multiop failed"
20414 }
20415 run_test 210 "lfs getstripe does not break leases"
20416
20417 function test_211() {
20418         local PID
20419         local id
20420         local rc
20421
20422         stack_trap "rm -f $DIR/$tfile" EXIT
20423         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20424                 error "can't create file"
20425         $LFS mirror extend -N $DIR/$tfile ||
20426                 error "can't create a replica"
20427         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20428         $LFS getstripe $DIR/$tfile
20429         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20430         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20431
20432         $MULTIOP $DIR/$tfile OeW_E+eUc &
20433         PID=$!
20434         sleep 0.3
20435
20436         id=$($LFS getstripe $DIR/$tfile |
20437                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20438         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20439                 error "removed last in-sync replica?"
20440
20441         kill -USR1 $PID
20442         wait $PID
20443         (( $? == 0 )) || error "failed split broke the lease"
20444 }
20445 run_test 211 "failed mirror split doesn't break write lease"
20446
20447 test_212() {
20448         size=`date +%s`
20449         size=$((size % 8192 + 1))
20450         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20451         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20452         rm -f $DIR/f212 $DIR/f212.xyz
20453 }
20454 run_test 212 "Sendfile test ============================================"
20455
20456 test_213() {
20457         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20458         cancel_lru_locks osc
20459         lctl set_param fail_loc=0x8000040f
20460         # generate a read lock
20461         cat $DIR/$tfile > /dev/null
20462         # write to the file, it will try to cancel the above read lock.
20463         cat /etc/hosts >> $DIR/$tfile
20464 }
20465 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20466
20467 test_214() { # for bug 20133
20468         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20469         for (( i=0; i < 340; i++ )) ; do
20470                 touch $DIR/$tdir/d214c/a$i
20471         done
20472
20473         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20474         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20475         ls $DIR/d214c || error "ls $DIR/d214c failed"
20476         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20477         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20478 }
20479 run_test 214 "hash-indexed directory test - bug 20133"
20480
20481 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20482 create_lnet_proc_files() {
20483         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20484 }
20485
20486 # counterpart of create_lnet_proc_files
20487 remove_lnet_proc_files() {
20488         rm -f $TMP/lnet_$1.sys
20489 }
20490
20491 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20492 # 3rd arg as regexp for body
20493 check_lnet_proc_stats() {
20494         local l=$(cat "$TMP/lnet_$1" |wc -l)
20495         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20496
20497         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20498 }
20499
20500 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20501 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20502 # optional and can be regexp for 2nd line (lnet.routes case)
20503 check_lnet_proc_entry() {
20504         local blp=2          # blp stands for 'position of 1st line of body'
20505         [ -z "$5" ] || blp=3 # lnet.routes case
20506
20507         local l=$(cat "$TMP/lnet_$1" |wc -l)
20508         # subtracting one from $blp because the body can be empty
20509         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20510
20511         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20512                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20513
20514         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20515                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20516
20517         # bail out if any unexpected line happened
20518         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20519         [ "$?" != 0 ] || error "$2 misformatted"
20520 }
20521
20522 test_215() { # for bugs 18102, 21079, 21517
20523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20524
20525         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20526         local P='[1-9][0-9]*'           # positive numeric
20527         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20528         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20529         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20530         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20531
20532         local L1 # regexp for 1st line
20533         local L2 # regexp for 2nd line (optional)
20534         local BR # regexp for the rest (body)
20535
20536         # lnet.stats should look as 11 space-separated non-negative numerics
20537         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20538         create_lnet_proc_files "stats"
20539         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20540         remove_lnet_proc_files "stats"
20541
20542         # lnet.routes should look like this:
20543         # Routing disabled/enabled
20544         # net hops priority state router
20545         # where net is a string like tcp0, hops > 0, priority >= 0,
20546         # state is up/down,
20547         # router is a string like 192.168.1.1@tcp2
20548         L1="^Routing (disabled|enabled)$"
20549         L2="^net +hops +priority +state +router$"
20550         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20551         create_lnet_proc_files "routes"
20552         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20553         remove_lnet_proc_files "routes"
20554
20555         # lnet.routers should look like this:
20556         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20557         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20558         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20559         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20560         L1="^ref +rtr_ref +alive +router$"
20561         BR="^$P +$P +(up|down) +$NID$"
20562         create_lnet_proc_files "routers"
20563         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20564         remove_lnet_proc_files "routers"
20565
20566         # lnet.peers should look like this:
20567         # nid refs state last max rtr min tx min queue
20568         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20569         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20570         # numeric (0 or >0 or <0), queue >= 0.
20571         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20572         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20573         create_lnet_proc_files "peers"
20574         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20575         remove_lnet_proc_files "peers"
20576
20577         # lnet.buffers  should look like this:
20578         # pages count credits min
20579         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20580         L1="^pages +count +credits +min$"
20581         BR="^ +$N +$N +$I +$I$"
20582         create_lnet_proc_files "buffers"
20583         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20584         remove_lnet_proc_files "buffers"
20585
20586         # lnet.nis should look like this:
20587         # nid status alive refs peer rtr max tx min
20588         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20589         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20590         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20591         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20592         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20593         create_lnet_proc_files "nis"
20594         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20595         remove_lnet_proc_files "nis"
20596
20597         # can we successfully write to lnet.stats?
20598         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20599 }
20600 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20601
20602 test_216() { # bug 20317
20603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20604         remote_ost_nodsh && skip "remote OST with nodsh"
20605
20606         local node
20607         local facets=$(get_facets OST)
20608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20609
20610         save_lustre_params client "osc.*.contention_seconds" > $p
20611         save_lustre_params $facets \
20612                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20613         save_lustre_params $facets \
20614                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20615         save_lustre_params $facets \
20616                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20617         clear_stats osc.*.osc_stats
20618
20619         # agressive lockless i/o settings
20620         do_nodes $(comma_list $(osts_nodes)) \
20621                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20622                         ldlm.namespaces.filter-*.contended_locks=0 \
20623                         ldlm.namespaces.filter-*.contention_seconds=60"
20624         lctl set_param -n osc.*.contention_seconds=60
20625
20626         $DIRECTIO write $DIR/$tfile 0 10 4096
20627         $CHECKSTAT -s 40960 $DIR/$tfile
20628
20629         # disable lockless i/o
20630         do_nodes $(comma_list $(osts_nodes)) \
20631                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20632                         ldlm.namespaces.filter-*.contended_locks=32 \
20633                         ldlm.namespaces.filter-*.contention_seconds=0"
20634         lctl set_param -n osc.*.contention_seconds=0
20635         clear_stats osc.*.osc_stats
20636
20637         dd if=/dev/zero of=$DIR/$tfile count=0
20638         $CHECKSTAT -s 0 $DIR/$tfile
20639
20640         restore_lustre_params <$p
20641         rm -f $p
20642         rm $DIR/$tfile
20643 }
20644 run_test 216 "check lockless direct write updates file size and kms correctly"
20645
20646 test_217() { # bug 22430
20647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20648
20649         local node
20650
20651         for node in $(nodes_list); do
20652                 local nid=$(host_nids_address $node $NETTYPE)
20653                 local node_ip=$(do_node $node getent ahostsv4 $node |
20654                                 awk '{ print $1; exit; }')
20655
20656                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20657                 # if hostname matches any NID, use hostname for better testing
20658                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20659                         echo "lctl ping node $node@$NETTYPE"
20660                         lctl ping $node@$NETTYPE
20661                 else # otherwise, at least test 'lctl ping' is working
20662                         echo "lctl ping nid $(h2nettype $nid)"
20663                         lctl ping $(h2nettype $nid)
20664                         echo "skipping $node (no hyphen detected)"
20665                 fi
20666         done
20667 }
20668 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20669
20670 test_218() {
20671         # do directio so as not to populate the page cache
20672         log "creating a 10 Mb file"
20673         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20674                 error "multiop failed while creating a file"
20675         log "starting reads"
20676         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20677         log "truncating the file"
20678         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20679                 error "multiop failed while truncating the file"
20680         log "killing dd"
20681         kill %+ || true # reads might have finished
20682         echo "wait until dd is finished"
20683         wait
20684         log "removing the temporary file"
20685         rm -rf $DIR/$tfile || error "tmp file removal failed"
20686 }
20687 run_test 218 "parallel read and truncate should not deadlock"
20688
20689 test_219() {
20690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20691
20692         # write one partial page
20693         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20694         # set no grant so vvp_io_commit_write will do sync write
20695         $LCTL set_param fail_loc=0x411
20696         # write a full page at the end of file
20697         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20698
20699         $LCTL set_param fail_loc=0
20700         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20701         $LCTL set_param fail_loc=0x411
20702         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20703
20704         # LU-4201
20705         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20706         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20707 }
20708 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20709
20710 test_220() { #LU-325
20711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20712         remote_ost_nodsh && skip "remote OST with nodsh"
20713         remote_mds_nodsh && skip "remote MDS with nodsh"
20714         remote_mgs_nodsh && skip "remote MGS with nodsh"
20715
20716         local OSTIDX=0
20717
20718         # create on MDT0000 so the last_id and next_id are correct
20719         mkdir_on_mdt0 $DIR/$tdir
20720         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20721         OST=${OST%_UUID}
20722
20723         # on the mdt's osc
20724         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20725         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20726                         osp.$mdtosc_proc1.prealloc_last_id)
20727         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20728                         osp.$mdtosc_proc1.prealloc_next_id)
20729
20730         $LFS df -i
20731
20732         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20733         #define OBD_FAIL_OST_ENOINO              0x229
20734         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20735         create_pool $FSNAME.$TESTNAME || return 1
20736         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20737
20738         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20739
20740         MDSOBJS=$((last_id - next_id))
20741         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20742
20743         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20744         echo "OST still has $count kbytes free"
20745
20746         echo "create $MDSOBJS files @next_id..."
20747         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20748
20749         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20750                         osp.$mdtosc_proc1.prealloc_last_id)
20751         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20752                         osp.$mdtosc_proc1.prealloc_next_id)
20753
20754         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20755         $LFS df -i
20756
20757         echo "cleanup..."
20758
20759         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20760         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20761
20762         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20763                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20764         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20765                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20766         echo "unlink $MDSOBJS files @$next_id..."
20767         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20768 }
20769 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20770
20771 test_221() {
20772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20773
20774         dd if=`which date` of=$MOUNT/date oflag=sync
20775         chmod +x $MOUNT/date
20776
20777         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20778         $LCTL set_param fail_loc=0x80001401
20779
20780         $MOUNT/date > /dev/null
20781         rm -f $MOUNT/date
20782 }
20783 run_test 221 "make sure fault and truncate race to not cause OOM"
20784
20785 test_222a () {
20786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20787
20788         rm -rf $DIR/$tdir
20789         test_mkdir $DIR/$tdir
20790         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20791         createmany -o $DIR/$tdir/$tfile 10
20792         cancel_lru_locks mdc
20793         cancel_lru_locks osc
20794         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20795         $LCTL set_param fail_loc=0x31a
20796         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20797         $LCTL set_param fail_loc=0
20798         rm -r $DIR/$tdir
20799 }
20800 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20801
20802 test_222b () {
20803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20804
20805         rm -rf $DIR/$tdir
20806         test_mkdir $DIR/$tdir
20807         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20808         createmany -o $DIR/$tdir/$tfile 10
20809         cancel_lru_locks mdc
20810         cancel_lru_locks osc
20811         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20812         $LCTL set_param fail_loc=0x31a
20813         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20814         $LCTL set_param fail_loc=0
20815 }
20816 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20817
20818 test_223 () {
20819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20820
20821         rm -rf $DIR/$tdir
20822         test_mkdir $DIR/$tdir
20823         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20824         createmany -o $DIR/$tdir/$tfile 10
20825         cancel_lru_locks mdc
20826         cancel_lru_locks osc
20827         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20828         $LCTL set_param fail_loc=0x31b
20829         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20830         $LCTL set_param fail_loc=0
20831         rm -r $DIR/$tdir
20832 }
20833 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20834
20835 test_224a() { # LU-1039, MRP-303
20836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20837         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20838         $LCTL set_param fail_loc=0x508
20839         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20840         $LCTL set_param fail_loc=0
20841         df $DIR
20842 }
20843 run_test 224a "Don't panic on bulk IO failure"
20844
20845 test_224bd_sub() { # LU-1039, MRP-303
20846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20847         local timeout=$1
20848
20849         shift
20850         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20851
20852         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20853
20854         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20855         cancel_lru_locks osc
20856         set_checksums 0
20857         stack_trap "set_checksums $ORIG_CSUM" EXIT
20858         local at_max_saved=0
20859
20860         # adaptive timeouts may prevent seeing the issue
20861         if at_is_enabled; then
20862                 at_max_saved=$(at_max_get mds)
20863                 at_max_set 0 mds client
20864                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20865         fi
20866
20867         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20868         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20869         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20870
20871         do_facet ost1 $LCTL set_param fail_loc=0
20872         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20873         df $DIR
20874 }
20875
20876 test_224b() {
20877         test_224bd_sub 3 error "dd failed"
20878 }
20879 run_test 224b "Don't panic on bulk IO failure"
20880
20881 test_224c() { # LU-6441
20882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20883         remote_mds_nodsh && skip "remote MDS with nodsh"
20884
20885         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20886         save_writethrough $p
20887         set_cache writethrough on
20888
20889         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20890         local at_max=$($LCTL get_param -n at_max)
20891         local timeout=$($LCTL get_param -n timeout)
20892         local test_at="at_max"
20893         local param_at="$FSNAME.sys.at_max"
20894         local test_timeout="timeout"
20895         local param_timeout="$FSNAME.sys.timeout"
20896
20897         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20898
20899         set_persistent_param_and_check client "$test_at" "$param_at" 0
20900         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20901
20902         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20903         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20904         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20905         stack_trap "rm -f $DIR/$tfile"
20906         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20907         sync
20908         do_facet ost1 "$LCTL set_param fail_loc=0"
20909
20910         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20911         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20912                 $timeout
20913
20914         $LCTL set_param -n $pages_per_rpc
20915         restore_lustre_params < $p
20916         rm -f $p
20917 }
20918 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20919
20920 test_224d() { # LU-11169
20921         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20922 }
20923 run_test 224d "Don't corrupt data on bulk IO timeout"
20924
20925 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20926 test_225a () {
20927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20928         if [ -z ${MDSSURVEY} ]; then
20929                 skip_env "mds-survey not found"
20930         fi
20931         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20932                 skip "Need MDS version at least 2.2.51"
20933
20934         local mds=$(facet_host $SINGLEMDS)
20935         local target=$(do_nodes $mds 'lctl dl' |
20936                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20937
20938         local cmd1="file_count=1000 thrhi=4"
20939         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20940         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20941         local cmd="$cmd1 $cmd2 $cmd3"
20942
20943         rm -f ${TMP}/mds_survey*
20944         echo + $cmd
20945         eval $cmd || error "mds-survey with zero-stripe failed"
20946         cat ${TMP}/mds_survey*
20947         rm -f ${TMP}/mds_survey*
20948 }
20949 run_test 225a "Metadata survey sanity with zero-stripe"
20950
20951 test_225b () {
20952         if [ -z ${MDSSURVEY} ]; then
20953                 skip_env "mds-survey not found"
20954         fi
20955         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20956                 skip "Need MDS version at least 2.2.51"
20957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20958         remote_mds_nodsh && skip "remote MDS with nodsh"
20959         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20960                 skip_env "Need to mount OST to test"
20961         fi
20962
20963         local mds=$(facet_host $SINGLEMDS)
20964         local target=$(do_nodes $mds 'lctl dl' |
20965                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20966
20967         local cmd1="file_count=1000 thrhi=4"
20968         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20969         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20970         local cmd="$cmd1 $cmd2 $cmd3"
20971
20972         rm -f ${TMP}/mds_survey*
20973         echo + $cmd
20974         eval $cmd || error "mds-survey with stripe_count failed"
20975         cat ${TMP}/mds_survey*
20976         rm -f ${TMP}/mds_survey*
20977 }
20978 run_test 225b "Metadata survey sanity with stripe_count = 1"
20979
20980 mcreate_path2fid () {
20981         local mode=$1
20982         local major=$2
20983         local minor=$3
20984         local name=$4
20985         local desc=$5
20986         local path=$DIR/$tdir/$name
20987         local fid
20988         local rc
20989         local fid_path
20990
20991         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20992                 error "cannot create $desc"
20993
20994         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20995         rc=$?
20996         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20997
20998         fid_path=$($LFS fid2path $MOUNT $fid)
20999         rc=$?
21000         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21001
21002         [ "$path" == "$fid_path" ] ||
21003                 error "fid2path returned $fid_path, expected $path"
21004
21005         echo "pass with $path and $fid"
21006 }
21007
21008 test_226a () {
21009         rm -rf $DIR/$tdir
21010         mkdir -p $DIR/$tdir
21011
21012         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21013         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21014         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21015         mcreate_path2fid 0040666 0 0 dir "directory"
21016         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21017         mcreate_path2fid 0100666 0 0 file "regular file"
21018         mcreate_path2fid 0120666 0 0 link "symbolic link"
21019         mcreate_path2fid 0140666 0 0 sock "socket"
21020 }
21021 run_test 226a "call path2fid and fid2path on files of all type"
21022
21023 test_226b () {
21024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21025
21026         local MDTIDX=1
21027
21028         rm -rf $DIR/$tdir
21029         mkdir -p $DIR/$tdir
21030         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21031                 error "create remote directory failed"
21032         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21033         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21034                                 "character special file (null)"
21035         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21036                                 "character special file (no device)"
21037         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21038         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21039                                 "block special file (loop)"
21040         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21041         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21042         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21043 }
21044 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21045
21046 test_226c () {
21047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21048         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21049                 skip "Need MDS version at least 2.13.55"
21050
21051         local submnt=/mnt/submnt
21052         local srcfile=/etc/passwd
21053         local dstfile=$submnt/passwd
21054         local path
21055         local fid
21056
21057         rm -rf $DIR/$tdir
21058         rm -rf $submnt
21059         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21060                 error "create remote directory failed"
21061         mkdir -p $submnt || error "create $submnt failed"
21062         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21063                 error "mount $submnt failed"
21064         stack_trap "umount $submnt" EXIT
21065
21066         cp $srcfile $dstfile
21067         fid=$($LFS path2fid $dstfile)
21068         path=$($LFS fid2path $submnt "$fid")
21069         [ "$path" = "$dstfile" ] ||
21070                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21071 }
21072 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21073
21074 test_226d () {
21075         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21076                 skip "Need client at least version 2.15.57"
21077
21078         # Define First test dataset
21079         local testdirs_01=$DIR/$tdir
21080         local testdata_01=$testdirs_01/${tdir}_01
21081         local testresult_01=${tdir}_01
21082         # Define Second test dataset
21083         local testdirs_02=$DIR/$tdir/$tdir
21084         local testdata_02=$testdirs_02/${tdir}_02
21085         local testresult_02=${tdir}_02
21086         # Define third test dataset (top level)
21087         local testdata_03=$DIR/${tdir}_03
21088         local testresult_03=${tdir}_03
21089
21090         # Create first test dataset
21091         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21092         touch $testdata_01 || error "cannot create file $testdata_01"
21093
21094         # Create second test dataset
21095         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21096         touch $testdata_02 || error "cannot create file $testdata_02"
21097
21098         # Create third test dataset
21099         touch $testdata_03 || error "cannot create file $testdata_03"
21100
21101         local fid01=$($LFS getstripe -F "$testdata_01") ||
21102                 error "getstripe failed on $testdata_01"
21103         local fid02=$($LFS getstripe -F "$testdata_02") ||
21104                 error "getstripe failed on $testdata_01"
21105         local fid03=$($LFS getstripe -F "$testdata_03") ||
21106                 error "getstripe failed on $testdata_03"
21107
21108         # Verify only -n option
21109         local out1=$($LFS fid2path -n $DIR $fid01) ||
21110                 error "fid2path failed on $fid01"
21111         local out2=$($LFS fid2path -n $DIR $fid02) ||
21112                 error "fid2path failed on $fid02"
21113         local out3=$($LFS fid2path -n $DIR $fid03) ||
21114                 error "fid2path failed on $fid03"
21115
21116         [[ "$out1" == "$testresult_01" ]] ||
21117                 error "fid2path failed: Expected $testresult_01 got $out1"
21118         [[ "$out2" == "$testresult_02" ]] ||
21119                 error "fid2path failed: Expected $testresult_02 got $out2"
21120         [[ "$out3" == "$testresult_03" ]] ||
21121                 error "fid2path failed: Expected $testresult_03 got $out3"
21122
21123         # Verify with option -fn together
21124         out1=$($LFS fid2path -fn $DIR $fid01) ||
21125                 error "fid2path -fn failed on $fid01"
21126         out2=$($LFS fid2path -fn $DIR $fid02) ||
21127                 error "fid2path -fn failed on $fid02"
21128         out3=$($LFS fid2path -fn $DIR $fid03) ||
21129                 error "fid2path -fn failed on $fid03"
21130
21131         local tmpout=$(echo $out1 | cut -d" " -f2)
21132         [[ "$tmpout" == "$testresult_01" ]] ||
21133                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21134
21135         tmpout=$(echo $out2 | cut -d" " -f2)
21136         [[ "$tmpout" == "$testresult_02" ]] ||
21137                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21138
21139         tmpout=$(echo $out3 | cut -d" " -f2)
21140         [[ "$tmpout" == "$testresult_03" ]] ||
21141                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21142 }
21143 run_test 226d "verify fid2path with -n and -fn option"
21144
21145 test_226e () {
21146         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21147                 skip "Need client at least version 2.15.56"
21148
21149         # Define filename with 'newline' and a space
21150         local testfile="Test"$'\n'"file 01"
21151         # Define link name with multiple 'newline' and a space
21152         local linkfile="Link"$'\n'"file "$'\n'"01"
21153         # Remove prior hard link
21154         rm -f $DIR/"$linkfile"
21155
21156         # Create file
21157         touch $DIR/"$testfile"
21158         # Create link
21159         ln $DIR/"$testfile" $DIR/"$linkfile"
21160
21161         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21162                 error "getstripe failed on $DIR/$testfile"
21163
21164         # Call with -0 option
21165         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21166                 echo "FILE:" | grep -c "FILE:")
21167
21168         # With -0 option the output should be exactly 2 lines.
21169         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21170 }
21171 run_test 226e "Verify path2fid -0 option with newline and space"
21172
21173 # LU-1299 Executing or running ldd on a truncated executable does not
21174 # cause an out-of-memory condition.
21175 test_227() {
21176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21177         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21178
21179         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21180         chmod +x $MOUNT/date
21181
21182         $MOUNT/date > /dev/null
21183         ldd $MOUNT/date > /dev/null
21184         rm -f $MOUNT/date
21185 }
21186 run_test 227 "running truncated executable does not cause OOM"
21187
21188 # LU-1512 try to reuse idle OI blocks
21189 test_228a() {
21190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21191         remote_mds_nodsh && skip "remote MDS with nodsh"
21192         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21193
21194         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21195         local myDIR=$DIR/$tdir
21196
21197         mkdir -p $myDIR
21198         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21199         $LCTL set_param fail_loc=0x80001002
21200         createmany -o $myDIR/t- 10000
21201         $LCTL set_param fail_loc=0
21202         # The guard is current the largest FID holder
21203         touch $myDIR/guard
21204         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21205                     tr -d '[')
21206         local IDX=$(($SEQ % 64))
21207
21208         do_facet $SINGLEMDS sync
21209         # Make sure journal flushed.
21210         sleep 6
21211         local blk1=$(do_facet $SINGLEMDS \
21212                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21213                      grep Blockcount | awk '{print $4}')
21214
21215         # Remove old files, some OI blocks will become idle.
21216         unlinkmany $myDIR/t- 10000
21217         # Create new files, idle OI blocks should be reused.
21218         createmany -o $myDIR/t- 2000
21219         do_facet $SINGLEMDS sync
21220         # Make sure journal flushed.
21221         sleep 6
21222         local blk2=$(do_facet $SINGLEMDS \
21223                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21224                      grep Blockcount | awk '{print $4}')
21225
21226         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21227 }
21228 run_test 228a "try to reuse idle OI blocks"
21229
21230 test_228b() {
21231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21232         remote_mds_nodsh && skip "remote MDS with nodsh"
21233         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21234
21235         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21236         local myDIR=$DIR/$tdir
21237
21238         mkdir -p $myDIR
21239         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21240         $LCTL set_param fail_loc=0x80001002
21241         createmany -o $myDIR/t- 10000
21242         $LCTL set_param fail_loc=0
21243         # The guard is current the largest FID holder
21244         touch $myDIR/guard
21245         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21246                     tr -d '[')
21247         local IDX=$(($SEQ % 64))
21248
21249         do_facet $SINGLEMDS sync
21250         # Make sure journal flushed.
21251         sleep 6
21252         local blk1=$(do_facet $SINGLEMDS \
21253                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21254                      grep Blockcount | awk '{print $4}')
21255
21256         # Remove old files, some OI blocks will become idle.
21257         unlinkmany $myDIR/t- 10000
21258
21259         # stop the MDT
21260         stop $SINGLEMDS || error "Fail to stop MDT."
21261         # remount the MDT
21262         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21263                 error "Fail to start MDT."
21264
21265         client_up || error "Fail to df."
21266         # Create new files, idle OI blocks should be reused.
21267         createmany -o $myDIR/t- 2000
21268         do_facet $SINGLEMDS sync
21269         # Make sure journal flushed.
21270         sleep 6
21271         local blk2=$(do_facet $SINGLEMDS \
21272                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21273                      grep Blockcount | awk '{print $4}')
21274
21275         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21276 }
21277 run_test 228b "idle OI blocks can be reused after MDT restart"
21278
21279 #LU-1881
21280 test_228c() {
21281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21282         remote_mds_nodsh && skip "remote MDS with nodsh"
21283         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21284
21285         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21286         local myDIR=$DIR/$tdir
21287
21288         mkdir -p $myDIR
21289         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21290         $LCTL set_param fail_loc=0x80001002
21291         # 20000 files can guarantee there are index nodes in the OI file
21292         createmany -o $myDIR/t- 20000
21293         $LCTL set_param fail_loc=0
21294         # The guard is current the largest FID holder
21295         touch $myDIR/guard
21296         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21297                     tr -d '[')
21298         local IDX=$(($SEQ % 64))
21299
21300         do_facet $SINGLEMDS sync
21301         # Make sure journal flushed.
21302         sleep 6
21303         local blk1=$(do_facet $SINGLEMDS \
21304                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21305                      grep Blockcount | awk '{print $4}')
21306
21307         # Remove old files, some OI blocks will become idle.
21308         unlinkmany $myDIR/t- 20000
21309         rm -f $myDIR/guard
21310         # The OI file should become empty now
21311
21312         # Create new files, idle OI blocks should be reused.
21313         createmany -o $myDIR/t- 2000
21314         do_facet $SINGLEMDS sync
21315         # Make sure journal flushed.
21316         sleep 6
21317         local blk2=$(do_facet $SINGLEMDS \
21318                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21319                      grep Blockcount | awk '{print $4}')
21320
21321         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21322 }
21323 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21324
21325 test_229() { # LU-2482, LU-3448
21326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21327         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21328         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21329                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21330
21331         rm -f $DIR/$tfile
21332
21333         # Create a file with a released layout and stripe count 2.
21334         $MULTIOP $DIR/$tfile H2c ||
21335                 error "failed to create file with released layout"
21336
21337         $LFS getstripe -v $DIR/$tfile
21338
21339         local pattern=$($LFS getstripe -L $DIR/$tfile)
21340         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21341
21342         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21343                 error "getstripe"
21344         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21345         stat $DIR/$tfile || error "failed to stat released file"
21346
21347         chown $RUNAS_ID $DIR/$tfile ||
21348                 error "chown $RUNAS_ID $DIR/$tfile failed"
21349
21350         chgrp $RUNAS_ID $DIR/$tfile ||
21351                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21352
21353         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21354         rm $DIR/$tfile || error "failed to remove released file"
21355 }
21356 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21357
21358 test_230a() {
21359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21361         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21362                 skip "Need MDS version at least 2.11.52"
21363
21364         local MDTIDX=1
21365
21366         test_mkdir $DIR/$tdir
21367         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21368         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21369         [ $mdt_idx -ne 0 ] &&
21370                 error "create local directory on wrong MDT $mdt_idx"
21371
21372         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21373                         error "create remote directory failed"
21374         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21375         [ $mdt_idx -ne $MDTIDX ] &&
21376                 error "create remote directory on wrong MDT $mdt_idx"
21377
21378         createmany -o $DIR/$tdir/test_230/t- 10 ||
21379                 error "create files on remote directory failed"
21380         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21381         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21382         rm -r $DIR/$tdir || error "unlink remote directory failed"
21383 }
21384 run_test 230a "Create remote directory and files under the remote directory"
21385
21386 test_230b() {
21387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21389         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21390                 skip "Need MDS version at least 2.11.52"
21391
21392         local MDTIDX=1
21393         local mdt_index
21394         local i
21395         local file
21396         local pid
21397         local stripe_count
21398         local migrate_dir=$DIR/$tdir/migrate_dir
21399         local other_dir=$DIR/$tdir/other_dir
21400
21401         test_mkdir $DIR/$tdir
21402         test_mkdir -i0 -c1 $migrate_dir
21403         test_mkdir -i0 -c1 $other_dir
21404         for ((i=0; i<10; i++)); do
21405                 mkdir -p $migrate_dir/dir_${i}
21406                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21407                         error "create files under remote dir failed $i"
21408         done
21409
21410         cp /etc/passwd $migrate_dir/$tfile
21411         cp /etc/passwd $other_dir/$tfile
21412         chattr +SAD $migrate_dir
21413         chattr +SAD $migrate_dir/$tfile
21414
21415         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21416         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21417         local old_dir_mode=$(stat -c%f $migrate_dir)
21418         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21419
21420         mkdir -p $migrate_dir/dir_default_stripe2
21421         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21422         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21423
21424         mkdir -p $other_dir
21425         ln $migrate_dir/$tfile $other_dir/luna
21426         ln $migrate_dir/$tfile $migrate_dir/sofia
21427         ln $other_dir/$tfile $migrate_dir/david
21428         ln -s $migrate_dir/$tfile $other_dir/zachary
21429         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21430         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21431
21432         local len
21433         local lnktgt
21434
21435         # inline symlink
21436         for len in 58 59 60; do
21437                 lnktgt=$(str_repeat 'l' $len)
21438                 touch $migrate_dir/$lnktgt
21439                 ln -s $lnktgt $migrate_dir/${len}char_ln
21440         done
21441
21442         # PATH_MAX
21443         for len in 4094 4095; do
21444                 lnktgt=$(str_repeat 'l' $len)
21445                 ln -s $lnktgt $migrate_dir/${len}char_ln
21446         done
21447
21448         # NAME_MAX
21449         for len in 254 255; do
21450                 touch $migrate_dir/$(str_repeat 'l' $len)
21451         done
21452
21453         $LFS migrate -m $MDTIDX $migrate_dir ||
21454                 error "fails on migrating remote dir to MDT1"
21455
21456         echo "migratate to MDT1, then checking.."
21457         for ((i = 0; i < 10; i++)); do
21458                 for file in $(find $migrate_dir/dir_${i}); do
21459                         mdt_index=$($LFS getstripe -m $file)
21460                         # broken symlink getstripe will fail
21461                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21462                                 error "$file is not on MDT${MDTIDX}"
21463                 done
21464         done
21465
21466         # the multiple link file should still in MDT0
21467         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21468         [ $mdt_index == 0 ] ||
21469                 error "$file is not on MDT${MDTIDX}"
21470
21471         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21472         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21473                 error " expect $old_dir_flag get $new_dir_flag"
21474
21475         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21476         [ "$old_file_flag" = "$new_file_flag" ] ||
21477                 error " expect $old_file_flag get $new_file_flag"
21478
21479         local new_dir_mode=$(stat -c%f $migrate_dir)
21480         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21481                 error "expect mode $old_dir_mode get $new_dir_mode"
21482
21483         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21484         [ "$old_file_mode" = "$new_file_mode" ] ||
21485                 error "expect mode $old_file_mode get $new_file_mode"
21486
21487         diff /etc/passwd $migrate_dir/$tfile ||
21488                 error "$tfile different after migration"
21489
21490         diff /etc/passwd $other_dir/luna ||
21491                 error "luna different after migration"
21492
21493         diff /etc/passwd $migrate_dir/sofia ||
21494                 error "sofia different after migration"
21495
21496         diff /etc/passwd $migrate_dir/david ||
21497                 error "david different after migration"
21498
21499         diff /etc/passwd $other_dir/zachary ||
21500                 error "zachary different after migration"
21501
21502         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21503                 error "${tfile}_ln different after migration"
21504
21505         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21506                 error "${tfile}_ln_other different after migration"
21507
21508         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21509         [ $stripe_count = 2 ] ||
21510                 error "dir strpe_count $d != 2 after migration."
21511
21512         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21513         [ $stripe_count = 2 ] ||
21514                 error "file strpe_count $d != 2 after migration."
21515
21516         #migrate back to MDT0
21517         MDTIDX=0
21518
21519         $LFS migrate -m $MDTIDX $migrate_dir ||
21520                 error "fails on migrating remote dir to MDT0"
21521
21522         echo "migrate back to MDT0, checking.."
21523         for file in $(find $migrate_dir); do
21524                 mdt_index=$($LFS getstripe -m $file)
21525                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21526                         error "$file is not on MDT${MDTIDX}"
21527         done
21528
21529         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21530         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21531                 error " expect $old_dir_flag get $new_dir_flag"
21532
21533         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21534         [ "$old_file_flag" = "$new_file_flag" ] ||
21535                 error " expect $old_file_flag get $new_file_flag"
21536
21537         local new_dir_mode=$(stat -c%f $migrate_dir)
21538         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21539                 error "expect mode $old_dir_mode get $new_dir_mode"
21540
21541         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21542         [ "$old_file_mode" = "$new_file_mode" ] ||
21543                 error "expect mode $old_file_mode get $new_file_mode"
21544
21545         diff /etc/passwd ${migrate_dir}/$tfile ||
21546                 error "$tfile different after migration"
21547
21548         diff /etc/passwd ${other_dir}/luna ||
21549                 error "luna different after migration"
21550
21551         diff /etc/passwd ${migrate_dir}/sofia ||
21552                 error "sofia different after migration"
21553
21554         diff /etc/passwd ${other_dir}/zachary ||
21555                 error "zachary different after migration"
21556
21557         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21558                 error "${tfile}_ln different after migration"
21559
21560         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21561                 error "${tfile}_ln_other different after migration"
21562
21563         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21564         [ $stripe_count = 2 ] ||
21565                 error "dir strpe_count $d != 2 after migration."
21566
21567         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21568         [ $stripe_count = 2 ] ||
21569                 error "file strpe_count $d != 2 after migration."
21570
21571         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21572 }
21573 run_test 230b "migrate directory"
21574
21575 test_230c() {
21576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21578         remote_mds_nodsh && skip "remote MDS with nodsh"
21579         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21580                 skip "Need MDS version at least 2.11.52"
21581
21582         local MDTIDX=1
21583         local total=3
21584         local mdt_index
21585         local file
21586         local migrate_dir=$DIR/$tdir/migrate_dir
21587
21588         #If migrating directory fails in the middle, all entries of
21589         #the directory is still accessiable.
21590         test_mkdir $DIR/$tdir
21591         test_mkdir -i0 -c1 $migrate_dir
21592         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21593         stat $migrate_dir
21594         createmany -o $migrate_dir/f $total ||
21595                 error "create files under ${migrate_dir} failed"
21596
21597         # fail after migrating top dir, and this will fail only once, so the
21598         # first sub file migration will fail (currently f3), others succeed.
21599         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21600         do_facet mds1 lctl set_param fail_loc=0x1801
21601         local t=$(ls $migrate_dir | wc -l)
21602         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21603                 error "migrate should fail"
21604         local u=$(ls $migrate_dir | wc -l)
21605         [ "$u" == "$t" ] || error "$u != $t during migration"
21606
21607         # add new dir/file should succeed
21608         mkdir $migrate_dir/dir ||
21609                 error "mkdir failed under migrating directory"
21610         touch $migrate_dir/file ||
21611                 error "create file failed under migrating directory"
21612
21613         # add file with existing name should fail
21614         for file in $migrate_dir/f*; do
21615                 stat $file > /dev/null || error "stat $file failed"
21616                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21617                         error "open(O_CREAT|O_EXCL) $file should fail"
21618                 $MULTIOP $file m && error "create $file should fail"
21619                 touch $DIR/$tdir/remote_dir/$tfile ||
21620                         error "touch $tfile failed"
21621                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21622                         error "link $file should fail"
21623                 mdt_index=$($LFS getstripe -m $file)
21624                 if [ $mdt_index == 0 ]; then
21625                         # file failed to migrate is not allowed to rename to
21626                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21627                                 error "rename to $file should fail"
21628                 else
21629                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21630                                 error "rename to $file failed"
21631                 fi
21632                 echo hello >> $file || error "write $file failed"
21633         done
21634
21635         # resume migration with different options should fail
21636         $LFS migrate -m 0 $migrate_dir &&
21637                 error "migrate -m 0 $migrate_dir should fail"
21638
21639         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21640                 error "migrate -c 2 $migrate_dir should fail"
21641
21642         # resume migration should succeed
21643         $LFS migrate -m $MDTIDX $migrate_dir ||
21644                 error "migrate $migrate_dir failed"
21645
21646         echo "Finish migration, then checking.."
21647         for file in $(find $migrate_dir); do
21648                 mdt_index=$($LFS getstripe -m $file)
21649                 [ $mdt_index == $MDTIDX ] ||
21650                         error "$file is not on MDT${MDTIDX}"
21651         done
21652
21653         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21654 }
21655 run_test 230c "check directory accessiblity if migration failed"
21656
21657 test_230d() {
21658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21660         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21661                 skip "Need MDS version at least 2.11.52"
21662         # LU-11235
21663         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21664
21665         local migrate_dir=$DIR/$tdir/migrate_dir
21666         local old_index
21667         local new_index
21668         local old_count
21669         local new_count
21670         local new_hash
21671         local mdt_index
21672         local i
21673         local j
21674
21675         old_index=$((RANDOM % MDSCOUNT))
21676         old_count=$((MDSCOUNT - old_index))
21677         new_index=$((RANDOM % MDSCOUNT))
21678         new_count=$((MDSCOUNT - new_index))
21679         new_hash=1 # for all_char
21680
21681         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21682         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21683
21684         test_mkdir $DIR/$tdir
21685         test_mkdir -i $old_index -c $old_count $migrate_dir
21686
21687         for ((i=0; i<100; i++)); do
21688                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21689                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21690                         error "create files under remote dir failed $i"
21691         done
21692
21693         echo -n "Migrate from MDT$old_index "
21694         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21695         echo -n "to MDT$new_index"
21696         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21697         echo
21698
21699         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21700         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21701                 error "migrate remote dir error"
21702
21703         echo "Finish migration, then checking.."
21704         for file in $(find $migrate_dir -maxdepth 1); do
21705                 mdt_index=$($LFS getstripe -m $file)
21706                 if [ $mdt_index -lt $new_index ] ||
21707                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21708                         error "$file is on MDT$mdt_index"
21709                 fi
21710         done
21711
21712         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21713 }
21714 run_test 230d "check migrate big directory"
21715
21716 test_230e() {
21717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21719         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21720                 skip "Need MDS version at least 2.11.52"
21721
21722         local i
21723         local j
21724         local a_fid
21725         local b_fid
21726
21727         mkdir_on_mdt0 $DIR/$tdir
21728         mkdir $DIR/$tdir/migrate_dir
21729         mkdir $DIR/$tdir/other_dir
21730         touch $DIR/$tdir/migrate_dir/a
21731         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21732         ls $DIR/$tdir/other_dir
21733
21734         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21735                 error "migrate dir fails"
21736
21737         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21738         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21739
21740         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21741         [ $mdt_index == 0 ] || error "a is not on MDT0"
21742
21743         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21744                 error "migrate dir fails"
21745
21746         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21747         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21748
21749         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21750         [ $mdt_index == 1 ] || error "a is not on MDT1"
21751
21752         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21753         [ $mdt_index == 1 ] || error "b is not on MDT1"
21754
21755         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21756         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21757
21758         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21759
21760         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21761 }
21762 run_test 230e "migrate mulitple local link files"
21763
21764 test_230f() {
21765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21766         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21767         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21768                 skip "Need MDS version at least 2.11.52"
21769
21770         local a_fid
21771         local ln_fid
21772
21773         mkdir -p $DIR/$tdir
21774         mkdir $DIR/$tdir/migrate_dir
21775         $LFS mkdir -i1 $DIR/$tdir/other_dir
21776         touch $DIR/$tdir/migrate_dir/a
21777         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21778         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21779         ls $DIR/$tdir/other_dir
21780
21781         # a should be migrated to MDT1, since no other links on MDT0
21782         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21783                 error "#1 migrate dir fails"
21784         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21785         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21786         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21787         [ $mdt_index == 1 ] || error "a is not on MDT1"
21788
21789         # a should stay on MDT1, because it is a mulitple link file
21790         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21791                 error "#2 migrate dir fails"
21792         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21793         [ $mdt_index == 1 ] || error "a is not on MDT1"
21794
21795         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21796                 error "#3 migrate dir fails"
21797
21798         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21799         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21800         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21801
21802         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21803         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21804
21805         # a should be migrated to MDT0, since no other links on MDT1
21806         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21807                 error "#4 migrate dir fails"
21808         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21809         [ $mdt_index == 0 ] || error "a is not on MDT0"
21810
21811         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21812 }
21813 run_test 230f "migrate mulitple remote link files"
21814
21815 test_230g() {
21816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21818         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21819                 skip "Need MDS version at least 2.11.52"
21820
21821         mkdir -p $DIR/$tdir/migrate_dir
21822
21823         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21824                 error "migrating dir to non-exist MDT succeeds"
21825         true
21826 }
21827 run_test 230g "migrate dir to non-exist MDT"
21828
21829 test_230h() {
21830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21831         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21832         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21833                 skip "Need MDS version at least 2.11.52"
21834
21835         local mdt_index
21836
21837         mkdir -p $DIR/$tdir/migrate_dir
21838
21839         $LFS migrate -m1 $DIR &&
21840                 error "migrating mountpoint1 should fail"
21841
21842         $LFS migrate -m1 $DIR/$tdir/.. &&
21843                 error "migrating mountpoint2 should fail"
21844
21845         # same as mv
21846         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21847                 error "migrating $tdir/migrate_dir/.. should fail"
21848
21849         true
21850 }
21851 run_test 230h "migrate .. and root"
21852
21853 test_230i() {
21854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21855         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21856         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21857                 skip "Need MDS version at least 2.11.52"
21858
21859         mkdir -p $DIR/$tdir/migrate_dir
21860
21861         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21862                 error "migration fails with a tailing slash"
21863
21864         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21865                 error "migration fails with two tailing slashes"
21866 }
21867 run_test 230i "lfs migrate -m tolerates trailing slashes"
21868
21869 test_230j() {
21870         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21871         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21872                 skip "Need MDS version at least 2.11.52"
21873
21874         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21875         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21876                 error "create $tfile failed"
21877         cat /etc/passwd > $DIR/$tdir/$tfile
21878
21879         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21880
21881         cmp /etc/passwd $DIR/$tdir/$tfile ||
21882                 error "DoM file mismatch after migration"
21883 }
21884 run_test 230j "DoM file data not changed after dir migration"
21885
21886 test_230k() {
21887         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21888         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21889                 skip "Need MDS version at least 2.11.56"
21890
21891         local total=20
21892         local files_on_starting_mdt=0
21893
21894         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21895         $LFS getdirstripe $DIR/$tdir
21896         for i in $(seq $total); do
21897                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21898                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21899                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21900         done
21901
21902         echo "$files_on_starting_mdt files on MDT0"
21903
21904         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21905         $LFS getdirstripe $DIR/$tdir
21906
21907         files_on_starting_mdt=0
21908         for i in $(seq $total); do
21909                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21910                         error "file $tfile.$i mismatch after migration"
21911                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21912                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21913         done
21914
21915         echo "$files_on_starting_mdt files on MDT1 after migration"
21916         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21917
21918         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21919         $LFS getdirstripe $DIR/$tdir
21920
21921         files_on_starting_mdt=0
21922         for i in $(seq $total); do
21923                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21924                         error "file $tfile.$i mismatch after 2nd migration"
21925                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21926                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21927         done
21928
21929         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21930         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21931
21932         true
21933 }
21934 run_test 230k "file data not changed after dir migration"
21935
21936 test_230l() {
21937         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21938         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21939                 skip "Need MDS version at least 2.11.56"
21940
21941         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21942         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21943                 error "create files under remote dir failed $i"
21944         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21945 }
21946 run_test 230l "readdir between MDTs won't crash"
21947
21948 test_230m() {
21949         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21950         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21951                 skip "Need MDS version at least 2.11.56"
21952
21953         local MDTIDX=1
21954         local mig_dir=$DIR/$tdir/migrate_dir
21955         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21956         local shortstr="b"
21957         local val
21958
21959         echo "Creating files and dirs with xattrs"
21960         test_mkdir $DIR/$tdir
21961         test_mkdir -i0 -c1 $mig_dir
21962         mkdir $mig_dir/dir
21963         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21964                 error "cannot set xattr attr1 on dir"
21965         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21966                 error "cannot set xattr attr2 on dir"
21967         touch $mig_dir/dir/f0
21968         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21969                 error "cannot set xattr attr1 on file"
21970         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21971                 error "cannot set xattr attr2 on file"
21972         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21973         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21974         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21975         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21976         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21977         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21978         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21979         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21980         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21981
21982         echo "Migrating to MDT1"
21983         $LFS migrate -m $MDTIDX $mig_dir ||
21984                 error "fails on migrating dir to MDT1"
21985
21986         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21987         echo "Checking xattrs"
21988         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21989         [ "$val" = $longstr ] ||
21990                 error "expecting xattr1 $longstr on dir, found $val"
21991         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21992         [ "$val" = $shortstr ] ||
21993                 error "expecting xattr2 $shortstr on dir, found $val"
21994         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21995         [ "$val" = $longstr ] ||
21996                 error "expecting xattr1 $longstr on file, found $val"
21997         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21998         [ "$val" = $shortstr ] ||
21999                 error "expecting xattr2 $shortstr on file, found $val"
22000 }
22001 run_test 230m "xattrs not changed after dir migration"
22002
22003 test_230n() {
22004         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22005         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22006                 skip "Need MDS version at least 2.13.53"
22007
22008         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22009         cat /etc/hosts > $DIR/$tdir/$tfile
22010         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22011         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22012
22013         cmp /etc/hosts $DIR/$tdir/$tfile ||
22014                 error "File data mismatch after migration"
22015 }
22016 run_test 230n "Dir migration with mirrored file"
22017
22018 test_230o() {
22019         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22020         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22021                 skip "Need MDS version at least 2.13.52"
22022
22023         local mdts=$(comma_list $(mdts_nodes))
22024         local timeout=100
22025         local restripe_status
22026         local delta
22027         local i
22028
22029         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22030
22031         # in case "crush" hash type is not set
22032         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22033
22034         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22035                            mdt.*MDT0000.enable_dir_restripe)
22036         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22037         stack_trap "do_nodes $mdts $LCTL set_param \
22038                     mdt.*.enable_dir_restripe=$restripe_status"
22039
22040         mkdir $DIR/$tdir
22041         createmany -m $DIR/$tdir/f 100 ||
22042                 error "create files under remote dir failed $i"
22043         createmany -d $DIR/$tdir/d 100 ||
22044                 error "create dirs under remote dir failed $i"
22045
22046         for i in $(seq 2 $MDSCOUNT); do
22047                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22048                 $LFS setdirstripe -c $i $DIR/$tdir ||
22049                         error "split -c $i $tdir failed"
22050                 wait_update $HOSTNAME \
22051                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22052                         error "dir split not finished"
22053                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22054                         awk '/migrate/ {sum += $2} END { print sum }')
22055                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22056                 # delta is around total_files/stripe_count
22057                 (( $delta < 200 / (i - 1) + 4 )) ||
22058                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22059         done
22060 }
22061 run_test 230o "dir split"
22062
22063 test_230p() {
22064         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22065         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22066                 skip "Need MDS version at least 2.13.52"
22067
22068         local mdts=$(comma_list $(mdts_nodes))
22069         local timeout=100
22070         local restripe_status
22071         local delta
22072         local c
22073
22074         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22075
22076         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22077
22078         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22079                            mdt.*MDT0000.enable_dir_restripe)
22080         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22081         stack_trap "do_nodes $mdts $LCTL set_param \
22082                     mdt.*.enable_dir_restripe=$restripe_status"
22083
22084         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22085         createmany -m $DIR/$tdir/f 100 ||
22086                 error "create files under remote dir failed"
22087         createmany -d $DIR/$tdir/d 100 ||
22088                 error "create dirs under remote dir failed"
22089
22090         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22091                 local mdt_hash="crush"
22092
22093                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22094                 $LFS setdirstripe -c $c $DIR/$tdir ||
22095                         error "split -c $c $tdir failed"
22096                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22097                         mdt_hash="$mdt_hash,fixed"
22098                 elif [ $c -eq 1 ]; then
22099                         mdt_hash="none"
22100                 fi
22101                 wait_update $HOSTNAME \
22102                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22103                         error "dir merge not finished"
22104                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22105                         awk '/migrate/ {sum += $2} END { print sum }')
22106                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22107                 # delta is around total_files/stripe_count
22108                 (( delta < 200 / c + 4 )) ||
22109                         error "$delta files migrated >= $((200 / c + 4))"
22110         done
22111 }
22112 run_test 230p "dir merge"
22113
22114 test_230q() {
22115         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22116         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22117                 skip "Need MDS version at least 2.13.52"
22118
22119         local mdts=$(comma_list $(mdts_nodes))
22120         local saved_threshold=$(do_facet mds1 \
22121                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22122         local saved_delta=$(do_facet mds1 \
22123                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22124         local threshold=100
22125         local delta=2
22126         local total=0
22127         local stripe_count=0
22128         local stripe_index
22129         local nr_files
22130         local create
22131
22132         # test with fewer files on ZFS
22133         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22134
22135         stack_trap "do_nodes $mdts $LCTL set_param \
22136                     mdt.*.dir_split_count=$saved_threshold"
22137         stack_trap "do_nodes $mdts $LCTL set_param \
22138                     mdt.*.dir_split_delta=$saved_delta"
22139         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22140         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22141         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22142         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22143         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22144         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22145
22146         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22147         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22148
22149         create=$((threshold * 3 / 2))
22150         while [ $stripe_count -lt $MDSCOUNT ]; do
22151                 createmany -m $DIR/$tdir/f $total $create ||
22152                         error "create sub files failed"
22153                 stat $DIR/$tdir > /dev/null
22154                 total=$((total + create))
22155                 stripe_count=$((stripe_count + delta))
22156                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22157
22158                 wait_update $HOSTNAME \
22159                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22160                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22161
22162                 wait_update $HOSTNAME \
22163                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22164                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22165
22166                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22167                 echo "$nr_files/$total files on MDT$stripe_index after split"
22168                 # allow 10% margin of imbalance with crush hash
22169                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22170                         error "$nr_files files on MDT$stripe_index after split"
22171
22172                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22173                 [ $nr_files -eq $total ] ||
22174                         error "total sub files $nr_files != $total"
22175         done
22176
22177         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22178
22179         echo "fixed layout directory won't auto split"
22180         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22181         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22182                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22183         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22184                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22185 }
22186 run_test 230q "dir auto split"
22187
22188 test_230r() {
22189         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22190         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22191         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22192                 skip "Need MDS version at least 2.13.54"
22193
22194         # maximum amount of local locks:
22195         # parent striped dir - 2 locks
22196         # new stripe in parent to migrate to - 1 lock
22197         # source and target - 2 locks
22198         # Total 5 locks for regular file
22199         mkdir -p $DIR/$tdir
22200         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22201         touch $DIR/$tdir/dir1/eee
22202
22203         # create 4 hardlink for 4 more locks
22204         # Total: 9 locks > RS_MAX_LOCKS (8)
22205         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22206         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22207         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22208         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22209         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22210         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22211         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22212         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22213
22214         cancel_lru_locks mdc
22215
22216         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22217                 error "migrate dir fails"
22218
22219         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22220 }
22221 run_test 230r "migrate with too many local locks"
22222
22223 test_230s() {
22224         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22225                 skip "Need MDS version at least 2.14.52"
22226
22227         local mdts=$(comma_list $(mdts_nodes))
22228         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22229                                 mdt.*MDT0000.enable_dir_restripe)
22230
22231         stack_trap "do_nodes $mdts $LCTL set_param \
22232                     mdt.*.enable_dir_restripe=$restripe_status"
22233
22234         local st
22235         for st in 0 1; do
22236                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22237                 test_mkdir $DIR/$tdir
22238                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22239                         error "$LFS mkdir should return EEXIST if target exists"
22240                 rmdir $DIR/$tdir
22241         done
22242 }
22243 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22244
22245 test_230t()
22246 {
22247         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22248         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22249                 skip "Need MDS version at least 2.14.50"
22250
22251         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22252         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22253         $LFS project -p 1 -s $DIR/$tdir ||
22254                 error "set $tdir project id failed"
22255         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22256                 error "set subdir project id failed"
22257         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22258 }
22259 run_test 230t "migrate directory with project ID set"
22260
22261 test_230u()
22262 {
22263         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22264         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22265                 skip "Need MDS version at least 2.14.53"
22266
22267         local count
22268
22269         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22270         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22271         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22272         for i in $(seq 0 $((MDSCOUNT - 1))); do
22273                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22274                 echo "$count dirs migrated to MDT$i"
22275         done
22276         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22277         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22278 }
22279 run_test 230u "migrate directory by QOS"
22280
22281 test_230v()
22282 {
22283         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22284         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22285                 skip "Need MDS version at least 2.14.53"
22286
22287         local count
22288
22289         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22290         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22291         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22292         for i in $(seq 0 $((MDSCOUNT - 1))); do
22293                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22294                 echo "$count subdirs migrated to MDT$i"
22295                 (( i == 3 )) && (( count > 0 )) &&
22296                         error "subdir shouldn't be migrated to MDT3"
22297         done
22298         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22299         (( count == 3 )) || error "dirs migrated to $count MDTs"
22300 }
22301 run_test 230v "subdir migrated to the MDT where its parent is located"
22302
22303 test_230w() {
22304         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22305         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22306                 skip "Need MDS version at least 2.15.0"
22307
22308         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22309         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22310         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22311
22312         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22313                 error "migrate failed"
22314
22315         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22316                 error "$tdir stripe count mismatch"
22317
22318         for i in $(seq 0 9); do
22319                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22320                         error "d$i is striped"
22321         done
22322 }
22323 run_test 230w "non-recursive mode dir migration"
22324
22325 test_230x() {
22326         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22327         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22328                 skip "Need MDS version at least 2.15.0"
22329
22330         mkdir -p $DIR/$tdir || error "mkdir failed"
22331         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22332
22333         local mdt_name=$(mdtname_from_index 0)
22334         local low=$(do_facet mds2 $LCTL get_param -n \
22335                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22336         local high=$(do_facet mds2 $LCTL get_param -n \
22337                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22338         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22339         local maxage=$(do_facet mds2 $LCTL get_param -n \
22340                 osp.*$mdt_name-osp-MDT0001.maxage)
22341
22342         stack_trap "do_facet mds2 $LCTL set_param -n \
22343                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22344                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22345         stack_trap "do_facet mds2 $LCTL set_param -n \
22346                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22347
22348         do_facet mds2 $LCTL set_param -n \
22349                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22350         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22351         sleep 4
22352         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22353                 error "migrate $tdir should fail"
22354
22355         do_facet mds2 $LCTL set_param -n \
22356                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22357         do_facet mds2 $LCTL set_param -n \
22358                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22359         sleep 4
22360         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22361                 error "migrate failed"
22362         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22363                 error "$tdir stripe count mismatch"
22364 }
22365 run_test 230x "dir migration check space"
22366
22367 test_230y() {
22368         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22369         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22370                 skip "Need MDS version at least 2.15.55.45"
22371
22372         local pid
22373
22374         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22375         $LFS getdirstripe $DIR/$tdir
22376         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22377         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22378         pid=$!
22379         sleep 1
22380
22381         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22382         do_facet mds2 lctl set_param fail_loc=0x1802
22383
22384         wait $pid
22385         do_facet mds2 lctl set_param fail_loc=0
22386         $LFS getdirstripe $DIR/$tdir
22387         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22388         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22389 }
22390 run_test 230y "unlink dir with bad hash type"
22391
22392 test_230z() {
22393         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22394         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22395                 skip "Need MDS version at least 2.15.55.45"
22396
22397         local pid
22398
22399         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22400         $LFS getdirstripe $DIR/$tdir
22401         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22402         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22403         pid=$!
22404         sleep 1
22405
22406         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22407         do_facet mds2 lctl set_param fail_loc=0x1802
22408
22409         wait $pid
22410         do_facet mds2 lctl set_param fail_loc=0
22411         $LFS getdirstripe $DIR/$tdir
22412
22413         # resume migration
22414         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22415                 error "resume migration failed"
22416         $LFS getdirstripe $DIR/$tdir
22417         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22418                 error "migration is not finished"
22419 }
22420 run_test 230z "resume dir migration with bad hash type"
22421
22422 test_231a()
22423 {
22424         # For simplicity this test assumes that max_pages_per_rpc
22425         # is the same across all OSCs
22426         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22427         local bulk_size=$((max_pages * PAGE_SIZE))
22428         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22429                                        head -n 1)
22430
22431         mkdir -p $DIR/$tdir
22432         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22433                 error "failed to set stripe with -S ${brw_size}M option"
22434         stack_trap "rm -rf $DIR/$tdir"
22435
22436         # clear the OSC stats
22437         $LCTL set_param osc.*.stats=0 &>/dev/null
22438         stop_writeback
22439
22440         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22441         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22442                 oflag=direct &>/dev/null || error "dd failed"
22443
22444         sync; sleep 1; sync # just to be safe
22445         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22446         if [ x$nrpcs != "x1" ]; then
22447                 $LCTL get_param osc.*.stats
22448                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22449         fi
22450
22451         start_writeback
22452         # Drop the OSC cache, otherwise we will read from it
22453         cancel_lru_locks osc
22454
22455         # clear the OSC stats
22456         $LCTL set_param osc.*.stats=0 &>/dev/null
22457
22458         # Client reads $bulk_size.
22459         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22460                 iflag=direct &>/dev/null || error "dd failed"
22461
22462         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22463         if [ x$nrpcs != "x1" ]; then
22464                 $LCTL get_param osc.*.stats
22465                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22466         fi
22467 }
22468 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22469
22470 test_231b() {
22471         mkdir -p $DIR/$tdir
22472         stack_trap "rm -rf $DIR/$tdir"
22473         local i
22474         for i in {0..1023}; do
22475                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22476                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22477                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22478         done
22479         sync
22480 }
22481 run_test 231b "must not assert on fully utilized OST request buffer"
22482
22483 test_232a() {
22484         mkdir -p $DIR/$tdir
22485         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22486
22487         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22488         do_facet ost1 $LCTL set_param fail_loc=0x31c
22489
22490         # ignore dd failure
22491         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22492         stack_trap "rm -f $DIR/$tdir/$tfile"
22493
22494         do_facet ost1 $LCTL set_param fail_loc=0
22495         umount_client $MOUNT || error "umount failed"
22496         mount_client $MOUNT || error "mount failed"
22497         stop ost1 || error "cannot stop ost1"
22498         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22499 }
22500 run_test 232a "failed lock should not block umount"
22501
22502 test_232b() {
22503         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22504                 skip "Need MDS version at least 2.10.58"
22505
22506         mkdir -p $DIR/$tdir
22507         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22508         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22509         stack_trap "rm -f $DIR/$tdir/$tfile"
22510         sync
22511         cancel_lru_locks osc
22512
22513         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22514         do_facet ost1 $LCTL set_param fail_loc=0x31c
22515
22516         # ignore failure
22517         $LFS data_version $DIR/$tdir/$tfile || true
22518
22519         do_facet ost1 $LCTL set_param fail_loc=0
22520         umount_client $MOUNT || error "umount failed"
22521         mount_client $MOUNT || error "mount failed"
22522         stop ost1 || error "cannot stop ost1"
22523         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22524 }
22525 run_test 232b "failed data version lock should not block umount"
22526
22527 test_233a() {
22528         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22529                 skip "Need MDS version at least 2.3.64"
22530         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22531
22532         local fid=$($LFS path2fid $MOUNT)
22533
22534         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22535                 error "cannot access $MOUNT using its FID '$fid'"
22536 }
22537 run_test 233a "checking that OBF of the FS root succeeds"
22538
22539 test_233b() {
22540         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22541                 skip "Need MDS version at least 2.5.90"
22542         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22543
22544         local fid=$($LFS path2fid $MOUNT/.lustre)
22545
22546         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22547                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22548
22549         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22550         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22551                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22552 }
22553 run_test 233b "checking that OBF of the FS .lustre succeeds"
22554
22555 test_234() {
22556         local p="$TMP/sanityN-$TESTNAME.parameters"
22557         save_lustre_params client "llite.*.xattr_cache" > $p
22558         lctl set_param llite.*.xattr_cache 1 ||
22559                 skip_env "xattr cache is not supported"
22560
22561         mkdir -p $DIR/$tdir || error "mkdir failed"
22562         touch $DIR/$tdir/$tfile || error "touch failed"
22563         # OBD_FAIL_LLITE_XATTR_ENOMEM
22564         $LCTL set_param fail_loc=0x1405
22565         getfattr -n user.attr $DIR/$tdir/$tfile &&
22566                 error "getfattr should have failed with ENOMEM"
22567         $LCTL set_param fail_loc=0x0
22568         rm -rf $DIR/$tdir
22569
22570         restore_lustre_params < $p
22571         rm -f $p
22572 }
22573 run_test 234 "xattr cache should not crash on ENOMEM"
22574
22575 test_235() {
22576         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22577                 skip "Need MDS version at least 2.4.52"
22578
22579         flock_deadlock $DIR/$tfile
22580         local RC=$?
22581         case $RC in
22582                 0)
22583                 ;;
22584                 124) error "process hangs on a deadlock"
22585                 ;;
22586                 *) error "error executing flock_deadlock $DIR/$tfile"
22587                 ;;
22588         esac
22589 }
22590 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22591
22592 #LU-2935
22593 test_236() {
22594         check_swap_layouts_support
22595
22596         local ref1=/etc/passwd
22597         local ref2=/etc/group
22598         local file1=$DIR/$tdir/f1
22599         local file2=$DIR/$tdir/f2
22600
22601         test_mkdir -c1 $DIR/$tdir
22602         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22603         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22604         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22605         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22606         local fd=$(free_fd)
22607         local cmd="exec $fd<>$file2"
22608         eval $cmd
22609         rm $file2
22610         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22611                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22612         cmd="exec $fd>&-"
22613         eval $cmd
22614         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22615
22616         #cleanup
22617         rm -rf $DIR/$tdir
22618 }
22619 run_test 236 "Layout swap on open unlinked file"
22620
22621 # LU-4659 linkea consistency
22622 test_238() {
22623         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22624                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22625                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22626                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22627
22628         touch $DIR/$tfile
22629         ln $DIR/$tfile $DIR/$tfile.lnk
22630         touch $DIR/$tfile.new
22631         mv $DIR/$tfile.new $DIR/$tfile
22632         local fid1=$($LFS path2fid $DIR/$tfile)
22633         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22634         local path1=$($LFS fid2path $FSNAME "$fid1")
22635         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22636         local path2=$($LFS fid2path $FSNAME "$fid2")
22637         [ $tfile.lnk == $path2 ] ||
22638                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22639         rm -f $DIR/$tfile*
22640 }
22641 run_test 238 "Verify linkea consistency"
22642
22643 test_239A() { # was test_239
22644         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22645                 skip "Need MDS version at least 2.5.60"
22646
22647         local list=$(comma_list $(mdts_nodes))
22648
22649         mkdir -p $DIR/$tdir
22650         createmany -o $DIR/$tdir/f- 5000
22651         unlinkmany $DIR/$tdir/f- 5000
22652         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22653                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22654         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22655                         osp.*MDT*.sync_in_flight" | calc_sum)
22656         [ "$changes" -eq 0 ] || error "$changes not synced"
22657 }
22658 run_test 239A "osp_sync test"
22659
22660 test_239a() { #LU-5297
22661         remote_mds_nodsh && skip "remote MDS with nodsh"
22662
22663         touch $DIR/$tfile
22664         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22665         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22666         chgrp $RUNAS_GID $DIR/$tfile
22667         wait_delete_completed
22668 }
22669 run_test 239a "process invalid osp sync record correctly"
22670
22671 test_239b() { #LU-5297
22672         remote_mds_nodsh && skip "remote MDS with nodsh"
22673
22674         touch $DIR/$tfile1
22675         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22676         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22677         chgrp $RUNAS_GID $DIR/$tfile1
22678         wait_delete_completed
22679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22680         touch $DIR/$tfile2
22681         chgrp $RUNAS_GID $DIR/$tfile2
22682         wait_delete_completed
22683 }
22684 run_test 239b "process osp sync record with ENOMEM error correctly"
22685
22686 test_240() {
22687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22688         remote_mds_nodsh && skip "remote MDS with nodsh"
22689
22690         mkdir -p $DIR/$tdir
22691
22692         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22693                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22694         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22695                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22696
22697         umount_client $MOUNT || error "umount failed"
22698         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22699         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22700         mount_client $MOUNT || error "failed to mount client"
22701
22702         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22703         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22704 }
22705 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22706
22707 test_241_bio() {
22708         local count=$1
22709         local bsize=$2
22710
22711         for LOOP in $(seq $count); do
22712                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22713                 cancel_lru_locks $OSC || true
22714         done
22715 }
22716
22717 test_241_dio() {
22718         local count=$1
22719         local bsize=$2
22720
22721         for LOOP in $(seq $1); do
22722                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22723                         2>/dev/null
22724         done
22725 }
22726
22727 test_241a() { # was test_241
22728         local bsize=$PAGE_SIZE
22729
22730         (( bsize < 40960 )) && bsize=40960
22731         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22732         ls -la $DIR/$tfile
22733         cancel_lru_locks $OSC
22734         test_241_bio 1000 $bsize &
22735         PID=$!
22736         test_241_dio 1000 $bsize
22737         wait $PID
22738 }
22739 run_test 241a "bio vs dio"
22740
22741 test_241b() {
22742         local bsize=$PAGE_SIZE
22743
22744         (( bsize < 40960 )) && bsize=40960
22745         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22746         ls -la $DIR/$tfile
22747         test_241_dio 1000 $bsize &
22748         PID=$!
22749         test_241_dio 1000 $bsize
22750         wait $PID
22751 }
22752 run_test 241b "dio vs dio"
22753
22754 test_242() {
22755         remote_mds_nodsh && skip "remote MDS with nodsh"
22756
22757         mkdir_on_mdt0 $DIR/$tdir
22758         touch $DIR/$tdir/$tfile
22759
22760         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22761         do_facet mds1 lctl set_param fail_loc=0x105
22762         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22763
22764         do_facet mds1 lctl set_param fail_loc=0
22765         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22766 }
22767 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22768
22769 test_243()
22770 {
22771         test_mkdir $DIR/$tdir
22772         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22773 }
22774 run_test 243 "various group lock tests"
22775
22776 test_244a()
22777 {
22778         test_mkdir $DIR/$tdir
22779         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22780         sendfile_grouplock $DIR/$tdir/$tfile || \
22781                 error "sendfile+grouplock failed"
22782         rm -rf $DIR/$tdir
22783 }
22784 run_test 244a "sendfile with group lock tests"
22785
22786 test_244b()
22787 {
22788         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22789
22790         local threads=50
22791         local size=$((1024*1024))
22792
22793         test_mkdir $DIR/$tdir
22794         for i in $(seq 1 $threads); do
22795                 local file=$DIR/$tdir/file_$((i / 10))
22796                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22797                 local pids[$i]=$!
22798         done
22799         for i in $(seq 1 $threads); do
22800                 wait ${pids[$i]}
22801         done
22802 }
22803 run_test 244b "multi-threaded write with group lock"
22804
22805 test_245a() {
22806         local flagname="multi_mod_rpcs"
22807         local connect_data_name="max_mod_rpcs"
22808         local out
22809
22810         # check if multiple modify RPCs flag is set
22811         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22812                 grep "connect_flags:")
22813         echo "$out"
22814
22815         echo "$out" | grep -qw $flagname
22816         if [ $? -ne 0 ]; then
22817                 echo "connect flag $flagname is not set"
22818                 return
22819         fi
22820
22821         # check if multiple modify RPCs data is set
22822         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22823         echo "$out"
22824
22825         echo "$out" | grep -qw $connect_data_name ||
22826                 error "import should have connect data $connect_data_name"
22827 }
22828 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22829
22830 test_245b() {
22831         local flagname="multi_mod_rpcs"
22832         local connect_data_name="max_mod_rpcs"
22833         local out
22834
22835         remote_mds_nodsh && skip "remote MDS with nodsh"
22836         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22837
22838         # check if multiple modify RPCs flag is set
22839         out=$(do_facet mds1 \
22840               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22841               grep "connect_flags:")
22842         echo "$out"
22843
22844         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22845
22846         # check if multiple modify RPCs data is set
22847         out=$(do_facet mds1 \
22848               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22849
22850         [[ "$out" =~ $connect_data_name ]] ||
22851                 {
22852                         echo "$out"
22853                         error "missing connect data $connect_data_name"
22854                 }
22855 }
22856 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22857
22858 cleanup_247() {
22859         local submount=$1
22860
22861         trap 0
22862         umount_client $submount
22863         rmdir $submount
22864 }
22865
22866 test_247a() {
22867         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22868                 grep -q subtree ||
22869                 skip_env "Fileset feature is not supported"
22870
22871         local submount=${MOUNT}_$tdir
22872
22873         mkdir $MOUNT/$tdir
22874         mkdir -p $submount || error "mkdir $submount failed"
22875         FILESET="$FILESET/$tdir" mount_client $submount ||
22876                 error "mount $submount failed"
22877         trap "cleanup_247 $submount" EXIT
22878         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22879         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22880                 error "read $MOUNT/$tdir/$tfile failed"
22881         cleanup_247 $submount
22882 }
22883 run_test 247a "mount subdir as fileset"
22884
22885 test_247b() {
22886         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22887                 skip_env "Fileset feature is not supported"
22888
22889         local submount=${MOUNT}_$tdir
22890
22891         rm -rf $MOUNT/$tdir
22892         mkdir -p $submount || error "mkdir $submount failed"
22893         SKIP_FILESET=1
22894         FILESET="$FILESET/$tdir" mount_client $submount &&
22895                 error "mount $submount should fail"
22896         rmdir $submount
22897 }
22898 run_test 247b "mount subdir that dose not exist"
22899
22900 test_247c() {
22901         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22902                 skip_env "Fileset feature is not supported"
22903
22904         local submount=${MOUNT}_$tdir
22905
22906         mkdir -p $MOUNT/$tdir/dir1
22907         mkdir -p $submount || error "mkdir $submount failed"
22908         trap "cleanup_247 $submount" EXIT
22909         FILESET="$FILESET/$tdir" mount_client $submount ||
22910                 error "mount $submount failed"
22911         local fid=$($LFS path2fid $MOUNT/)
22912         $LFS fid2path $submount $fid && error "fid2path should fail"
22913         cleanup_247 $submount
22914 }
22915 run_test 247c "running fid2path outside subdirectory root"
22916
22917 test_247d() {
22918         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22919                 skip "Fileset feature is not supported"
22920
22921         local submount=${MOUNT}_$tdir
22922
22923         mkdir -p $MOUNT/$tdir/dir1
22924         mkdir -p $submount || error "mkdir $submount failed"
22925         FILESET="$FILESET/$tdir" mount_client $submount ||
22926                 error "mount $submount failed"
22927         trap "cleanup_247 $submount" EXIT
22928
22929         local td=$submount/dir1
22930         local fid=$($LFS path2fid $td)
22931         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22932
22933         # check that we get the same pathname back
22934         local rootpath
22935         local found
22936         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22937                 echo "$rootpath $fid"
22938                 found=$($LFS fid2path $rootpath "$fid")
22939                 [ -n "$found" ] || error "fid2path should succeed"
22940                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22941         done
22942         # check wrong root path format
22943         rootpath=$submount"_wrong"
22944         found=$($LFS fid2path $rootpath "$fid")
22945         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22946
22947         cleanup_247 $submount
22948 }
22949 run_test 247d "running fid2path inside subdirectory root"
22950
22951 # LU-8037
22952 test_247e() {
22953         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22954                 grep -q subtree ||
22955                 skip "Fileset feature is not supported"
22956
22957         local submount=${MOUNT}_$tdir
22958
22959         mkdir $MOUNT/$tdir
22960         mkdir -p $submount || error "mkdir $submount failed"
22961         FILESET="$FILESET/.." mount_client $submount &&
22962                 error "mount $submount should fail"
22963         rmdir $submount
22964 }
22965 run_test 247e "mount .. as fileset"
22966
22967 test_247f() {
22968         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22969         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22970                 skip "Need at least version 2.14.50.162"
22971         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22972                 skip "Fileset feature is not supported"
22973
22974         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22975         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22976                 error "mkdir remote failed"
22977         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22978                 error "mkdir remote/subdir failed"
22979         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22980                 error "mkdir striped failed"
22981         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22982
22983         local submount=${MOUNT}_$tdir
22984
22985         mkdir -p $submount || error "mkdir $submount failed"
22986         stack_trap "rmdir $submount"
22987
22988         local dir
22989         local fileset=$FILESET
22990         local mdts=$(comma_list $(mdts_nodes))
22991
22992         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22993         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22994                 $tdir/striped/subdir $tdir/striped/.; do
22995                 FILESET="$fileset/$dir" mount_client $submount ||
22996                         error "mount $dir failed"
22997                 umount_client $submount
22998         done
22999 }
23000 run_test 247f "mount striped or remote directory as fileset"
23001
23002 test_subdir_mount_lock()
23003 {
23004         local testdir=$1
23005         local submount=${MOUNT}_$(basename $testdir)
23006
23007         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23008
23009         mkdir -p $submount || error "mkdir $submount failed"
23010         stack_trap "rmdir $submount"
23011
23012         FILESET="$fileset/$testdir" mount_client $submount ||
23013                 error "mount $FILESET failed"
23014         stack_trap "umount $submount"
23015
23016         local mdts=$(comma_list $(mdts_nodes))
23017
23018         local nrpcs
23019
23020         stat $submount > /dev/null || error "stat $submount failed"
23021         cancel_lru_locks $MDC
23022         stat $submount > /dev/null || error "stat $submount failed"
23023         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23024         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23025         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23026         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23027                 awk '/getattr/ {sum += $2} END {print sum}')
23028
23029         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23030 }
23031
23032 test_247g() {
23033         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23034
23035         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23036                 error "mkdir $tdir failed"
23037         test_subdir_mount_lock $tdir
23038 }
23039 run_test 247g "striped directory submount revalidate ROOT from cache"
23040
23041 test_247h() {
23042         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23043         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23044                 skip "Need MDS version at least 2.15.51"
23045
23046         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23047         test_subdir_mount_lock $tdir
23048         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23049         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23050                 error "mkdir $tdir.1 failed"
23051         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23052 }
23053 run_test 247h "remote directory submount revalidate ROOT from cache"
23054
23055 test_248a() {
23056         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23057         [ -z "$fast_read_sav" ] && skip "no fast read support"
23058
23059         # create a large file for fast read verification
23060         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23061
23062         # make sure the file is created correctly
23063         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23064                 { rm -f $DIR/$tfile; skip "file creation error"; }
23065
23066         echo "Test 1: verify that fast read is 4 times faster on cache read"
23067
23068         # small read with fast read enabled
23069         $LCTL set_param -n llite.*.fast_read=1
23070         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23071                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23072                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23073         # small read with fast read disabled
23074         $LCTL set_param -n llite.*.fast_read=0
23075         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23076                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23077                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23078
23079         # verify that fast read is 4 times faster for cache read
23080         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23081                 error_not_in_vm "fast read was not 4 times faster: " \
23082                            "$t_fast vs $t_slow"
23083
23084         echo "Test 2: verify the performance between big and small read"
23085         $LCTL set_param -n llite.*.fast_read=1
23086
23087         # 1k non-cache read
23088         cancel_lru_locks osc
23089         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23090                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23091                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23092
23093         # 1M non-cache read
23094         cancel_lru_locks osc
23095         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23096                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23097                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23098
23099         # verify that big IO is not 4 times faster than small IO
23100         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23101                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23102
23103         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23104         rm -f $DIR/$tfile
23105 }
23106 run_test 248a "fast read verification"
23107
23108 test_248b() {
23109         # Default short_io_bytes=16384, try both smaller and larger sizes.
23110         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23111         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23112         echo "bs=53248 count=113 normal buffered write"
23113         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23114                 error "dd of initial data file failed"
23115         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23116
23117         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23118         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23119                 error "dd with sync normal writes failed"
23120         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23121
23122         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23123         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23124                 error "dd with sync small writes failed"
23125         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23126
23127         cancel_lru_locks osc
23128
23129         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23130         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23131         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23132         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23133                 iflag=direct || error "dd with O_DIRECT small read failed"
23134         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23135         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23136                 error "compare $TMP/$tfile.1 failed"
23137
23138         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23139         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23140
23141         # just to see what the maximum tunable value is, and test parsing
23142         echo "test invalid parameter 2MB"
23143         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23144                 error "too-large short_io_bytes allowed"
23145         echo "test maximum parameter 512KB"
23146         # if we can set a larger short_io_bytes, run test regardless of version
23147         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23148                 # older clients may not allow setting it this large, that's OK
23149                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23150                         skip "Need at least client version 2.13.50"
23151                 error "medium short_io_bytes failed"
23152         fi
23153         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23154         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23155
23156         echo "test large parameter 64KB"
23157         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23158         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23159
23160         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23161         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23162                 error "dd with sync large writes failed"
23163         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23164
23165         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23166         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23167         num=$((113 * 4096 / PAGE_SIZE))
23168         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23169         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23170                 error "dd with O_DIRECT large writes failed"
23171         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23172                 error "compare $DIR/$tfile.3 failed"
23173
23174         cancel_lru_locks osc
23175
23176         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23177         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23178                 error "dd with O_DIRECT large read failed"
23179         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23180                 error "compare $TMP/$tfile.2 failed"
23181
23182         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23183         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23184                 error "dd with O_DIRECT large read failed"
23185         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23186                 error "compare $TMP/$tfile.3 failed"
23187 }
23188 run_test 248b "test short_io read and write for both small and large sizes"
23189
23190 test_249() { # LU-7890
23191         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23192                 skip "Need at least version 2.8.54"
23193
23194         rm -f $DIR/$tfile
23195         $LFS setstripe -c 1 $DIR/$tfile
23196         # Offset 2T == 4k * 512M
23197         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23198                 error "dd to 2T offset failed"
23199 }
23200 run_test 249 "Write above 2T file size"
23201
23202 test_250() {
23203         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23204          && skip "no 16TB file size limit on ZFS"
23205
23206         $LFS setstripe -c 1 $DIR/$tfile
23207         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23208         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23209         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23210         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23211                 conv=notrunc,fsync && error "append succeeded"
23212         return 0
23213 }
23214 run_test 250 "Write above 16T limit"
23215
23216 test_251() {
23217         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23218
23219         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23220         #Skip once - writing the first stripe will succeed
23221         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23222         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23223                 error "short write happened"
23224
23225         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23226         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23227                 error "short read happened"
23228
23229         rm -f $DIR/$tfile
23230 }
23231 run_test 251 "Handling short read and write correctly"
23232
23233 test_252() {
23234         remote_mds_nodsh && skip "remote MDS with nodsh"
23235         remote_ost_nodsh && skip "remote OST with nodsh"
23236         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23237                 skip_env "ldiskfs only test"
23238         fi
23239
23240         local tgt
23241         local dev
23242         local out
23243         local uuid
23244         local num
23245         local gen
23246
23247         # check lr_reader on OST0000
23248         tgt=ost1
23249         dev=$(facet_device $tgt)
23250         out=$(do_facet $tgt $LR_READER $dev)
23251         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23252         echo "$out"
23253         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23254         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23255                 error "Invalid uuid returned by $LR_READER on target $tgt"
23256         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23257
23258         # check lr_reader -c on MDT0000
23259         tgt=mds1
23260         dev=$(facet_device $tgt)
23261         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23262                 skip "$LR_READER does not support additional options"
23263         fi
23264         out=$(do_facet $tgt $LR_READER -c $dev)
23265         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23266         echo "$out"
23267         num=$(echo "$out" | grep -c "mdtlov")
23268         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23269                 error "Invalid number of mdtlov clients returned by $LR_READER"
23270         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23271
23272         # check lr_reader -cr on MDT0000
23273         out=$(do_facet $tgt $LR_READER -cr $dev)
23274         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23275         echo "$out"
23276         echo "$out" | grep -q "^reply_data:$" ||
23277                 error "$LR_READER should have returned 'reply_data' section"
23278         num=$(echo "$out" | grep -c "client_generation")
23279         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23280 }
23281 run_test 252 "check lr_reader tool"
23282
23283 test_253() {
23284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23285         remote_mds_nodsh && skip "remote MDS with nodsh"
23286         remote_mgs_nodsh && skip "remote MGS with nodsh"
23287
23288         local ostidx=0
23289         local rc=0
23290         local ost_name=$(ostname_from_index $ostidx)
23291
23292         # on the mdt's osc
23293         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23294         do_facet $SINGLEMDS $LCTL get_param -n \
23295                 osp.$mdtosc_proc1.reserved_mb_high ||
23296                 skip  "remote MDS does not support reserved_mb_high"
23297
23298         rm -rf $DIR/$tdir
23299         wait_mds_ost_sync
23300         wait_delete_completed
23301         mkdir $DIR/$tdir
23302         stack_trap "rm -rf $DIR/$tdir"
23303
23304         pool_add $TESTNAME || error "Pool creation failed"
23305         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23306
23307         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23308                 error "Setstripe failed"
23309
23310         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23311
23312         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23313                     grep "watermarks")
23314         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23315
23316         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23317                         osp.$mdtosc_proc1.prealloc_status)
23318         echo "prealloc_status $oa_status"
23319
23320         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23321                 error "File creation should fail"
23322
23323         #object allocation was stopped, but we still able to append files
23324         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23325                 oflag=append || error "Append failed"
23326
23327         rm -f $DIR/$tdir/$tfile.0
23328
23329         # For this test, we want to delete the files we created to go out of
23330         # space but leave the watermark, so we remain nearly out of space
23331         ost_watermarks_enospc_delete_files $tfile $ostidx
23332
23333         wait_delete_completed
23334
23335         sleep_maxage
23336
23337         for i in $(seq 10 12); do
23338                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23339                         2>/dev/null || error "File creation failed after rm"
23340         done
23341
23342         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23343                         osp.$mdtosc_proc1.prealloc_status)
23344         echo "prealloc_status $oa_status"
23345
23346         if (( oa_status != 0 )); then
23347                 error "Object allocation still disable after rm"
23348         fi
23349 }
23350 run_test 253 "Check object allocation limit"
23351
23352 test_254() {
23353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23354         remote_mds_nodsh && skip "remote MDS with nodsh"
23355
23356         local mdt=$(facet_svc $SINGLEMDS)
23357
23358         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23359                 skip "MDS does not support changelog_size"
23360
23361         local cl_user
23362
23363         changelog_register || error "changelog_register failed"
23364
23365         changelog_clear 0 || error "changelog_clear failed"
23366
23367         local size1=$(do_facet $SINGLEMDS \
23368                       $LCTL get_param -n mdd.$mdt.changelog_size)
23369         echo "Changelog size $size1"
23370
23371         rm -rf $DIR/$tdir
23372         $LFS mkdir -i 0 $DIR/$tdir
23373         # change something
23374         mkdir -p $DIR/$tdir/pics/2008/zachy
23375         touch $DIR/$tdir/pics/2008/zachy/timestamp
23376         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23377         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23378         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23379         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23380         rm $DIR/$tdir/pics/desktop.jpg
23381
23382         local size2=$(do_facet $SINGLEMDS \
23383                       $LCTL get_param -n mdd.$mdt.changelog_size)
23384         echo "Changelog size after work $size2"
23385
23386         (( $size2 > $size1 )) ||
23387                 error "new Changelog size=$size2 less than old size=$size1"
23388 }
23389 run_test 254 "Check changelog size"
23390
23391 ladvise_no_type()
23392 {
23393         local type=$1
23394         local file=$2
23395
23396         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23397                 awk -F: '{print $2}' | grep $type > /dev/null
23398         if [ $? -ne 0 ]; then
23399                 return 0
23400         fi
23401         return 1
23402 }
23403
23404 ladvise_no_ioctl()
23405 {
23406         local file=$1
23407
23408         lfs ladvise -a willread $file > /dev/null 2>&1
23409         if [ $? -eq 0 ]; then
23410                 return 1
23411         fi
23412
23413         lfs ladvise -a willread $file 2>&1 |
23414                 grep "Inappropriate ioctl for device" > /dev/null
23415         if [ $? -eq 0 ]; then
23416                 return 0
23417         fi
23418         return 1
23419 }
23420
23421 percent() {
23422         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23423 }
23424
23425 # run a random read IO workload
23426 # usage: random_read_iops <filename> <filesize> <iosize>
23427 random_read_iops() {
23428         local file=$1
23429         local fsize=$2
23430         local iosize=${3:-4096}
23431
23432         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23433                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23434 }
23435
23436 drop_file_oss_cache() {
23437         local file="$1"
23438         local nodes="$2"
23439
23440         $LFS ladvise -a dontneed $file 2>/dev/null ||
23441                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23442 }
23443
23444 ladvise_willread_performance()
23445 {
23446         local repeat=10
23447         local average_origin=0
23448         local average_cache=0
23449         local average_ladvise=0
23450
23451         for ((i = 1; i <= $repeat; i++)); do
23452                 echo "Iter $i/$repeat: reading without willread hint"
23453                 cancel_lru_locks osc
23454                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23455                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23456                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23457                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23458
23459                 cancel_lru_locks osc
23460                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23461                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23462                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23463
23464                 cancel_lru_locks osc
23465                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23466                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23467                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23468                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23469                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23470         done
23471         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23472         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23473         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23474
23475         speedup_cache=$(percent $average_cache $average_origin)
23476         speedup_ladvise=$(percent $average_ladvise $average_origin)
23477
23478         echo "Average uncached read: $average_origin"
23479         echo "Average speedup with OSS cached read: " \
23480                 "$average_cache = +$speedup_cache%"
23481         echo "Average speedup with ladvise willread: " \
23482                 "$average_ladvise = +$speedup_ladvise%"
23483
23484         local lowest_speedup=20
23485         if (( ${average_cache%.*} < $lowest_speedup )); then
23486                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23487                      " got $average_cache%. Skipping ladvise willread check."
23488                 return 0
23489         fi
23490
23491         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23492         # it is still good to run until then to exercise 'ladvise willread'
23493         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23494                 [ "$ost1_FSTYPE" = "zfs" ] &&
23495                 echo "osd-zfs does not support dontneed or drop_caches" &&
23496                 return 0
23497
23498         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23499         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23500                 error_not_in_vm "Speedup with willread is less than " \
23501                         "$lowest_speedup%, got $average_ladvise%"
23502 }
23503
23504 test_255a() {
23505         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23506                 skip "lustre < 2.8.54 does not support ladvise "
23507         remote_ost_nodsh && skip "remote OST with nodsh"
23508
23509         stack_trap "rm -f $DIR/$tfile"
23510         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23511
23512         ladvise_no_type willread $DIR/$tfile &&
23513                 skip "willread ladvise is not supported"
23514
23515         ladvise_no_ioctl $DIR/$tfile &&
23516                 skip "ladvise ioctl is not supported"
23517
23518         local size_mb=100
23519         local size=$((size_mb * 1048576))
23520         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23521                 error "dd to $DIR/$tfile failed"
23522
23523         lfs ladvise -a willread $DIR/$tfile ||
23524                 error "Ladvise failed with no range argument"
23525
23526         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23527                 error "Ladvise failed with no -l or -e argument"
23528
23529         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23530                 error "Ladvise failed with only -e argument"
23531
23532         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23533                 error "Ladvise failed with only -l argument"
23534
23535         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23536                 error "End offset should not be smaller than start offset"
23537
23538         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23539                 error "End offset should not be equal to start offset"
23540
23541         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23542                 error "Ladvise failed with overflowing -s argument"
23543
23544         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23545                 error "Ladvise failed with overflowing -e argument"
23546
23547         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23548                 error "Ladvise failed with overflowing -l argument"
23549
23550         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23551                 error "Ladvise succeeded with conflicting -l and -e arguments"
23552
23553         echo "Synchronous ladvise should wait"
23554         local delay=8
23555 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23556         do_nodes $(comma_list $(osts_nodes)) \
23557                 $LCTL set_param fail_val=$delay fail_loc=0x237
23558         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23559                 $LCTL set_param fail_loc=0"
23560
23561         local start_ts=$SECONDS
23562         lfs ladvise -a willread $DIR/$tfile ||
23563                 error "Ladvise failed with no range argument"
23564         local end_ts=$SECONDS
23565         local inteval_ts=$((end_ts - start_ts))
23566
23567         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23568                 error "Synchronous advice didn't wait reply"
23569         fi
23570
23571         echo "Asynchronous ladvise shouldn't wait"
23572         local start_ts=$SECONDS
23573         lfs ladvise -a willread -b $DIR/$tfile ||
23574                 error "Ladvise failed with no range argument"
23575         local end_ts=$SECONDS
23576         local inteval_ts=$((end_ts - start_ts))
23577
23578         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23579                 error "Asynchronous advice blocked"
23580         fi
23581
23582         ladvise_willread_performance
23583 }
23584 run_test 255a "check 'lfs ladvise -a willread'"
23585
23586 facet_meminfo() {
23587         local facet=$1
23588         local info=$2
23589
23590         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23591 }
23592
23593 test_255b() {
23594         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23595                 skip "lustre < 2.8.54 does not support ladvise "
23596         remote_ost_nodsh && skip "remote OST with nodsh"
23597
23598         stack_trap "rm -f $DIR/$tfile"
23599         lfs setstripe -c 1 -i 0 $DIR/$tfile
23600
23601         ladvise_no_type dontneed $DIR/$tfile &&
23602                 skip "dontneed ladvise is not supported"
23603
23604         ladvise_no_ioctl $DIR/$tfile &&
23605                 skip "ladvise ioctl is not supported"
23606
23607         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23608                 [ "$ost1_FSTYPE" = "zfs" ] &&
23609                 skip "zfs-osd does not support 'ladvise dontneed'"
23610
23611         local size_mb=100
23612         local size=$((size_mb * 1048576))
23613         # In order to prevent disturbance of other processes, only check 3/4
23614         # of the memory usage
23615         local kibibytes=$((size_mb * 1024 * 3 / 4))
23616
23617         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23618                 error "dd to $DIR/$tfile failed"
23619
23620         #force write to complete before dropping OST cache & checking memory
23621         sync
23622
23623         local total=$(facet_meminfo ost1 MemTotal)
23624         echo "Total memory: $total KiB"
23625
23626         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23627         local before_read=$(facet_meminfo ost1 Cached)
23628         echo "Cache used before read: $before_read KiB"
23629
23630         lfs ladvise -a willread $DIR/$tfile ||
23631                 error "Ladvise willread failed"
23632         local after_read=$(facet_meminfo ost1 Cached)
23633         echo "Cache used after read: $after_read KiB"
23634
23635         lfs ladvise -a dontneed $DIR/$tfile ||
23636                 error "Ladvise dontneed again failed"
23637         local no_read=$(facet_meminfo ost1 Cached)
23638         echo "Cache used after dontneed ladvise: $no_read KiB"
23639
23640         if [ $total -lt $((before_read + kibibytes)) ]; then
23641                 echo "Memory is too small, abort checking"
23642                 return 0
23643         fi
23644
23645         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23646                 error "Ladvise willread should use more memory" \
23647                         "than $kibibytes KiB"
23648         fi
23649
23650         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23651                 error "Ladvise dontneed should release more memory" \
23652                         "than $kibibytes KiB"
23653         fi
23654 }
23655 run_test 255b "check 'lfs ladvise -a dontneed'"
23656
23657 test_255c() {
23658         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23659                 skip "lustre < 2.10.50 does not support lockahead"
23660
23661         local ost1_imp=$(get_osc_import_name client ost1)
23662         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23663                          cut -d'.' -f2)
23664         local count
23665         local new_count
23666         local difference
23667         local i
23668         local rc
23669
23670         test_mkdir -p $DIR/$tdir
23671         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23672
23673         #test 10 returns only success/failure
23674         i=10
23675         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23676         rc=$?
23677         if [ $rc -eq 255 ]; then
23678                 error "Ladvise test${i} failed, ${rc}"
23679         fi
23680
23681         #test 11 counts lock enqueue requests, all others count new locks
23682         i=11
23683         count=$(do_facet ost1 \
23684                 $LCTL get_param -n ost.OSS.ost.stats)
23685         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23686
23687         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23688         rc=$?
23689         if [ $rc -eq 255 ]; then
23690                 error "Ladvise test${i} failed, ${rc}"
23691         fi
23692
23693         new_count=$(do_facet ost1 \
23694                 $LCTL get_param -n ost.OSS.ost.stats)
23695         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23696                    awk '{ print $2 }')
23697
23698         difference="$((new_count - count))"
23699         if [ $difference -ne $rc ]; then
23700                 error "Ladvise test${i}, bad enqueue count, returned " \
23701                       "${rc}, actual ${difference}"
23702         fi
23703
23704         for i in $(seq 12 21); do
23705                 # If we do not do this, we run the risk of having too many
23706                 # locks and starting lock cancellation while we are checking
23707                 # lock counts.
23708                 cancel_lru_locks osc
23709
23710                 count=$($LCTL get_param -n \
23711                        ldlm.namespaces.$imp_name.lock_unused_count)
23712
23713                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23714                 rc=$?
23715                 if [ $rc -eq 255 ]; then
23716                         error "Ladvise test ${i} failed, ${rc}"
23717                 fi
23718
23719                 new_count=$($LCTL get_param -n \
23720                        ldlm.namespaces.$imp_name.lock_unused_count)
23721                 difference="$((new_count - count))"
23722
23723                 # Test 15 output is divided by 100 to map down to valid return
23724                 if [ $i -eq 15 ]; then
23725                         rc="$((rc * 100))"
23726                 fi
23727
23728                 if [ $difference -ne $rc ]; then
23729                         error "Ladvise test ${i}, bad lock count, returned " \
23730                               "${rc}, actual ${difference}"
23731                 fi
23732         done
23733
23734         #test 22 returns only success/failure
23735         i=22
23736         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23737         rc=$?
23738         if [ $rc -eq 255 ]; then
23739                 error "Ladvise test${i} failed, ${rc}"
23740         fi
23741 }
23742 run_test 255c "suite of ladvise lockahead tests"
23743
23744 test_256() {
23745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23746         remote_mds_nodsh && skip "remote MDS with nodsh"
23747         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23748         changelog_users $SINGLEMDS | grep "^cl" &&
23749                 skip "active changelog user"
23750
23751         local cl_user
23752         local cat_sl
23753         local mdt_dev
23754
23755         mdt_dev=$(facet_device $SINGLEMDS)
23756         echo $mdt_dev
23757
23758         changelog_register || error "changelog_register failed"
23759
23760         rm -rf $DIR/$tdir
23761         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23762
23763         changelog_clear 0 || error "changelog_clear failed"
23764
23765         # change something
23766         touch $DIR/$tdir/{1..10}
23767
23768         # stop the MDT
23769         stop $SINGLEMDS || error "Fail to stop MDT"
23770
23771         # remount the MDT
23772         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23773                 error "Fail to start MDT"
23774
23775         #after mount new plainllog is used
23776         touch $DIR/$tdir/{11..19}
23777         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23778         stack_trap "rm -f $tmpfile"
23779         cat_sl=$(do_facet $SINGLEMDS "sync; \
23780                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23781                  llog_reader $tmpfile | grep -c type=1064553b")
23782         do_facet $SINGLEMDS llog_reader $tmpfile
23783
23784         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23785
23786         changelog_clear 0 || error "changelog_clear failed"
23787
23788         cat_sl=$(do_facet $SINGLEMDS "sync; \
23789                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23790                  llog_reader $tmpfile | grep -c type=1064553b")
23791
23792         if (( cat_sl == 2 )); then
23793                 error "Empty plain llog was not deleted from changelog catalog"
23794         elif (( cat_sl != 1 )); then
23795                 error "Active plain llog shouldn't be deleted from catalog"
23796         fi
23797 }
23798 run_test 256 "Check llog delete for empty and not full state"
23799
23800 test_257() {
23801         remote_mds_nodsh && skip "remote MDS with nodsh"
23802         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23803                 skip "Need MDS version at least 2.8.55"
23804
23805         test_mkdir $DIR/$tdir
23806
23807         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23808                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23809         stat $DIR/$tdir
23810
23811 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23812         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23813         local facet=mds$((mdtidx + 1))
23814         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23815         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23816
23817         stop $facet || error "stop MDS failed"
23818         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23819                 error "start MDS fail"
23820         wait_recovery_complete $facet
23821 }
23822 run_test 257 "xattr locks are not lost"
23823
23824 # Verify we take the i_mutex when security requires it
23825 test_258a() {
23826 #define OBD_FAIL_IMUTEX_SEC 0x141c
23827         $LCTL set_param fail_loc=0x141c
23828         touch $DIR/$tfile
23829         chmod u+s $DIR/$tfile
23830         chmod a+rwx $DIR/$tfile
23831         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23832         RC=$?
23833         if [ $RC -ne 0 ]; then
23834                 error "error, failed to take i_mutex, rc=$?"
23835         fi
23836         rm -f $DIR/$tfile
23837 }
23838 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23839
23840 # Verify we do NOT take the i_mutex in the normal case
23841 test_258b() {
23842 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23843         $LCTL set_param fail_loc=0x141d
23844         touch $DIR/$tfile
23845         chmod a+rwx $DIR
23846         chmod a+rw $DIR/$tfile
23847         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23848         RC=$?
23849         if [ $RC -ne 0 ]; then
23850                 error "error, took i_mutex unnecessarily, rc=$?"
23851         fi
23852         rm -f $DIR/$tfile
23853
23854 }
23855 run_test 258b "verify i_mutex security behavior"
23856
23857 test_259() {
23858         local file=$DIR/$tfile
23859         local before
23860         local after
23861
23862         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23863
23864         stack_trap "rm -f $file" EXIT
23865
23866         wait_delete_completed
23867         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23868         echo "before: $before"
23869
23870         $LFS setstripe -i 0 -c 1 $file
23871         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23872         sync_all_data
23873         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23874         echo "after write: $after"
23875
23876 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23877         do_facet ost1 $LCTL set_param fail_loc=0x2301
23878         $TRUNCATE $file 0
23879         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23880         echo "after truncate: $after"
23881
23882         stop ost1
23883         do_facet ost1 $LCTL set_param fail_loc=0
23884         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23885         sleep 2
23886         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23887         echo "after restart: $after"
23888         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23889                 error "missing truncate?"
23890
23891         return 0
23892 }
23893 run_test 259 "crash at delayed truncate"
23894
23895 test_260() {
23896 #define OBD_FAIL_MDC_CLOSE               0x806
23897         $LCTL set_param fail_loc=0x80000806
23898         touch $DIR/$tfile
23899
23900 }
23901 run_test 260 "Check mdc_close fail"
23902
23903 ### Data-on-MDT sanity tests ###
23904 test_270a() {
23905         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23906                 skip "Need MDS version at least 2.10.55 for DoM"
23907
23908         # create DoM file
23909         local dom=$DIR/$tdir/dom_file
23910         local tmp=$DIR/$tdir/tmp_file
23911
23912         mkdir_on_mdt0 $DIR/$tdir
23913
23914         # basic checks for DoM component creation
23915         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23916                 error "Can set MDT layout to non-first entry"
23917
23918         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23919                 error "Can define multiple entries as MDT layout"
23920
23921         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23922
23923         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23924         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23925         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23926
23927         local mdtidx=$($LFS getstripe -m $dom)
23928         local mdtname=MDT$(printf %04x $mdtidx)
23929         local facet=mds$((mdtidx + 1))
23930         local space_check=1
23931
23932         # Skip free space checks with ZFS
23933         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23934
23935         # write
23936         sync
23937         local size_tmp=$((65536 * 3))
23938         local mdtfree1=$(do_facet $facet \
23939                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23940
23941         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23942         # check also direct IO along write
23943         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23944         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23945         sync
23946         cmp $tmp $dom || error "file data is different"
23947         [ $(stat -c%s $dom) == $size_tmp ] ||
23948                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23949         if [ $space_check == 1 ]; then
23950                 local mdtfree2=$(do_facet $facet \
23951                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23952
23953                 # increase in usage from by $size_tmp
23954                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23955                         error "MDT free space wrong after write: " \
23956                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23957         fi
23958
23959         # truncate
23960         local size_dom=10000
23961
23962         $TRUNCATE $dom $size_dom
23963         [ $(stat -c%s $dom) == $size_dom ] ||
23964                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23965         if [ $space_check == 1 ]; then
23966                 mdtfree1=$(do_facet $facet \
23967                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23968                 # decrease in usage from $size_tmp to new $size_dom
23969                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23970                   $(((size_tmp - size_dom) / 1024)) ] ||
23971                         error "MDT free space is wrong after truncate: " \
23972                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23973         fi
23974
23975         # append
23976         cat $tmp >> $dom
23977         sync
23978         size_dom=$((size_dom + size_tmp))
23979         [ $(stat -c%s $dom) == $size_dom ] ||
23980                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23981         if [ $space_check == 1 ]; then
23982                 mdtfree2=$(do_facet $facet \
23983                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23984                 # increase in usage by $size_tmp from previous
23985                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23986                         error "MDT free space is wrong after append: " \
23987                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23988         fi
23989
23990         # delete
23991         rm $dom
23992         if [ $space_check == 1 ]; then
23993                 mdtfree1=$(do_facet $facet \
23994                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23995                 # decrease in usage by $size_dom from previous
23996                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23997                         error "MDT free space is wrong after removal: " \
23998                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23999         fi
24000
24001         # combined striping
24002         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24003                 error "Can't create DoM + OST striping"
24004
24005         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24006         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24007         # check also direct IO along write
24008         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24009         sync
24010         cmp $tmp $dom || error "file data is different"
24011         [ $(stat -c%s $dom) == $size_tmp ] ||
24012                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24013         rm $dom $tmp
24014
24015         return 0
24016 }
24017 run_test 270a "DoM: basic functionality tests"
24018
24019 test_270b() {
24020         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24021                 skip "Need MDS version at least 2.10.55"
24022
24023         local dom=$DIR/$tdir/dom_file
24024         local max_size=1048576
24025
24026         mkdir -p $DIR/$tdir
24027         $LFS setstripe -E $max_size -L mdt $dom
24028
24029         # truncate over the limit
24030         $TRUNCATE $dom $(($max_size + 1)) &&
24031                 error "successful truncate over the maximum size"
24032         # write over the limit
24033         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24034                 error "successful write over the maximum size"
24035         # append over the limit
24036         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24037         echo "12345" >> $dom && error "successful append over the maximum size"
24038         rm $dom
24039
24040         return 0
24041 }
24042 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24043
24044 test_270c() {
24045         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24046                 skip "Need MDS version at least 2.10.55"
24047
24048         mkdir -p $DIR/$tdir
24049         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24050
24051         # check files inherit DoM EA
24052         touch $DIR/$tdir/first
24053         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24054                 error "bad pattern"
24055         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24056                 error "bad stripe count"
24057         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24058                 error "bad stripe size"
24059
24060         # check directory inherits DoM EA and uses it as default
24061         mkdir $DIR/$tdir/subdir
24062         touch $DIR/$tdir/subdir/second
24063         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24064                 error "bad pattern in sub-directory"
24065         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24066                 error "bad stripe count in sub-directory"
24067         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24068                 error "bad stripe size in sub-directory"
24069         return 0
24070 }
24071 run_test 270c "DoM: DoM EA inheritance tests"
24072
24073 test_270d() {
24074         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24075                 skip "Need MDS version at least 2.10.55"
24076
24077         mkdir -p $DIR/$tdir
24078         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24079
24080         # inherit default DoM striping
24081         mkdir $DIR/$tdir/subdir
24082         touch $DIR/$tdir/subdir/f1
24083
24084         # change default directory striping
24085         $LFS setstripe -c 1 $DIR/$tdir/subdir
24086         touch $DIR/$tdir/subdir/f2
24087         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24088                 error "wrong default striping in file 2"
24089         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24090                 error "bad pattern in file 2"
24091         return 0
24092 }
24093 run_test 270d "DoM: change striping from DoM to RAID0"
24094
24095 test_270e() {
24096         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24097                 skip "Need MDS version at least 2.10.55"
24098
24099         mkdir -p $DIR/$tdir/dom
24100         mkdir -p $DIR/$tdir/norm
24101         DOMFILES=20
24102         NORMFILES=10
24103         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24104         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24105
24106         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24107         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24108
24109         # find DoM files by layout
24110         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24111         [ $NUM -eq  $DOMFILES ] ||
24112                 error "lfs find -L: found $NUM, expected $DOMFILES"
24113         echo "Test 1: lfs find 20 DOM files by layout: OK"
24114
24115         # there should be 1 dir with default DOM striping
24116         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24117         [ $NUM -eq  1 ] ||
24118                 error "lfs find -L: found $NUM, expected 1 dir"
24119         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24120
24121         # find DoM files by stripe size
24122         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24123         [ $NUM -eq  $DOMFILES ] ||
24124                 error "lfs find -S: found $NUM, expected $DOMFILES"
24125         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24126
24127         # find files by stripe offset except DoM files
24128         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24129         [ $NUM -eq  $NORMFILES ] ||
24130                 error "lfs find -i: found $NUM, expected $NORMFILES"
24131         echo "Test 5: lfs find no DOM files by stripe index: OK"
24132         return 0
24133 }
24134 run_test 270e "DoM: lfs find with DoM files test"
24135
24136 test_270f() {
24137         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24138                 skip "Need MDS version at least 2.10.55"
24139
24140         local mdtname=${FSNAME}-MDT0000-mdtlov
24141         local dom=$DIR/$tdir/dom_file
24142         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24143                                                 lod.$mdtname.dom_stripesize)
24144         local dom_limit=131072
24145
24146         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24147         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24148                                                 lod.$mdtname.dom_stripesize)
24149         [ ${dom_limit} -eq ${dom_current} ] ||
24150                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24151
24152         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24153         $LFS setstripe -d $DIR/$tdir
24154         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24155                 error "Can't set directory default striping"
24156
24157         # exceed maximum stripe size
24158         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24159                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24160         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24161                 error "Able to create DoM component size more than LOD limit"
24162
24163         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24164         dom_current=$(do_facet mds1 $LCTL get_param -n \
24165                                                 lod.$mdtname.dom_stripesize)
24166         [ 0 -eq ${dom_current} ] ||
24167                 error "Can't set zero DoM stripe limit"
24168         rm $dom
24169
24170         # attempt to create DoM file on server with disabled DoM should
24171         # remove DoM entry from layout and be succeed
24172         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24173                 error "Can't create DoM file (DoM is disabled)"
24174         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24175                 error "File has DoM component while DoM is disabled"
24176         rm $dom
24177
24178         # attempt to create DoM file with only DoM stripe should return error
24179         $LFS setstripe -E $dom_limit -L mdt $dom &&
24180                 error "Able to create DoM-only file while DoM is disabled"
24181
24182         # too low values to be aligned with smallest stripe size 64K
24183         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24184         dom_current=$(do_facet mds1 $LCTL get_param -n \
24185                                                 lod.$mdtname.dom_stripesize)
24186         [ 30000 -eq ${dom_current} ] &&
24187                 error "Can set too small DoM stripe limit"
24188
24189         # 64K is a minimal stripe size in Lustre, expect limit of that size
24190         [ 65536 -eq ${dom_current} ] ||
24191                 error "Limit is not set to 64K but ${dom_current}"
24192
24193         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24194         dom_current=$(do_facet mds1 $LCTL get_param -n \
24195                                                 lod.$mdtname.dom_stripesize)
24196         echo $dom_current
24197         [ 2147483648 -eq ${dom_current} ] &&
24198                 error "Can set too large DoM stripe limit"
24199
24200         do_facet mds1 $LCTL set_param -n \
24201                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24202         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24203                 error "Can't create DoM component size after limit change"
24204         do_facet mds1 $LCTL set_param -n \
24205                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24206         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24207                 error "Can't create DoM file after limit decrease"
24208         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24209                 error "Can create big DoM component after limit decrease"
24210         touch ${dom}_def ||
24211                 error "Can't create file with old default layout"
24212
24213         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24214         return 0
24215 }
24216 run_test 270f "DoM: maximum DoM stripe size checks"
24217
24218 test_270g() {
24219         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24220                 skip "Need MDS version at least 2.13.52"
24221         local dom=$DIR/$tdir/$tfile
24222
24223         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24224         local lodname=${FSNAME}-MDT0000-mdtlov
24225
24226         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24227         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24228         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24229         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24230
24231         local dom_limit=1024
24232         local dom_threshold="50%"
24233
24234         $LFS setstripe -d $DIR/$tdir
24235         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24236                 error "Can't set directory default striping"
24237
24238         do_facet mds1 $LCTL set_param -n \
24239                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24240         # set 0 threshold and create DOM file to change tunable stripesize
24241         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24242         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24243                 error "Failed to create $dom file"
24244         # now tunable dom_cur_stripesize should reach maximum
24245         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24246                                         lod.${lodname}.dom_stripesize_cur_kb)
24247         [[ $dom_current == $dom_limit ]] ||
24248                 error "Current DOM stripesize is not maximum"
24249         rm $dom
24250
24251         # set threshold for further tests
24252         do_facet mds1 $LCTL set_param -n \
24253                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24254         echo "DOM threshold is $dom_threshold free space"
24255         local dom_def
24256         local dom_set
24257         # Spoof bfree to exceed threshold
24258         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24259         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24260         for spfree in 40 20 0 15 30 55; do
24261                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24262                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24263                         error "Failed to create $dom file"
24264                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24265                                         lod.${lodname}.dom_stripesize_cur_kb)
24266                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24267                 [[ $dom_def != $dom_current ]] ||
24268                         error "Default stripe size was not changed"
24269                 if (( spfree > 0 )) ; then
24270                         dom_set=$($LFS getstripe -S $dom)
24271                         (( dom_set == dom_def * 1024 )) ||
24272                                 error "DOM component size is still old"
24273                 else
24274                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24275                                 error "DoM component is set with no free space"
24276                 fi
24277                 rm $dom
24278                 dom_current=$dom_def
24279         done
24280 }
24281 run_test 270g "DoM: default DoM stripe size depends on free space"
24282
24283 test_270h() {
24284         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24285                 skip "Need MDS version at least 2.13.53"
24286
24287         local mdtname=${FSNAME}-MDT0000-mdtlov
24288         local dom=$DIR/$tdir/$tfile
24289         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24290
24291         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24292         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24293
24294         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24295         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24296                 error "can't create OST file"
24297         # mirrored file with DOM entry in the second mirror
24298         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24299                 error "can't create mirror with DoM component"
24300
24301         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24302
24303         # DOM component in the middle and has other enries in the same mirror,
24304         # should succeed but lost DoM component
24305         $LFS setstripe --copy=${dom}_1 $dom ||
24306                 error "Can't create file from OST|DOM mirror layout"
24307         # check new file has no DoM layout after all
24308         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24309                 error "File has DoM component while DoM is disabled"
24310 }
24311 run_test 270h "DoM: DoM stripe removal when disabled on server"
24312
24313 test_270i() {
24314         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24315                 skip "Need MDS version at least 2.14.54"
24316
24317         mkdir $DIR/$tdir
24318         # DoM with plain layout
24319         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24320                 error "default plain layout with DoM must fail"
24321         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24322                 error "setstripe plain file layout with DoM must fail"
24323         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24324                 error "default DoM layout with bad striping must fail"
24325         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24326                 error "setstripe to DoM layout with bad striping must fail"
24327         return 0
24328 }
24329 run_test 270i "DoM: setting invalid DoM striping should fail"
24330
24331 test_270j() {
24332         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24333                 skip "Need MDS version at least 2.15.55.203"
24334
24335         local dom=$DIR/$tdir/$tfile
24336         local odv
24337         local ndv
24338
24339         mkdir -p $DIR/$tdir
24340
24341         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24342
24343         odv=$($LFS data_version $dom)
24344         chmod 666 $dom
24345         mv $dom ${dom}_moved
24346         link ${dom}_moved $dom
24347         setfattr -n user.attrx -v "some_attr" $dom
24348         ndv=$($LFS data_version $dom)
24349         (( $ndv == $odv )) ||
24350                 error "data version was changed by metadata operations"
24351
24352         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24353                 error "failed to write data into $dom"
24354         cancel_lru_locks mdc
24355         ndv=$($LFS data_version $dom)
24356         (( $ndv != $odv )) ||
24357                 error "data version wasn't changed on write"
24358
24359         odv=$ndv
24360         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24361         ndv=$($LFS data_version $dom)
24362         (( $ndv != $odv )) ||
24363                 error "data version wasn't changed on truncate down"
24364
24365         odv=$ndv
24366         $TRUNCATE $dom 25000
24367         ndv=$($LFS data_version $dom)
24368         (( $ndv != $odv )) ||
24369                 error "data version wasn't changed on truncate up"
24370
24371         # check also fallocate for ldiskfs
24372         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24373                 odv=$ndv
24374                 fallocate -l 1048576 $dom
24375                 ndv=$($LFS data_version $dom)
24376                 (( $ndv != $odv )) ||
24377                         error "data version wasn't changed on fallocate"
24378
24379                 odv=$ndv
24380                 fallocate -p --offset 4096 -l 4096 $dom
24381                 ndv=$($LFS data_version $dom)
24382                 (( $ndv != $odv )) ||
24383                         error "data version wasn't changed on fallocate punch"
24384         fi
24385 }
24386 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24387
24388 test_271a() {
24389         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24390                 skip "Need MDS version at least 2.10.55"
24391
24392         local dom=$DIR/$tdir/dom
24393
24394         mkdir -p $DIR/$tdir
24395
24396         $LFS setstripe -E 1024K -L mdt $dom
24397
24398         lctl set_param -n mdc.*.stats=clear
24399         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24400         cat $dom > /dev/null
24401         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24402         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24403         ls $dom
24404         rm -f $dom
24405 }
24406 run_test 271a "DoM: data is cached for read after write"
24407
24408 test_271b() {
24409         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24410                 skip "Need MDS version at least 2.10.55"
24411
24412         local dom=$DIR/$tdir/dom
24413
24414         mkdir -p $DIR/$tdir
24415
24416         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24417
24418         lctl set_param -n mdc.*.stats=clear
24419         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24420         cancel_lru_locks mdc
24421         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24422         # second stat to check size is cached on client
24423         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24424         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24425         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24426         rm -f $dom
24427 }
24428 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24429
24430 test_271ba() {
24431         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24432                 skip "Need MDS version at least 2.10.55"
24433
24434         local dom=$DIR/$tdir/dom
24435
24436         mkdir -p $DIR/$tdir
24437
24438         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24439
24440         lctl set_param -n mdc.*.stats=clear
24441         lctl set_param -n osc.*.stats=clear
24442         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24443         cancel_lru_locks mdc
24444         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24445         # second stat to check size is cached on client
24446         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24447         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24448         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24449         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24450         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24451         rm -f $dom
24452 }
24453 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24454
24455
24456 get_mdc_stats() {
24457         local mdtidx=$1
24458         local param=$2
24459         local mdt=MDT$(printf %04x $mdtidx)
24460
24461         if [ -z $param ]; then
24462                 lctl get_param -n mdc.*$mdt*.stats
24463         else
24464                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24465         fi
24466 }
24467
24468 test_271c() {
24469         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24470                 skip "Need MDS version at least 2.10.55"
24471
24472         local dom=$DIR/$tdir/dom
24473
24474         mkdir -p $DIR/$tdir
24475
24476         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24477
24478         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24479         local facet=mds$((mdtidx + 1))
24480
24481         cancel_lru_locks mdc
24482         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24483         createmany -o $dom 1000
24484         lctl set_param -n mdc.*.stats=clear
24485         smalliomany -w $dom 1000 200
24486         get_mdc_stats $mdtidx
24487         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24488         # Each file has 1 open, 1 IO enqueues, total 2000
24489         # but now we have also +1 getxattr for security.capability, total 3000
24490         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24491         unlinkmany $dom 1000
24492
24493         cancel_lru_locks mdc
24494         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24495         createmany -o $dom 1000
24496         lctl set_param -n mdc.*.stats=clear
24497         smalliomany -w $dom 1000 200
24498         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24499         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24500         # for OPEN and IO lock.
24501         [ $((enq - enq_2)) -ge 1000 ] ||
24502                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24503         unlinkmany $dom 1000
24504         return 0
24505 }
24506 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24507
24508 cleanup_271def_tests() {
24509         trap 0
24510         rm -f $1
24511 }
24512
24513 test_271d() {
24514         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24515                 skip "Need MDS version at least 2.10.57"
24516
24517         local dom=$DIR/$tdir/dom
24518         local tmp=$TMP/$tfile
24519         trap "cleanup_271def_tests $tmp" EXIT
24520
24521         mkdir -p $DIR/$tdir
24522
24523         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24524
24525         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24526
24527         cancel_lru_locks mdc
24528         dd if=/dev/urandom of=$tmp bs=1000 count=1
24529         dd if=$tmp of=$dom bs=1000 count=1
24530         cancel_lru_locks mdc
24531
24532         cat /etc/hosts >> $tmp
24533         lctl set_param -n mdc.*.stats=clear
24534
24535         # append data to the same file it should update local page
24536         echo "Append to the same page"
24537         cat /etc/hosts >> $dom
24538         local num=$(get_mdc_stats $mdtidx ost_read)
24539         local ra=$(get_mdc_stats $mdtidx req_active)
24540         local rw=$(get_mdc_stats $mdtidx req_waittime)
24541
24542         [ -z $num ] || error "$num READ RPC occured"
24543         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24544         echo "... DONE"
24545
24546         # compare content
24547         cmp $tmp $dom || error "file miscompare"
24548
24549         cancel_lru_locks mdc
24550         lctl set_param -n mdc.*.stats=clear
24551
24552         echo "Open and read file"
24553         cat $dom > /dev/null
24554         local num=$(get_mdc_stats $mdtidx ost_read)
24555         local ra=$(get_mdc_stats $mdtidx req_active)
24556         local rw=$(get_mdc_stats $mdtidx req_waittime)
24557
24558         [ -z $num ] || error "$num READ RPC occured"
24559         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24560         echo "... DONE"
24561
24562         # compare content
24563         cmp $tmp $dom || error "file miscompare"
24564
24565         return 0
24566 }
24567 run_test 271d "DoM: read on open (1K file in reply buffer)"
24568
24569 test_271f() {
24570         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24571                 skip "Need MDS version at least 2.10.57"
24572
24573         local dom=$DIR/$tdir/dom
24574         local tmp=$TMP/$tfile
24575         trap "cleanup_271def_tests $tmp" EXIT
24576
24577         mkdir -p $DIR/$tdir
24578
24579         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24580
24581         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24582
24583         cancel_lru_locks mdc
24584         dd if=/dev/urandom of=$tmp bs=265000 count=1
24585         dd if=$tmp of=$dom bs=265000 count=1
24586         cancel_lru_locks mdc
24587         cat /etc/hosts >> $tmp
24588         lctl set_param -n mdc.*.stats=clear
24589
24590         echo "Append to the same page"
24591         cat /etc/hosts >> $dom
24592         local num=$(get_mdc_stats $mdtidx ost_read)
24593         local ra=$(get_mdc_stats $mdtidx req_active)
24594         local rw=$(get_mdc_stats $mdtidx req_waittime)
24595
24596         [ -z $num ] || error "$num READ RPC occured"
24597         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24598         echo "... DONE"
24599
24600         # compare content
24601         cmp $tmp $dom || error "file miscompare"
24602
24603         cancel_lru_locks mdc
24604         lctl set_param -n mdc.*.stats=clear
24605
24606         echo "Open and read file"
24607         cat $dom > /dev/null
24608         local num=$(get_mdc_stats $mdtidx ost_read)
24609         local ra=$(get_mdc_stats $mdtidx req_active)
24610         local rw=$(get_mdc_stats $mdtidx req_waittime)
24611
24612         [ -z $num ] && num=0
24613         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24614         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24615         echo "... DONE"
24616
24617         # compare content
24618         cmp $tmp $dom || error "file miscompare"
24619
24620         return 0
24621 }
24622 run_test 271f "DoM: read on open (200K file and read tail)"
24623
24624 test_271g() {
24625         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24626                 skip "Skipping due to old client or server version"
24627
24628         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24629         # to get layout
24630         $CHECKSTAT -t file $DIR1/$tfile
24631
24632         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24633         MULTIOP_PID=$!
24634         sleep 1
24635         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24636         $LCTL set_param fail_loc=0x80000314
24637         rm $DIR1/$tfile || error "Unlink fails"
24638         RC=$?
24639         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24640         [ $RC -eq 0 ] || error "Failed write to stale object"
24641 }
24642 run_test 271g "Discard DoM data vs client flush race"
24643
24644 test_272a() {
24645         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24646                 skip "Need MDS version at least 2.11.50"
24647
24648         local dom=$DIR/$tdir/dom
24649         mkdir -p $DIR/$tdir
24650
24651         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24652         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24653                 error "failed to write data into $dom"
24654         local old_md5=$(md5sum $dom)
24655
24656         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24657                 error "failed to migrate to the same DoM component"
24658
24659         local new_md5=$(md5sum $dom)
24660
24661         [ "$old_md5" == "$new_md5" ] ||
24662                 error "md5sum differ: $old_md5, $new_md5"
24663
24664         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24665                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24666 }
24667 run_test 272a "DoM migration: new layout with the same DOM component"
24668
24669 test_272b() {
24670         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24671                 skip "Need MDS version at least 2.11.50"
24672
24673         local dom=$DIR/$tdir/dom
24674         mkdir -p $DIR/$tdir
24675         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24676         stack_trap "rm -rf $DIR/$tdir"
24677
24678         local mdtidx=$($LFS getstripe -m $dom)
24679         local mdtname=MDT$(printf %04x $mdtidx)
24680         local facet=mds$((mdtidx + 1))
24681
24682         local mdtfree1=$(do_facet $facet \
24683                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24684         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24685                 error "failed to write data into $dom"
24686         local old_md5=$(md5sum $dom)
24687         cancel_lru_locks mdc
24688         local mdtfree1=$(do_facet $facet \
24689                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24690
24691         $LFS migrate -c2 $dom ||
24692                 error "failed to migrate to the new composite layout"
24693         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24694                 error "MDT stripe was not removed"
24695         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24696                 error "$dir1 shouldn't have DATAVER EA"
24697
24698         cancel_lru_locks mdc
24699         local new_md5=$(md5sum $dom)
24700         [ "$old_md5" == "$new_md5" ] ||
24701                 error "$old_md5 != $new_md5"
24702
24703         # Skip free space checks with ZFS
24704         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24705                 local mdtfree2=$(do_facet $facet \
24706                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24707                 [ $mdtfree2 -gt $mdtfree1 ] ||
24708                         error "MDT space is not freed after migration"
24709         fi
24710         return 0
24711 }
24712 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24713
24714 test_272c() {
24715         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24716                 skip "Need MDS version at least 2.11.50"
24717
24718         local dom=$DIR/$tdir/$tfile
24719         mkdir -p $DIR/$tdir
24720         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24721         stack_trap "rm -rf $DIR/$tdir"
24722
24723         local mdtidx=$($LFS getstripe -m $dom)
24724         local mdtname=MDT$(printf %04x $mdtidx)
24725         local facet=mds$((mdtidx + 1))
24726
24727         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24728                 error "failed to write data into $dom"
24729         local old_md5=$(md5sum $dom)
24730         cancel_lru_locks mdc
24731         local mdtfree1=$(do_facet $facet \
24732                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24733
24734         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24735                 error "failed to migrate to the new composite layout"
24736         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24737                 error "MDT stripe was not removed"
24738
24739         cancel_lru_locks mdc
24740         local new_md5=$(md5sum $dom)
24741         [ "$old_md5" == "$new_md5" ] ||
24742                 error "$old_md5 != $new_md5"
24743
24744         # Skip free space checks with ZFS
24745         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24746                 local mdtfree2=$(do_facet $facet \
24747                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24748                 [ $mdtfree2 -gt $mdtfree1 ] ||
24749                         error "MDS space is not freed after migration"
24750         fi
24751         return 0
24752 }
24753 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24754
24755 test_272d() {
24756         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24757                 skip "Need MDS version at least 2.12.55"
24758
24759         local dom=$DIR/$tdir/$tfile
24760         mkdir -p $DIR/$tdir
24761         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24762
24763         local mdtidx=$($LFS getstripe -m $dom)
24764         local mdtname=MDT$(printf %04x $mdtidx)
24765         local facet=mds$((mdtidx + 1))
24766
24767         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24768                 error "failed to write data into $dom"
24769         local old_md5=$(md5sum $dom)
24770         cancel_lru_locks mdc
24771         local mdtfree1=$(do_facet $facet \
24772                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24773
24774         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24775                 error "failed mirroring to the new composite layout"
24776         $LFS mirror resync $dom ||
24777                 error "failed mirror resync"
24778         $LFS mirror split --mirror-id 1 -d $dom ||
24779                 error "failed mirror split"
24780
24781         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24782                 error "MDT stripe was not removed"
24783
24784         cancel_lru_locks mdc
24785         local new_md5=$(md5sum $dom)
24786         [ "$old_md5" == "$new_md5" ] ||
24787                 error "$old_md5 != $new_md5"
24788
24789         # Skip free space checks with ZFS
24790         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24791                 local mdtfree2=$(do_facet $facet \
24792                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24793                 [ $mdtfree2 -gt $mdtfree1 ] ||
24794                         error "MDS space is not freed after DOM mirror deletion"
24795         fi
24796         return 0
24797 }
24798 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24799
24800 test_272e() {
24801         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24802                 skip "Need MDS version at least 2.12.55"
24803
24804         local dom=$DIR/$tdir/$tfile
24805         mkdir -p $DIR/$tdir
24806         $LFS setstripe -c 2 $dom
24807
24808         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24809                 error "failed to write data into $dom"
24810         local old_md5=$(md5sum $dom)
24811         cancel_lru_locks
24812
24813         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24814                 error "failed mirroring to the DOM layout"
24815         $LFS mirror resync $dom ||
24816                 error "failed mirror resync"
24817         $LFS mirror split --mirror-id 1 -d $dom ||
24818                 error "failed mirror split"
24819
24820         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24821                 error "MDT stripe wasn't set"
24822
24823         cancel_lru_locks
24824         local new_md5=$(md5sum $dom)
24825         [ "$old_md5" == "$new_md5" ] ||
24826                 error "$old_md5 != $new_md5"
24827
24828         return 0
24829 }
24830 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24831
24832 test_272f() {
24833         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24834                 skip "Need MDS version at least 2.12.55"
24835
24836         local dom=$DIR/$tdir/$tfile
24837         mkdir -p $DIR/$tdir
24838         $LFS setstripe -c 2 $dom
24839
24840         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24841                 error "failed to write data into $dom"
24842         local old_md5=$(md5sum $dom)
24843         cancel_lru_locks
24844
24845         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24846                 error "failed migrating to the DOM file"
24847
24848         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24849                 error "MDT stripe wasn't set"
24850
24851         cancel_lru_locks
24852         local new_md5=$(md5sum $dom)
24853         [ "$old_md5" != "$new_md5" ] &&
24854                 error "$old_md5 != $new_md5"
24855
24856         return 0
24857 }
24858 run_test 272f "DoM migration: OST-striped file to DOM file"
24859
24860 test_273a() {
24861         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24862                 skip "Need MDS version at least 2.11.50"
24863
24864         # Layout swap cannot be done if either file has DOM component,
24865         # this will never be supported, migration should be used instead
24866
24867         local dom=$DIR/$tdir/$tfile
24868         mkdir -p $DIR/$tdir
24869
24870         $LFS setstripe -c2 ${dom}_plain
24871         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24872         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24873                 error "can swap layout with DoM component"
24874         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24875                 error "can swap layout with DoM component"
24876
24877         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24878         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24879                 error "can swap layout with DoM component"
24880         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24881                 error "can swap layout with DoM component"
24882         return 0
24883 }
24884 run_test 273a "DoM: layout swapping should fail with DOM"
24885
24886 test_273b() {
24887         mkdir -p $DIR/$tdir
24888         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24889
24890 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24891         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24892
24893         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24894 }
24895 run_test 273b "DoM: race writeback and object destroy"
24896
24897 test_273c() {
24898         mkdir -p $DIR/$tdir
24899         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24900
24901         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24902         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24903
24904         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24905 }
24906 run_test 273c "race writeback and object destroy"
24907
24908 test_275() {
24909         remote_ost_nodsh && skip "remote OST with nodsh"
24910         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24911                 skip "Need OST version >= 2.10.57"
24912
24913         local file=$DIR/$tfile
24914         local oss
24915
24916         oss=$(comma_list $(osts_nodes))
24917
24918         dd if=/dev/urandom of=$file bs=1M count=2 ||
24919                 error "failed to create a file"
24920         stack_trap "rm -f $file"
24921         cancel_lru_locks osc
24922
24923         #lock 1
24924         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24925                 error "failed to read a file"
24926
24927 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24928         $LCTL set_param fail_loc=0x8000031f
24929
24930         cancel_lru_locks osc &
24931         sleep 1
24932
24933 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24934         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24935         #IO takes another lock, but matches the PENDING one
24936         #and places it to the IO RPC
24937         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24938                 error "failed to read a file with PENDING lock"
24939 }
24940 run_test 275 "Read on a canceled duplicate lock"
24941
24942 test_276() {
24943         remote_ost_nodsh && skip "remote OST with nodsh"
24944         local pid
24945
24946         do_facet ost1 "(while true; do \
24947                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24948                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24949         pid=$!
24950
24951         for LOOP in $(seq 20); do
24952                 stop ost1
24953                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24954         done
24955         kill -9 $pid
24956         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24957                 rm $TMP/sanity_276_pid"
24958 }
24959 run_test 276 "Race between mount and obd_statfs"
24960
24961 test_277() {
24962         $LCTL set_param ldlm.namespaces.*.lru_size=0
24963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24964         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24965                         grep ^used_mb | awk '{print $2}')
24966         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24967         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24968                 oflag=direct conv=notrunc
24969         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24970                         grep ^used_mb | awk '{print $2}')
24971         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24972 }
24973 run_test 277 "Direct IO shall drop page cache"
24974
24975 test_278() {
24976         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24977         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24978         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24979                 skip "needs the same host for mdt1 mdt2" && return
24980
24981         local pid1
24982         local pid2
24983
24984 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24985         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24986         stop mds2 &
24987         pid2=$!
24988
24989         stop mds1
24990
24991         echo "Starting MDTs"
24992         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24993         wait $pid2
24994 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24995 #will return NULL
24996         do_facet mds2 $LCTL set_param fail_loc=0
24997
24998         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24999         wait_recovery_complete mds2
25000 }
25001 run_test 278 "Race starting MDS between MDTs stop/start"
25002
25003 test_280() {
25004         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25005                 skip "Need MGS version at least 2.13.52"
25006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25007         combined_mgs_mds || skip "needs combined MGS/MDT"
25008
25009         umount_client $MOUNT
25010 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25011         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25012
25013         mount_client $MOUNT &
25014         sleep 1
25015         stop mgs || error "stop mgs failed"
25016         #for a race mgs would crash
25017         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25018         # make sure we unmount client before remounting
25019         wait
25020         umount_client $MOUNT
25021         mount_client $MOUNT || error "mount client failed"
25022 }
25023 run_test 280 "Race between MGS umount and client llog processing"
25024
25025 cleanup_test_300() {
25026         trap 0
25027         umask $SAVE_UMASK
25028 }
25029 test_striped_dir() {
25030         local mdt_index=$1
25031         local stripe_count
25032         local stripe_index
25033
25034         mkdir -p $DIR/$tdir
25035
25036         SAVE_UMASK=$(umask)
25037         trap cleanup_test_300 RETURN EXIT
25038
25039         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25040                                                 $DIR/$tdir/striped_dir ||
25041                 error "set striped dir error"
25042
25043         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25044         [ "$mode" = "755" ] || error "expect 755 got $mode"
25045
25046         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25047                 error "getdirstripe failed"
25048         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25049         if [ "$stripe_count" != "2" ]; then
25050                 error "1:stripe_count is $stripe_count, expect 2"
25051         fi
25052         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25053         if [ "$stripe_count" != "2" ]; then
25054                 error "2:stripe_count is $stripe_count, expect 2"
25055         fi
25056
25057         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25058         if [ "$stripe_index" != "$mdt_index" ]; then
25059                 error "stripe_index is $stripe_index, expect $mdt_index"
25060         fi
25061
25062         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25063                 error "nlink error after create striped dir"
25064
25065         mkdir $DIR/$tdir/striped_dir/a
25066         mkdir $DIR/$tdir/striped_dir/b
25067
25068         stat $DIR/$tdir/striped_dir/a ||
25069                 error "create dir under striped dir failed"
25070         stat $DIR/$tdir/striped_dir/b ||
25071                 error "create dir under striped dir failed"
25072
25073         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25074                 error "nlink error after mkdir"
25075
25076         rmdir $DIR/$tdir/striped_dir/a
25077         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25078                 error "nlink error after rmdir"
25079
25080         rmdir $DIR/$tdir/striped_dir/b
25081         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25082                 error "nlink error after rmdir"
25083
25084         chattr +i $DIR/$tdir/striped_dir
25085         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25086                 error "immutable flags not working under striped dir!"
25087         chattr -i $DIR/$tdir/striped_dir
25088
25089         rmdir $DIR/$tdir/striped_dir ||
25090                 error "rmdir striped dir error"
25091
25092         cleanup_test_300
25093
25094         true
25095 }
25096
25097 test_300a() {
25098         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25099                 skip "skipped for lustre < 2.7.0"
25100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25102
25103         test_striped_dir 0 || error "failed on striped dir on MDT0"
25104         test_striped_dir 1 || error "failed on striped dir on MDT0"
25105 }
25106 run_test 300a "basic striped dir sanity test"
25107
25108 test_300b() {
25109         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25110                 skip "skipped for lustre < 2.7.0"
25111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25113
25114         local i
25115         local mtime1
25116         local mtime2
25117         local mtime3
25118
25119         test_mkdir $DIR/$tdir || error "mkdir fail"
25120         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25121                 error "set striped dir error"
25122         for i in {0..9}; do
25123                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25124                 sleep 1
25125                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25126                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25127                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25128                 sleep 1
25129                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25130                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25131                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25132         done
25133         true
25134 }
25135 run_test 300b "check ctime/mtime for striped dir"
25136
25137 test_300c() {
25138         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25139                 skip "skipped for lustre < 2.7.0"
25140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25142
25143         local file_count
25144
25145         mkdir_on_mdt0 $DIR/$tdir
25146         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25147                 error "set striped dir error"
25148
25149         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25150                 error "chown striped dir failed"
25151
25152         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25153                 error "create 5k files failed"
25154
25155         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25156
25157         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25158
25159         rm -rf $DIR/$tdir
25160 }
25161 run_test 300c "chown && check ls under striped directory"
25162
25163 test_300d() {
25164         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25165                 skip "skipped for lustre < 2.7.0"
25166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25168
25169         local stripe_count
25170         local file
25171
25172         mkdir -p $DIR/$tdir
25173         $LFS setstripe -c 2 $DIR/$tdir
25174
25175         #local striped directory
25176         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25177                 error "set striped dir error"
25178         #look at the directories for debug purposes
25179         ls -l $DIR/$tdir
25180         $LFS getdirstripe $DIR/$tdir
25181         ls -l $DIR/$tdir/striped_dir
25182         $LFS getdirstripe $DIR/$tdir/striped_dir
25183         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25184                 error "create 10 files failed"
25185
25186         #remote striped directory
25187         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25188                 error "set striped dir error"
25189         #look at the directories for debug purposes
25190         ls -l $DIR/$tdir
25191         $LFS getdirstripe $DIR/$tdir
25192         ls -l $DIR/$tdir/remote_striped_dir
25193         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25194         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25195                 error "create 10 files failed"
25196
25197         for file in $(find $DIR/$tdir); do
25198                 stripe_count=$($LFS getstripe -c $file)
25199                 [ $stripe_count -eq 2 ] ||
25200                         error "wrong stripe $stripe_count for $file"
25201         done
25202
25203         rm -rf $DIR/$tdir
25204 }
25205 run_test 300d "check default stripe under striped directory"
25206
25207 test_300e() {
25208         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25209                 skip "Need MDS version at least 2.7.55"
25210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25212
25213         local stripe_count
25214         local file
25215
25216         mkdir -p $DIR/$tdir
25217
25218         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25219                 error "set striped dir error"
25220
25221         touch $DIR/$tdir/striped_dir/a
25222         touch $DIR/$tdir/striped_dir/b
25223         touch $DIR/$tdir/striped_dir/c
25224
25225         mkdir $DIR/$tdir/striped_dir/dir_a
25226         mkdir $DIR/$tdir/striped_dir/dir_b
25227         mkdir $DIR/$tdir/striped_dir/dir_c
25228
25229         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25230                 error "set striped adir under striped dir error"
25231
25232         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25233                 error "set striped bdir under striped dir error"
25234
25235         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25236                 error "set striped cdir under striped dir error"
25237
25238         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25239                 error "rename dir under striped dir fails"
25240
25241         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25242                 error "rename dir under different stripes fails"
25243
25244         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25245                 error "rename file under striped dir should succeed"
25246
25247         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25248                 error "rename dir under striped dir should succeed"
25249
25250         rm -rf $DIR/$tdir
25251 }
25252 run_test 300e "check rename under striped directory"
25253
25254 test_300f() {
25255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25258                 skip "Need MDS version at least 2.7.55"
25259
25260         local stripe_count
25261         local file
25262
25263         rm -rf $DIR/$tdir
25264         mkdir -p $DIR/$tdir
25265
25266         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25267                 error "set striped dir error"
25268
25269         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25270                 error "set striped dir error"
25271
25272         touch $DIR/$tdir/striped_dir/a
25273         mkdir $DIR/$tdir/striped_dir/dir_a
25274         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25275                 error "create striped dir under striped dir fails"
25276
25277         touch $DIR/$tdir/striped_dir1/b
25278         mkdir $DIR/$tdir/striped_dir1/dir_b
25279         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25280                 error "create striped dir under striped dir fails"
25281
25282         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25283                 error "rename dir under different striped dir should fail"
25284
25285         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25286                 error "rename striped dir under diff striped dir should fail"
25287
25288         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25289                 error "rename file under diff striped dirs fails"
25290
25291         rm -rf $DIR/$tdir
25292 }
25293 run_test 300f "check rename cross striped directory"
25294
25295 test_300_check_default_striped_dir()
25296 {
25297         local dirname=$1
25298         local default_count=$2
25299         local default_index=$3
25300         local stripe_count
25301         local stripe_index
25302         local dir_stripe_index
25303         local dir
25304
25305         echo "checking $dirname $default_count $default_index"
25306         $LFS setdirstripe -D -c $default_count -i $default_index \
25307                                 -H all_char $DIR/$tdir/$dirname ||
25308                 error "set default stripe on striped dir error"
25309         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25310         [ $stripe_count -eq $default_count ] ||
25311                 error "expect $default_count get $stripe_count for $dirname"
25312
25313         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25314         [ $stripe_index -eq $default_index ] ||
25315                 error "expect $default_index get $stripe_index for $dirname"
25316
25317         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25318                                                 error "create dirs failed"
25319
25320         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25321         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25322         for dir in $(find $DIR/$tdir/$dirname/*); do
25323                 stripe_count=$($LFS getdirstripe -c $dir)
25324                 (( $stripe_count == $default_count )) ||
25325                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25326                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25327                 error "stripe count $default_count != $stripe_count for $dir"
25328
25329                 stripe_index=$($LFS getdirstripe -i $dir)
25330                 [ $default_index -eq -1 ] ||
25331                         [ $stripe_index -eq $default_index ] ||
25332                         error "$stripe_index != $default_index for $dir"
25333
25334                 #check default stripe
25335                 stripe_count=$($LFS getdirstripe -D -c $dir)
25336                 [ $stripe_count -eq $default_count ] ||
25337                 error "default count $default_count != $stripe_count for $dir"
25338
25339                 stripe_index=$($LFS getdirstripe -D -i $dir)
25340                 [ $stripe_index -eq $default_index ] ||
25341                 error "default index $default_index != $stripe_index for $dir"
25342         done
25343         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25344 }
25345
25346 test_300g() {
25347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25348         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25349                 skip "Need MDS version at least 2.7.55"
25350
25351         local dir
25352         local stripe_count
25353         local stripe_index
25354
25355         mkdir_on_mdt0 $DIR/$tdir
25356         mkdir $DIR/$tdir/normal_dir
25357
25358         #Checking when client cache stripe index
25359         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25360         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25361                 error "create striped_dir failed"
25362
25363         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25364                 error "create dir0 fails"
25365         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25366         [ $stripe_index -eq 0 ] ||
25367                 error "dir0 expect index 0 got $stripe_index"
25368
25369         mkdir $DIR/$tdir/striped_dir/dir1 ||
25370                 error "create dir1 fails"
25371         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25372         [ $stripe_index -eq 1 ] ||
25373                 error "dir1 expect index 1 got $stripe_index"
25374
25375         #check default stripe count/stripe index
25376         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25377         test_300_check_default_striped_dir normal_dir 1 0
25378         test_300_check_default_striped_dir normal_dir -1 1
25379         test_300_check_default_striped_dir normal_dir 2 -1
25380
25381         #delete default stripe information
25382         echo "delete default stripeEA"
25383         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25384                 error "set default stripe on striped dir error"
25385
25386         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25387         for dir in $(find $DIR/$tdir/normal_dir/*); do
25388                 stripe_count=$($LFS getdirstripe -c $dir)
25389                 [ $stripe_count -eq 0 ] ||
25390                         error "expect 1 get $stripe_count for $dir"
25391         done
25392 }
25393 run_test 300g "check default striped directory for normal directory"
25394
25395 test_300h() {
25396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25397         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25398                 skip "Need MDS version at least 2.7.55"
25399
25400         local dir
25401         local stripe_count
25402
25403         mkdir $DIR/$tdir
25404         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25405                 error "set striped dir error"
25406
25407         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25408         test_300_check_default_striped_dir striped_dir 1 0
25409         test_300_check_default_striped_dir striped_dir -1 1
25410         test_300_check_default_striped_dir striped_dir 2 -1
25411
25412         #delete default stripe information
25413         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25414                 error "set default stripe on striped dir error"
25415
25416         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25417         for dir in $(find $DIR/$tdir/striped_dir/*); do
25418                 stripe_count=$($LFS getdirstripe -c $dir)
25419                 [ $stripe_count -eq 0 ] ||
25420                         error "expect 1 get $stripe_count for $dir"
25421         done
25422 }
25423 run_test 300h "check default striped directory for striped directory"
25424
25425 test_300i() {
25426         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25427         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25428         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25429                 skip "Need MDS version at least 2.7.55"
25430
25431         local stripe_count
25432         local file
25433
25434         mkdir $DIR/$tdir
25435
25436         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25437                 error "set striped dir error"
25438
25439         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25440                 error "create files under striped dir failed"
25441
25442         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25443                 error "set striped hashdir error"
25444
25445         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25446                 error "create dir0 under hash dir failed"
25447         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25448                 error "create dir1 under hash dir failed"
25449         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25450                 error "create dir2 under hash dir failed"
25451
25452         # unfortunately, we need to umount to clear dir layout cache for now
25453         # once we fully implement dir layout, we can drop this
25454         umount_client $MOUNT || error "umount failed"
25455         mount_client $MOUNT || error "mount failed"
25456
25457         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25458         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25459         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25460
25461         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25462                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25463                         error "create crush2 dir $tdir/hashdir/d3 failed"
25464                 $LFS find -H crush2 $DIR/$tdir/hashdir
25465                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25466                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25467
25468                 # mkdir with an invalid hash type (hash=fail_val) from client
25469                 # should be replaced on MDS with a valid (default) hash type
25470                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25471                 $LCTL set_param fail_loc=0x1901 fail_val=99
25472                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25473
25474                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25475                 local expect=$(do_facet mds1 \
25476                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25477                 [[ $hash == $expect ]] ||
25478                         error "d99 hash '$hash' != expected hash '$expect'"
25479         fi
25480
25481         #set the stripe to be unknown hash type on read
25482         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25483         $LCTL set_param fail_loc=0x1901 fail_val=99
25484         for ((i = 0; i < 10; i++)); do
25485                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25486                         error "stat f-$i failed"
25487                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25488         done
25489
25490         touch $DIR/$tdir/striped_dir/f0 &&
25491                 error "create under striped dir with unknown hash should fail"
25492
25493         $LCTL set_param fail_loc=0
25494
25495         umount_client $MOUNT || error "umount failed"
25496         mount_client $MOUNT || error "mount failed"
25497
25498         return 0
25499 }
25500 run_test 300i "client handle unknown hash type striped directory"
25501
25502 test_300j() {
25503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25505         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25506                 skip "Need MDS version at least 2.7.55"
25507
25508         local stripe_count
25509         local file
25510
25511         mkdir $DIR/$tdir
25512
25513         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25514         $LCTL set_param fail_loc=0x1702
25515         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25516                 error "set striped dir error"
25517
25518         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25519                 error "create files under striped dir failed"
25520
25521         $LCTL set_param fail_loc=0
25522
25523         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25524
25525         return 0
25526 }
25527 run_test 300j "test large update record"
25528
25529 test_300k() {
25530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25531         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25532         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25533                 skip "Need MDS version at least 2.7.55"
25534
25535         # this test needs a huge transaction
25536         local kb
25537         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25538              osd*.$FSNAME-MDT0000.kbytestotal")
25539         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25540
25541         local stripe_count
25542         local file
25543
25544         mkdir $DIR/$tdir
25545
25546         #define OBD_FAIL_LARGE_STRIPE   0x1703
25547         $LCTL set_param fail_loc=0x1703
25548         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25549                 error "set striped dir error"
25550         $LCTL set_param fail_loc=0
25551
25552         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25553                 error "getstripeddir fails"
25554         rm -rf $DIR/$tdir/striped_dir ||
25555                 error "unlink striped dir fails"
25556
25557         return 0
25558 }
25559 run_test 300k "test large striped directory"
25560
25561 test_300l() {
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 stripe_index
25568
25569         test_mkdir -p $DIR/$tdir/striped_dir
25570         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25571                         error "chown $RUNAS_ID failed"
25572         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25573                 error "set default striped dir failed"
25574
25575         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25576         $LCTL set_param fail_loc=0x80000158
25577         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25578
25579         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25580         [ $stripe_index -eq 1 ] ||
25581                 error "expect 1 get $stripe_index for $dir"
25582 }
25583 run_test 300l "non-root user to create dir under striped dir with stale layout"
25584
25585 test_300m() {
25586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25587         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25588         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25589                 skip "Need MDS version at least 2.7.55"
25590
25591         mkdir -p $DIR/$tdir/striped_dir
25592         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25593                 error "set default stripes dir error"
25594
25595         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25596
25597         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25598         [ $stripe_count -eq 0 ] ||
25599                         error "expect 0 get $stripe_count for a"
25600
25601         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25602                 error "set default stripes dir error"
25603
25604         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25605
25606         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25607         [ $stripe_count -eq 0 ] ||
25608                         error "expect 0 get $stripe_count for b"
25609
25610         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25611                 error "set default stripes dir error"
25612
25613         mkdir $DIR/$tdir/striped_dir/c &&
25614                 error "default stripe_index is invalid, mkdir c should fails"
25615
25616         rm -rf $DIR/$tdir || error "rmdir fails"
25617 }
25618 run_test 300m "setstriped directory on single MDT FS"
25619
25620 cleanup_300n() {
25621         local list=$(comma_list $(mdts_nodes))
25622
25623         trap 0
25624         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25625 }
25626
25627 test_300n() {
25628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25630         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25631                 skip "Need MDS version at least 2.7.55"
25632         remote_mds_nodsh && skip "remote MDS with nodsh"
25633
25634         local stripe_index
25635         local list=$(comma_list $(mdts_nodes))
25636
25637         trap cleanup_300n RETURN EXIT
25638         mkdir -p $DIR/$tdir
25639         chmod 777 $DIR/$tdir
25640         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25641                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25642                 error "create striped dir succeeds with gid=0"
25643
25644         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25645         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25646                 error "create striped dir fails with gid=-1"
25647
25648         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25649         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25650                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25651                 error "set default striped dir succeeds with gid=0"
25652
25653
25654         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25655         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25656                 error "set default striped dir fails with gid=-1"
25657
25658
25659         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25660         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25661                                         error "create test_dir fails"
25662         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25663                                         error "create test_dir1 fails"
25664         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25665                                         error "create test_dir2 fails"
25666         cleanup_300n
25667 }
25668 run_test 300n "non-root user to create dir under striped dir with default EA"
25669
25670 test_300o() {
25671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25673         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25674                 skip "Need MDS version at least 2.7.55"
25675
25676         local numfree1
25677         local numfree2
25678
25679         mkdir -p $DIR/$tdir
25680
25681         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25682         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25683         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25684                 skip "not enough free inodes $numfree1 $numfree2"
25685         fi
25686
25687         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25688         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25689         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25690                 skip "not enough free space $numfree1 $numfree2"
25691         fi
25692
25693         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25694                 error "setdirstripe fails"
25695
25696         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25697                 error "create dirs fails"
25698
25699         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25700         ls $DIR/$tdir/striped_dir > /dev/null ||
25701                 error "ls striped dir fails"
25702         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25703                 error "unlink big striped dir fails"
25704 }
25705 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25706
25707 test_300p() {
25708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25710         remote_mds_nodsh && skip "remote MDS with nodsh"
25711
25712         mkdir_on_mdt0 $DIR/$tdir
25713
25714         #define OBD_FAIL_OUT_ENOSPC     0x1704
25715         do_facet mds2 lctl set_param fail_loc=0x80001704
25716         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25717                  && error "create striped directory should fail"
25718
25719         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25720
25721         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25722         true
25723 }
25724 run_test 300p "create striped directory without space"
25725
25726 test_300q() {
25727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25728         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25729
25730         local fd=$(free_fd)
25731         local cmd="exec $fd<$tdir"
25732         cd $DIR
25733         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25734         eval $cmd
25735         cmd="exec $fd<&-"
25736         trap "eval $cmd" EXIT
25737         cd $tdir || error "cd $tdir fails"
25738         rmdir  ../$tdir || error "rmdir $tdir fails"
25739         mkdir local_dir && error "create dir succeeds"
25740         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25741         eval $cmd
25742         return 0
25743 }
25744 run_test 300q "create remote directory under orphan directory"
25745
25746 test_300r() {
25747         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25748                 skip "Need MDS version at least 2.7.55" && return
25749         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25750
25751         mkdir $DIR/$tdir
25752
25753         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25754                 error "set striped dir error"
25755
25756         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25757                 error "getstripeddir fails"
25758
25759         local stripe_count
25760         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25761                       awk '/lmv_stripe_count:/ { print $2 }')
25762
25763         [ $MDSCOUNT -ne $stripe_count ] &&
25764                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25765
25766         rm -rf $DIR/$tdir/striped_dir ||
25767                 error "unlink striped dir fails"
25768 }
25769 run_test 300r "test -1 striped directory"
25770
25771 test_300s_helper() {
25772         local count=$1
25773
25774         local stripe_dir=$DIR/$tdir/striped_dir.$count
25775
25776         $LFS mkdir -c $count $stripe_dir ||
25777                 error "lfs mkdir -c error"
25778
25779         $LFS getdirstripe $stripe_dir ||
25780                 error "lfs getdirstripe fails"
25781
25782         local stripe_count
25783         stripe_count=$($LFS getdirstripe $stripe_dir |
25784                       awk '/lmv_stripe_count:/ { print $2 }')
25785
25786         [ $count -ne $stripe_count ] &&
25787                 error_noexit "bad stripe count $stripe_count expected $count"
25788
25789         local dupe_stripes
25790         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25791                 awk '/0x/ {count[$1] += 1}; END {
25792                         for (idx in count) {
25793                                 if (count[idx]>1) {
25794                                         print "index " idx " count " count[idx]
25795                                 }
25796                         }
25797                 }')
25798
25799         if [[ -n "$dupe_stripes" ]] ; then
25800                 lfs getdirstripe $stripe_dir
25801                 error_noexit "Dupe MDT above: $dupe_stripes "
25802         fi
25803
25804         rm -rf $stripe_dir ||
25805                 error_noexit "unlink $stripe_dir fails"
25806 }
25807
25808 test_300s() {
25809         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25810                 skip "Need MDS version at least 2.7.55" && return
25811         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25812
25813         mkdir $DIR/$tdir
25814         for count in $(seq 2 $MDSCOUNT); do
25815                 test_300s_helper $count
25816         done
25817 }
25818 run_test 300s "test lfs mkdir -c without -i"
25819
25820 test_300t() {
25821         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25822                 skip "need MDS 2.14.55 or later"
25823         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25824
25825         local testdir="$DIR/$tdir/striped_dir"
25826         local dir1=$testdir/dir1
25827         local dir2=$testdir/dir2
25828
25829         mkdir -p $testdir
25830
25831         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25832                 error "failed to set default stripe count for $testdir"
25833
25834         mkdir $dir1
25835         local stripe_count=$($LFS getdirstripe -c $dir1)
25836
25837         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25838
25839         local max_count=$((MDSCOUNT - 1))
25840         local mdts=$(comma_list $(mdts_nodes))
25841
25842         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25843         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25844
25845         mkdir $dir2
25846         stripe_count=$($LFS getdirstripe -c $dir2)
25847
25848         (( $stripe_count == $max_count )) || error "wrong stripe count"
25849 }
25850 run_test 300t "test max_mdt_stripecount"
25851
25852 prepare_remote_file() {
25853         mkdir $DIR/$tdir/src_dir ||
25854                 error "create remote source failed"
25855
25856         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25857                  error "cp to remote source failed"
25858         touch $DIR/$tdir/src_dir/a
25859
25860         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25861                 error "create remote target dir failed"
25862
25863         touch $DIR/$tdir/tgt_dir/b
25864
25865         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25866                 error "rename dir cross MDT failed!"
25867
25868         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25869                 error "src_child still exists after rename"
25870
25871         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25872                 error "missing file(a) after rename"
25873
25874         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25875                 error "diff after rename"
25876 }
25877
25878 test_310a() {
25879         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25881
25882         local remote_file=$DIR/$tdir/tgt_dir/b
25883
25884         mkdir -p $DIR/$tdir
25885
25886         prepare_remote_file || error "prepare remote file failed"
25887
25888         #open-unlink file
25889         $OPENUNLINK $remote_file $remote_file ||
25890                 error "openunlink $remote_file failed"
25891         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25892 }
25893 run_test 310a "open unlink remote file"
25894
25895 test_310b() {
25896         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25898
25899         local remote_file=$DIR/$tdir/tgt_dir/b
25900
25901         mkdir -p $DIR/$tdir
25902
25903         prepare_remote_file || error "prepare remote file failed"
25904
25905         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25906         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25907         $CHECKSTAT -t file $remote_file || error "check file failed"
25908 }
25909 run_test 310b "unlink remote file with multiple links while open"
25910
25911 test_310c() {
25912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25913         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25914
25915         local remote_file=$DIR/$tdir/tgt_dir/b
25916
25917         mkdir -p $DIR/$tdir
25918
25919         prepare_remote_file || error "prepare remote file failed"
25920
25921         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25922         multiop_bg_pause $remote_file O_uc ||
25923                         error "mulitop failed for remote file"
25924         MULTIPID=$!
25925         $MULTIOP $DIR/$tfile Ouc
25926         kill -USR1 $MULTIPID
25927         wait $MULTIPID
25928 }
25929 run_test 310c "open-unlink remote file with multiple links"
25930
25931 #LU-4825
25932 test_311() {
25933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25934         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25935         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25936                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25937         remote_mds_nodsh && skip "remote MDS with nodsh"
25938
25939         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25940         local mdts=$(comma_list $(mdts_nodes))
25941
25942         mkdir -p $DIR/$tdir
25943         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25944         createmany -o $DIR/$tdir/$tfile. 1000
25945
25946         # statfs data is not real time, let's just calculate it
25947         old_iused=$((old_iused + 1000))
25948
25949         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25950                         osp.*OST0000*MDT0000.create_count")
25951         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25952                                 osp.*OST0000*MDT0000.max_create_count")
25953         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25954
25955         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25956         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25957         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25958
25959         unlinkmany $DIR/$tdir/$tfile. 1000
25960
25961         do_nodes $mdts "$LCTL set_param -n \
25962                         osp.*OST0000*.max_create_count=$max_count"
25963         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25964                 do_nodes $mdts "$LCTL set_param -n \
25965                                 osp.*OST0000*.create_count=$count"
25966         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25967                         grep "=0" && error "create_count is zero"
25968
25969         local new_iused
25970         for i in $(seq 120); do
25971                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25972                 # system may be too busy to destroy all objs in time, use
25973                 # a somewhat small value to not fail autotest
25974                 [ $((old_iused - new_iused)) -gt 400 ] && break
25975                 sleep 1
25976         done
25977
25978         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25979         [ $((old_iused - new_iused)) -gt 400 ] ||
25980                 error "objs not destroyed after unlink"
25981 }
25982 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25983
25984 zfs_get_objid()
25985 {
25986         local ost=$1
25987         local tf=$2
25988         local fid=($($LFS getstripe $tf | grep 0x))
25989         local seq=${fid[3]#0x}
25990         local objid=${fid[1]}
25991
25992         local vdevdir=$(dirname $(facet_vdevice $ost))
25993         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25994         local zfs_zapid=$(do_facet $ost $cmd |
25995                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25996                           awk '/Object/{getline; print $1}')
25997         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25998                           awk "/$objid = /"'{printf $3}')
25999
26000         echo $zfs_objid
26001 }
26002
26003 zfs_object_blksz() {
26004         local ost=$1
26005         local objid=$2
26006
26007         local vdevdir=$(dirname $(facet_vdevice $ost))
26008         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26009         local blksz=$(do_facet $ost $cmd $objid |
26010                       awk '/dblk/{getline; printf $4}')
26011
26012         case "${blksz: -1}" in
26013                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26014                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26015                 *) ;;
26016         esac
26017
26018         echo $blksz
26019 }
26020
26021 test_312() { # LU-4856
26022         remote_ost_nodsh && skip "remote OST with nodsh"
26023         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26024
26025         local max_blksz=$(do_facet ost1 \
26026                           $ZFS get -p recordsize $(facet_device ost1) |
26027                           awk '!/VALUE/{print $3}')
26028         local tf=$DIR/$tfile
26029
26030         $LFS setstripe -c1 $tf
26031         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26032
26033         # Get ZFS object id
26034         local zfs_objid=$(zfs_get_objid $facet $tf)
26035         # block size change by sequential overwrite
26036         local bs
26037
26038         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26039                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26040
26041                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26042                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26043         done
26044         rm -f $tf
26045
26046         $LFS setstripe -c1 $tf
26047         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26048
26049         # block size change by sequential append write
26050         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26051         zfs_objid=$(zfs_get_objid $facet $tf)
26052         local count
26053
26054         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26055                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26056                         oflag=sync conv=notrunc
26057
26058                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26059                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26060                         error "blksz error, actual $blksz, " \
26061                                 "expected: 2 * $count * $PAGE_SIZE"
26062         done
26063         rm -f $tf
26064
26065         # random write
26066         $LFS setstripe -c1 $tf
26067         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26068         zfs_objid=$(zfs_get_objid $facet $tf)
26069
26070         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26071         blksz=$(zfs_object_blksz $facet $zfs_objid)
26072         (( blksz == PAGE_SIZE )) ||
26073                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26074
26075         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26076         blksz=$(zfs_object_blksz $facet $zfs_objid)
26077         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26078
26079         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26080         blksz=$(zfs_object_blksz $facet $zfs_objid)
26081         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26082 }
26083 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26084
26085 test_313() {
26086         remote_ost_nodsh && skip "remote OST with nodsh"
26087
26088         local file=$DIR/$tfile
26089
26090         rm -f $file
26091         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26092
26093         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26094         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26095         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26096                 error "write should failed"
26097         do_facet ost1 "$LCTL set_param fail_loc=0"
26098         rm -f $file
26099 }
26100 run_test 313 "io should fail after last_rcvd update fail"
26101
26102 test_314() {
26103         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26104
26105         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26106         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26107         rm -f $DIR/$tfile
26108         wait_delete_completed
26109         do_facet ost1 "$LCTL set_param fail_loc=0"
26110 }
26111 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26112
26113 test_315() { # LU-618
26114         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26115
26116         local file=$DIR/$tfile
26117         rm -f $file
26118
26119         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26120                 error "multiop file write failed"
26121         $MULTIOP $file oO_RDONLY:r4063232_c &
26122         PID=$!
26123
26124         sleep 2
26125
26126         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26127         kill -USR1 $PID
26128
26129         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26130         rm -f $file
26131 }
26132 run_test 315 "read should be accounted"
26133
26134 test_316() {
26135         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26136         large_xattr_enabled || skip "ea_inode feature disabled"
26137
26138         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26139         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26140         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26141         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26142
26143         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26144 }
26145 run_test 316 "lfs migrate of file with large_xattr enabled"
26146
26147 test_317() {
26148         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26149                 skip "Need MDS version at least 2.11.53"
26150         if [ "$ost1_FSTYPE" == "zfs" ]; then
26151                 skip "LU-10370: no implementation for ZFS"
26152         fi
26153
26154         local trunc_sz
26155         local grant_blk_size
26156
26157         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26158                         awk '/grant_block_size:/ { print $2; exit; }')
26159         #
26160         # Create File of size 5M. Truncate it to below size's and verify
26161         # blocks count.
26162         #
26163         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26164                 error "Create file $DIR/$tfile failed"
26165         stack_trap "rm -f $DIR/$tfile" EXIT
26166
26167         for trunc_sz in 2097152 4097 4000 509 0; do
26168                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26169                         error "truncate $tfile to $trunc_sz failed"
26170                 local sz=$(stat --format=%s $DIR/$tfile)
26171                 local blk=$(stat --format=%b $DIR/$tfile)
26172                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26173                                      grant_blk_size) * 8))
26174
26175                 if [[ $blk -ne $trunc_blk ]]; then
26176                         $(which stat) $DIR/$tfile
26177                         error "Expected Block $trunc_blk got $blk for $tfile"
26178                 fi
26179
26180                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26181                         error "Expected Size $trunc_sz got $sz for $tfile"
26182         done
26183
26184         #
26185         # sparse file test
26186         # Create file with a hole and write actual 65536 bytes which aligned
26187         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26188         #
26189         local bs=65536
26190         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26191                 error "Create file : $DIR/$tfile"
26192
26193         #
26194         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26195         # blocks. The block count must drop to 8.
26196         #
26197         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26198                 ((bs - grant_blk_size) + 1)))
26199         $TRUNCATE $DIR/$tfile $trunc_sz ||
26200                 error "truncate $tfile to $trunc_sz failed"
26201
26202         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26203         sz=$(stat --format=%s $DIR/$tfile)
26204         blk=$(stat --format=%b $DIR/$tfile)
26205
26206         if [[ $blk -ne $trunc_bsz ]]; then
26207                 $(which stat) $DIR/$tfile
26208                 error "Expected Block $trunc_bsz got $blk for $tfile"
26209         fi
26210
26211         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26212                 error "Expected Size $trunc_sz got $sz for $tfile"
26213 }
26214 run_test 317 "Verify blocks get correctly update after truncate"
26215
26216 test_318() {
26217         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26218         local old_max_active=$($LCTL get_param -n \
26219                             ${llite_name}.max_read_ahead_async_active \
26220                             2>/dev/null)
26221
26222         $LCTL set_param llite.*.max_read_ahead_async_active=256
26223         local max_active=$($LCTL get_param -n \
26224                            ${llite_name}.max_read_ahead_async_active \
26225                            2>/dev/null)
26226         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26227
26228         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26229                 error "set max_read_ahead_async_active should succeed"
26230
26231         $LCTL set_param llite.*.max_read_ahead_async_active=512
26232         max_active=$($LCTL get_param -n \
26233                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26234         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26235
26236         # restore @max_active
26237         [ $old_max_active -ne 0 ] && $LCTL set_param \
26238                 llite.*.max_read_ahead_async_active=$old_max_active
26239
26240         local old_threshold=$($LCTL get_param -n \
26241                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26242         local max_per_file_mb=$($LCTL get_param -n \
26243                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26244
26245         local invalid=$(($max_per_file_mb + 1))
26246         $LCTL set_param \
26247                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26248                         && error "set $invalid should fail"
26249
26250         local valid=$(($invalid - 1))
26251         $LCTL set_param \
26252                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26253                         error "set $valid should succeed"
26254         local threshold=$($LCTL get_param -n \
26255                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26256         [ $threshold -eq $valid ] || error \
26257                 "expect threshold $valid got $threshold"
26258         $LCTL set_param \
26259                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26260 }
26261 run_test 318 "Verify async readahead tunables"
26262
26263 test_319() {
26264         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26265
26266         local before=$(date +%s)
26267         local evict
26268         local mdir=$DIR/$tdir
26269         local file=$mdir/xxx
26270
26271         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26272         touch $file
26273
26274 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26275         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26276         $LFS migrate -m1 $mdir &
26277
26278         sleep 1
26279         dd if=$file of=/dev/null
26280         wait
26281         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26282           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26283
26284         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26285 }
26286 run_test 319 "lost lease lock on migrate error"
26287
26288 test_398a() { # LU-4198
26289         local ost1_imp=$(get_osc_import_name client ost1)
26290         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26291                          cut -d'.' -f2)
26292
26293         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26294         stack_trap "rm -f $DIR/$tfile"
26295         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26296
26297         # request a new lock on client
26298         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26299
26300         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26301         local lock_count=$($LCTL get_param -n \
26302                            ldlm.namespaces.$imp_name.lru_size)
26303         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26304
26305         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26306
26307         # no lock cached, should use lockless DIO and not enqueue new lock
26308         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26309         lock_count=$($LCTL get_param -n \
26310                      ldlm.namespaces.$imp_name.lru_size)
26311         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26312
26313         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26314
26315         # no lock cached, should use locked DIO append
26316         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26317                 conv=notrunc || error "DIO append failed"
26318         lock_count=$($LCTL get_param -n \
26319                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26320         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26321 }
26322 run_test 398a "direct IO should cancel lock otherwise lockless"
26323
26324 test_398b() { # LU-4198
26325         local before=$(date +%s)
26326         local njobs=4
26327         local size=48
26328
26329         which fio || skip_env "no fio installed"
26330         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26331         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26332
26333         # Single page, multiple pages, stripe size, 4*stripe size
26334         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26335                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26336                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26337                         --numjobs=$njobs --fallocate=none \
26338                         --iodepth=16 --allow_file_create=0 \
26339                         --size=$((size/njobs))M \
26340                         --filename=$DIR/$tfile &
26341                 bg_pid=$!
26342
26343                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26344                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26345                         --numjobs=$njobs --fallocate=none \
26346                         --iodepth=16 --allow_file_create=0 \
26347                         --size=$((size/njobs))M \
26348                         --filename=$DIR/$tfile || true
26349                 wait $bg_pid
26350         done
26351
26352         evict=$(do_facet client $LCTL get_param \
26353                 osc.$FSNAME-OST*-osc-*/state |
26354             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26355
26356         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26357                 (do_facet client $LCTL get_param \
26358                         osc.$FSNAME-OST*-osc-*/state;
26359                     error "eviction happened: $evict before:$before")
26360
26361         rm -f $DIR/$tfile
26362 }
26363 run_test 398b "DIO and buffer IO race"
26364
26365 test_398c() { # LU-4198
26366         local ost1_imp=$(get_osc_import_name client ost1)
26367         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26368                          cut -d'.' -f2)
26369
26370         which fio || skip_env "no fio installed"
26371
26372         saved_debug=$($LCTL get_param -n debug)
26373         $LCTL set_param debug=0
26374
26375         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26376         ((size /= 1024)) # by megabytes
26377         ((size /= 2)) # write half of the OST at most
26378         [ $size -gt 40 ] && size=40 #reduce test time anyway
26379
26380         $LFS setstripe -c 1 $DIR/$tfile
26381
26382         # it seems like ldiskfs reserves more space than necessary if the
26383         # writing blocks are not mapped, so it extends the file firstly
26384         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26385         cancel_lru_locks osc
26386
26387         # clear and verify rpc_stats later
26388         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26389
26390         local njobs=4
26391         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26392         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26393                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26394                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26395                 --filename=$DIR/$tfile
26396         [ $? -eq 0 ] || error "fio write error"
26397
26398         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26399                 error "Locks were requested while doing AIO"
26400
26401         # get the percentage of 1-page I/O
26402         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26403                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26404                 awk '{print $7}')
26405         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26406
26407         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26408         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26409                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26410                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26411                 --filename=$DIR/$tfile
26412         [ $? -eq 0 ] || error "fio mixed read write error"
26413
26414         echo "AIO with large block size ${size}M"
26415         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26416                 --numjobs=1 --fallocate=none --ioengine=libaio \
26417                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26418                 --filename=$DIR/$tfile
26419         [ $? -eq 0 ] || error "fio large block size failed"
26420
26421         rm -f $DIR/$tfile
26422         $LCTL set_param debug="$saved_debug"
26423 }
26424 run_test 398c "run fio to test AIO"
26425
26426 test_398d() { #  LU-13846
26427         which aiocp || skip_env "no aiocp installed"
26428         local aio_file=$DIR/$tfile.aio
26429
26430         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26431
26432         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26433         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26434         stack_trap "rm -f $DIR/$tfile $aio_file"
26435
26436         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26437
26438         # make sure we don't crash and fail properly
26439         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26440                 error "aio not aligned with PAGE SIZE should fail"
26441
26442         rm -f $DIR/$tfile $aio_file
26443 }
26444 run_test 398d "run aiocp to verify block size > stripe size"
26445
26446 test_398e() {
26447         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26448         touch $DIR/$tfile.new
26449         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26450 }
26451 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26452
26453 test_398f() { #  LU-14687
26454         which aiocp || skip_env "no aiocp installed"
26455         local aio_file=$DIR/$tfile.aio
26456
26457         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26458
26459         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26460         stack_trap "rm -f $DIR/$tfile $aio_file"
26461
26462         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26463         $LCTL set_param fail_loc=0x1418
26464         # make sure we don't crash and fail properly
26465         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26466                 error "aio with page allocation failure succeeded"
26467         $LCTL set_param fail_loc=0
26468         diff $DIR/$tfile $aio_file
26469         [[ $? != 0 ]] || error "no diff after failed aiocp"
26470 }
26471 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26472
26473 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26474 # stripe and i/o size must be > stripe size
26475 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26476 # single RPC in flight.  This test shows async DIO submission is working by
26477 # showing multiple RPCs in flight.
26478 test_398g() { #  LU-13798
26479         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26480
26481         # We need to do some i/o first to acquire enough grant to put our RPCs
26482         # in flight; otherwise a new connection may not have enough grant
26483         # available
26484         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26485                 error "parallel dio failed"
26486         stack_trap "rm -f $DIR/$tfile"
26487
26488         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26489         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26490         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26491         stack_trap "$LCTL set_param -n $pages_per_rpc"
26492
26493         # Recreate file so it's empty
26494         rm -f $DIR/$tfile
26495         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26496         #Pause rpc completion to guarantee we see multiple rpcs in flight
26497         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26498         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26499         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26500
26501         # Clear rpc stats
26502         $LCTL set_param osc.*.rpc_stats=c
26503
26504         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26505                 error "parallel dio failed"
26506         stack_trap "rm -f $DIR/$tfile"
26507
26508         $LCTL get_param osc.*-OST0000-*.rpc_stats
26509         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26510                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26511                 grep "8:" | awk '{print $8}')
26512         # We look at the "8 rpcs in flight" field, and verify A) it is present
26513         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26514         # as expected for an 8M DIO to a file with 1M stripes.
26515         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26516
26517         # Verify turning off parallel dio works as expected
26518         # Clear rpc stats
26519         $LCTL set_param osc.*.rpc_stats=c
26520         $LCTL set_param llite.*.parallel_dio=0
26521         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26522
26523         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26524                 error "dio with parallel dio disabled failed"
26525
26526         # Ideally, we would see only one RPC in flight here, but there is an
26527         # unavoidable race between i/o completion and RPC in flight counting,
26528         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26529         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26530         # So instead we just verify it's always < 8.
26531         $LCTL get_param osc.*-OST0000-*.rpc_stats
26532         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26533                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26534                 grep '^$' -B1 | grep . | awk '{print $1}')
26535         [ $ret != "8:" ] ||
26536                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26537 }
26538 run_test 398g "verify parallel dio async RPC submission"
26539
26540 test_398h() { #  LU-13798
26541         local dio_file=$DIR/$tfile.dio
26542
26543         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26544
26545         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26546         stack_trap "rm -f $DIR/$tfile $dio_file"
26547
26548         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26549                 error "parallel dio failed"
26550         diff $DIR/$tfile $dio_file
26551         [[ $? == 0 ]] || error "file diff after aiocp"
26552 }
26553 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26554
26555 test_398i() { #  LU-13798
26556         local dio_file=$DIR/$tfile.dio
26557
26558         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26559
26560         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26561         stack_trap "rm -f $DIR/$tfile $dio_file"
26562
26563         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26564         $LCTL set_param fail_loc=0x1418
26565         # make sure we don't crash and fail properly
26566         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26567                 error "parallel dio page allocation failure succeeded"
26568         diff $DIR/$tfile $dio_file
26569         [[ $? != 0 ]] || error "no diff after failed aiocp"
26570 }
26571 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26572
26573 test_398j() { #  LU-13798
26574         # Stripe size > RPC size but less than i/o size tests split across
26575         # stripes and RPCs for individual i/o op
26576         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26577
26578         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26579         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26580         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26581         stack_trap "$LCTL set_param -n $pages_per_rpc"
26582
26583         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26584                 error "parallel dio write failed"
26585         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26586
26587         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26588                 error "parallel dio read failed"
26589         diff $DIR/$tfile $DIR/$tfile.2
26590         [[ $? == 0 ]] || error "file diff after parallel dio read"
26591 }
26592 run_test 398j "test parallel dio where stripe size > rpc_size"
26593
26594 test_398k() { #  LU-13798
26595         wait_delete_completed
26596         wait_mds_ost_sync
26597
26598         # 4 stripe file; we will cause out of space on OST0
26599         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26600
26601         # Fill OST0 (if it's not too large)
26602         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26603                    head -n1)
26604         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26605                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26606         fi
26607         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26608         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26609                 error "dd should fill OST0"
26610         stack_trap "rm -f $DIR/$tfile.1"
26611
26612         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26613         err=$?
26614
26615         ls -la $DIR/$tfile
26616         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26617                 error "file is not 0 bytes in size"
26618
26619         # dd above should not succeed, but don't error until here so we can
26620         # get debug info above
26621         [[ $err != 0 ]] ||
26622                 error "parallel dio write with enospc succeeded"
26623         stack_trap "rm -f $DIR/$tfile"
26624 }
26625 run_test 398k "test enospc on first stripe"
26626
26627 test_398l() { #  LU-13798
26628         wait_delete_completed
26629         wait_mds_ost_sync
26630
26631         # 4 stripe file; we will cause out of space on OST0
26632         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26633         # happens on the second i/o chunk we issue
26634         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26635
26636         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26637         stack_trap "rm -f $DIR/$tfile"
26638
26639         # Fill OST0 (if it's not too large)
26640         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26641                    head -n1)
26642         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26643                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26644         fi
26645         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26646         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26647                 error "dd should fill OST0"
26648         stack_trap "rm -f $DIR/$tfile.1"
26649
26650         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26651         err=$?
26652         stack_trap "rm -f $DIR/$tfile.2"
26653
26654         # Check that short write completed as expected
26655         ls -la $DIR/$tfile.2
26656         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26657                 error "file is not 1M in size"
26658
26659         # dd above should not succeed, but don't error until here so we can
26660         # get debug info above
26661         [[ $err != 0 ]] ||
26662                 error "parallel dio write with enospc succeeded"
26663
26664         # Truncate source file to same length as output file and diff them
26665         $TRUNCATE $DIR/$tfile 1048576
26666         diff $DIR/$tfile $DIR/$tfile.2
26667         [[ $? == 0 ]] || error "data incorrect after short write"
26668 }
26669 run_test 398l "test enospc on intermediate stripe/RPC"
26670
26671 test_398m() { #  LU-13798
26672         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26673
26674         # Set up failure on OST0, the first stripe:
26675         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26676         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26677         # OST0 is on ost1, OST1 is on ost2.
26678         # So this fail_val specifies OST0
26679         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26680         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26681
26682         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26683                 error "parallel dio write with failure on first stripe succeeded"
26684         stack_trap "rm -f $DIR/$tfile"
26685         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26686
26687         # Place data in file for read
26688         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26689                 error "parallel dio write failed"
26690
26691         # Fail read on OST0, first stripe
26692         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26693         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26694         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26695                 error "parallel dio read with error on first stripe succeeded"
26696         rm -f $DIR/$tfile.2
26697         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26698
26699         # Switch to testing on OST1, second stripe
26700         # Clear file contents, maintain striping
26701         echo > $DIR/$tfile
26702         # Set up failure on OST1, second stripe:
26703         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26704         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26705
26706         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26707                 error "parallel dio write with failure on second stripe succeeded"
26708         stack_trap "rm -f $DIR/$tfile"
26709         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26710
26711         # Place data in file for read
26712         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26713                 error "parallel dio write failed"
26714
26715         # Fail read on OST1, second stripe
26716         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26717         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26718         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26719                 error "parallel dio read with error on second stripe succeeded"
26720         rm -f $DIR/$tfile.2
26721         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26722 }
26723 run_test 398m "test RPC failures with parallel dio"
26724
26725 # Parallel submission of DIO should not cause problems for append, but it's
26726 # important to verify.
26727 test_398n() { #  LU-13798
26728         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26729
26730         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26731                 error "dd to create source file failed"
26732         stack_trap "rm -f $DIR/$tfile"
26733
26734         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26735                 error "parallel dio write with failure on second stripe succeeded"
26736         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26737         diff $DIR/$tfile $DIR/$tfile.1
26738         [[ $? == 0 ]] || error "data incorrect after append"
26739
26740 }
26741 run_test 398n "test append with parallel DIO"
26742
26743 test_398o() {
26744         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26745 }
26746 run_test 398o "right kms with DIO"
26747
26748 test_398p()
26749 {
26750         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26751         which aiocp || skip_env "no aiocp installed"
26752
26753         local stripe_size=$((1024 * 1024)) #1 MiB
26754         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26755         local file_size=$((25 * stripe_size))
26756
26757         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26758         stack_trap "rm -f $DIR/$tfile*"
26759         # Just a bit bigger than the largest size in the test set below
26760         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26761                 error "buffered i/o to create file failed"
26762
26763         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26764                 $((stripe_size * 4)); do
26765
26766                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26767
26768                 echo "bs: $bs, file_size $file_size"
26769                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26770                         $DIR/$tfile.1 $DIR/$tfile.2 &
26771                 pid_dio1=$!
26772                 # Buffered I/O with similar but not the same block size
26773                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26774                         conv=notrunc &
26775                 pid_bio2=$!
26776                 wait $pid_dio1
26777                 rc1=$?
26778                 wait $pid_bio2
26779                 rc2=$?
26780                 if (( rc1 != 0 )); then
26781                         error "aio copy 1 w/bsize $bs failed: $rc1"
26782                 fi
26783                 if (( rc2 != 0 )); then
26784                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26785                 fi
26786
26787                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26788                         error "size incorrect"
26789                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26790                         error "files differ, bsize $bs"
26791                 rm -f $DIR/$tfile.2
26792         done
26793 }
26794 run_test 398p "race aio with buffered i/o"
26795
26796 test_398q()
26797 {
26798         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26799
26800         local stripe_size=$((1024 * 1024)) #1 MiB
26801         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26802         local file_size=$((25 * stripe_size))
26803
26804         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26805         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26806
26807         # Just a bit bigger than the largest size in the test set below
26808         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26809                 error "buffered i/o to create file failed"
26810
26811         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26812                 $((stripe_size * 4)); do
26813
26814                 echo "bs: $bs, file_size $file_size"
26815                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26816                         conv=notrunc oflag=direct iflag=direct &
26817                 pid_dio1=$!
26818                 # Buffered I/O with similar but not the same block size
26819                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26820                         conv=notrunc &
26821                 pid_bio2=$!
26822                 wait $pid_dio1
26823                 rc1=$?
26824                 wait $pid_bio2
26825                 rc2=$?
26826                 if (( rc1 != 0 )); then
26827                         error "dio copy 1 w/bsize $bs failed: $rc1"
26828                 fi
26829                 if (( rc2 != 0 )); then
26830                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26831                 fi
26832
26833                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26834                         error "size incorrect"
26835                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26836                         error "files differ, bsize $bs"
26837         done
26838
26839         rm -f $DIR/$tfile*
26840 }
26841 run_test 398q "race dio with buffered i/o"
26842
26843 test_fake_rw() {
26844         local read_write=$1
26845         if [ "$read_write" = "write" ]; then
26846                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26847         elif [ "$read_write" = "read" ]; then
26848                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26849         else
26850                 error "argument error"
26851         fi
26852
26853         # turn off debug for performance testing
26854         local saved_debug=$($LCTL get_param -n debug)
26855         $LCTL set_param debug=0
26856
26857         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26858
26859         # get ost1 size - $FSNAME-OST0000
26860         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26861         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26862         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26863
26864         if [ "$read_write" = "read" ]; then
26865                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26866         fi
26867
26868         local start_time=$(date +%s.%N)
26869         $dd_cmd bs=1M count=$blocks oflag=sync ||
26870                 error "real dd $read_write error"
26871         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26872
26873         if [ "$read_write" = "write" ]; then
26874                 rm -f $DIR/$tfile
26875         fi
26876
26877         # define OBD_FAIL_OST_FAKE_RW           0x238
26878         do_facet ost1 $LCTL set_param fail_loc=0x238
26879
26880         local start_time=$(date +%s.%N)
26881         $dd_cmd bs=1M count=$blocks oflag=sync ||
26882                 error "fake dd $read_write error"
26883         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26884
26885         if [ "$read_write" = "write" ]; then
26886                 # verify file size
26887                 cancel_lru_locks osc
26888                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26889                         error "$tfile size not $blocks MB"
26890         fi
26891         do_facet ost1 $LCTL set_param fail_loc=0
26892
26893         echo "fake $read_write $duration_fake vs. normal $read_write" \
26894                 "$duration in seconds"
26895         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26896                 error_not_in_vm "fake write is slower"
26897
26898         $LCTL set_param -n debug="$saved_debug"
26899         rm -f $DIR/$tfile
26900 }
26901 test_399a() { # LU-7655 for OST fake write
26902         remote_ost_nodsh && skip "remote OST with nodsh"
26903
26904         test_fake_rw write
26905 }
26906 run_test 399a "fake write should not be slower than normal write"
26907
26908 test_399b() { # LU-8726 for OST fake read
26909         remote_ost_nodsh && skip "remote OST with nodsh"
26910         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26911                 skip_env "ldiskfs only test"
26912         fi
26913
26914         test_fake_rw read
26915 }
26916 run_test 399b "fake read should not be slower than normal read"
26917
26918 test_400a() { # LU-1606, was conf-sanity test_74
26919         if ! which $CC > /dev/null 2>&1; then
26920                 skip_env "$CC is not installed"
26921         fi
26922
26923         local extra_flags=''
26924         local out=$TMP/$tfile
26925         local prefix=/usr/include/lustre
26926         local prog
26927
26928         # Oleg removes .c files in his test rig so test if any c files exist
26929         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26930                 skip_env "Needed .c test files are missing"
26931
26932         if ! [[ -d $prefix ]]; then
26933                 # Assume we're running in tree and fixup the include path.
26934                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26935                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26936                 extra_flags+=" -L$LUSTRE/utils/.libs"
26937         fi
26938
26939         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26940                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26941                         error "client api broken"
26942         done
26943         rm -f $out
26944 }
26945 run_test 400a "Lustre client api program can compile and link"
26946
26947 test_400b() { # LU-1606, LU-5011
26948         local header
26949         local out=$TMP/$tfile
26950         local prefix=/usr/include/linux/lustre
26951
26952         # We use a hard coded prefix so that this test will not fail
26953         # when run in tree. There are headers in lustre/include/lustre/
26954         # that are not packaged (like lustre_idl.h) and have more
26955         # complicated include dependencies (like config.h and lnet/types.h).
26956         # Since this test about correct packaging we just skip them when
26957         # they don't exist (see below) rather than try to fixup cppflags.
26958
26959         if ! which $CC > /dev/null 2>&1; then
26960                 skip_env "$CC is not installed"
26961         fi
26962
26963         for header in $prefix/*.h; do
26964                 if ! [[ -f "$header" ]]; then
26965                         continue
26966                 fi
26967
26968                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26969                         continue # lustre_ioctl.h is internal header
26970                 fi
26971
26972                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26973                         error "cannot compile '$header'"
26974         done
26975         rm -f $out
26976 }
26977 run_test 400b "packaged headers can be compiled"
26978
26979 test_401a() { #LU-7437
26980         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26981         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26982
26983         #count the number of parameters by "list_param -R"
26984         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26985         #count the number of parameters by listing proc files
26986         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26987         echo "proc_dirs='$proc_dirs'"
26988         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26989         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26990                       sort -u | wc -l)
26991
26992         [ $params -eq $procs ] ||
26993                 error "found $params parameters vs. $procs proc files"
26994
26995         # test the list_param -D option only returns directories
26996         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26997         #count the number of parameters by listing proc directories
26998         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26999                 sort -u | wc -l)
27000
27001         [ $params -eq $procs ] ||
27002                 error "found $params parameters vs. $procs proc files"
27003 }
27004 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27005
27006 test_401b() {
27007         # jobid_var may not allow arbitrary values, so use jobid_name
27008         # if available
27009         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27010                 local testname=jobid_name tmp='testing%p'
27011         else
27012                 local testname=jobid_var tmp=testing
27013         fi
27014
27015         local save=$($LCTL get_param -n $testname)
27016
27017         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27018                 error "no error returned when setting bad parameters"
27019
27020         local jobid_new=$($LCTL get_param -n foe $testname baz)
27021         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27022
27023         $LCTL set_param -n fog=bam $testname=$save bat=fog
27024         local jobid_old=$($LCTL get_param -n foe $testname bag)
27025         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27026 }
27027 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27028
27029 test_401c() {
27030         # jobid_var may not allow arbitrary values, so use jobid_name
27031         # if available
27032         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27033                 local testname=jobid_name
27034         else
27035                 local testname=jobid_var
27036         fi
27037
27038         local jobid_var_old=$($LCTL get_param -n $testname)
27039         local jobid_var_new
27040
27041         $LCTL set_param $testname= &&
27042                 error "no error returned for 'set_param a='"
27043
27044         jobid_var_new=$($LCTL get_param -n $testname)
27045         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27046                 error "$testname was changed by setting without value"
27047
27048         $LCTL set_param $testname &&
27049                 error "no error returned for 'set_param a'"
27050
27051         jobid_var_new=$($LCTL get_param -n $testname)
27052         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27053                 error "$testname was changed by setting without value"
27054 }
27055 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27056
27057 test_401d() {
27058         # jobid_var may not allow arbitrary values, so use jobid_name
27059         # if available
27060         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27061                 local testname=jobid_name new_value='foo=bar%p'
27062         else
27063                 local testname=jobid_var new_valuie=foo=bar
27064         fi
27065
27066         local jobid_var_old=$($LCTL get_param -n $testname)
27067         local jobid_var_new
27068
27069         $LCTL set_param $testname=$new_value ||
27070                 error "'set_param a=b' did not accept a value containing '='"
27071
27072         jobid_var_new=$($LCTL get_param -n $testname)
27073         [[ "$jobid_var_new" == "$new_value" ]] ||
27074                 error "'set_param a=b' failed on a value containing '='"
27075
27076         # Reset the $testname to test the other format
27077         $LCTL set_param $testname=$jobid_var_old
27078         jobid_var_new=$($LCTL get_param -n $testname)
27079         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27080                 error "failed to reset $testname"
27081
27082         $LCTL set_param $testname $new_value ||
27083                 error "'set_param a b' did not accept a value containing '='"
27084
27085         jobid_var_new=$($LCTL get_param -n $testname)
27086         [[ "$jobid_var_new" == "$new_value" ]] ||
27087                 error "'set_param a b' failed on a value containing '='"
27088
27089         $LCTL set_param $testname $jobid_var_old
27090         jobid_var_new=$($LCTL get_param -n $testname)
27091         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27092                 error "failed to reset $testname"
27093 }
27094 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27095
27096 test_401e() { # LU-14779
27097         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27098                 error "lctl list_param MGC* failed"
27099         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27100         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27101                 error "lctl get_param lru_size failed"
27102 }
27103 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27104
27105 test_402() {
27106         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27107         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27108                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27109         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27110                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27111                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27112         remote_mds_nodsh && skip "remote MDS with nodsh"
27113
27114         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27115 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27116         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27117         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27118                 echo "Touch failed - OK"
27119 }
27120 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27121
27122 test_403() {
27123         local file1=$DIR/$tfile.1
27124         local file2=$DIR/$tfile.2
27125         local tfile=$TMP/$tfile
27126
27127         rm -f $file1 $file2 $tfile
27128
27129         touch $file1
27130         ln $file1 $file2
27131
27132         # 30 sec OBD_TIMEOUT in ll_getattr()
27133         # right before populating st_nlink
27134         $LCTL set_param fail_loc=0x80001409
27135         stat -c %h $file1 > $tfile &
27136
27137         # create an alias, drop all locks and reclaim the dentry
27138         < $file2
27139         cancel_lru_locks mdc
27140         cancel_lru_locks osc
27141         sysctl -w vm.drop_caches=2
27142
27143         wait
27144
27145         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27146
27147         rm -f $tfile $file1 $file2
27148 }
27149 run_test 403 "i_nlink should not drop to zero due to aliasing"
27150
27151 test_404() { # LU-6601
27152         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27153                 skip "Need server version newer than 2.8.52"
27154         remote_mds_nodsh && skip "remote MDS with nodsh"
27155
27156         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27157                 awk '/osp .*-osc-MDT/ { print $4}')
27158
27159         local osp
27160         for osp in $mosps; do
27161                 echo "Deactivate: " $osp
27162                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27163                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27164                         awk -vp=$osp '$4 == p { print $2 }')
27165                 [ $stat = IN ] || {
27166                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27167                         error "deactivate error"
27168                 }
27169                 echo "Activate: " $osp
27170                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27171                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27172                         awk -vp=$osp '$4 == p { print $2 }')
27173                 [ $stat = UP ] || {
27174                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27175                         error "activate error"
27176                 }
27177         done
27178 }
27179 run_test 404 "validate manual {de}activated works properly for OSPs"
27180
27181 test_405() {
27182         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27183         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27184                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27185                         skip "Layout swap lock is not supported"
27186
27187         check_swap_layouts_support
27188         check_swap_layout_no_dom $DIR
27189
27190         test_mkdir $DIR/$tdir
27191         swap_lock_test -d $DIR/$tdir ||
27192                 error "One layout swap locked test failed"
27193 }
27194 run_test 405 "Various layout swap lock tests"
27195
27196 test_406() {
27197         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27198         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27199         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27201         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27202                 skip "Need MDS version at least 2.8.50"
27203
27204         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27205         local test_pool=$TESTNAME
27206
27207         pool_add $test_pool || error "pool_add failed"
27208         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27209                 error "pool_add_targets failed"
27210
27211         save_layout_restore_at_exit $MOUNT
27212
27213         # parent set default stripe count only, child will stripe from both
27214         # parent and fs default
27215         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27216                 error "setstripe $MOUNT failed"
27217         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27218         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27219         for i in $(seq 10); do
27220                 local f=$DIR/$tdir/$tfile.$i
27221                 touch $f || error "touch failed"
27222                 local count=$($LFS getstripe -c $f)
27223                 [ $count -eq $OSTCOUNT ] ||
27224                         error "$f stripe count $count != $OSTCOUNT"
27225                 local offset=$($LFS getstripe -i $f)
27226                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27227                 local size=$($LFS getstripe -S $f)
27228                 [ $size -eq $((def_stripe_size * 2)) ] ||
27229                         error "$f stripe size $size != $((def_stripe_size * 2))"
27230                 local pool=$($LFS getstripe -p $f)
27231                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27232         done
27233
27234         # change fs default striping, delete parent default striping, now child
27235         # will stripe from new fs default striping only
27236         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27237                 error "change $MOUNT default stripe failed"
27238         $LFS setstripe -c 0 $DIR/$tdir ||
27239                 error "delete $tdir default stripe failed"
27240         for i in $(seq 11 20); do
27241                 local f=$DIR/$tdir/$tfile.$i
27242                 touch $f || error "touch $f failed"
27243                 local count=$($LFS getstripe -c $f)
27244                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27245                 local offset=$($LFS getstripe -i $f)
27246                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27247                 local size=$($LFS getstripe -S $f)
27248                 [ $size -eq $def_stripe_size ] ||
27249                         error "$f stripe size $size != $def_stripe_size"
27250                 local pool=$($LFS getstripe -p $f)
27251                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27252         done
27253
27254         unlinkmany $DIR/$tdir/$tfile. 1 20
27255
27256         local f=$DIR/$tdir/$tfile
27257         pool_remove_all_targets $test_pool $f
27258         pool_remove $test_pool $f
27259 }
27260 run_test 406 "DNE support fs default striping"
27261
27262 test_407() {
27263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27264         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27265                 skip "Need MDS version at least 2.8.55"
27266         remote_mds_nodsh && skip "remote MDS with nodsh"
27267
27268         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27269                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27270         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27271                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27272         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27273
27274         #define OBD_FAIL_DT_TXN_STOP    0x2019
27275         for idx in $(seq $MDSCOUNT); do
27276                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27277         done
27278         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27279         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27280                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27281         true
27282 }
27283 run_test 407 "transaction fail should cause operation fail"
27284
27285 test_408() {
27286         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27287
27288         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27289         lctl set_param fail_loc=0x8000040a
27290         # let ll_prepare_partial_page() fail
27291         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27292
27293         rm -f $DIR/$tfile
27294
27295         # create at least 100 unused inodes so that
27296         # shrink_icache_memory(0) should not return 0
27297         touch $DIR/$tfile-{0..100}
27298         rm -f $DIR/$tfile-{0..100}
27299         sync
27300
27301         echo 2 > /proc/sys/vm/drop_caches
27302 }
27303 run_test 408 "drop_caches should not hang due to page leaks"
27304
27305 test_409()
27306 {
27307         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27308
27309         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27310         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27311         touch $DIR/$tdir/guard || error "(2) Fail to create"
27312
27313         local PREFIX=$(str_repeat 'A' 128)
27314         echo "Create 1K hard links start at $(date)"
27315         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27316                 error "(3) Fail to hard link"
27317
27318         echo "Links count should be right although linkEA overflow"
27319         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27320         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27321         [ $linkcount -eq 1001 ] ||
27322                 error "(5) Unexpected hard links count: $linkcount"
27323
27324         echo "List all links start at $(date)"
27325         ls -l $DIR/$tdir/foo > /dev/null ||
27326                 error "(6) Fail to list $DIR/$tdir/foo"
27327
27328         echo "Unlink hard links start at $(date)"
27329         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27330                 error "(7) Fail to unlink"
27331         echo "Unlink hard links finished at $(date)"
27332 }
27333 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27334
27335 test_410()
27336 {
27337         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27338                 skip "Need client version at least 2.9.59"
27339         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27340                 skip "Need MODULES build"
27341
27342         # Create a file, and stat it from the kernel
27343         local testfile=$DIR/$tfile
27344         touch $testfile
27345
27346         local run_id=$RANDOM
27347         local my_ino=$(stat --format "%i" $testfile)
27348
27349         # Try to insert the module. This will always fail as the
27350         # module is designed to not be inserted.
27351         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27352             &> /dev/null
27353
27354         # Anything but success is a test failure
27355         dmesg | grep -q \
27356             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27357             error "no inode match"
27358 }
27359 run_test 410 "Test inode number returned from kernel thread"
27360
27361 cleanup_test411_cgroup() {
27362         trap 0
27363         rmdir "$1"
27364 }
27365
27366 test_411() {
27367         local cg_basedir=/sys/fs/cgroup/memory
27368         # LU-9966
27369         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27370                 skip "no setup for cgroup"
27371
27372         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27373                 error "test file creation failed"
27374         cancel_lru_locks osc
27375
27376         # Create a very small memory cgroup to force a slab allocation error
27377         local cgdir=$cg_basedir/osc_slab_alloc
27378         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27379         trap "cleanup_test411_cgroup $cgdir" EXIT
27380         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27381         echo 1M > $cgdir/memory.limit_in_bytes
27382
27383         # Should not LBUG, just be killed by oom-killer
27384         # dd will return 0 even allocation failure in some environment.
27385         # So don't check return value
27386         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27387         cleanup_test411_cgroup $cgdir
27388
27389         return 0
27390 }
27391 run_test 411 "Slab allocation error with cgroup does not LBUG"
27392
27393 test_412() {
27394         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27395         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27396                 skip "Need server version at least 2.10.55"
27397
27398         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27399                 error "mkdir failed"
27400         $LFS getdirstripe $DIR/$tdir
27401         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27402         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27403                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27404         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27405         [ $stripe_count -eq 2 ] ||
27406                 error "expect 2 get $stripe_count"
27407
27408         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27409
27410         local index
27411         local index2
27412
27413         # subdirs should be on the same MDT as parent
27414         for i in $(seq 0 $((MDSCOUNT - 1))); do
27415                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27416                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27417                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27418                 (( index == i )) || error "mdt$i/sub on MDT$index"
27419         done
27420
27421         # stripe offset -1, ditto
27422         for i in {1..10}; do
27423                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27424                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27425                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27426                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27427                 (( index == index2 )) ||
27428                         error "qos$i on MDT$index, sub on MDT$index2"
27429         done
27430
27431         local testdir=$DIR/$tdir/inherit
27432
27433         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27434         # inherit 2 levels
27435         for i in 1 2; do
27436                 testdir=$testdir/s$i
27437                 mkdir $testdir || error "mkdir $testdir failed"
27438                 index=$($LFS getstripe -m $testdir)
27439                 (( index == 1 )) ||
27440                         error "$testdir on MDT$index"
27441         done
27442
27443         # not inherit any more
27444         testdir=$testdir/s3
27445         mkdir $testdir || error "mkdir $testdir failed"
27446         getfattr -d -m dmv $testdir | grep dmv &&
27447                 error "default LMV set on $testdir" || true
27448 }
27449 run_test 412 "mkdir on specific MDTs"
27450
27451 TEST413_COUNT=${TEST413_COUNT:-200}
27452
27453 #
27454 # set_maxage() is used by test_413 only.
27455 # This is a helper function to set maxage. Does not return any value.
27456 # Input: maxage to set
27457 #
27458 set_maxage() {
27459         local lmv_qos_maxage
27460         local lod_qos_maxage
27461         local new_maxage=$1
27462
27463         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27464         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27465         stack_trap "$LCTL set_param \
27466                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27467         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27468                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27469         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27470                 lod.*.mdt_qos_maxage=$new_maxage
27471         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27472                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27473 }
27474
27475 generate_uneven_mdts() {
27476         local threshold=$1
27477         local ffree
27478         local bavail
27479         local max
27480         local min
27481         local max_index
27482         local min_index
27483         local tmp
27484         local i
27485
27486         echo
27487         echo "Check for uneven MDTs: "
27488
27489         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27490         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27491         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27492
27493         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27494         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27495         max_index=0
27496         min_index=0
27497         for ((i = 1; i < ${#ffree[@]}; i++)); do
27498                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27499                 if [ $tmp -gt $max ]; then
27500                         max=$tmp
27501                         max_index=$i
27502                 fi
27503                 if [ $tmp -lt $min ]; then
27504                         min=$tmp
27505                         min_index=$i
27506                 fi
27507         done
27508
27509         (( min > 0 )) || skip "low space on MDT$min_index"
27510         (( ${ffree[min_index]} > 0 )) ||
27511                 skip "no free files on MDT$min_index"
27512         (( ${ffree[min_index]} < 10000000 )) ||
27513                 skip "too many free files on MDT$min_index"
27514
27515         # Check if we need to generate uneven MDTs
27516         local diff=$(((max - min) * 100 / min))
27517         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27518         local testdir # individual folder within $testdirp
27519         local start
27520         local cmd
27521
27522         # fallocate is faster to consume space on MDT, if available
27523         if check_fallocate_supported mds$((min_index + 1)); then
27524                 cmd="fallocate -l 128K "
27525         else
27526                 cmd="dd if=/dev/zero bs=128K count=1 of="
27527         fi
27528
27529         echo "using cmd $cmd"
27530         for (( i = 0; diff < threshold; i++ )); do
27531                 testdir=${testdirp}/$i
27532                 [ -d $testdir ] && continue
27533
27534                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27535
27536                 mkdir -p $testdirp
27537                 # generate uneven MDTs, create till $threshold% diff
27538                 echo -n "weight diff=$diff% must be > $threshold% ..."
27539                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27540                 $LFS mkdir -i $min_index $testdir ||
27541                         error "mkdir $testdir failed"
27542                 $LFS setstripe -E 1M -L mdt $testdir ||
27543                         error "setstripe $testdir failed"
27544                 start=$SECONDS
27545                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27546                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27547                 done
27548                 sync; sleep 1; sync
27549
27550                 # wait for QOS to update
27551                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27552
27553                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27554                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27555                 max=$(((${ffree[max_index]} >> 8) *
27556                         (${bavail[max_index]} * bsize >> 16)))
27557                 min=$(((${ffree[min_index]} >> 8) *
27558                         (${bavail[min_index]} * bsize >> 16)))
27559                 (( min > 0 )) || skip "low space on MDT$min_index"
27560                 diff=$(((max - min) * 100 / min))
27561         done
27562
27563         echo "MDT filesfree available: ${ffree[*]}"
27564         echo "MDT blocks available: ${bavail[*]}"
27565         echo "weight diff=$diff%"
27566 }
27567
27568 test_qos_mkdir() {
27569         local mkdir_cmd=$1
27570         local stripe_count=$2
27571         local mdts=$(comma_list $(mdts_nodes))
27572
27573         local testdir
27574         local lmv_qos_prio_free
27575         local lmv_qos_threshold_rr
27576         local lod_qos_prio_free
27577         local lod_qos_threshold_rr
27578         local total
27579         local count
27580         local i
27581
27582         # @total is total directories created if it's testing plain
27583         # directories, otherwise it's total stripe object count for
27584         # striped directories test.
27585         # remote/striped directory unlinking is slow on zfs and may
27586         # timeout, test with fewer directories
27587         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27588
27589         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27590         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27591         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27592                 head -n1)
27593         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27594         stack_trap "$LCTL set_param \
27595                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27596         stack_trap "$LCTL set_param \
27597                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27598
27599         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27600                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27601         lod_qos_prio_free=${lod_qos_prio_free%%%}
27602         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27603                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27604         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27605         stack_trap "do_nodes $mdts $LCTL set_param \
27606                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27607         stack_trap "do_nodes $mdts $LCTL set_param \
27608                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27609
27610         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27611         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27612
27613         testdir=$DIR/$tdir-s$stripe_count/rr
27614
27615         local stripe_index=$($LFS getstripe -m $testdir)
27616         local test_mkdir_rr=true
27617
27618         getfattr -d -m dmv -e hex $testdir | grep dmv
27619         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27620                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27621                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27622                         test_mkdir_rr=false
27623         fi
27624
27625         echo
27626         $test_mkdir_rr &&
27627                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27628                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27629
27630         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27631         for (( i = 0; i < total / stripe_count; i++ )); do
27632                 eval $mkdir_cmd $testdir/subdir$i ||
27633                         error "$mkdir_cmd subdir$i failed"
27634         done
27635
27636         for (( i = 0; i < $MDSCOUNT; i++ )); do
27637                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27638                 echo "$count directories created on MDT$i"
27639                 if $test_mkdir_rr; then
27640                         (( count == total / stripe_count / MDSCOUNT )) ||
27641                                 error "subdirs are not evenly distributed"
27642                 elif (( i == stripe_index )); then
27643                         (( count == total / stripe_count )) ||
27644                                 error "$count subdirs created on MDT$i"
27645                 else
27646                         (( count == 0 )) ||
27647                                 error "$count subdirs created on MDT$i"
27648                 fi
27649
27650                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27651                         count=$($LFS getdirstripe $testdir/* |
27652                                 grep -c -P "^\s+$i\t")
27653                         echo "$count stripes created on MDT$i"
27654                         # deviation should < 5% of average
27655                         delta=$((count - total / MDSCOUNT))
27656                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27657                                 error "stripes are not evenly distributed"
27658                 fi
27659         done
27660
27661         echo
27662         echo "Check for uneven MDTs: "
27663
27664         local ffree
27665         local bavail
27666         local max
27667         local min
27668         local max_index
27669         local min_index
27670         local tmp
27671
27672         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27673         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27674         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27675
27676         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27677         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27678         max_index=0
27679         min_index=0
27680         for ((i = 1; i < ${#ffree[@]}; i++)); do
27681                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27682                 if [ $tmp -gt $max ]; then
27683                         max=$tmp
27684                         max_index=$i
27685                 fi
27686                 if [ $tmp -lt $min ]; then
27687                         min=$tmp
27688                         min_index=$i
27689                 fi
27690         done
27691         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27692
27693         (( min > 0 )) || skip "low space on MDT$min_index"
27694         (( ${ffree[min_index]} < 10000000 )) ||
27695                 skip "too many free files on MDT$min_index"
27696
27697         generate_uneven_mdts 120
27698
27699         echo "MDT filesfree available: ${ffree[*]}"
27700         echo "MDT blocks available: ${bavail[*]}"
27701         echo "weight diff=$(((max - min) * 100 / min))%"
27702         echo
27703         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27704
27705         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27706         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27707         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27708         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27709         # decrease statfs age, so that it can be updated in time
27710         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27711         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27712
27713         sleep 1
27714
27715         testdir=$DIR/$tdir-s$stripe_count/qos
27716
27717         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27718         for (( i = 0; i < total / stripe_count; i++ )); do
27719                 eval $mkdir_cmd $testdir/subdir$i ||
27720                         error "$mkdir_cmd subdir$i failed"
27721         done
27722
27723         max=0
27724         for (( i = 0; i < $MDSCOUNT; i++ )); do
27725                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27726                 (( count > max )) && max=$count
27727                 echo "$count directories created on MDT$i : curmax=$max"
27728         done
27729
27730         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27731
27732         # D-value should > 10% of average
27733         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27734                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27735
27736         # ditto for stripes
27737         if (( stripe_count > 1 )); then
27738                 max=0
27739                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27740                         count=$($LFS getdirstripe $testdir/* |
27741                                 grep -c -P "^\s+$i\t")
27742                         (( count > max )) && max=$count
27743                         echo "$count stripes created on MDT$i"
27744                 done
27745
27746                 min=$($LFS getdirstripe $testdir/* |
27747                         grep -c -P "^\s+$min_index\t")
27748                 (( max - min > total / MDSCOUNT / 10 )) ||
27749                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27750         fi
27751 }
27752
27753 most_full_mdt() {
27754         local ffree
27755         local bavail
27756         local bsize
27757         local min
27758         local min_index
27759         local tmp
27760
27761         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27762         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27763         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27764
27765         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27766         min_index=0
27767         for ((i = 1; i < ${#ffree[@]}; i++)); do
27768                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27769                 (( tmp < min )) && min=$tmp && min_index=$i
27770         done
27771
27772         echo -n $min_index
27773 }
27774
27775 test_413a() {
27776         [ $MDSCOUNT -lt 2 ] &&
27777                 skip "We need at least 2 MDTs for this test"
27778
27779         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27780                 skip "Need server version at least 2.12.52"
27781
27782         local stripe_max=$((MDSCOUNT - 1))
27783         local stripe_count
27784
27785         # let caller set maxage for latest result
27786         set_maxage 1
27787
27788         # fill MDT unevenly
27789         generate_uneven_mdts 120
27790
27791         # test 4-stripe directory at most, otherwise it's too slow
27792         # We are being very defensive. Although Autotest uses 4 MDTs.
27793         # We make sure stripe_max does not go over 4.
27794         (( stripe_max > 4 )) && stripe_max=4
27795         # unlinking striped directory is slow on zfs, and may timeout, only test
27796         # plain directory
27797         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27798         for stripe_count in $(seq 1 $stripe_max); do
27799                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27800                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27801                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27802                         error "mkdir failed"
27803                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27804         done
27805 }
27806 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27807
27808 test_413b() {
27809         [ $MDSCOUNT -lt 2 ] &&
27810                 skip "We need at least 2 MDTs for this test"
27811
27812         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27813                 skip "Need server version at least 2.12.52"
27814
27815         local stripe_max=$((MDSCOUNT - 1))
27816         local testdir
27817         local stripe_count
27818
27819         # let caller set maxage for latest result
27820         set_maxage 1
27821
27822         # fill MDT unevenly
27823         generate_uneven_mdts 120
27824
27825         # test 4-stripe directory at most, otherwise it's too slow
27826         # We are being very defensive. Although Autotest uses 4 MDTs.
27827         # We make sure stripe_max does not go over 4.
27828         (( stripe_max > 4 )) && stripe_max=4
27829         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27830         for stripe_count in $(seq 1 $stripe_max); do
27831                 testdir=$DIR/$tdir-s$stripe_count
27832                 mkdir $testdir || error "mkdir $testdir failed"
27833                 mkdir $testdir/rr || error "mkdir rr failed"
27834                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27835                         error "mkdir qos failed"
27836                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27837                         $testdir/rr || error "setdirstripe rr failed"
27838                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27839                         error "setdirstripe failed"
27840                 test_qos_mkdir "mkdir" $stripe_count
27841         done
27842 }
27843 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27844
27845 test_413c() {
27846         (( $MDSCOUNT >= 2 )) ||
27847                 skip "We need at least 2 MDTs for this test"
27848
27849         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27850                 skip "Need server version at least 2.14.51"
27851
27852         local testdir
27853         local inherit
27854         local inherit_rr
27855         local lmv_qos_maxage
27856         local lod_qos_maxage
27857
27858         # let caller set maxage for latest result
27859         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27860         $LCTL set_param lmv.*.qos_maxage=1
27861         stack_trap "$LCTL set_param \
27862                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27863         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27864                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27865         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27866                 lod.*.mdt_qos_maxage=1
27867         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27868                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27869
27870         # fill MDT unevenly
27871         generate_uneven_mdts 120
27872
27873         testdir=$DIR/${tdir}-s1
27874         mkdir $testdir || error "mkdir $testdir failed"
27875         mkdir $testdir/rr || error "mkdir rr failed"
27876         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27877         # default max_inherit is -1, default max_inherit_rr is 0
27878         $LFS setdirstripe -D -c 1 $testdir/rr ||
27879                 error "setdirstripe rr failed"
27880         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27881                 error "setdirstripe qos failed"
27882         test_qos_mkdir "mkdir" 1
27883
27884         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27885         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27886         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27887         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27888         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27889
27890         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27891         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27892         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27893         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27894         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27895         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27896         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27897                 error "level2 shouldn't have default LMV" || true
27898 }
27899 run_test 413c "mkdir with default LMV max inherit rr"
27900
27901 test_413d() {
27902         (( MDSCOUNT >= 2 )) ||
27903                 skip "We need at least 2 MDTs for this test"
27904
27905         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27906                 skip "Need server version at least 2.14.51"
27907
27908         local lmv_qos_threshold_rr
27909
27910         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27911                 head -n1)
27912         stack_trap "$LCTL set_param \
27913                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27914
27915         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27916         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27917         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27918                 error "$tdir shouldn't have default LMV"
27919         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27920                 error "mkdir sub failed"
27921
27922         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27923
27924         (( count == 100 )) || error "$count subdirs on MDT0"
27925 }
27926 run_test 413d "inherit ROOT default LMV"
27927
27928 test_413e() {
27929         (( MDSCOUNT >= 2 )) ||
27930                 skip "We need at least 2 MDTs for this test"
27931         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27932                 skip "Need server version at least 2.14.55"
27933
27934         local testdir=$DIR/$tdir
27935         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27936         local max_inherit
27937         local sub_max_inherit
27938
27939         mkdir -p $testdir || error "failed to create $testdir"
27940
27941         # set default max-inherit to -1 if stripe count is 0 or 1
27942         $LFS setdirstripe -D -c 1 $testdir ||
27943                 error "failed to set default LMV"
27944         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27945         (( max_inherit == -1 )) ||
27946                 error "wrong max_inherit value $max_inherit"
27947
27948         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27949         $LFS setdirstripe -D -c -1 $testdir ||
27950                 error "failed to set default LMV"
27951         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27952         (( max_inherit > 0 )) ||
27953                 error "wrong max_inherit value $max_inherit"
27954
27955         # and the subdir will decrease the max_inherit by 1
27956         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27957         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27958         (( sub_max_inherit == max_inherit - 1)) ||
27959                 error "wrong max-inherit of subdir $sub_max_inherit"
27960
27961         # check specified --max-inherit and warning message
27962         stack_trap "rm -f $tmpfile"
27963         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27964                 error "failed to set default LMV"
27965         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27966         (( max_inherit == -1 )) ||
27967                 error "wrong max_inherit value $max_inherit"
27968
27969         # check the warning messages
27970         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27971                 error "failed to detect warning string"
27972         fi
27973 }
27974 run_test 413e "check default max-inherit value"
27975
27976 test_fs_dmv_inherit()
27977 {
27978         local testdir=$DIR/$tdir
27979
27980         local count
27981         local inherit
27982         local inherit_rr
27983
27984         for i in 1 2; do
27985                 mkdir $testdir || error "mkdir $testdir failed"
27986                 count=$($LFS getdirstripe -D -c $testdir)
27987                 (( count == 1 )) ||
27988                         error "$testdir default LMV count mismatch $count != 1"
27989                 inherit=$($LFS getdirstripe -D -X $testdir)
27990                 (( inherit == 3 - i )) ||
27991                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27992                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27993                 (( inherit_rr == 3 - i )) ||
27994                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27995                 testdir=$testdir/sub
27996         done
27997
27998         mkdir $testdir || error "mkdir $testdir failed"
27999         count=$($LFS getdirstripe -D -c $testdir)
28000         (( count == 0 )) ||
28001                 error "$testdir default LMV count not zero: $count"
28002 }
28003
28004 test_413f() {
28005         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28006
28007         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28008                 skip "Need server version at least 2.14.55"
28009
28010         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28011                 error "dump $DIR default LMV failed"
28012         stack_trap "setfattr --restore=$TMP/dmv.ea"
28013
28014         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28015                 error "set $DIR default LMV failed"
28016
28017         test_fs_dmv_inherit
28018 }
28019 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28020
28021 test_413g() {
28022         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28023
28024         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28025         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28026                 error "dump $DIR default LMV failed"
28027         stack_trap "setfattr --restore=$TMP/dmv.ea"
28028
28029         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28030                 error "set $DIR default LMV failed"
28031
28032         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28033                 error "mount $MOUNT2 failed"
28034         stack_trap "umount_client $MOUNT2"
28035
28036         local saved_DIR=$DIR
28037
28038         export DIR=$MOUNT2
28039
28040         stack_trap "export DIR=$saved_DIR"
28041
28042         # first check filesystem-wide default LMV inheritance
28043         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28044
28045         # then check subdirs are spread to all MDTs
28046         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28047
28048         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28049
28050         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28051 }
28052 run_test 413g "enforce ROOT default LMV on subdir mount"
28053
28054 test_413h() {
28055         (( MDSCOUNT >= 2 )) ||
28056                 skip "We need at least 2 MDTs for this test"
28057
28058         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28059                 skip "Need server version at least 2.15.50.6"
28060
28061         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28062
28063         stack_trap "$LCTL set_param \
28064                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28065         $LCTL set_param lmv.*.qos_maxage=1
28066
28067         local depth=5
28068         local rr_depth=4
28069         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28070         local count=$((MDSCOUNT * 20))
28071
28072         generate_uneven_mdts 50
28073
28074         mkdir -p $dir || error "mkdir $dir failed"
28075         stack_trap "rm -rf $dir"
28076         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28077                 --max-inherit-rr=$rr_depth $dir
28078
28079         for ((d=0; d < depth + 2; d++)); do
28080                 log "dir=$dir:"
28081                 for ((sub=0; sub < count; sub++)); do
28082                         mkdir $dir/d$sub
28083                 done
28084                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28085                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28086                 # subdirs within $rr_depth should be created round-robin
28087                 if (( d < rr_depth )); then
28088                         (( ${num[0]} != count )) ||
28089                                 error "all objects created on MDT ${num[1]}"
28090                 fi
28091
28092                 dir=$dir/d0
28093         done
28094 }
28095 run_test 413h "don't stick to parent for round-robin dirs"
28096
28097 test_413i() {
28098         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28099
28100         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28101                 skip "Need server version at least 2.14.55"
28102
28103         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28104                 error "dump $DIR default LMV failed"
28105         stack_trap "setfattr --restore=$TMP/dmv.ea"
28106
28107         local testdir=$DIR/$tdir
28108         local def_max_rr=1
28109         local def_max=3
28110         local count
28111
28112         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28113                 --max-inherit-rr=$def_max_rr $DIR ||
28114                 error "set $DIR default LMV failed"
28115
28116         for i in $(seq 2 3); do
28117                 def_max=$((def_max - 1))
28118                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28119
28120                 mkdir $testdir
28121                 # RR is decremented and keeps zeroed once exhausted
28122                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28123                 (( count == def_max_rr )) ||
28124                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28125
28126                 # max-inherit is decremented
28127                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28128                 (( count == def_max )) ||
28129                         error_noexit "$testdir: max-inherit $count != $def_max"
28130
28131                 testdir=$testdir/d$i
28132         done
28133
28134         # d3 is the last inherited from ROOT, no inheritance anymore
28135         # i.e. no the default layout anymore
28136         mkdir -p $testdir/d4/d5
28137         count=$($LFS getdirstripe -D --max-inherit $testdir)
28138         (( count == -1 )) ||
28139                 error_noexit "$testdir: max-inherit $count != -1"
28140
28141         local p_count=$($LFS getdirstripe -i $testdir)
28142
28143         for i in $(seq 4 5); do
28144                 testdir=$testdir/d$i
28145
28146                 # the root default layout is not applied once exhausted
28147                 count=$($LFS getdirstripe -i $testdir)
28148                 (( count == p_count )) ||
28149                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28150         done
28151
28152         $LFS setdirstripe -i 0 $DIR/d2
28153         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28154         (( count == -1 )) ||
28155                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28156 }
28157 run_test 413i "check default layout inheritance"
28158
28159 test_413z() {
28160         local pids=""
28161         local subdir
28162         local pid
28163
28164         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28165                 unlinkmany $subdir/f. $TEST413_COUNT &
28166                 pids="$pids $!"
28167         done
28168
28169         for pid in $pids; do
28170                 wait $pid
28171         done
28172
28173         true
28174 }
28175 run_test 413z "413 test cleanup"
28176
28177 test_414() {
28178 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28179         $LCTL set_param fail_loc=0x80000521
28180         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28181         rm -f $DIR/$tfile
28182 }
28183 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28184
28185 test_415() {
28186         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28187         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28188                 skip "Need server version at least 2.11.52"
28189
28190         # LU-11102
28191         local total=500
28192         local max=120
28193
28194         # this test may be slow on ZFS
28195         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28196
28197         # though this test is designed for striped directory, let's test normal
28198         # directory too since lock is always saved as CoS lock.
28199         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28200         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28201         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28202         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28203         wait_delete_completed_mds
28204
28205         # run a loop without concurrent touch to measure rename duration.
28206         # only for test debug/robustness, NOT part of COS functional test.
28207         local start_time=$SECONDS
28208         for ((i = 0; i < total; i++)); do
28209                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28210                         > /dev/null
28211         done
28212         local baseline=$((SECONDS - start_time))
28213         echo "rename $total files without 'touch' took $baseline sec"
28214
28215         (
28216                 while true; do
28217                         touch $DIR/$tdir
28218                 done
28219         ) &
28220         local setattr_pid=$!
28221
28222         # rename files back to original name so unlinkmany works
28223         start_time=$SECONDS
28224         for ((i = 0; i < total; i++)); do
28225                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28226                         > /dev/null
28227         done
28228         local duration=$((SECONDS - start_time))
28229
28230         kill -9 $setattr_pid
28231
28232         echo "rename $total files with 'touch' took $duration sec"
28233         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28234         (( duration <= max )) ||
28235                 error_not_in_vm "rename took $duration > $max sec"
28236 }
28237 run_test 415 "lock revoke is not missing"
28238
28239 test_416() {
28240         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28241                 skip "Need server version at least 2.11.55"
28242
28243         # define OBD_FAIL_OSD_TXN_START    0x19a
28244         do_facet mds1 lctl set_param fail_loc=0x19a
28245
28246         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28247
28248         true
28249 }
28250 run_test 416 "transaction start failure won't cause system hung"
28251
28252 cleanup_417() {
28253         trap 0
28254         do_nodes $(comma_list $(mdts_nodes)) \
28255                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28256         do_nodes $(comma_list $(mdts_nodes)) \
28257                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28258         do_nodes $(comma_list $(mdts_nodes)) \
28259                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28260 }
28261
28262 test_417() {
28263         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28264         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28265                 skip "Need MDS version at least 2.11.56"
28266
28267         trap cleanup_417 RETURN EXIT
28268
28269         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28270         do_nodes $(comma_list $(mdts_nodes)) \
28271                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28272         $LFS migrate -m 0 $DIR/$tdir.1 &&
28273                 error "migrate dir $tdir.1 should fail"
28274
28275         do_nodes $(comma_list $(mdts_nodes)) \
28276                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28277         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28278                 error "create remote dir $tdir.2 should fail"
28279
28280         do_nodes $(comma_list $(mdts_nodes)) \
28281                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28282         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28283                 error "create striped dir $tdir.3 should fail"
28284         true
28285 }
28286 run_test 417 "disable remote dir, striped dir and dir migration"
28287
28288 # Checks that the outputs of df [-i] and lfs df [-i] match
28289 #
28290 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28291 check_lfs_df() {
28292         local dir=$2
28293         local inodes
28294         local df_out
28295         local lfs_df_out
28296         local count
28297         local passed=false
28298
28299         # blocks or inodes
28300         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28301
28302         for count in {1..100}; do
28303                 do_nodes "$CLIENTS" \
28304                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28305                 sync; sleep 0.2
28306
28307                 # read the lines of interest
28308                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28309                         error "df $inodes $dir | tail -n +2 failed"
28310                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28311                         error "lfs df $inodes $dir | grep summary: failed"
28312
28313                 # skip first substrings of each output as they are different
28314                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28315                 # compare the two outputs
28316                 passed=true
28317                 #  skip "available" on MDT until LU-13997 is fixed.
28318                 #for i in {1..5}; do
28319                 for i in 1 2 4 5; do
28320                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28321                 done
28322                 $passed && break
28323         done
28324
28325         if ! $passed; then
28326                 df -P $inodes $dir
28327                 echo
28328                 lfs df $inodes $dir
28329                 error "df and lfs df $1 output mismatch: "      \
28330                       "df ${inodes}: ${df_out[*]}, "            \
28331                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28332         fi
28333 }
28334
28335 test_418() {
28336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28337
28338         local dir=$DIR/$tdir
28339         local numfiles=$((RANDOM % 4096 + 2))
28340         local numblocks=$((RANDOM % 256 + 1))
28341
28342         wait_delete_completed
28343         test_mkdir $dir
28344
28345         # check block output
28346         check_lfs_df blocks $dir
28347         # check inode output
28348         check_lfs_df inodes $dir
28349
28350         # create a single file and retest
28351         echo "Creating a single file and testing"
28352         createmany -o $dir/$tfile- 1 &>/dev/null ||
28353                 error "creating 1 file in $dir failed"
28354         check_lfs_df blocks $dir
28355         check_lfs_df inodes $dir
28356
28357         # create a random number of files
28358         echo "Creating $((numfiles - 1)) files and testing"
28359         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28360                 error "creating $((numfiles - 1)) files in $dir failed"
28361
28362         # write a random number of blocks to the first test file
28363         echo "Writing $numblocks 4K blocks and testing"
28364         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28365                 count=$numblocks &>/dev/null ||
28366                 error "dd to $dir/${tfile}-0 failed"
28367
28368         # retest
28369         check_lfs_df blocks $dir
28370         check_lfs_df inodes $dir
28371
28372         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28373                 error "unlinking $numfiles files in $dir failed"
28374 }
28375 run_test 418 "df and lfs df outputs match"
28376
28377 test_419()
28378 {
28379         local dir=$DIR/$tdir
28380
28381         mkdir -p $dir
28382         touch $dir/file
28383
28384         cancel_lru_locks mdc
28385
28386         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28387         $LCTL set_param fail_loc=0x1410
28388         cat $dir/file
28389         $LCTL set_param fail_loc=0
28390         rm -rf $dir
28391 }
28392 run_test 419 "Verify open file by name doesn't crash kernel"
28393
28394 test_420()
28395 {
28396         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28397                 skip "Need MDS version at least 2.12.53"
28398
28399         local SAVE_UMASK=$(umask)
28400         local dir=$DIR/$tdir
28401         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28402
28403         mkdir -p $dir
28404         umask 0000
28405         mkdir -m03777 $dir/testdir
28406         ls -dn $dir/testdir
28407         # Need to remove trailing '.' when SELinux is enabled
28408         local dirperms=$(ls -dn $dir/testdir |
28409                          awk '{ sub(/\.$/, "", $1); print $1}')
28410         [ $dirperms == "drwxrwsrwt" ] ||
28411                 error "incorrect perms on $dir/testdir"
28412
28413         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28414                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28415         ls -n $dir/testdir/testfile
28416         local fileperms=$(ls -n $dir/testdir/testfile |
28417                           awk '{ sub(/\.$/, "", $1); print $1}')
28418         [ $fileperms == "-rwxr-xr-x" ] ||
28419                 error "incorrect perms on $dir/testdir/testfile"
28420
28421         umask $SAVE_UMASK
28422 }
28423 run_test 420 "clear SGID bit on non-directories for non-members"
28424
28425 test_421a() {
28426         local cnt
28427         local fid1
28428         local fid2
28429
28430         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28431                 skip "Need MDS version at least 2.12.54"
28432
28433         test_mkdir $DIR/$tdir
28434         createmany -o $DIR/$tdir/f 3
28435         cnt=$(ls -1 $DIR/$tdir | wc -l)
28436         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28437
28438         fid1=$(lfs path2fid $DIR/$tdir/f1)
28439         fid2=$(lfs path2fid $DIR/$tdir/f2)
28440         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28441
28442         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28443         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28444
28445         cnt=$(ls -1 $DIR/$tdir | wc -l)
28446         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28447
28448         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28449         createmany -o $DIR/$tdir/f 3
28450         cnt=$(ls -1 $DIR/$tdir | wc -l)
28451         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28452
28453         fid1=$(lfs path2fid $DIR/$tdir/f1)
28454         fid2=$(lfs path2fid $DIR/$tdir/f2)
28455         echo "remove using fsname $FSNAME"
28456         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28457
28458         cnt=$(ls -1 $DIR/$tdir | wc -l)
28459         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28460 }
28461 run_test 421a "simple rm by fid"
28462
28463 test_421b() {
28464         local cnt
28465         local FID1
28466         local FID2
28467
28468         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28469                 skip "Need MDS version at least 2.12.54"
28470
28471         test_mkdir $DIR/$tdir
28472         createmany -o $DIR/$tdir/f 3
28473         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28474         MULTIPID=$!
28475
28476         FID1=$(lfs path2fid $DIR/$tdir/f1)
28477         FID2=$(lfs path2fid $DIR/$tdir/f2)
28478         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28479
28480         kill -USR1 $MULTIPID
28481         wait
28482
28483         cnt=$(ls $DIR/$tdir | wc -l)
28484         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28485 }
28486 run_test 421b "rm by fid on open file"
28487
28488 test_421c() {
28489         local cnt
28490         local FIDS
28491
28492         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28493                 skip "Need MDS version at least 2.12.54"
28494
28495         test_mkdir $DIR/$tdir
28496         createmany -o $DIR/$tdir/f 3
28497         touch $DIR/$tdir/$tfile
28498         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28499         cnt=$(ls -1 $DIR/$tdir | wc -l)
28500         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28501
28502         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28503         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28504
28505         cnt=$(ls $DIR/$tdir | wc -l)
28506         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28507 }
28508 run_test 421c "rm by fid against hardlinked files"
28509
28510 test_421d() {
28511         local cnt
28512         local FIDS
28513
28514         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28515                 skip "Need MDS version at least 2.12.54"
28516
28517         test_mkdir $DIR/$tdir
28518         createmany -o $DIR/$tdir/f 4097
28519         cnt=$(ls -1 $DIR/$tdir | wc -l)
28520         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28521
28522         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28523         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28524
28525         cnt=$(ls $DIR/$tdir | wc -l)
28526         rm -rf $DIR/$tdir
28527         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28528 }
28529 run_test 421d "rmfid en masse"
28530
28531 test_421e() {
28532         local cnt
28533         local FID
28534
28535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28536         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28537                 skip "Need MDS version at least 2.12.54"
28538
28539         mkdir -p $DIR/$tdir
28540         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28541         createmany -o $DIR/$tdir/striped_dir/f 512
28542         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28543         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28544
28545         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28546                 sed "s/[/][^:]*://g")
28547         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28548
28549         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28550         rm -rf $DIR/$tdir
28551         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28552 }
28553 run_test 421e "rmfid in DNE"
28554
28555 test_421f() {
28556         local cnt
28557         local FID
28558
28559         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28560                 skip "Need MDS version at least 2.12.54"
28561
28562         test_mkdir $DIR/$tdir
28563         touch $DIR/$tdir/f
28564         cnt=$(ls -1 $DIR/$tdir | wc -l)
28565         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28566
28567         FID=$(lfs path2fid $DIR/$tdir/f)
28568         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28569         # rmfid should fail
28570         cnt=$(ls -1 $DIR/$tdir | wc -l)
28571         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28572
28573         chmod a+rw $DIR/$tdir
28574         ls -la $DIR/$tdir
28575         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28576         # rmfid should fail
28577         cnt=$(ls -1 $DIR/$tdir | wc -l)
28578         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28579
28580         rm -f $DIR/$tdir/f
28581         $RUNAS touch $DIR/$tdir/f
28582         FID=$(lfs path2fid $DIR/$tdir/f)
28583         echo "rmfid as root"
28584         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28585         cnt=$(ls -1 $DIR/$tdir | wc -l)
28586         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28587
28588         rm -f $DIR/$tdir/f
28589         $RUNAS touch $DIR/$tdir/f
28590         cnt=$(ls -1 $DIR/$tdir | wc -l)
28591         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28592         FID=$(lfs path2fid $DIR/$tdir/f)
28593         # rmfid w/o user_fid2path mount option should fail
28594         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28595         cnt=$(ls -1 $DIR/$tdir | wc -l)
28596         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28597
28598         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28599         stack_trap "rmdir $tmpdir"
28600         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28601                 error "failed to mount client'"
28602         stack_trap "umount_client $tmpdir"
28603
28604         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28605         # rmfid should succeed
28606         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28607         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28608
28609         # rmfid shouldn't allow to remove files due to dir's permission
28610         chmod a+rwx $tmpdir/$tdir
28611         touch $tmpdir/$tdir/f
28612         ls -la $tmpdir/$tdir
28613         FID=$(lfs path2fid $tmpdir/$tdir/f)
28614         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28615         return 0
28616 }
28617 run_test 421f "rmfid checks permissions"
28618
28619 test_421g() {
28620         local cnt
28621         local FIDS
28622
28623         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28624         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28625                 skip "Need MDS version at least 2.12.54"
28626
28627         mkdir -p $DIR/$tdir
28628         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28629         createmany -o $DIR/$tdir/striped_dir/f 512
28630         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28631         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28632
28633         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28634                 sed "s/[/][^:]*://g")
28635
28636         rm -f $DIR/$tdir/striped_dir/f1*
28637         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28638         removed=$((512 - cnt))
28639
28640         # few files have been just removed, so we expect
28641         # rmfid to fail on their fids
28642         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28643         [ $removed != $errors ] && error "$errors != $removed"
28644
28645         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28646         rm -rf $DIR/$tdir
28647         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28648 }
28649 run_test 421g "rmfid to return errors properly"
28650
28651 test_421h() {
28652         local mount_other
28653         local mount_ret
28654         local rmfid_ret
28655         local old_fid
28656         local fidA
28657         local fidB
28658         local fidC
28659         local fidD
28660
28661         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28662                 skip "Need MDS version at least 2.15.53"
28663
28664         test_mkdir $DIR/$tdir
28665         test_mkdir $DIR/$tdir/subdir
28666         touch $DIR/$tdir/subdir/file0
28667         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28668         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28669         rm -f $DIR/$tdir/subdir/file0
28670         touch $DIR/$tdir/subdir/fileA
28671         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28672         echo File $DIR/$tdir/subdir/fileA FID $fidA
28673         touch $DIR/$tdir/subdir/fileB
28674         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28675         echo File $DIR/$tdir/subdir/fileB FID $fidB
28676         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28677         touch $DIR/$tdir/subdir/fileC
28678         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28679         echo File $DIR/$tdir/subdir/fileC FID $fidC
28680         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28681         touch $DIR/$tdir/fileD
28682         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28683         echo File $DIR/$tdir/fileD FID $fidD
28684
28685         # mount another client mount point with subdirectory mount
28686         export FILESET=/$tdir/subdir
28687         mount_other=${MOUNT}_other
28688         mount_client $mount_other ${MOUNT_OPTS}
28689         mount_ret=$?
28690         export FILESET=""
28691         (( mount_ret == 0 )) || error "mount $mount_other failed"
28692
28693         echo Removing FIDs:
28694         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28695         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28696         rmfid_ret=$?
28697
28698         umount_client $mount_other || error "umount $mount_other failed"
28699
28700         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28701
28702         # fileA should have been deleted
28703         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28704
28705         # fileB should have been deleted
28706         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28707
28708         # fileC should not have been deleted, fid also exists outside of fileset
28709         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28710
28711         # fileD should not have been deleted, it exists outside of fileset
28712         stat $DIR/$tdir/fileD || error "fileD deleted"
28713 }
28714 run_test 421h "rmfid with fileset mount"
28715
28716 test_422() {
28717         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28718         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28719         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28720         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28721         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28722
28723         local amc=$(at_max_get client)
28724         local amo=$(at_max_get mds1)
28725         local timeout=`lctl get_param -n timeout`
28726
28727         at_max_set 0 client
28728         at_max_set 0 mds1
28729
28730 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28731         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28732                         fail_val=$(((2*timeout + 10)*1000))
28733         touch $DIR/$tdir/d3/file &
28734         sleep 2
28735 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28736         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28737                         fail_val=$((2*timeout + 5))
28738         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28739         local pid=$!
28740         sleep 1
28741         kill -9 $pid
28742         sleep $((2 * timeout))
28743         echo kill $pid
28744         kill -9 $pid
28745         lctl mark touch
28746         touch $DIR/$tdir/d2/file3
28747         touch $DIR/$tdir/d2/file4
28748         touch $DIR/$tdir/d2/file5
28749
28750         wait
28751         at_max_set $amc client
28752         at_max_set $amo mds1
28753
28754         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28755         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28756                 error "Watchdog is always throttled"
28757 }
28758 run_test 422 "kill a process with RPC in progress"
28759
28760 stat_test() {
28761     df -h $MOUNT &
28762     df -h $MOUNT &
28763     df -h $MOUNT &
28764     df -h $MOUNT &
28765     df -h $MOUNT &
28766     df -h $MOUNT &
28767 }
28768
28769 test_423() {
28770     local _stats
28771     # ensure statfs cache is expired
28772     sleep 2;
28773
28774     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28775     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28776
28777     return 0
28778 }
28779 run_test 423 "statfs should return a right data"
28780
28781 test_424() {
28782 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28783         $LCTL set_param fail_loc=0x80000522
28784         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28785         rm -f $DIR/$tfile
28786 }
28787 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28788
28789 test_425() {
28790         test_mkdir -c -1 $DIR/$tdir
28791         $LFS setstripe -c -1 $DIR/$tdir
28792
28793         lru_resize_disable "" 100
28794         stack_trap "lru_resize_enable" EXIT
28795
28796         sleep 5
28797
28798         for i in $(seq $((MDSCOUNT * 125))); do
28799                 local t=$DIR/$tdir/$tfile_$i
28800
28801                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28802                         error_noexit "Create file $t"
28803         done
28804         stack_trap "rm -rf $DIR/$tdir" EXIT
28805
28806         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28807                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28808                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28809
28810                 [ $lock_count -le $lru_size ] ||
28811                         error "osc lock count $lock_count > lru size $lru_size"
28812         done
28813
28814         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28815                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28816                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28817
28818                 [ $lock_count -le $lru_size ] ||
28819                         error "mdc lock count $lock_count > lru size $lru_size"
28820         done
28821 }
28822 run_test 425 "lock count should not exceed lru size"
28823
28824 test_426() {
28825         splice-test -r $DIR/$tfile
28826         splice-test -rd $DIR/$tfile
28827         splice-test $DIR/$tfile
28828         splice-test -d $DIR/$tfile
28829 }
28830 run_test 426 "splice test on Lustre"
28831
28832 test_427() {
28833         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28834         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28835                 skip "Need MDS version at least 2.12.4"
28836         local log
28837
28838         mkdir $DIR/$tdir
28839         mkdir $DIR/$tdir/1
28840         mkdir $DIR/$tdir/2
28841         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28842         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28843
28844         $LFS getdirstripe $DIR/$tdir/1/dir
28845
28846         #first setfattr for creating updatelog
28847         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28848
28849 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28850         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28851         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28852         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28853
28854         sleep 2
28855         fail mds2
28856         wait_recovery_complete mds2 $((2*TIMEOUT))
28857
28858         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28859         echo $log | grep "get update log failed" &&
28860                 error "update log corruption is detected" || true
28861 }
28862 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28863
28864 test_428() {
28865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28866         local cache_limit=$CACHE_MAX
28867
28868         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28869         $LCTL set_param -n llite.*.max_cached_mb=64
28870
28871         mkdir $DIR/$tdir
28872         $LFS setstripe -c 1 $DIR/$tdir
28873         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28874         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28875         #test write
28876         for f in $(seq 4); do
28877                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28878         done
28879         wait
28880
28881         cancel_lru_locks osc
28882         # Test read
28883         for f in $(seq 4); do
28884                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28885         done
28886         wait
28887 }
28888 run_test 428 "large block size IO should not hang"
28889
28890 test_429() { # LU-7915 / LU-10948
28891         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28892         local testfile=$DIR/$tfile
28893         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28894         local new_flag=1
28895         local first_rpc
28896         local second_rpc
28897         local third_rpc
28898
28899         $LCTL get_param $ll_opencache_threshold_count ||
28900                 skip "client does not have opencache parameter"
28901
28902         set_opencache $new_flag
28903         stack_trap "restore_opencache"
28904         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28905                 error "enable opencache failed"
28906         touch $testfile
28907         # drop MDC DLM locks
28908         cancel_lru_locks mdc
28909         # clear MDC RPC stats counters
28910         $LCTL set_param $mdc_rpcstats=clear
28911
28912         # According to the current implementation, we need to run 3 times
28913         # open & close file to verify if opencache is enabled correctly.
28914         # 1st, RPCs are sent for lookup/open and open handle is released on
28915         #      close finally.
28916         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28917         #      so open handle won't be released thereafter.
28918         # 3rd, No RPC is sent out.
28919         $MULTIOP $testfile oc || error "multiop failed"
28920         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28921         echo "1st: $first_rpc RPCs in flight"
28922
28923         $MULTIOP $testfile oc || error "multiop failed"
28924         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28925         echo "2nd: $second_rpc RPCs in flight"
28926
28927         $MULTIOP $testfile oc || error "multiop failed"
28928         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28929         echo "3rd: $third_rpc RPCs in flight"
28930
28931         #verify no MDC RPC is sent
28932         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28933 }
28934 run_test 429 "verify if opencache flag on client side does work"
28935
28936 lseek_test_430() {
28937         local offset
28938         local file=$1
28939
28940         # data at [200K, 400K)
28941         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28942                 error "256K->512K dd fails"
28943         # data at [2M, 3M)
28944         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28945                 error "2M->3M dd fails"
28946         # data at [4M, 5M)
28947         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28948                 error "4M->5M dd fails"
28949         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28950         # start at first component hole #1
28951         printf "Seeking hole from 1000 ... "
28952         offset=$(lseek_test -l 1000 $file)
28953         echo $offset
28954         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28955         printf "Seeking data from 1000 ... "
28956         offset=$(lseek_test -d 1000 $file)
28957         echo $offset
28958         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28959
28960         # start at first component data block
28961         printf "Seeking hole from 300000 ... "
28962         offset=$(lseek_test -l 300000 $file)
28963         echo $offset
28964         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28965         printf "Seeking data from 300000 ... "
28966         offset=$(lseek_test -d 300000 $file)
28967         echo $offset
28968         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28969
28970         # start at the first component but beyond end of object size
28971         printf "Seeking hole from 1000000 ... "
28972         offset=$(lseek_test -l 1000000 $file)
28973         echo $offset
28974         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28975         printf "Seeking data from 1000000 ... "
28976         offset=$(lseek_test -d 1000000 $file)
28977         echo $offset
28978         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28979
28980         # start at second component stripe 2 (empty file)
28981         printf "Seeking hole from 1500000 ... "
28982         offset=$(lseek_test -l 1500000 $file)
28983         echo $offset
28984         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28985         printf "Seeking data from 1500000 ... "
28986         offset=$(lseek_test -d 1500000 $file)
28987         echo $offset
28988         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28989
28990         # start at second component stripe 1 (all data)
28991         printf "Seeking hole from 3000000 ... "
28992         offset=$(lseek_test -l 3000000 $file)
28993         echo $offset
28994         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28995         printf "Seeking data from 3000000 ... "
28996         offset=$(lseek_test -d 3000000 $file)
28997         echo $offset
28998         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28999
29000         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29001                 error "2nd dd fails"
29002         echo "Add data block at 640K...1280K"
29003
29004         # start at before new data block, in hole
29005         printf "Seeking hole from 600000 ... "
29006         offset=$(lseek_test -l 600000 $file)
29007         echo $offset
29008         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29009         printf "Seeking data from 600000 ... "
29010         offset=$(lseek_test -d 600000 $file)
29011         echo $offset
29012         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29013
29014         # start at the first component new data block
29015         printf "Seeking hole from 1000000 ... "
29016         offset=$(lseek_test -l 1000000 $file)
29017         echo $offset
29018         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29019         printf "Seeking data from 1000000 ... "
29020         offset=$(lseek_test -d 1000000 $file)
29021         echo $offset
29022         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29023
29024         # start at second component stripe 2, new data
29025         printf "Seeking hole from 1200000 ... "
29026         offset=$(lseek_test -l 1200000 $file)
29027         echo $offset
29028         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29029         printf "Seeking data from 1200000 ... "
29030         offset=$(lseek_test -d 1200000 $file)
29031         echo $offset
29032         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29033
29034         # start beyond file end
29035         printf "Using offset > filesize ... "
29036         lseek_test -l 4000000 $file && error "lseek should fail"
29037         printf "Using offset > filesize ... "
29038         lseek_test -d 4000000 $file && error "lseek should fail"
29039
29040         printf "Done\n\n"
29041 }
29042
29043 test_430a() {
29044         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29045                 skip "MDT does not support SEEK_HOLE"
29046
29047         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29048                 skip "OST does not support SEEK_HOLE"
29049
29050         local file=$DIR/$tdir/$tfile
29051
29052         mkdir -p $DIR/$tdir
29053
29054         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29055         # OST stripe #1 will have continuous data at [1M, 3M)
29056         # OST stripe #2 is empty
29057         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29058         lseek_test_430 $file
29059         rm $file
29060         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29061         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29062         lseek_test_430 $file
29063         rm $file
29064         $LFS setstripe -c2 -S 512K $file
29065         echo "Two stripes, stripe size 512K"
29066         lseek_test_430 $file
29067         rm $file
29068         # FLR with stale mirror
29069         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29070                        -N -c2 -S 1M $file
29071         echo "Mirrored file:"
29072         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29073         echo "Plain 2 stripes 1M"
29074         lseek_test_430 $file
29075         rm $file
29076 }
29077 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29078
29079 test_430b() {
29080         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29081                 skip "OST does not support SEEK_HOLE"
29082
29083         local offset
29084         local file=$DIR/$tdir/$tfile
29085
29086         mkdir -p $DIR/$tdir
29087         # Empty layout lseek should fail
29088         $MCREATE $file
29089         # seek from 0
29090         printf "Seeking hole from 0 ... "
29091         lseek_test -l 0 $file && error "lseek should fail"
29092         printf "Seeking data from 0 ... "
29093         lseek_test -d 0 $file && error "lseek should fail"
29094         rm $file
29095
29096         # 1M-hole file
29097         $LFS setstripe -E 1M -c2 -E eof $file
29098         $TRUNCATE $file 1048576
29099         printf "Seeking hole from 1000000 ... "
29100         offset=$(lseek_test -l 1000000 $file)
29101         echo $offset
29102         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29103         printf "Seeking data from 1000000 ... "
29104         lseek_test -d 1000000 $file && error "lseek should fail"
29105         rm $file
29106
29107         # full component followed by non-inited one
29108         $LFS setstripe -E 1M -c2 -E eof $file
29109         dd if=/dev/urandom of=$file bs=1M count=1
29110         printf "Seeking hole from 1000000 ... "
29111         offset=$(lseek_test -l 1000000 $file)
29112         echo $offset
29113         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29114         printf "Seeking hole from 1048576 ... "
29115         lseek_test -l 1048576 $file && error "lseek should fail"
29116         # init second component and truncate back
29117         echo "123" >> $file
29118         $TRUNCATE $file 1048576
29119         printf "Seeking hole from 1000000 ... "
29120         offset=$(lseek_test -l 1000000 $file)
29121         echo $offset
29122         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29123         printf "Seeking hole from 1048576 ... "
29124         lseek_test -l 1048576 $file && error "lseek should fail"
29125         # boundary checks for big values
29126         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29127         offset=$(lseek_test -d 0 $file.10g)
29128         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29129         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29130         offset=$(lseek_test -d 0 $file.100g)
29131         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29132         return 0
29133 }
29134 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29135
29136 test_430c() {
29137         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29138                 skip "OST does not support SEEK_HOLE"
29139
29140         local file=$DIR/$tdir/$tfile
29141         local start
29142
29143         mkdir -p $DIR/$tdir
29144         stack_trap "rm -f $file $file.tmp"
29145         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29146
29147         # cp version 8.33+ prefers lseek over fiemap
29148         local ver=$(cp --version | awk '{ print $4; exit; }')
29149
29150         echo "cp $ver installed"
29151         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29152                 start=$SECONDS
29153                 time cp -v $file $file.tmp || error "cp $file failed"
29154                 (( SECONDS - start < 5 )) || {
29155                         strace cp $file $file.tmp |&
29156                                 grep -E "open|read|seek|FIEMAP" |
29157                                 grep -A 100 $file
29158                         error "cp: too long runtime $((SECONDS - start))"
29159                 }
29160         else
29161                 echo "cp test skipped due to $ver < 8.33"
29162         fi
29163
29164         # tar version 1.29+ supports SEEK_HOLE/DATA
29165         ver=$(tar --version | awk '{ print $4; exit; }')
29166         echo "tar $ver installed"
29167         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29168                 start=$SECONDS
29169                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29170                 (( SECONDS - start < 5 )) || {
29171                         strace tar cf $file.tmp --sparse $file |&
29172                                 grep -E "open|read|seek|FIEMAP" |
29173                                 grep -A 100 $file
29174                         error "tar: too long runtime $((SECONDS - start))"
29175                 }
29176         else
29177                 echo "tar test skipped due to $ver < 1.29"
29178         fi
29179 }
29180 run_test 430c "lseek: external tools check"
29181
29182 test_431() { # LU-14187
29183         local file=$DIR/$tdir/$tfile
29184
29185         mkdir -p $DIR/$tdir
29186         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29187         dd if=/dev/urandom of=$file bs=4k count=1
29188         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29189         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29190         #define OBD_FAIL_OST_RESTART_IO 0x251
29191         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29192         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29193         cp $file $file.0
29194         cancel_lru_locks
29195         sync_all_data
29196         echo 3 > /proc/sys/vm/drop_caches
29197         diff  $file $file.0 || error "data diff"
29198 }
29199 run_test 431 "Restart transaction for IO"
29200
29201 cleanup_test_432() {
29202         do_facet mgs $LCTL nodemap_activate 0
29203         wait_nm_sync active
29204 }
29205
29206 test_432() {
29207         local tmpdir=$TMP/dir432
29208
29209         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29210                 skip "Need MDS version at least 2.14.52"
29211
29212         stack_trap cleanup_test_432 EXIT
29213         mkdir $DIR/$tdir
29214         mkdir $tmpdir
29215
29216         do_facet mgs $LCTL nodemap_activate 1
29217         wait_nm_sync active
29218         do_facet mgs $LCTL nodemap_modify --name default \
29219                 --property admin --value 1
29220         do_facet mgs $LCTL nodemap_modify --name default \
29221                 --property trusted --value 1
29222         cancel_lru_locks mdc
29223         wait_nm_sync default admin_nodemap
29224         wait_nm_sync default trusted_nodemap
29225
29226         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29227                grep -ci "Operation not permitted") -ne 0 ]; then
29228                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29229         fi
29230 }
29231 run_test 432 "mv dir from outside Lustre"
29232
29233 test_433() {
29234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29235
29236         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29237                 skip "inode cache not supported"
29238
29239         $LCTL set_param llite.*.inode_cache=0
29240         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29241
29242         local count=256
29243         local before
29244         local after
29245
29246         cancel_lru_locks mdc
29247         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29248         createmany -m $DIR/$tdir/f $count
29249         createmany -d $DIR/$tdir/d $count
29250         ls -l $DIR/$tdir > /dev/null
29251         stack_trap "rm -rf $DIR/$tdir"
29252
29253         before=$(num_objects)
29254         cancel_lru_locks mdc
29255         after=$(num_objects)
29256
29257         # sometimes even @before is less than 2 * count
29258         while (( before - after < count )); do
29259                 sleep 1
29260                 after=$(num_objects)
29261                 wait=$((wait + 1))
29262                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29263                 if (( wait > 60 )); then
29264                         error "inode slab grew from $before to $after"
29265                 fi
29266         done
29267
29268         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29269 }
29270 run_test 433 "ldlm lock cancel releases dentries and inodes"
29271
29272 test_434() {
29273         local file
29274         local getxattr_count
29275         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29276         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29277
29278         [[ $(getenforce) == "Disabled" ]] ||
29279                 skip "lsm selinux module have to be disabled for this test"
29280
29281         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29282                 error "fail to create $DIR/$tdir/ on MDT0000"
29283
29284         touch $DIR/$tdir/$tfile-{001..100}
29285
29286         # disable the xattr cache
29287         save_lustre_params client "llite.*.xattr_cache" > $p
29288         lctl set_param llite.*.xattr_cache=0
29289         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29290
29291         # clear clients mdc stats
29292         clear_stats $mdc_stat_param ||
29293                 error "fail to clear stats on mdc MDT0000"
29294
29295         for file in $DIR/$tdir/$tfile-{001..100}; do
29296                 getfattr -n security.selinux $file |&
29297                         grep -q "Operation not supported" ||
29298                         error "getxattr on security.selinux should return EOPNOTSUPP"
29299         done
29300
29301         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29302         (( getxattr_count < 100 )) ||
29303                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29304 }
29305 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29306
29307 test_440() {
29308         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29309                 source $LUSTRE/scripts/bash-completion/lustre
29310         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29311                 source /usr/share/bash-completion/completions/lustre
29312         else
29313                 skip "bash completion scripts not found"
29314         fi
29315
29316         local lctl_completions
29317         local lfs_completions
29318
29319         lctl_completions=$(_lustre_cmds lctl)
29320         if [[ ! $lctl_completions =~ "get_param" ]]; then
29321                 error "lctl bash completion failed"
29322         fi
29323
29324         lfs_completions=$(_lustre_cmds lfs)
29325         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29326                 error "lfs bash completion failed"
29327         fi
29328 }
29329 run_test 440 "bash completion for lfs, lctl"
29330
29331 prep_801() {
29332         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29333         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29334                 skip "Need server version at least 2.9.55"
29335
29336         start_full_debug_logging
29337 }
29338
29339 post_801() {
29340         stop_full_debug_logging
29341 }
29342
29343 barrier_stat() {
29344         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29345                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29346                            awk '/The barrier for/ { print $7 }')
29347                 echo $st
29348         else
29349                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29350                 echo \'$st\'
29351         fi
29352 }
29353
29354 barrier_expired() {
29355         local expired
29356
29357         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29358                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29359                           awk '/will be expired/ { print $7 }')
29360         else
29361                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29362         fi
29363
29364         echo $expired
29365 }
29366
29367 test_801a() {
29368         prep_801
29369
29370         echo "Start barrier_freeze at: $(date)"
29371         #define OBD_FAIL_BARRIER_DELAY          0x2202
29372         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29373         # Do not reduce barrier time - See LU-11873
29374         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29375
29376         sleep 2
29377         local b_status=$(barrier_stat)
29378         echo "Got barrier status at: $(date)"
29379         [ "$b_status" = "'freezing_p1'" ] ||
29380                 error "(1) unexpected barrier status $b_status"
29381
29382         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29383         wait
29384         b_status=$(barrier_stat)
29385         [ "$b_status" = "'frozen'" ] ||
29386                 error "(2) unexpected barrier status $b_status"
29387
29388         local expired=$(barrier_expired)
29389         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29390         sleep $((expired + 3))
29391
29392         b_status=$(barrier_stat)
29393         [ "$b_status" = "'expired'" ] ||
29394                 error "(3) unexpected barrier status $b_status"
29395
29396         # Do not reduce barrier time - See LU-11873
29397         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29398                 error "(4) fail to freeze barrier"
29399
29400         b_status=$(barrier_stat)
29401         [ "$b_status" = "'frozen'" ] ||
29402                 error "(5) unexpected barrier status $b_status"
29403
29404         echo "Start barrier_thaw at: $(date)"
29405         #define OBD_FAIL_BARRIER_DELAY          0x2202
29406         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29407         do_facet mgs $LCTL barrier_thaw $FSNAME &
29408
29409         sleep 2
29410         b_status=$(barrier_stat)
29411         echo "Got barrier status at: $(date)"
29412         [ "$b_status" = "'thawing'" ] ||
29413                 error "(6) unexpected barrier status $b_status"
29414
29415         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29416         wait
29417         b_status=$(barrier_stat)
29418         [ "$b_status" = "'thawed'" ] ||
29419                 error "(7) unexpected barrier status $b_status"
29420
29421         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29422         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29423         do_facet mgs $LCTL barrier_freeze $FSNAME
29424
29425         b_status=$(barrier_stat)
29426         [ "$b_status" = "'failed'" ] ||
29427                 error "(8) unexpected barrier status $b_status"
29428
29429         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29430         do_facet mgs $LCTL barrier_thaw $FSNAME
29431
29432         post_801
29433 }
29434 run_test 801a "write barrier user interfaces and stat machine"
29435
29436 test_801b() {
29437         prep_801
29438
29439         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29440         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29441         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29442         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29443         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29444
29445         cancel_lru_locks mdc
29446
29447         # 180 seconds should be long enough
29448         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29449
29450         local b_status=$(barrier_stat)
29451         [ "$b_status" = "'frozen'" ] ||
29452                 error "(6) unexpected barrier status $b_status"
29453
29454         mkdir $DIR/$tdir/d0/d10 &
29455         mkdir_pid=$!
29456
29457         touch $DIR/$tdir/d1/f13 &
29458         touch_pid=$!
29459
29460         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29461         ln_pid=$!
29462
29463         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29464         mv_pid=$!
29465
29466         rm -f $DIR/$tdir/d4/f12 &
29467         rm_pid=$!
29468
29469         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29470
29471         # To guarantee taht the 'stat' is not blocked
29472         b_status=$(barrier_stat)
29473         [ "$b_status" = "'frozen'" ] ||
29474                 error "(8) unexpected barrier status $b_status"
29475
29476         # let above commands to run at background
29477         sleep 5
29478
29479         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29480         ps -p $touch_pid || error "(10) touch should be blocked"
29481         ps -p $ln_pid || error "(11) link should be blocked"
29482         ps -p $mv_pid || error "(12) rename should be blocked"
29483         ps -p $rm_pid || error "(13) unlink should be blocked"
29484
29485         b_status=$(barrier_stat)
29486         [ "$b_status" = "'frozen'" ] ||
29487                 error "(14) unexpected barrier status $b_status"
29488
29489         do_facet mgs $LCTL barrier_thaw $FSNAME
29490         b_status=$(barrier_stat)
29491         [ "$b_status" = "'thawed'" ] ||
29492                 error "(15) unexpected barrier status $b_status"
29493
29494         wait $mkdir_pid || error "(16) mkdir should succeed"
29495         wait $touch_pid || error "(17) touch should succeed"
29496         wait $ln_pid || error "(18) link should succeed"
29497         wait $mv_pid || error "(19) rename should succeed"
29498         wait $rm_pid || error "(20) unlink should succeed"
29499
29500         post_801
29501 }
29502 run_test 801b "modification will be blocked by write barrier"
29503
29504 test_801c() {
29505         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29506
29507         prep_801
29508
29509         stop mds2 || error "(1) Fail to stop mds2"
29510
29511         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29512
29513         local b_status=$(barrier_stat)
29514         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29515                 do_facet mgs $LCTL barrier_thaw $FSNAME
29516                 error "(2) unexpected barrier status $b_status"
29517         }
29518
29519         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29520                 error "(3) Fail to rescan barrier bitmap"
29521
29522         # Do not reduce barrier time - See LU-11873
29523         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29524
29525         b_status=$(barrier_stat)
29526         [ "$b_status" = "'frozen'" ] ||
29527                 error "(4) unexpected barrier status $b_status"
29528
29529         do_facet mgs $LCTL barrier_thaw $FSNAME
29530         b_status=$(barrier_stat)
29531         [ "$b_status" = "'thawed'" ] ||
29532                 error "(5) unexpected barrier status $b_status"
29533
29534         local devname=$(mdsdevname 2)
29535
29536         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29537
29538         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29539                 error "(7) Fail to rescan barrier bitmap"
29540
29541         post_801
29542 }
29543 run_test 801c "rescan barrier bitmap"
29544
29545 test_802b() {
29546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29547         remote_mds_nodsh && skip "remote MDS with nodsh"
29548
29549         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29550                 skip "readonly option not available"
29551
29552         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29553
29554         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29555                 error "(2) Fail to copy"
29556
29557         # write back all cached data before setting MDT to readonly
29558         cancel_lru_locks
29559         sync_all_data
29560
29561         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29562         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29563
29564         echo "Modify should be refused"
29565         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29566
29567         echo "Read should be allowed"
29568         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29569                 error "(7) Read should succeed under ro mode"
29570
29571         # disable readonly
29572         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29573 }
29574 run_test 802b "be able to set MDTs to readonly"
29575
29576 test_803a() {
29577         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29578         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29579                 skip "MDS needs to be newer than 2.10.54"
29580
29581         mkdir_on_mdt0 $DIR/$tdir
29582         # Create some objects on all MDTs to trigger related logs objects
29583         for idx in $(seq $MDSCOUNT); do
29584                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29585                         $DIR/$tdir/dir${idx} ||
29586                         error "Fail to create $DIR/$tdir/dir${idx}"
29587         done
29588
29589         wait_delete_completed # ensure old test cleanups are finished
29590         sleep 3
29591         echo "before create:"
29592         $LFS df -i $MOUNT
29593         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29594
29595         for i in {1..10}; do
29596                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29597                         error "Fail to create $DIR/$tdir/foo$i"
29598         done
29599
29600         # sync ZFS-on-MDS to refresh statfs data
29601         wait_zfs_commit mds1
29602         sleep 3
29603         echo "after create:"
29604         $LFS df -i $MOUNT
29605         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29606
29607         # allow for an llog to be cleaned up during the test
29608         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29609                 error "before ($before_used) + 10 > after ($after_used)"
29610
29611         for i in {1..10}; do
29612                 rm -rf $DIR/$tdir/foo$i ||
29613                         error "Fail to remove $DIR/$tdir/foo$i"
29614         done
29615
29616         # sync ZFS-on-MDS to refresh statfs data
29617         wait_zfs_commit mds1
29618         wait_delete_completed
29619         sleep 3 # avoid MDT return cached statfs
29620         echo "after unlink:"
29621         $LFS df -i $MOUNT
29622         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29623
29624         # allow for an llog to be created during the test
29625         [ $after_used -le $((before_used + 1)) ] ||
29626                 error "after ($after_used) > before ($before_used) + 1"
29627 }
29628 run_test 803a "verify agent object for remote object"
29629
29630 test_803b() {
29631         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29632         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29633                 skip "MDS needs to be newer than 2.13.56"
29634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29635
29636         for i in $(seq 0 $((MDSCOUNT - 1))); do
29637                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29638         done
29639
29640         local before=0
29641         local after=0
29642
29643         local tmp
29644
29645         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29646         for i in $(seq 0 $((MDSCOUNT - 1))); do
29647                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29648                         awk '/getattr/ { print $2 }')
29649                 before=$((before + tmp))
29650         done
29651         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29652         for i in $(seq 0 $((MDSCOUNT - 1))); do
29653                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29654                         awk '/getattr/ { print $2 }')
29655                 after=$((after + tmp))
29656         done
29657
29658         [ $before -eq $after ] || error "getattr count $before != $after"
29659 }
29660 run_test 803b "remote object can getattr from cache"
29661
29662 test_804() {
29663         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29664         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29665                 skip "MDS needs to be newer than 2.10.54"
29666         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29667
29668         mkdir -p $DIR/$tdir
29669         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29670                 error "Fail to create $DIR/$tdir/dir0"
29671
29672         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29673         local dev=$(mdsdevname 2)
29674
29675         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29676                 grep ${fid} || error "NOT found agent entry for dir0"
29677
29678         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29679                 error "Fail to create $DIR/$tdir/dir1"
29680
29681         touch $DIR/$tdir/dir1/foo0 ||
29682                 error "Fail to create $DIR/$tdir/dir1/foo0"
29683         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29684         local rc=0
29685
29686         for idx in $(seq $MDSCOUNT); do
29687                 dev=$(mdsdevname $idx)
29688                 do_facet mds${idx} \
29689                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29690                         grep ${fid} && rc=$idx
29691         done
29692
29693         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29694                 error "Fail to rename foo0 to foo1"
29695         if [ $rc -eq 0 ]; then
29696                 for idx in $(seq $MDSCOUNT); do
29697                         dev=$(mdsdevname $idx)
29698                         do_facet mds${idx} \
29699                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29700                         grep ${fid} && rc=$idx
29701                 done
29702         fi
29703
29704         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29705                 error "Fail to rename foo1 to foo2"
29706         if [ $rc -eq 0 ]; then
29707                 for idx in $(seq $MDSCOUNT); do
29708                         dev=$(mdsdevname $idx)
29709                         do_facet mds${idx} \
29710                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29711                         grep ${fid} && rc=$idx
29712                 done
29713         fi
29714
29715         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29716
29717         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29718                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29719         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29720                 error "Fail to rename foo2 to foo0"
29721         unlink $DIR/$tdir/dir1/foo0 ||
29722                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29723         rm -rf $DIR/$tdir/dir0 ||
29724                 error "Fail to rm $DIR/$tdir/dir0"
29725
29726         for idx in $(seq $MDSCOUNT); do
29727                 rc=0
29728
29729                 stop mds${idx}
29730                 dev=$(mdsdevname $idx)
29731                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29732                         rc=$?
29733                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29734                         error "mount mds$idx failed"
29735                 df $MOUNT > /dev/null 2>&1
29736
29737                 # e2fsck should not return error
29738                 [ $rc -eq 0 ] ||
29739                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29740         done
29741 }
29742 run_test 804 "verify agent entry for remote entry"
29743
29744 cleanup_805() {
29745         do_facet $SINGLEMDS zfs set quota=$old $fsset
29746         unlinkmany $DIR/$tdir/f- 1000000
29747         trap 0
29748 }
29749
29750 test_805() {
29751         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29752         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29753         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29754                 skip "netfree not implemented before 0.7"
29755         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29756                 skip "Need MDS version at least 2.10.57"
29757
29758         local fsset
29759         local freekb
29760         local usedkb
29761         local old
29762         local quota
29763         local pref="osd-zfs.$FSNAME-MDT0000."
29764
29765         # limit available space on MDS dataset to meet nospace issue
29766         # quickly. then ZFS 0.7.2 can use reserved space if asked
29767         # properly (using netfree flag in osd_declare_destroy()
29768         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29769         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29770                 gawk '{print $3}')
29771         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29772         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29773         let "usedkb=usedkb-freekb"
29774         let "freekb=freekb/2"
29775         if let "freekb > 5000"; then
29776                 let "freekb=5000"
29777         fi
29778         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29779         trap cleanup_805 EXIT
29780         mkdir_on_mdt0 $DIR/$tdir
29781         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29782                 error "Can't set PFL layout"
29783         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29784         rm -rf $DIR/$tdir || error "not able to remove"
29785         do_facet $SINGLEMDS zfs set quota=$old $fsset
29786         trap 0
29787 }
29788 run_test 805 "ZFS can remove from full fs"
29789
29790 # Size-on-MDS test
29791 check_lsom_data()
29792 {
29793         local file=$1
29794         local expect=$(stat -c %s $file)
29795
29796         check_lsom_size $1 $expect
29797
29798         local blocks=$($LFS getsom -b $file)
29799         expect=$(stat -c %b $file)
29800         [[ $blocks == $expect ]] ||
29801                 error "$file expected blocks: $expect, got: $blocks"
29802 }
29803
29804 check_lsom_size()
29805 {
29806         local size
29807         local expect=$2
29808
29809         cancel_lru_locks mdc
29810
29811         size=$($LFS getsom -s $1)
29812         [[ $size == $expect ]] ||
29813                 error "$file expected size: $expect, got: $size"
29814 }
29815
29816 test_806() {
29817         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29818                 skip "Need MDS version at least 2.11.52"
29819
29820         local bs=1048576
29821
29822         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29823
29824         disable_opencache
29825         stack_trap "restore_opencache"
29826
29827         # single-threaded write
29828         echo "Test SOM for single-threaded write"
29829         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29830                 error "write $tfile failed"
29831         check_lsom_size $DIR/$tfile $bs
29832
29833         local num=32
29834         local size=$(($num * $bs))
29835         local offset=0
29836         local i
29837
29838         echo "Test SOM for single client multi-threaded($num) write"
29839         $TRUNCATE $DIR/$tfile 0
29840         for ((i = 0; i < $num; i++)); do
29841                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29842                 local pids[$i]=$!
29843                 offset=$((offset + $bs))
29844         done
29845         for (( i=0; i < $num; i++ )); do
29846                 wait ${pids[$i]}
29847         done
29848         check_lsom_size $DIR/$tfile $size
29849
29850         $TRUNCATE $DIR/$tfile 0
29851         for ((i = 0; i < $num; i++)); do
29852                 offset=$((offset - $bs))
29853                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29854                 local pids[$i]=$!
29855         done
29856         for (( i=0; i < $num; i++ )); do
29857                 wait ${pids[$i]}
29858         done
29859         check_lsom_size $DIR/$tfile $size
29860
29861         # multi-client writes
29862         num=$(get_node_count ${CLIENTS//,/ })
29863         size=$(($num * $bs))
29864         offset=0
29865         i=0
29866
29867         echo "Test SOM for multi-client ($num) writes"
29868         $TRUNCATE $DIR/$tfile 0
29869         for client in ${CLIENTS//,/ }; do
29870                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29871                 local pids[$i]=$!
29872                 i=$((i + 1))
29873                 offset=$((offset + $bs))
29874         done
29875         for (( i=0; i < $num; i++ )); do
29876                 wait ${pids[$i]}
29877         done
29878         check_lsom_size $DIR/$tfile $offset
29879
29880         i=0
29881         $TRUNCATE $DIR/$tfile 0
29882         for client in ${CLIENTS//,/ }; do
29883                 offset=$((offset - $bs))
29884                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29885                 local pids[$i]=$!
29886                 i=$((i + 1))
29887         done
29888         for (( i=0; i < $num; i++ )); do
29889                 wait ${pids[$i]}
29890         done
29891         check_lsom_size $DIR/$tfile $size
29892
29893         # verify SOM blocks count
29894         echo "Verify SOM block count"
29895         $TRUNCATE $DIR/$tfile 0
29896         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29897                 error "failed to write file $tfile with fdatasync and fstat"
29898         check_lsom_data $DIR/$tfile
29899
29900         $TRUNCATE $DIR/$tfile 0
29901         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29902                 error "failed to write file $tfile with fdatasync"
29903         check_lsom_data $DIR/$tfile
29904
29905         $TRUNCATE $DIR/$tfile 0
29906         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29907                 error "failed to write file $tfile with sync IO"
29908         check_lsom_data $DIR/$tfile
29909
29910         # verify truncate
29911         echo "Test SOM for truncate"
29912         # use ftruncate to sync blocks on close request
29913         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29914         check_lsom_size $DIR/$tfile 16384
29915         check_lsom_data $DIR/$tfile
29916
29917         $TRUNCATE $DIR/$tfile 1234
29918         check_lsom_size $DIR/$tfile 1234
29919         # sync blocks on the MDT
29920         $MULTIOP $DIR/$tfile oc
29921         check_lsom_data $DIR/$tfile
29922 }
29923 run_test 806 "Verify Lazy Size on MDS"
29924
29925 test_807() {
29926         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29927         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29928                 skip "Need MDS version at least 2.11.52"
29929
29930         # Registration step
29931         changelog_register || error "changelog_register failed"
29932         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29933         changelog_users $SINGLEMDS | grep -q $cl_user ||
29934                 error "User $cl_user not found in changelog_users"
29935
29936         rm -rf $DIR/$tdir || error "rm $tdir failed"
29937         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29938         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29939         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29940         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29941                 error "truncate $tdir/trunc failed"
29942
29943         local bs=1048576
29944         echo "Test SOM for single-threaded write with fsync"
29945         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29946                 error "write $tfile failed"
29947         sync;sync;sync
29948
29949         # multi-client wirtes
29950         local num=$(get_node_count ${CLIENTS//,/ })
29951         local offset=0
29952         local i=0
29953
29954         echo "Test SOM for multi-client ($num) writes"
29955         touch $DIR/$tfile || error "touch $tfile failed"
29956         $TRUNCATE $DIR/$tfile 0
29957         for client in ${CLIENTS//,/ }; do
29958                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29959                 local pids[$i]=$!
29960                 i=$((i + 1))
29961                 offset=$((offset + $bs))
29962         done
29963         for (( i=0; i < $num; i++ )); do
29964                 wait ${pids[$i]}
29965         done
29966
29967         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29968         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29969         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29970         check_lsom_data $DIR/$tdir/trunc
29971         check_lsom_data $DIR/$tdir/single_dd
29972         check_lsom_data $DIR/$tfile
29973
29974         rm -rf $DIR/$tdir
29975         # Deregistration step
29976         changelog_deregister || error "changelog_deregister failed"
29977 }
29978 run_test 807 "verify LSOM syncing tool"
29979
29980 check_som_nologged()
29981 {
29982         local lines=$($LFS changelog $FSNAME-MDT0000 |
29983                 grep 'x=trusted.som' | wc -l)
29984         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29985 }
29986
29987 test_808() {
29988         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29989                 skip "Need MDS version at least 2.11.55"
29990
29991         # Registration step
29992         changelog_register || error "changelog_register failed"
29993
29994         touch $DIR/$tfile || error "touch $tfile failed"
29995         check_som_nologged
29996
29997         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29998                 error "write $tfile failed"
29999         check_som_nologged
30000
30001         $TRUNCATE $DIR/$tfile 1234
30002         check_som_nologged
30003
30004         $TRUNCATE $DIR/$tfile 1048576
30005         check_som_nologged
30006
30007         # Deregistration step
30008         changelog_deregister || error "changelog_deregister failed"
30009 }
30010 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30011
30012 check_som_nodata()
30013 {
30014         $LFS getsom $1
30015         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30016 }
30017
30018 test_809() {
30019         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30020                 skip "Need MDS version at least 2.11.56"
30021
30022         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30023                 error "failed to create DoM-only file $DIR/$tfile"
30024         touch $DIR/$tfile || error "touch $tfile failed"
30025         check_som_nodata $DIR/$tfile
30026
30027         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30028                 error "write $tfile failed"
30029         check_som_nodata $DIR/$tfile
30030
30031         $TRUNCATE $DIR/$tfile 1234
30032         check_som_nodata $DIR/$tfile
30033
30034         $TRUNCATE $DIR/$tfile 4097
30035         check_som_nodata $DIR/$file
30036 }
30037 run_test 809 "Verify no SOM xattr store for DoM-only files"
30038
30039 test_810() {
30040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30041         $GSS && skip_env "could not run with gss"
30042         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30043                 skip "OST < 2.12.58 doesn't align checksum"
30044
30045         set_checksums 1
30046         stack_trap "set_checksums $ORIG_CSUM" EXIT
30047         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30048
30049         local csum
30050         local before
30051         local after
30052         for csum in $CKSUM_TYPES; do
30053                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30054                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30055                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30056                         eval set -- $i
30057                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30058                         before=$(md5sum $DIR/$tfile)
30059                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30060                         after=$(md5sum $DIR/$tfile)
30061                         [ "$before" == "$after" ] ||
30062                                 error "$csum: $before != $after bs=$1 seek=$2"
30063                 done
30064         done
30065 }
30066 run_test 810 "partial page writes on ZFS (LU-11663)"
30067
30068 test_812a() {
30069         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30070                 skip "OST < 2.12.51 doesn't support this fail_loc"
30071
30072         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30073         # ensure ost1 is connected
30074         stat $DIR/$tfile >/dev/null || error "can't stat"
30075         wait_osc_import_state client ost1 FULL
30076         # no locks, no reqs to let the connection idle
30077         cancel_lru_locks osc
30078
30079         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30080 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30081         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30082         wait_osc_import_state client ost1 CONNECTING
30083         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30084
30085         stat $DIR/$tfile >/dev/null || error "can't stat file"
30086 }
30087 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30088
30089 test_812b() { # LU-12378
30090         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30091                 skip "OST < 2.12.51 doesn't support this fail_loc"
30092
30093         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30094         # ensure ost1 is connected
30095         stat $DIR/$tfile >/dev/null || error "can't stat"
30096         wait_osc_import_state client ost1 FULL
30097         # no locks, no reqs to let the connection idle
30098         cancel_lru_locks osc
30099
30100         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30101 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30102         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30103         wait_osc_import_state client ost1 CONNECTING
30104         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30105
30106         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30107         wait_osc_import_state client ost1 IDLE
30108 }
30109 run_test 812b "do not drop no resend request for idle connect"
30110
30111 test_812c() {
30112         local old
30113
30114         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30115
30116         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30117         $LFS getstripe $DIR/$tfile
30118         $LCTL set_param osc.*.idle_timeout=10
30119         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30120         # ensure ost1 is connected
30121         stat $DIR/$tfile >/dev/null || error "can't stat"
30122         wait_osc_import_state client ost1 FULL
30123         # no locks, no reqs to let the connection idle
30124         cancel_lru_locks osc
30125
30126 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30127         $LCTL set_param fail_loc=0x80000533
30128         sleep 15
30129         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30130 }
30131 run_test 812c "idle import vs lock enqueue race"
30132
30133 test_813() {
30134         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30135         [ -z "$file_heat_sav" ] && skip "no file heat support"
30136
30137         local readsample
30138         local writesample
30139         local readbyte
30140         local writebyte
30141         local readsample1
30142         local writesample1
30143         local readbyte1
30144         local writebyte1
30145
30146         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30147         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30148
30149         $LCTL set_param -n llite.*.file_heat=1
30150         echo "Turn on file heat"
30151         echo "Period second: $period_second, Decay percentage: $decay_pct"
30152
30153         echo "QQQQ" > $DIR/$tfile
30154         echo "QQQQ" > $DIR/$tfile
30155         echo "QQQQ" > $DIR/$tfile
30156         cat $DIR/$tfile > /dev/null
30157         cat $DIR/$tfile > /dev/null
30158         cat $DIR/$tfile > /dev/null
30159         cat $DIR/$tfile > /dev/null
30160
30161         local out=$($LFS heat_get $DIR/$tfile)
30162
30163         $LFS heat_get $DIR/$tfile
30164         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30165         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30166         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30167         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30168
30169         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30170         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30171         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30172         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30173
30174         sleep $((period_second + 3))
30175         echo "Sleep $((period_second + 3)) seconds..."
30176         # The recursion formula to calculate the heat of the file f is as
30177         # follow:
30178         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30179         # Where Hi is the heat value in the period between time points i*I and
30180         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30181         # to the weight of Ci.
30182         out=$($LFS heat_get $DIR/$tfile)
30183         $LFS heat_get $DIR/$tfile
30184         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30185         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30186         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30187         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30188
30189         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30190                 error "read sample ($readsample) is wrong"
30191         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30192                 error "write sample ($writesample) is wrong"
30193         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30194                 error "read bytes ($readbyte) is wrong"
30195         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30196                 error "write bytes ($writebyte) is wrong"
30197
30198         echo "QQQQ" > $DIR/$tfile
30199         echo "QQQQ" > $DIR/$tfile
30200         echo "QQQQ" > $DIR/$tfile
30201         cat $DIR/$tfile > /dev/null
30202         cat $DIR/$tfile > /dev/null
30203         cat $DIR/$tfile > /dev/null
30204         cat $DIR/$tfile > /dev/null
30205
30206         sleep $((period_second + 3))
30207         echo "Sleep $((period_second + 3)) seconds..."
30208
30209         out=$($LFS heat_get $DIR/$tfile)
30210         $LFS heat_get $DIR/$tfile
30211         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30212         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30213         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30214         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30215
30216         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30217                 4 * $decay_pct) / 100") -eq 1 ] ||
30218                 error "read sample ($readsample1) is wrong"
30219         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30220                 3 * $decay_pct) / 100") -eq 1 ] ||
30221                 error "write sample ($writesample1) is wrong"
30222         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30223                 20 * $decay_pct) / 100") -eq 1 ] ||
30224                 error "read bytes ($readbyte1) is wrong"
30225         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30226                 15 * $decay_pct) / 100") -eq 1 ] ||
30227                 error "write bytes ($writebyte1) is wrong"
30228
30229         echo "Turn off file heat for the file $DIR/$tfile"
30230         $LFS heat_set -o $DIR/$tfile
30231
30232         echo "QQQQ" > $DIR/$tfile
30233         echo "QQQQ" > $DIR/$tfile
30234         echo "QQQQ" > $DIR/$tfile
30235         cat $DIR/$tfile > /dev/null
30236         cat $DIR/$tfile > /dev/null
30237         cat $DIR/$tfile > /dev/null
30238         cat $DIR/$tfile > /dev/null
30239
30240         out=$($LFS heat_get $DIR/$tfile)
30241         $LFS heat_get $DIR/$tfile
30242         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30243         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30244         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30245         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30246
30247         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30248         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30249         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30250         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30251
30252         echo "Trun on file heat for the file $DIR/$tfile"
30253         $LFS heat_set -O $DIR/$tfile
30254
30255         echo "QQQQ" > $DIR/$tfile
30256         echo "QQQQ" > $DIR/$tfile
30257         echo "QQQQ" > $DIR/$tfile
30258         cat $DIR/$tfile > /dev/null
30259         cat $DIR/$tfile > /dev/null
30260         cat $DIR/$tfile > /dev/null
30261         cat $DIR/$tfile > /dev/null
30262
30263         out=$($LFS heat_get $DIR/$tfile)
30264         $LFS heat_get $DIR/$tfile
30265         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30266         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30267         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30268         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30269
30270         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30271         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30272         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30273         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30274
30275         $LFS heat_set -c $DIR/$tfile
30276         $LCTL set_param -n llite.*.file_heat=0
30277         echo "Turn off file heat support for the Lustre filesystem"
30278
30279         echo "QQQQ" > $DIR/$tfile
30280         echo "QQQQ" > $DIR/$tfile
30281         echo "QQQQ" > $DIR/$tfile
30282         cat $DIR/$tfile > /dev/null
30283         cat $DIR/$tfile > /dev/null
30284         cat $DIR/$tfile > /dev/null
30285         cat $DIR/$tfile > /dev/null
30286
30287         out=$($LFS heat_get $DIR/$tfile)
30288         $LFS heat_get $DIR/$tfile
30289         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30290         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30291         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30292         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30293
30294         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30295         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30296         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30297         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30298
30299         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30300         rm -f $DIR/$tfile
30301 }
30302 run_test 813 "File heat verfication"
30303
30304 test_814()
30305 {
30306         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30307         echo -n y >> $DIR/$tfile
30308         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30309         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30310 }
30311 run_test 814 "sparse cp works as expected (LU-12361)"
30312
30313 test_815()
30314 {
30315         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30316         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30317 }
30318 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30319
30320 test_816() {
30321         local ost1_imp=$(get_osc_import_name client ost1)
30322         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30323                          cut -d'.' -f2)
30324
30325         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30326         # ensure ost1 is connected
30327
30328         stat $DIR/$tfile >/dev/null || error "can't stat"
30329         wait_osc_import_state client ost1 FULL
30330         # no locks, no reqs to let the connection idle
30331         cancel_lru_locks osc
30332         lru_resize_disable osc
30333         local before
30334         local now
30335         before=$($LCTL get_param -n \
30336                  ldlm.namespaces.$imp_name.lru_size)
30337
30338         wait_osc_import_state client ost1 IDLE
30339         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30340         now=$($LCTL get_param -n \
30341               ldlm.namespaces.$imp_name.lru_size)
30342         [ $before == $now ] || error "lru_size changed $before != $now"
30343 }
30344 run_test 816 "do not reset lru_resize on idle reconnect"
30345
30346 cleanup_817() {
30347         umount $tmpdir
30348         exportfs -u localhost:$DIR/nfsexp
30349         rm -rf $DIR/nfsexp
30350 }
30351
30352 test_817() {
30353         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30354
30355         mkdir -p $DIR/nfsexp
30356         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30357                 error "failed to export nfs"
30358
30359         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30360         stack_trap cleanup_817 EXIT
30361
30362         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30363                 error "failed to mount nfs to $tmpdir"
30364
30365         cp /bin/true $tmpdir
30366         $DIR/nfsexp/true || error "failed to execute 'true' command"
30367 }
30368 run_test 817 "nfsd won't cache write lock for exec file"
30369
30370 test_818() {
30371         test_mkdir -i0 -c1 $DIR/$tdir
30372         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30373         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30374         stop $SINGLEMDS
30375
30376         # restore osp-syn threads
30377         stack_trap "fail $SINGLEMDS"
30378
30379         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30380         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30381         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30382                 error "start $SINGLEMDS failed"
30383         rm -rf $DIR/$tdir
30384
30385         local testid=$(echo $TESTNAME | tr '_' ' ')
30386
30387         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30388                 grep "run LFSCK" || error "run LFSCK is not suggested"
30389 }
30390 run_test 818 "unlink with failed llog"
30391
30392 test_819a() {
30393         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30394         cancel_lru_locks osc
30395         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30396         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30397         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30398         rm -f $TDIR/$tfile
30399 }
30400 run_test 819a "too big niobuf in read"
30401
30402 test_819b() {
30403         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30404         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30405         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30406         cancel_lru_locks osc
30407         sleep 1
30408         rm -f $TDIR/$tfile
30409 }
30410 run_test 819b "too big niobuf in write"
30411
30412
30413 function test_820_start_ost() {
30414         sleep 5
30415
30416         for num in $(seq $OSTCOUNT); do
30417                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30418         done
30419 }
30420
30421 test_820() {
30422         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30423
30424         mkdir $DIR/$tdir
30425         umount_client $MOUNT || error "umount failed"
30426         for num in $(seq $OSTCOUNT); do
30427                 stop ost$num
30428         done
30429
30430         # mount client with no active OSTs
30431         # so that the client can't initialize max LOV EA size
30432         # from OSC notifications
30433         mount_client $MOUNT || error "mount failed"
30434         # delay OST starting to keep this 0 max EA size for a while
30435         test_820_start_ost &
30436
30437         # create a directory on MDS2
30438         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30439                 error "Failed to create directory"
30440         # open intent should update default EA size
30441         # see mdc_update_max_ea_from_body()
30442         # notice this is the very first RPC to MDS2
30443         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30444         ret=$?
30445         echo $out
30446         # With SSK, this situation can lead to -EPERM being returned.
30447         # In that case, simply retry.
30448         if [ $ret -ne 0 ] && $SHARED_KEY; then
30449                 if echo "$out" | grep -q "not permitted"; then
30450                         cp /etc/services $DIR/$tdir/mds2
30451                         ret=$?
30452                 fi
30453         fi
30454         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30455 }
30456 run_test 820 "update max EA from open intent"
30457
30458 test_823() {
30459         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30460         local OST_MAX_PRECREATE=20000
30461
30462         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30463                 skip "Need MDS version at least 2.14.56"
30464
30465         save_lustre_params mds1 \
30466                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30467         do_facet $SINGLEMDS "$LCTL set_param -n \
30468                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30469         do_facet $SINGLEMDS "$LCTL set_param -n \
30470                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30471
30472         stack_trap "restore_lustre_params < $p; rm $p"
30473
30474         do_facet $SINGLEMDS "$LCTL set_param -n \
30475                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30476
30477         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30478                       osp.$FSNAME-OST0000*MDT0000.create_count")
30479         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30480                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30481         local expect_count=$(((($max/2)/256) * 256))
30482
30483         log "setting create_count to 100200:"
30484         log " -result- count: $count with max: $max, expecting: $expect_count"
30485
30486         [[ $count -eq expect_count ]] ||
30487                 error "Create count not set to max precreate."
30488 }
30489 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30490
30491 test_831() {
30492         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30493                 skip "Need MDS version 2.14.56"
30494
30495         local sync_changes=$(do_facet $SINGLEMDS \
30496                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30497
30498         [ "$sync_changes" -gt 100 ] &&
30499                 skip "Sync changes $sync_changes > 100 already"
30500
30501         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30502
30503         $LFS mkdir -i 0 $DIR/$tdir
30504         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30505
30506         save_lustre_params mds1 \
30507                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30508         save_lustre_params mds1 \
30509                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30510
30511         do_facet mds1 "$LCTL set_param -n \
30512                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30513                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30514         stack_trap "restore_lustre_params < $p" EXIT
30515
30516         createmany -o $DIR/$tdir/f- 1000
30517         unlinkmany $DIR/$tdir/f- 1000 &
30518         local UNLINK_PID=$!
30519
30520         while sleep 1; do
30521                 sync_changes=$(do_facet mds1 \
30522                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30523                 # the check in the code is racy, fail the test
30524                 # if the value above the limit by 10.
30525                 [ $sync_changes -gt 110 ] && {
30526                         kill -2 $UNLINK_PID
30527                         wait
30528                         error "osp changes throttling failed, $sync_changes>110"
30529                 }
30530                 kill -0 $UNLINK_PID 2> /dev/null || break
30531         done
30532         wait
30533 }
30534 run_test 831 "throttling unlink/setattr queuing on OSP"
30535
30536 test_832() {
30537         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30538         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30539                 skip "Need MDS version 2.15.52+"
30540         is_rmentry_supported || skip "rm_entry not supported"
30541
30542         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30543         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30544         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30545                 error "mkdir remote_dir failed"
30546         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30547                 error "mkdir striped_dir failed"
30548         touch $DIR/$tdir/file || error "touch file failed"
30549         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30550         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30551 }
30552 run_test 832 "lfs rm_entry"
30553
30554 test_833() {
30555         local file=$DIR/$tfile
30556
30557         stack_trap "rm -f $file" EXIT
30558         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30559
30560         local wpid
30561         local rpid
30562         local rpid2
30563
30564         # Buffered I/O write
30565         (
30566                 while [ ! -e $DIR/sanity.833.lck ]; do
30567                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30568                                 error "failed to write $file"
30569                         sleep 0.$((RANDOM % 4 + 1))
30570                 done
30571         )&
30572         wpid=$!
30573
30574         # Buffered I/O read
30575         (
30576                 while [ ! -e $DIR/sanity.833.lck ]; do
30577                         dd if=$file of=/dev/null bs=1M count=50 ||
30578                                 error "failed to read $file"
30579                         sleep 0.$((RANDOM % 4 + 1))
30580                 done
30581         )&
30582         rpid=$!
30583
30584         # Direct I/O read
30585         (
30586                 while [ ! -e $DIR/sanity.833.lck ]; do
30587                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30588                                 error "failed to read $file in direct I/O mode"
30589                         sleep 0.$((RANDOM % 4 + 1))
30590                 done
30591         )&
30592         rpid2=$!
30593
30594         sleep 30
30595         touch $DIR/sanity.833.lck
30596         wait $wpid || error "$?: buffered write failed"
30597         wait $rpid || error "$?: buffered read failed"
30598         wait $rpid2 || error "$?: direct read failed"
30599 }
30600 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30601
30602 #
30603 # tests that do cleanup/setup should be run at the end
30604 #
30605
30606 test_900() {
30607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30608         local ls
30609
30610         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30611         $LCTL set_param fail_loc=0x903
30612
30613         cancel_lru_locks MGC
30614
30615         FAIL_ON_ERROR=true cleanup
30616         FAIL_ON_ERROR=true setup
30617 }
30618 run_test 900 "umount should not race with any mgc requeue thread"
30619
30620 # LUS-6253/LU-11185
30621 test_901() {
30622         local old
30623         local count
30624         local oldc
30625         local newc
30626         local olds
30627         local news
30628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30629
30630         # some get_param have a bug to handle dot in param name
30631         cancel_lru_locks MGC
30632         old=$(mount -t lustre | wc -l)
30633         # 1 config+sptlrpc
30634         # 2 params
30635         # 3 nodemap
30636         # 4 IR
30637         old=$((old * 4))
30638         oldc=0
30639         count=0
30640         while [ $old -ne $oldc ]; do
30641                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30642                 sleep 1
30643                 ((count++))
30644                 if [ $count -ge $TIMEOUT ]; then
30645                         error "too large timeout"
30646                 fi
30647         done
30648         umount_client $MOUNT || error "umount failed"
30649         mount_client $MOUNT || error "mount failed"
30650         cancel_lru_locks MGC
30651         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30652
30653         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30654
30655         return 0
30656 }
30657 run_test 901 "don't leak a mgc lock on client umount"
30658
30659 # LU-13377
30660 test_902() {
30661         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30662                 skip "client does not have LU-13377 fix"
30663         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30664         $LCTL set_param fail_loc=0x1415
30665         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30666         cancel_lru_locks osc
30667         rm -f $DIR/$tfile
30668 }
30669 run_test 902 "test short write doesn't hang lustre"
30670
30671 # LU-14711
30672 test_903() {
30673         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30674         echo "blah" > $DIR/${tfile}-2
30675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30676         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30677         $LCTL set_param fail_loc=0x417 fail_val=20
30678
30679         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30680         sleep 1 # To start the destroy
30681         wait_destroy_complete 150 || error "Destroy taking too long"
30682         cat $DIR/$tfile > /dev/null || error "Evicted"
30683 }
30684 run_test 903 "Test long page discard does not cause evictions"
30685
30686 test_904() {
30687         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30688         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30689                 grep -q project || skip "skip project quota not supported"
30690
30691         local testfile="$DIR/$tdir/$tfile"
30692         local xattr="trusted.projid"
30693         local projid
30694         local mdts=$(comma_list $(mdts_nodes))
30695         local saved=$(do_facet mds1 $LCTL get_param -n \
30696                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30697
30698         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30699         stack_trap "do_nodes $mdts $LCTL set_param \
30700                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30701
30702         mkdir -p $DIR/$tdir
30703         touch $testfile
30704         #hide projid xattr on server
30705         $LFS project -p 1 $testfile ||
30706                 error "set $testfile project id failed"
30707         getfattr -m - $testfile | grep $xattr &&
30708                 error "do not show trusted.projid when disabled on server"
30709         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30710         #should be hidden when projid is 0
30711         $LFS project -p 0 $testfile ||
30712                 error "set $testfile project id failed"
30713         getfattr -m - $testfile | grep $xattr &&
30714                 error "do not show trusted.projid with project ID 0"
30715
30716         #still can getxattr explicitly
30717         projid=$(getfattr -n $xattr $testfile |
30718                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30719         [ $projid == "0" ] ||
30720                 error "projid expected 0 not $projid"
30721
30722         #set the projid via setxattr
30723         setfattr -n $xattr -v "1000" $testfile ||
30724                 error "setattr failed with $?"
30725         projid=($($LFS project $testfile))
30726         [ ${projid[0]} == "1000" ] ||
30727                 error "projid expected 1000 not $projid"
30728
30729         #check the new projid via getxattr
30730         $LFS project -p 1001 $testfile ||
30731                 error "set $testfile project id failed"
30732         getfattr -m - $testfile | grep $xattr ||
30733                 error "should show trusted.projid when project ID != 0"
30734         projid=$(getfattr -n $xattr $testfile |
30735                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30736         [ $projid == "1001" ] ||
30737                 error "projid expected 1001 not $projid"
30738
30739         #try to set invalid projid
30740         setfattr -n $xattr -v "4294967295" $testfile &&
30741                 error "set invalid projid should fail"
30742
30743         #remove the xattr means setting projid to 0
30744         setfattr -x $xattr $testfile ||
30745                 error "setfattr failed with $?"
30746         projid=($($LFS project $testfile))
30747         [ ${projid[0]} == "0" ] ||
30748                 error "projid expected 0 not $projid"
30749
30750         #should be hidden when parent has inherit flag and same projid
30751         $LFS project -srp 1002 $DIR/$tdir ||
30752                 error "set $tdir project id failed"
30753         getfattr -m - $testfile | grep $xattr &&
30754                 error "do not show trusted.projid with inherit flag"
30755
30756         #still can getxattr explicitly
30757         projid=$(getfattr -n $xattr $testfile |
30758                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30759         [ $projid == "1002" ] ||
30760                 error "projid expected 1002 not $projid"
30761 }
30762 run_test 904 "virtual project ID xattr"
30763
30764 # LU-8582
30765 test_905() {
30766         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30767                 skip "need OST version >= 2.15.50.220 for fail_loc"
30768
30769         remote_ost_nodsh && skip "remote OST with nodsh"
30770         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30771
30772         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30773
30774         #define OBD_FAIL_OST_OPCODE 0x253
30775         # OST_LADVISE = 21
30776         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30777         $LFS ladvise -a willread $DIR/$tfile &&
30778                 error "unexpected success of ladvise with fault injection"
30779         $LFS ladvise -a willread $DIR/$tfile |&
30780                 grep -q "Operation not supported"
30781         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30782 }
30783 run_test 905 "bad or new opcode should not stuck client"
30784
30785 test_906() {
30786         grep -q io_uring_setup /proc/kallsyms ||
30787                 skip "Client OS does not support io_uring I/O engine"
30788         io_uring_probe || skip "kernel does not support io_uring fully"
30789         which fio || skip_env "no fio installed"
30790         fio --enghelp | grep -q io_uring ||
30791                 skip_env "fio does not support io_uring I/O engine"
30792
30793         local file=$DIR/$tfile
30794         local ioengine="io_uring"
30795         local numjobs=2
30796         local size=50M
30797
30798         fio --name=seqwrite --ioengine=$ioengine        \
30799                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30800                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30801                 error "fio seqwrite $file failed"
30802
30803         fio --name=seqread --ioengine=$ioengine \
30804                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30805                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30806                 error "fio seqread $file failed"
30807
30808         rm -f $file || error "rm -f $file failed"
30809 }
30810 run_test 906 "Simple test for io_uring I/O engine via fio"
30811
30812 complete_test $SECONDS
30813 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30814 check_and_cleanup_lustre
30815 if [ "$I_MOUNTED" != "yes" ]; then
30816         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30817 fi
30818 exit_status