Whamcloud - gitweb
LU-16980 build: fix gcc-12 [-Werror=use-after-free] error
[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         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2592         [ $? -ne 0 ] || error "must be an error for not existent OST#"
2593 }
2594 run_test 27Cg "test setstripe with wrong OST idx"
2595
2596 test_27D() {
2597         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2598         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2599         remote_mds_nodsh && skip "remote MDS with nodsh"
2600
2601         local POOL=${POOL:-testpool}
2602         local first_ost=0
2603         local last_ost=$(($OSTCOUNT - 1))
2604         local ost_step=1
2605         local ost_list=$(seq $first_ost $ost_step $last_ost)
2606         local ost_range="$first_ost $last_ost $ost_step"
2607
2608         test_mkdir $DIR/$tdir
2609         pool_add $POOL || error "pool_add failed"
2610         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2611
2612         local skip27D
2613         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2614                 skip27D+="-s 29"
2615         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2616                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2617                         skip27D+=" -s 30,31"
2618         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2619           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2620                 skip27D+=" -s 32,33"
2621         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2622                 skip27D+=" -s 34"
2623         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2624                 error "llapi_layout_test failed"
2625
2626         destroy_test_pools || error "destroy test pools failed"
2627 }
2628 run_test 27D "validate llapi_layout API"
2629
2630 # Verify that default_easize is increased from its initial value after
2631 # accessing a widely striped file.
2632 test_27E() {
2633         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2634         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2635                 skip "client does not have LU-3338 fix"
2636
2637         # 72 bytes is the minimum space required to store striping
2638         # information for a file striped across one OST:
2639         # (sizeof(struct lov_user_md_v3) +
2640         #  sizeof(struct lov_user_ost_data_v1))
2641         local min_easize=72
2642         $LCTL set_param -n llite.*.default_easize $min_easize ||
2643                 error "lctl set_param failed"
2644         local easize=$($LCTL get_param -n llite.*.default_easize)
2645
2646         [ $easize -eq $min_easize ] ||
2647                 error "failed to set default_easize"
2648
2649         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2650                 error "setstripe failed"
2651         # In order to ensure stat() call actually talks to MDS we need to
2652         # do something drastic to this file to shake off all lock, e.g.
2653         # rename it (kills lookup lock forcing cache cleaning)
2654         mv $DIR/$tfile $DIR/${tfile}-1
2655         ls -l $DIR/${tfile}-1
2656         rm $DIR/${tfile}-1
2657
2658         easize=$($LCTL get_param -n llite.*.default_easize)
2659
2660         [ $easize -gt $min_easize ] ||
2661                 error "default_easize not updated"
2662 }
2663 run_test 27E "check that default extended attribute size properly increases"
2664
2665 test_27F() { # LU-5346/LU-7975
2666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2667         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2668         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2669                 skip "Need MDS version at least 2.8.51"
2670         remote_ost_nodsh && skip "remote OST with nodsh"
2671
2672         test_mkdir $DIR/$tdir
2673         rm -f $DIR/$tdir/f0
2674         $LFS setstripe -c 2 $DIR/$tdir
2675
2676         # stop all OSTs to reproduce situation for LU-7975 ticket
2677         for num in $(seq $OSTCOUNT); do
2678                 stop ost$num
2679         done
2680
2681         # open/create f0 with O_LOV_DELAY_CREATE
2682         # truncate f0 to a non-0 size
2683         # close
2684         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2685
2686         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2687         # open/write it again to force delayed layout creation
2688         cat /etc/hosts > $DIR/$tdir/f0 &
2689         catpid=$!
2690
2691         # restart OSTs
2692         for num in $(seq $OSTCOUNT); do
2693                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2694                         error "ost$num failed to start"
2695         done
2696
2697         wait $catpid || error "cat failed"
2698
2699         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2700         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2701                 error "wrong stripecount"
2702
2703 }
2704 run_test 27F "Client resend delayed layout creation with non-zero size"
2705
2706 test_27G() { #LU-10629
2707         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2708                 skip "Need MDS version at least 2.11.51"
2709         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2710         remote_mds_nodsh && skip "remote MDS with nodsh"
2711         local POOL=${POOL:-testpool}
2712         local ostrange="0 0 1"
2713
2714         test_mkdir $DIR/$tdir
2715         touch $DIR/$tdir/$tfile.nopool
2716         pool_add $POOL || error "pool_add failed"
2717         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2718         $LFS setstripe -p $POOL $DIR/$tdir
2719
2720         local pool=$($LFS getstripe -p $DIR/$tdir)
2721
2722         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2723         touch $DIR/$tdir/$tfile.default
2724         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2725         $LFS find $DIR/$tdir -type f --pool $POOL
2726         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2727         [[ "$found" == "2" ]] ||
2728                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2729
2730         $LFS setstripe -d $DIR/$tdir
2731
2732         pool=$($LFS getstripe -p -d $DIR/$tdir)
2733
2734         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2735 }
2736 run_test 27G "Clear OST pool from stripe"
2737
2738 test_27H() {
2739         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2740                 skip "Need MDS version newer than 2.11.54"
2741         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2742         test_mkdir $DIR/$tdir
2743         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2744         touch $DIR/$tdir/$tfile
2745         $LFS getstripe -c $DIR/$tdir/$tfile
2746         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2747                 error "two-stripe file doesn't have two stripes"
2748
2749         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2750         $LFS getstripe -y $DIR/$tdir/$tfile
2751         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2752              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2753                 error "expected l_ost_idx: [02]$ not matched"
2754
2755         # make sure ost list has been cleared
2756         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2757         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2758                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2759         touch $DIR/$tdir/f3
2760         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2761 }
2762 run_test 27H "Set specific OSTs stripe"
2763
2764 test_27I() {
2765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2766         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2767         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2768                 skip "Need MDS version newer than 2.12.52"
2769         local pool=$TESTNAME
2770         local ostrange="1 1 1"
2771
2772         save_layout_restore_at_exit $MOUNT
2773         $LFS setstripe -c 2 -i 0 $MOUNT
2774         pool_add $pool || error "pool_add failed"
2775         pool_add_targets $pool $ostrange ||
2776                 error "pool_add_targets failed"
2777         test_mkdir $DIR/$tdir
2778         $LFS setstripe -p $pool $DIR/$tdir
2779         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2780         $LFS getstripe $DIR/$tdir/$tfile
2781 }
2782 run_test 27I "check that root dir striping does not break parent dir one"
2783
2784 test_27J() {
2785         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2786                 skip "Need MDS version newer than 2.12.51"
2787
2788         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2789         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2790         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2791            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2792                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2793
2794         test_mkdir $DIR/$tdir
2795         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2796         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2797
2798         # create foreign file (raw way)
2799         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2800                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2801
2802         ! $LFS setstripe --foreign --flags foo \
2803                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2804                         error "creating $tfile with '--flags foo' should fail"
2805
2806         ! $LFS setstripe --foreign --flags 0xffffffff \
2807                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2808                         error "creating $tfile w/ 0xffffffff flags should fail"
2809
2810         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2811                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2812
2813         # verify foreign file (raw way)
2814         parse_foreign_file -f $DIR/$tdir/$tfile |
2815                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2816                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2817         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2819         parse_foreign_file -f $DIR/$tdir/$tfile |
2820                 grep "lov_foreign_size: 73" ||
2821                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_type: 1" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2825         parse_foreign_file -f $DIR/$tdir/$tfile |
2826                 grep "lov_foreign_flags: 0x0000DA08" ||
2827                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2828         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2829                 grep "lov_foreign_value: 0x" |
2830                 sed -e 's/lov_foreign_value: 0x//')
2831         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2832         [[ $lov = ${lov2// /} ]] ||
2833                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2834
2835         # create foreign file (lfs + API)
2836         $LFS setstripe --foreign=none --flags 0xda08 \
2837                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2838                 error "$DIR/$tdir/${tfile}2: create failed"
2839
2840         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2841                 grep "lfm_magic:.*0x0BD70BD0" ||
2842                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2843         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2844         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2845                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2846         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2847                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2849                 grep "lfm_flags:.*0x0000DA08" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2851         $LFS getstripe $DIR/$tdir/${tfile}2 |
2852                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2854
2855         # modify striping should fail
2856         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2857                 error "$DIR/$tdir/$tfile: setstripe should fail"
2858         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2859                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2860
2861         # R/W should fail
2862         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2863         cat $DIR/$tdir/${tfile}2 &&
2864                 error "$DIR/$tdir/${tfile}2: read should fail"
2865         cat /etc/passwd > $DIR/$tdir/$tfile &&
2866                 error "$DIR/$tdir/$tfile: write should fail"
2867         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2868                 error "$DIR/$tdir/${tfile}2: write should fail"
2869
2870         # chmod should work
2871         chmod 222 $DIR/$tdir/$tfile ||
2872                 error "$DIR/$tdir/$tfile: chmod failed"
2873         chmod 222 $DIR/$tdir/${tfile}2 ||
2874                 error "$DIR/$tdir/${tfile}2: chmod failed"
2875
2876         # chown should work
2877         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2878                 error "$DIR/$tdir/$tfile: chown failed"
2879         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2880                 error "$DIR/$tdir/${tfile}2: chown failed"
2881
2882         # rename should work
2883         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2884                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2885         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2886                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2887
2888         #remove foreign file
2889         rm $DIR/$tdir/${tfile}.new ||
2890                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2891         rm $DIR/$tdir/${tfile}2.new ||
2892                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2893 }
2894 run_test 27J "basic ops on file with foreign LOV"
2895
2896 test_27K() {
2897         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2898                 skip "Need MDS version newer than 2.12.49"
2899
2900         test_mkdir $DIR/$tdir
2901         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2902         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2903
2904         # create foreign dir (raw way)
2905         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2906                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2907
2908         ! $LFS setdirstripe --foreign --flags foo \
2909                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2910                         error "creating $tdir with '--flags foo' should fail"
2911
2912         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2913                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2914                         error "creating $tdir w/ 0xffffffff flags should fail"
2915
2916         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2917                 error "create_foreign_dir FAILED"
2918
2919         # verify foreign dir (raw way)
2920         parse_foreign_dir -d $DIR/$tdir/$tdir |
2921                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2922                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2923         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2924                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2925         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2926                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2927         parse_foreign_dir -d $DIR/$tdir/$tdir |
2928                 grep "lmv_foreign_flags: 55813$" ||
2929                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2930         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2931                 grep "lmv_foreign_value: 0x" |
2932                 sed 's/lmv_foreign_value: 0x//')
2933         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2934                 sed 's/ //g')
2935         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2936
2937         # create foreign dir (lfs + API)
2938         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2939                 $DIR/$tdir/${tdir}2 ||
2940                 error "$DIR/$tdir/${tdir}2: create failed"
2941
2942         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2943
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2945                 grep "lfm_magic:.*0x0CD50CD0" ||
2946                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2947         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2948         # - sizeof(lfm_type) - sizeof(lfm_flags)
2949         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2950                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2953         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2954                 grep "lfm_flags:.*0x0000DA05" ||
2955                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2956         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2957                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2959
2960         # file create in dir should fail
2961         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2962         touch $DIR/$tdir/${tdir}2/$tfile &&
2963                 error "$DIR/${tdir}2: file create should fail"
2964
2965         # chmod should work
2966         chmod 777 $DIR/$tdir/$tdir ||
2967                 error "$DIR/$tdir: chmod failed"
2968         chmod 777 $DIR/$tdir/${tdir}2 ||
2969                 error "$DIR/${tdir}2: chmod failed"
2970
2971         # chown should work
2972         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2973                 error "$DIR/$tdir: chown failed"
2974         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2975                 error "$DIR/${tdir}2: chown failed"
2976
2977         # rename should work
2978         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2979                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2980         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2981                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2982
2983         #remove foreign dir
2984         rmdir $DIR/$tdir/${tdir}.new ||
2985                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2986         rmdir $DIR/$tdir/${tdir}2.new ||
2987                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2988 }
2989 run_test 27K "basic ops on dir with foreign LMV"
2990
2991 test_27L() {
2992         remote_mds_nodsh && skip "remote MDS with nodsh"
2993
2994         local POOL=${POOL:-$TESTNAME}
2995
2996         pool_add $POOL || error "pool_add failed"
2997
2998         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2999                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3000                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3001 }
3002 run_test 27L "lfs pool_list gives correct pool name"
3003
3004 test_27M() {
3005         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3006                 skip "Need MDS version >= than 2.12.57"
3007         remote_mds_nodsh && skip "remote MDS with nodsh"
3008         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3009
3010         # Set default striping on directory
3011         local setcount=4
3012         local stripe_opt
3013         local mdts=$(comma_list $(mdts_nodes))
3014
3015         # if we run against a 2.12 server which lacks overstring support
3016         # then the connect_flag will not report overstriping, even if client
3017         # is 2.14+
3018         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3019                 stripe_opt="-C $setcount"
3020         elif (( $OSTCOUNT >= $setcount )); then
3021                 stripe_opt="-c $setcount"
3022         else
3023                 skip "server does not support overstriping"
3024         fi
3025
3026         test_mkdir $DIR/$tdir
3027
3028         # Validate existing append_* params and ensure restore
3029         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3030         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3031         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3032
3033         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3034         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3035         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3036
3037         $LFS setstripe $stripe_opt $DIR/$tdir
3038
3039         echo 1 > $DIR/$tdir/${tfile}.1
3040         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3041         [ $count -eq $setcount ] ||
3042                 error "(1) stripe count $count, should be $setcount"
3043
3044         local appendcount=$orig_count
3045         echo 1 >> $DIR/$tdir/${tfile}.2_append
3046         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3047         [ $count -eq $appendcount ] ||
3048                 error "(2)stripe count $count, should be $appendcount for append"
3049
3050         # Disable O_APPEND striping, verify it works
3051         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3052
3053         # Should now get the default striping, which is 4
3054         setcount=4
3055         echo 1 >> $DIR/$tdir/${tfile}.3_append
3056         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3057         [ $count -eq $setcount ] ||
3058                 error "(3) stripe count $count, should be $setcount"
3059
3060         # Try changing the stripe count for append files
3061         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3062
3063         # Append striping is now 2 (directory default is still 4)
3064         appendcount=2
3065         echo 1 >> $DIR/$tdir/${tfile}.4_append
3066         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3067         [ $count -eq $appendcount ] ||
3068                 error "(4) stripe count $count, should be $appendcount for append"
3069
3070         # Test append stripe count of -1
3071         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3072         appendcount=$OSTCOUNT
3073         echo 1 >> $DIR/$tdir/${tfile}.5
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3075         [ $count -eq $appendcount ] ||
3076                 error "(5) stripe count $count, should be $appendcount for append"
3077
3078         # Set append striping back to default of 1
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3080
3081         # Try a new default striping, PFL + DOM
3082         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3083
3084         # Create normal DOM file, DOM returns stripe count == 0
3085         setcount=0
3086         touch $DIR/$tdir/${tfile}.6
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3088         [ $count -eq $setcount ] ||
3089                 error "(6) stripe count $count, should be $setcount"
3090
3091         # Show
3092         appendcount=1
3093         echo 1 >> $DIR/$tdir/${tfile}.7_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3095         [ $count -eq $appendcount ] ||
3096                 error "(7) stripe count $count, should be $appendcount for append"
3097
3098         # Clean up DOM layout
3099         $LFS setstripe -d $DIR/$tdir
3100
3101         save_layout_restore_at_exit $MOUNT
3102         # Now test that append striping works when layout is from root
3103         $LFS setstripe -c 2 $MOUNT
3104         # Make a special directory for this
3105         mkdir $DIR/${tdir}/${tdir}.2
3106
3107         # Verify for normal file
3108         setcount=2
3109         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3110         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3111         [ $count -eq $setcount ] ||
3112                 error "(8) stripe count $count, should be $setcount"
3113
3114         appendcount=1
3115         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3116         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3117         [ $count -eq $appendcount ] ||
3118                 error "(9) stripe count $count, should be $appendcount for append"
3119
3120         # Now test O_APPEND striping with pools
3121         pool_add $TESTNAME || error "pool creation failed"
3122         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3123         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3124
3125         echo 1 >> $DIR/$tdir/${tfile}.10_append
3126
3127         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3128         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3129
3130         # Check that count is still correct
3131         appendcount=1
3132         echo 1 >> $DIR/$tdir/${tfile}.11_append
3133         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3134         [ $count -eq $appendcount ] ||
3135                 error "(11) stripe count $count, should be $appendcount for append"
3136
3137         # Disable O_APPEND stripe count, verify pool works separately
3138         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3139
3140         echo 1 >> $DIR/$tdir/${tfile}.12_append
3141
3142         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3143         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3144
3145         # Remove pool setting, verify it's not applied
3146         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3147
3148         echo 1 >> $DIR/$tdir/${tfile}.13_append
3149
3150         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3151         [ "$pool" = "" ] || error "(13) pool found: $pool"
3152 }
3153 run_test 27M "test O_APPEND striping"
3154
3155 test_27N() {
3156         combined_mgs_mds && skip "needs separate MGS/MDT"
3157
3158         pool_add $TESTNAME || error "pool_add failed"
3159         do_facet mgs "$LCTL pool_list $FSNAME" |
3160                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3161                 error "lctl pool_list on MGS failed"
3162 }
3163 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3164
3165 clean_foreign_symlink() {
3166         trap 0
3167         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3168         for i in $DIR/$tdir/* ; do
3169                 $LFS unlink_foreign $i || true
3170         done
3171 }
3172
3173 test_27O() {
3174         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3175                 skip "Need MDS version newer than 2.12.51"
3176
3177         test_mkdir $DIR/$tdir
3178         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3179         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3180
3181         trap clean_foreign_symlink EXIT
3182
3183         # enable foreign_symlink behaviour
3184         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3185
3186         # foreign symlink LOV format is a partial path by default
3187
3188         # create foreign file (lfs + API)
3189         $LFS setstripe --foreign=symlink --flags 0xda05 \
3190                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3191                 error "$DIR/$tdir/${tfile}: create failed"
3192
3193         $LFS getstripe -v $DIR/$tdir/${tfile} |
3194                 grep "lfm_magic:.*0x0BD70BD0" ||
3195                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3196         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3197                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3198         $LFS getstripe -v $DIR/$tdir/${tfile} |
3199                 grep "lfm_flags:.*0x0000DA05" ||
3200                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3201         $LFS getstripe $DIR/$tdir/${tfile} |
3202                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3204
3205         # modify striping should fail
3206         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3207                 error "$DIR/$tdir/$tfile: setstripe should fail"
3208
3209         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3210         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3211         cat /etc/passwd > $DIR/$tdir/$tfile &&
3212                 error "$DIR/$tdir/$tfile: write should fail"
3213
3214         # rename should succeed
3215         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3216                 error "$DIR/$tdir/$tfile: rename has failed"
3217
3218         #remove foreign_symlink file should fail
3219         rm $DIR/$tdir/${tfile}.new &&
3220                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3221
3222         #test fake symlink
3223         mkdir /tmp/${uuid1} ||
3224                 error "/tmp/${uuid1}: mkdir has failed"
3225         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3226                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3227         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3228         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3229                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3230         #read should succeed now
3231         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3232                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3233         #write should succeed now
3234         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3235                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3236         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3237                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3238         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3239                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3240
3241         #check that getstripe still works
3242         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3244
3245         # chmod should still succeed
3246         chmod 644 $DIR/$tdir/${tfile}.new ||
3247                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3248
3249         # chown should still succeed
3250         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3252
3253         # rename should still succeed
3254         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3255                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3256
3257         #remove foreign_symlink file should still fail
3258         rm $DIR/$tdir/${tfile} &&
3259                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3260
3261         #use special ioctl() to unlink foreign_symlink file
3262         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3263                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3264
3265 }
3266 run_test 27O "basic ops on foreign file of symlink type"
3267
3268 test_27P() {
3269         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3270                 skip "Need MDS version newer than 2.12.49"
3271
3272         test_mkdir $DIR/$tdir
3273         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3274         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3275
3276         trap clean_foreign_symlink EXIT
3277
3278         # enable foreign_symlink behaviour
3279         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3280
3281         # foreign symlink LMV format is a partial path by default
3282
3283         # create foreign dir (lfs + API)
3284         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3285                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3286                 error "$DIR/$tdir/${tdir}: create failed"
3287
3288         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3289
3290         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3291                 grep "lfm_magic:.*0x0CD50CD0" ||
3292                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3293         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3294                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3295         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3296                 grep "lfm_flags:.*0x0000DA05" ||
3297                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3298         $LFS getdirstripe $DIR/$tdir/${tdir} |
3299                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3301
3302         # file create in dir should fail
3303         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3304         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3305
3306         # rename should succeed
3307         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3308                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3309
3310         #remove foreign_symlink dir should fail
3311         rmdir $DIR/$tdir/${tdir}.new &&
3312                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3313
3314         #test fake symlink
3315         mkdir -p /tmp/${uuid1}/${uuid2} ||
3316                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3317         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3318                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3319         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3320         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3321                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3322         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3323                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3324
3325         #check that getstripe fails now that foreign_symlink enabled
3326         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3327                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3328
3329         # file create in dir should work now
3330         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3331                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3332         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3333                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3334         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3335                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3336
3337         # chmod should still succeed
3338         chmod 755 $DIR/$tdir/${tdir}.new ||
3339                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3340
3341         # chown should still succeed
3342         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3343                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3344
3345         # rename should still succeed
3346         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3347                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3348
3349         #remove foreign_symlink dir should still fail
3350         rmdir $DIR/$tdir/${tdir} &&
3351                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3352
3353         #use special ioctl() to unlink foreign_symlink file
3354         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3355                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3356
3357         #created file should still exist
3358         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3359                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3360         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3361                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3362 }
3363 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3364
3365 test_27Q() {
3366         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3367         stack_trap "rm -f $TMP/$tfile*"
3368
3369         test_mkdir $DIR/$tdir-1
3370         test_mkdir $DIR/$tdir-2
3371
3372         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3373         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3374
3375         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3376         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3377
3378         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3379         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3380
3381         # Create some bad symlinks and ensure that we don't loop
3382         # forever or something. These should return ELOOP (40) and
3383         # ENOENT (2) but I don't want to test for that because there's
3384         # always some weirdo architecture that needs to ruin
3385         # everything by defining these error numbers differently.
3386
3387         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3388         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3389
3390         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3391         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3392
3393         return 0
3394 }
3395 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3396
3397 test_27R() {
3398         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3399                 skip "need MDS 2.14.55 or later"
3400         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3401
3402         local testdir="$DIR/$tdir"
3403         test_mkdir -p $testdir
3404         stack_trap "rm -rf $testdir"
3405         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3406
3407         local f1="$testdir/f1"
3408         touch $f1 || error "failed to touch $f1"
3409         local count=$($LFS getstripe -c $f1)
3410         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3411
3412         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3413         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3414
3415         local maxcount=$(($OSTCOUNT - 1))
3416         local mdts=$(comma_list $(mdts_nodes))
3417         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3418         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3419
3420         local f2="$testdir/f2"
3421         touch $f2 || error "failed to touch $f2"
3422         local count=$($LFS getstripe -c $f2)
3423         (( $count == $maxcount )) || error "wrong stripe count"
3424 }
3425 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3426
3427 test_27T() {
3428         [ $(facet_host client) == $(facet_host ost1) ] &&
3429                 skip "need ost1 and client on different nodes"
3430
3431 #define OBD_FAIL_OSC_NO_GRANT            0x411
3432         $LCTL set_param fail_loc=0x20000411 fail_val=1
3433 #define OBD_FAIL_OST_ENOSPC              0x215
3434         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3435         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3436         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3437                 error "multiop failed"
3438 }
3439 run_test 27T "no eio on close on partial write due to enosp"
3440
3441 test_27U() {
3442         local dir=$DIR/$tdir
3443         local file=$dir/$tfile
3444         local append_pool=${TESTNAME}-append
3445         local normal_pool=${TESTNAME}-normal
3446         local pool
3447         local stripe_count
3448         local stripe_count2
3449         local mdts=$(comma_list $(mdts_nodes))
3450
3451         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3452                 skip "Need MDS version at least 2.15.51 for append pool feature"
3453
3454         # Validate existing append_* params and ensure restore
3455         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3456         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3457         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3458
3459         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3460         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3461         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3462
3463         pool_add $append_pool || error "pool creation failed"
3464         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3465
3466         pool_add $normal_pool || error "pool creation failed"
3467         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3468
3469         test_mkdir $dir
3470         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3471
3472         echo XXX >> $file.1
3473         $LFS getstripe $file.1
3474
3475         pool=$($LFS getstripe -p $file.1)
3476         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3477
3478         stripe_count2=$($LFS getstripe -c $file.1)
3479         ((stripe_count2 == stripe_count)) ||
3480                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3481
3482         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3483
3484         echo XXX >> $file.2
3485         $LFS getstripe $file.2
3486
3487         pool=$($LFS getstripe -p $file.2)
3488         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3489
3490         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3491
3492         echo XXX >> $file.3
3493         $LFS getstripe $file.3
3494
3495         stripe_count2=$($LFS getstripe -c $file.3)
3496         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3497 }
3498 run_test 27U "append pool and stripe count work with composite default layout"
3499
3500 # createtest also checks that device nodes are created and
3501 # then visible correctly (#2091)
3502 test_28() { # bug 2091
3503         test_mkdir $DIR/d28
3504         $CREATETEST $DIR/d28/ct || error "createtest failed"
3505 }
3506 run_test 28 "create/mknod/mkdir with bad file types ============"
3507
3508 test_29() {
3509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3510
3511         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3512                 disable_opencache
3513                 stack_trap "restore_opencache"
3514         }
3515
3516         sync; sleep 1; sync # flush out any dirty pages from previous tests
3517         cancel_lru_locks
3518         test_mkdir $DIR/d29
3519         touch $DIR/d29/foo
3520         log 'first d29'
3521         ls -l $DIR/d29
3522
3523         declare -i LOCKCOUNTORIG=0
3524         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3525                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3526         done
3527         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3528
3529         declare -i LOCKUNUSEDCOUNTORIG=0
3530         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3531                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3532         done
3533
3534         log 'second d29'
3535         ls -l $DIR/d29
3536         log 'done'
3537
3538         declare -i LOCKCOUNTCURRENT=0
3539         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3540                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3541         done
3542
3543         declare -i LOCKUNUSEDCOUNTCURRENT=0
3544         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3545                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3546         done
3547
3548         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3549                 $LCTL set_param -n ldlm.dump_namespaces ""
3550                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3551                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3552                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3553                 return 2
3554         fi
3555         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3556                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3557                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3558                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3559                 return 3
3560         fi
3561 }
3562 run_test 29 "IT_GETATTR regression  ============================"
3563
3564 test_30a() { # was test_30
3565         cp $(which ls) $DIR || cp /bin/ls $DIR
3566         $DIR/ls / || error "Can't execute binary from lustre"
3567         rm $DIR/ls
3568 }
3569 run_test 30a "execute binary from Lustre (execve) =============="
3570
3571 test_30b() {
3572         cp `which ls` $DIR || cp /bin/ls $DIR
3573         chmod go+rx $DIR/ls
3574         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3575         rm $DIR/ls
3576 }
3577 run_test 30b "execute binary from Lustre as non-root ==========="
3578
3579 test_30c() { # b=22376
3580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3581
3582         cp $(which ls) $DIR || cp /bin/ls $DIR
3583         chmod a-rw $DIR/ls
3584         cancel_lru_locks mdc
3585         cancel_lru_locks osc
3586         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3587         rm -f $DIR/ls
3588 }
3589 run_test 30c "execute binary from Lustre without read perms ===="
3590
3591 test_30d() {
3592         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3593
3594         for i in {1..10}; do
3595                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3596                 local PID=$!
3597                 sleep 1
3598                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3599                 wait $PID || error "executing dd from Lustre failed"
3600                 rm -f $DIR/$tfile
3601         done
3602
3603         rm -f $DIR/dd
3604 }
3605 run_test 30d "execute binary from Lustre while clear locks"
3606
3607 test_31a() {
3608         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3609         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3610 }
3611 run_test 31a "open-unlink file =================================="
3612
3613 test_31b() {
3614         touch $DIR/f31 || error "touch $DIR/f31 failed"
3615         ln $DIR/f31 $DIR/f31b || error "ln failed"
3616         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3617         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3618 }
3619 run_test 31b "unlink file with multiple links while open ======="
3620
3621 test_31c() {
3622         touch $DIR/f31 || error "touch $DIR/f31 failed"
3623         ln $DIR/f31 $DIR/f31c || error "ln failed"
3624         multiop_bg_pause $DIR/f31 O_uc ||
3625                 error "multiop_bg_pause for $DIR/f31 failed"
3626         MULTIPID=$!
3627         $MULTIOP $DIR/f31c Ouc
3628         kill -USR1 $MULTIPID
3629         wait $MULTIPID
3630 }
3631 run_test 31c "open-unlink file with multiple links ============="
3632
3633 test_31d() {
3634         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3635         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3636 }
3637 run_test 31d "remove of open directory ========================="
3638
3639 test_31e() { # bug 2904
3640         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3641 }
3642 run_test 31e "remove of open non-empty directory ==============="
3643
3644 test_31f() { # bug 4554
3645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3646
3647         set -vx
3648         test_mkdir $DIR/d31f
3649         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3650         cp /etc/hosts $DIR/d31f
3651         ls -l $DIR/d31f
3652         $LFS getstripe $DIR/d31f/hosts
3653         multiop_bg_pause $DIR/d31f D_c || return 1
3654         MULTIPID=$!
3655
3656         rm -rv $DIR/d31f || error "first of $DIR/d31f"
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         MULTIPID2=$!
3664
3665         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3666         wait $MULTIPID || error "first opendir $MULTIPID failed"
3667
3668         sleep 6
3669
3670         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3671         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3672         set +vx
3673 }
3674 run_test 31f "remove of open directory with open-unlink file ==="
3675
3676 test_31g() {
3677         echo "-- cross directory link --"
3678         test_mkdir -c1 $DIR/${tdir}ga
3679         test_mkdir -c1 $DIR/${tdir}gb
3680         touch $DIR/${tdir}ga/f
3681         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3682         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3683         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3684         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3685         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3686 }
3687 run_test 31g "cross directory link==============="
3688
3689 test_31h() {
3690         echo "-- cross directory link --"
3691         test_mkdir -c1 $DIR/${tdir}
3692         test_mkdir -c1 $DIR/${tdir}/dir
3693         touch $DIR/${tdir}/f
3694         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3695         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3696         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3697         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3698         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3699 }
3700 run_test 31h "cross directory link under child==============="
3701
3702 test_31i() {
3703         echo "-- cross directory link --"
3704         test_mkdir -c1 $DIR/$tdir
3705         test_mkdir -c1 $DIR/$tdir/dir
3706         touch $DIR/$tdir/dir/f
3707         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3708         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3709         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3710         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3711         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3712 }
3713 run_test 31i "cross directory link under parent==============="
3714
3715 test_31j() {
3716         test_mkdir -c1 -p $DIR/$tdir
3717         test_mkdir -c1 -p $DIR/$tdir/dir1
3718         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3719         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3720         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3721         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3722         return 0
3723 }
3724 run_test 31j "link for directory==============="
3725
3726 test_31k() {
3727         test_mkdir -c1 -p $DIR/$tdir
3728         touch $DIR/$tdir/s
3729         touch $DIR/$tdir/exist
3730         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3731         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3732         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3733         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3734         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3735         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3736         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3737         return 0
3738 }
3739 run_test 31k "link to file: the same, non-existing, dir==============="
3740
3741 test_31l() {
3742         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3743
3744         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3745         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3746                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3747
3748         touch $DIR/$tfile || error "create failed"
3749         mkdir $DIR/$tdir || error "mkdir failed"
3750         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3751 }
3752 run_test 31l "link to file: target dir has trailing slash"
3753
3754 test_31m() {
3755         mkdir $DIR/d31m
3756         touch $DIR/d31m/s
3757         mkdir $DIR/d31m2
3758         touch $DIR/d31m2/exist
3759         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3760         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3761         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3762         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3763         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3764         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3765         return 0
3766 }
3767 run_test 31m "link to file: the same, non-existing, dir==============="
3768
3769 test_31n() {
3770         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3771         nlink=$(stat --format=%h $DIR/$tfile)
3772         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3773         local fd=$(free_fd)
3774         local cmd="exec $fd<$DIR/$tfile"
3775         eval $cmd
3776         cmd="exec $fd<&-"
3777         trap "eval $cmd" EXIT
3778         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3779         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3780         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3781         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3782         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3783         eval $cmd
3784 }
3785 run_test 31n "check link count of unlinked file"
3786
3787 link_one() {
3788         local tempfile=$(mktemp $1_XXXXXX)
3789         mlink $tempfile $1 2> /dev/null &&
3790                 echo "$BASHPID: link $tempfile to $1 succeeded"
3791         munlink $tempfile
3792 }
3793
3794 test_31o() { # LU-2901
3795         test_mkdir $DIR/$tdir
3796         for LOOP in $(seq 100); do
3797                 rm -f $DIR/$tdir/$tfile*
3798                 for THREAD in $(seq 8); do
3799                         link_one $DIR/$tdir/$tfile.$LOOP &
3800                 done
3801                 wait
3802                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3803                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3804                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3805                         break || true
3806         done
3807 }
3808 run_test 31o "duplicate hard links with same filename"
3809
3810 test_31p() {
3811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3812
3813         test_mkdir $DIR/$tdir
3814         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3815         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3816
3817         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3818                 error "open unlink test1 failed"
3819         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3820                 error "open unlink test2 failed"
3821
3822         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3823                 error "test1 still exists"
3824         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3825                 error "test2 still exists"
3826 }
3827 run_test 31p "remove of open striped directory"
3828
3829 test_31q() {
3830         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3831
3832         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3833         index=$($LFS getdirstripe -i $DIR/$tdir)
3834         [ $index -eq 3 ] || error "first stripe index $index != 3"
3835         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3836         [ $index -eq 1 ] || error "second stripe index $index != 1"
3837
3838         # when "-c <stripe_count>" is set, the number of MDTs specified after
3839         # "-i" should equal to the stripe count
3840         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3841 }
3842 run_test 31q "create striped directory on specific MDTs"
3843
3844 #LU-14949
3845 test_31r() {
3846         touch $DIR/$tfile.target
3847         touch $DIR/$tfile.source
3848
3849         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3850         $LCTL set_param fail_loc=0x1419 fail_val=3
3851         cat $DIR/$tfile.target &
3852         CATPID=$!
3853
3854         # Guarantee open is waiting before we get here
3855         sleep 1
3856         mv $DIR/$tfile.source $DIR/$tfile.target
3857
3858         wait $CATPID
3859         RC=$?
3860         if [[ $RC -ne 0 ]]; then
3861                 error "open with cat failed, rc=$RC"
3862         fi
3863 }
3864 run_test 31r "open-rename(replace) race"
3865
3866 cleanup_test32_mount() {
3867         local rc=0
3868         trap 0
3869         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3870         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3871         losetup -d $loopdev || true
3872         rm -rf $DIR/$tdir
3873         return $rc
3874 }
3875
3876 test_32a() {
3877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3878
3879         echo "== more mountpoints and symlinks ================="
3880         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3881         trap cleanup_test32_mount EXIT
3882         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3883         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3884                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3885         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3886                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3887         cleanup_test32_mount
3888 }
3889 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3890
3891 test_32b() {
3892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3893
3894         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3895         trap cleanup_test32_mount EXIT
3896         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3900                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3901         cleanup_test32_mount
3902 }
3903 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3904
3905 test_32c() {
3906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3907
3908         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3909         trap cleanup_test32_mount EXIT
3910         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         test_mkdir -p $DIR/$tdir/d2/test_dir
3914         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3915                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3916         cleanup_test32_mount
3917 }
3918 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3919
3920 test_32d() {
3921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3922
3923         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3924         trap cleanup_test32_mount EXIT
3925         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3926         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3927                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3928         test_mkdir -p $DIR/$tdir/d2/test_dir
3929         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3930                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3931         cleanup_test32_mount
3932 }
3933 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3934
3935 test_32e() {
3936         rm -fr $DIR/$tdir
3937         test_mkdir -p $DIR/$tdir/tmp
3938         local tmp_dir=$DIR/$tdir/tmp
3939         ln -s $DIR/$tdir $tmp_dir/symlink11
3940         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3941         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3942         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3943 }
3944 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3945
3946 test_32f() {
3947         rm -fr $DIR/$tdir
3948         test_mkdir -p $DIR/$tdir/tmp
3949         local tmp_dir=$DIR/$tdir/tmp
3950         ln -s $DIR/$tdir $tmp_dir/symlink11
3951         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3952         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3953         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3954 }
3955 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3956
3957 test_32g() {
3958         local tmp_dir=$DIR/$tdir/tmp
3959         test_mkdir -p $tmp_dir
3960         test_mkdir $DIR/${tdir}2
3961         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3962         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3963         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3964         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3965         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3966         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3967 }
3968 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3969
3970 test_32h() {
3971         rm -fr $DIR/$tdir $DIR/${tdir}2
3972         tmp_dir=$DIR/$tdir/tmp
3973         test_mkdir -p $tmp_dir
3974         test_mkdir $DIR/${tdir}2
3975         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3976         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3977         ls $tmp_dir/symlink12 || error "listing symlink12"
3978         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3979 }
3980 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3981
3982 test_32i() {
3983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3984
3985         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3986         trap cleanup_test32_mount EXIT
3987         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3988         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3989                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3990         touch $DIR/$tdir/test_file
3991         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3992                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3993         cleanup_test32_mount
3994 }
3995 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3996
3997 test_32j() {
3998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3999
4000         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4001         trap cleanup_test32_mount EXIT
4002         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4003         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4004                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4005         touch $DIR/$tdir/test_file
4006         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4007                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4008         cleanup_test32_mount
4009 }
4010 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4011
4012 test_32k() {
4013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4014
4015         rm -fr $DIR/$tdir
4016         trap cleanup_test32_mount EXIT
4017         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4018         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4019                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4020         test_mkdir -p $DIR/$tdir/d2
4021         touch $DIR/$tdir/d2/test_file || error "touch failed"
4022         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4023                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4024         cleanup_test32_mount
4025 }
4026 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4027
4028 test_32l() {
4029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4030
4031         rm -fr $DIR/$tdir
4032         trap cleanup_test32_mount EXIT
4033         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4034         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4035                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4036         test_mkdir -p $DIR/$tdir/d2
4037         touch $DIR/$tdir/d2/test_file || error "touch failed"
4038         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4039                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4040         cleanup_test32_mount
4041 }
4042 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4043
4044 test_32m() {
4045         rm -fr $DIR/d32m
4046         test_mkdir -p $DIR/d32m/tmp
4047         TMP_DIR=$DIR/d32m/tmp
4048         ln -s $DIR $TMP_DIR/symlink11
4049         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4050         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4051                 error "symlink11 not a link"
4052         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4053                 error "symlink01 not a link"
4054 }
4055 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4056
4057 test_32n() {
4058         rm -fr $DIR/d32n
4059         test_mkdir -p $DIR/d32n/tmp
4060         TMP_DIR=$DIR/d32n/tmp
4061         ln -s $DIR $TMP_DIR/symlink11
4062         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4063         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4064         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4065 }
4066 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4067
4068 test_32o() {
4069         touch $DIR/$tfile
4070         test_mkdir -p $DIR/d32o/tmp
4071         TMP_DIR=$DIR/d32o/tmp
4072         ln -s $DIR/$tfile $TMP_DIR/symlink12
4073         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4074         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4075                 error "symlink12 not a link"
4076         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4077         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4078                 error "$DIR/d32o/tmp/symlink12 not file type"
4079         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4080                 error "$DIR/d32o/symlink02 not file type"
4081 }
4082 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4083
4084 test_32p() {
4085         log 32p_1
4086         rm -fr $DIR/d32p
4087         log 32p_2
4088         rm -f $DIR/$tfile
4089         log 32p_3
4090         touch $DIR/$tfile
4091         log 32p_4
4092         test_mkdir -p $DIR/d32p/tmp
4093         log 32p_5
4094         TMP_DIR=$DIR/d32p/tmp
4095         log 32p_6
4096         ln -s $DIR/$tfile $TMP_DIR/symlink12
4097         log 32p_7
4098         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4099         log 32p_8
4100         cat $DIR/d32p/tmp/symlink12 ||
4101                 error "Can't open $DIR/d32p/tmp/symlink12"
4102         log 32p_9
4103         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4104         log 32p_10
4105 }
4106 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4107
4108 test_32q() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110
4111         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4112         trap cleanup_test32_mount EXIT
4113         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4114         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4115         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4116                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4117         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4118         cleanup_test32_mount
4119 }
4120 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4121
4122 test_32r() {
4123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4124
4125         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4126         trap cleanup_test32_mount EXIT
4127         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4128         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4129         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4130                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4131         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4132         cleanup_test32_mount
4133 }
4134 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4135
4136 test_33aa() {
4137         rm -f $DIR/$tfile
4138         touch $DIR/$tfile
4139         chmod 444 $DIR/$tfile
4140         chown $RUNAS_ID $DIR/$tfile
4141         log 33_1
4142         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4143         log 33_2
4144 }
4145 run_test 33aa "write file with mode 444 (should return error)"
4146
4147 test_33a() {
4148         rm -fr $DIR/$tdir
4149         test_mkdir $DIR/$tdir
4150         chown $RUNAS_ID $DIR/$tdir
4151         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4152                 error "$RUNAS create $tdir/$tfile failed"
4153         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4154                 error "open RDWR" || true
4155 }
4156 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4157
4158 test_33b() {
4159         rm -fr $DIR/$tdir
4160         test_mkdir $DIR/$tdir
4161         chown $RUNAS_ID $DIR/$tdir
4162         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4163 }
4164 run_test 33b "test open file with malformed flags (No panic)"
4165
4166 test_33c() {
4167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4168         remote_ost_nodsh && skip "remote OST with nodsh"
4169
4170         local ostnum
4171         local ostname
4172         local write_bytes
4173         local all_zeros
4174
4175         all_zeros=true
4176         test_mkdir $DIR/$tdir
4177         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4178
4179         sync
4180         for ostnum in $(seq $OSTCOUNT); do
4181                 # test-framework's OST numbering is one-based, while Lustre's
4182                 # is zero-based
4183                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4184                 # check if at least some write_bytes stats are counted
4185                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4186                               obdfilter.$ostname.stats |
4187                               awk '/^write_bytes/ {print $7}' )
4188                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4189                 if (( ${write_bytes:-0} > 0 )); then
4190                         all_zeros=false
4191                         break
4192                 fi
4193         done
4194
4195         $all_zeros || return 0
4196
4197         # Write four bytes
4198         echo foo > $DIR/$tdir/bar
4199         # Really write them
4200         sync
4201
4202         # Total up write_bytes after writing.  We'd better find non-zeros.
4203         for ostnum in $(seq $OSTCOUNT); do
4204                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4205                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4206                               obdfilter/$ostname/stats |
4207                               awk '/^write_bytes/ {print $7}' )
4208                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4209                 if (( ${write_bytes:-0} > 0 )); then
4210                         all_zeros=false
4211                         break
4212                 fi
4213         done
4214
4215         if $all_zeros; then
4216                 for ostnum in $(seq $OSTCOUNT); do
4217                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4218                         echo "Check write_bytes is in obdfilter.*.stats:"
4219                         do_facet ost$ostnum lctl get_param -n \
4220                                 obdfilter.$ostname.stats
4221                 done
4222                 error "OST not keeping write_bytes stats (b=22312)"
4223         fi
4224 }
4225 run_test 33c "test write_bytes stats"
4226
4227 test_33d() {
4228         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4230
4231         local MDTIDX=1
4232         local remote_dir=$DIR/$tdir/remote_dir
4233
4234         test_mkdir $DIR/$tdir
4235         $LFS mkdir -i $MDTIDX $remote_dir ||
4236                 error "create remote directory failed"
4237
4238         touch $remote_dir/$tfile
4239         chmod 444 $remote_dir/$tfile
4240         chown $RUNAS_ID $remote_dir/$tfile
4241
4242         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4243
4244         chown $RUNAS_ID $remote_dir
4245         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4246                                         error "create" || true
4247         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4248                                     error "open RDWR" || true
4249         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4250 }
4251 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4252
4253 test_33e() {
4254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4255
4256         mkdir $DIR/$tdir
4257
4258         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4259         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4260         mkdir $DIR/$tdir/local_dir
4261
4262         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4263         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4264         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4265
4266         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4267                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4268
4269         rmdir $DIR/$tdir/* || error "rmdir failed"
4270
4271         umask 777
4272         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4273         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4274         mkdir $DIR/$tdir/local_dir
4275
4276         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4277         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4278         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4279
4280         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4281                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4282
4283         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4284
4285         umask 000
4286         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4287         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4288         mkdir $DIR/$tdir/local_dir
4289
4290         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4291         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4292         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4293
4294         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4295                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4296 }
4297 run_test 33e "mkdir and striped directory should have same mode"
4298
4299 cleanup_33f() {
4300         trap 0
4301         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4302 }
4303
4304 test_33f() {
4305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4306         remote_mds_nodsh && skip "remote MDS with nodsh"
4307
4308         mkdir $DIR/$tdir
4309         chmod go+rwx $DIR/$tdir
4310         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4311         trap cleanup_33f EXIT
4312
4313         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4314                 error "cannot create striped directory"
4315
4316         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4317                 error "cannot create files in striped directory"
4318
4319         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4320                 error "cannot remove files in striped directory"
4321
4322         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4323                 error "cannot remove striped directory"
4324
4325         cleanup_33f
4326 }
4327 run_test 33f "nonroot user can create, access, and remove a striped directory"
4328
4329 test_33g() {
4330         mkdir -p $DIR/$tdir/dir2
4331
4332         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4333         echo $err
4334         [[ $err =~ "exists" ]] || error "Not exists error"
4335 }
4336 run_test 33g "nonroot user create already existing root created file"
4337
4338 sub_33h() {
4339         local hash_type=$1
4340         local count=250
4341
4342         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4343                 error "lfs mkdir -H $hash_type $tdir failed"
4344         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4345
4346         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4347         local index2
4348         local fname
4349
4350         for fname in $DIR/$tdir/$tfile.bak \
4351                      $DIR/$tdir/$tfile.SAV \
4352                      $DIR/$tdir/$tfile.orig \
4353                      $DIR/$tdir/$tfile~; do
4354                 touch $fname || error "touch $fname failed"
4355                 index2=$($LFS getstripe -m $fname)
4356                 (( $index == $index2 )) ||
4357                         error "$fname MDT index mismatch $index != $index2"
4358         done
4359
4360         local failed=0
4361         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4362         local pattern
4363
4364         for pattern in ${patterns[*]}; do
4365                 echo "pattern $pattern"
4366                 fname=$DIR/$tdir/$pattern
4367                 for (( i = 0; i < $count; i++ )); do
4368                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4369                                 error "mktemp $DIR/$tdir/$pattern failed"
4370                         index2=$($LFS getstripe -m $fname)
4371                         (( $index == $index2 )) && continue
4372
4373                         failed=$((failed + 1))
4374                         echo "$fname MDT index mismatch $index != $index2"
4375                 done
4376         done
4377
4378         echo "$failed/$count MDT index mismatches, expect ~2-4"
4379         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4380
4381         local same=0
4382         local expect
4383
4384         # verify that "crush" is still broken with all files on same MDT,
4385         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4386         [[ "$hash_type" == "crush" ]] && expect=$count ||
4387                 expect=$((count / MDSCOUNT))
4388
4389         # crush2 doesn't put all-numeric suffixes on the same MDT,
4390         # filename like $tfile.12345678 should *not* be considered temp
4391         for pattern in ${patterns[*]}; do
4392                 local base=${pattern%%X*}
4393                 local suff=${pattern#$base}
4394
4395                 echo "pattern $pattern"
4396                 for (( i = 0; i < $count; i++ )); do
4397                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4398                         touch $fname || error "touch $fname failed"
4399                         index2=$($LFS getstripe -m $fname)
4400                         (( $index != $index2 )) && continue
4401
4402                         same=$((same + 1))
4403                 done
4404         done
4405
4406         # the number of "bad" hashes is random, as it depends on the random
4407         # filenames generated by "mktemp".  Allow some margin in the results.
4408         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4409         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4410            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4411                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4412         same=0
4413
4414         # crush2 doesn't put suffixes with special characters on the same MDT
4415         # filename like $tfile.txt.1234 should *not* be considered temp
4416         for pattern in ${patterns[*]}; do
4417                 local base=${pattern%%X*}
4418                 local suff=${pattern#$base}
4419
4420                 pattern=$base...${suff/XXX}
4421                 echo "pattern=$pattern"
4422                 for (( i = 0; i < $count; i++ )); do
4423                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4424                                 error "touch $fname failed"
4425                         index2=$($LFS getstripe -m $fname)
4426                         (( $index != $index2 )) && continue
4427
4428                         same=$((same + 1))
4429                 done
4430         done
4431
4432         # the number of "bad" hashes is random, as it depends on the random
4433         # filenames generated by "mktemp".  Allow some margin in the results.
4434         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4435         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4436            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4437                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4438 }
4439
4440 test_33h() {
4441         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4442         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4443                 skip "Need MDS version at least 2.13.50"
4444
4445         sub_33h crush
4446 }
4447 run_test 33h "temp file is located on the same MDT as target (crush)"
4448
4449 test_33hh() {
4450         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4451         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4452         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4453                 skip "Need MDS version at least 2.15.0 for crush2"
4454
4455         sub_33h crush2
4456 }
4457 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4458
4459 test_33i()
4460 {
4461         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4462
4463         local FNAME=$(str_repeat 'f' 250)
4464
4465         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4466         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4467
4468         local count
4469         local total
4470
4471         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4472
4473         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4474
4475         lctl --device %$MDC deactivate
4476         stack_trap "lctl --device %$MDC activate"
4477         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4478         total=$(\ls -l $DIR/$tdir | wc -l)
4479         # "ls -l" will list total in the first line
4480         total=$((total - 1))
4481         (( total + count == 1000 )) ||
4482                 error "ls list $total files, $count files on MDT1"
4483 }
4484 run_test 33i "striped directory can be accessed when one MDT is down"
4485
4486 test_33j() {
4487         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4488
4489         mkdir -p $DIR/$tdir/
4490
4491         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4492                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4493
4494         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4495                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4496
4497         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4498                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4499
4500         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4501                 error "-D was not specified, but still failed"
4502 }
4503 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4504
4505 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4506 test_34a() {
4507         rm -f $DIR/f34
4508         $MCREATE $DIR/f34 || error "mcreate failed"
4509         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4510                 error "getstripe failed"
4511         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4512         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4513                 error "getstripe failed"
4514         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4515                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4516 }
4517 run_test 34a "truncate file that has not been opened ==========="
4518
4519 test_34b() {
4520         [ ! -f $DIR/f34 ] && test_34a
4521         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4522                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4523         $OPENFILE -f O_RDONLY $DIR/f34
4524         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4525                 error "getstripe failed"
4526         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4527                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4528 }
4529 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4530
4531 test_34c() {
4532         [ ! -f $DIR/f34 ] && test_34a
4533         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4534                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4535         $OPENFILE -f O_RDWR $DIR/f34
4536         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4537                 error "$LFS getstripe failed"
4538         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4539                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4540 }
4541 run_test 34c "O_RDWR opening file-with-size works =============="
4542
4543 test_34d() {
4544         [ ! -f $DIR/f34 ] && test_34a
4545         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4546                 error "dd failed"
4547         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4548                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4549         rm $DIR/f34
4550 }
4551 run_test 34d "write to sparse file ============================="
4552
4553 test_34e() {
4554         rm -f $DIR/f34e
4555         $MCREATE $DIR/f34e || error "mcreate failed"
4556         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4557         $CHECKSTAT -s 1000 $DIR/f34e ||
4558                 error "Size of $DIR/f34e not equal to 1000 bytes"
4559         $OPENFILE -f O_RDWR $DIR/f34e
4560         $CHECKSTAT -s 1000 $DIR/f34e ||
4561                 error "Size of $DIR/f34e not equal to 1000 bytes"
4562 }
4563 run_test 34e "create objects, some with size and some without =="
4564
4565 test_34f() { # bug 6242, 6243
4566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4567
4568         SIZE34F=48000
4569         rm -f $DIR/f34f
4570         $MCREATE $DIR/f34f || error "mcreate failed"
4571         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4572         dd if=$DIR/f34f of=$TMP/f34f
4573         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4574         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4575         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4576         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4577         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4578 }
4579 run_test 34f "read from a file with no objects until EOF ======="
4580
4581 test_34g() {
4582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4583
4584         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4585                 error "dd failed"
4586         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4587         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4588                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4589         cancel_lru_locks osc
4590         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4591                 error "wrong size after lock cancel"
4592
4593         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4594         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4595                 error "expanding truncate failed"
4596         cancel_lru_locks osc
4597         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4598                 error "wrong expanded size after lock cancel"
4599 }
4600 run_test 34g "truncate long file ==============================="
4601
4602 test_34h() {
4603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4604
4605         local gid=10
4606         local sz=1000
4607
4608         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4609         sync # Flush the cache so that multiop below does not block on cache
4610              # flush when getting the group lock
4611         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4612         MULTIPID=$!
4613
4614         # Since just timed wait is not good enough, let's do a sync write
4615         # that way we are sure enough time for a roundtrip + processing
4616         # passed + 2 seconds of extra margin.
4617         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4618         rm $DIR/${tfile}-1
4619         sleep 2
4620
4621         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4622                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4623                 kill -9 $MULTIPID
4624         fi
4625         wait $MULTIPID
4626         local nsz=`stat -c %s $DIR/$tfile`
4627         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4628 }
4629 run_test 34h "ftruncate file under grouplock should not block"
4630
4631 test_35a() {
4632         cp /bin/sh $DIR/f35a
4633         chmod 444 $DIR/f35a
4634         chown $RUNAS_ID $DIR/f35a
4635         $RUNAS $DIR/f35a && error || true
4636         rm $DIR/f35a
4637 }
4638 run_test 35a "exec file with mode 444 (should return and not leak)"
4639
4640 test_36a() {
4641         rm -f $DIR/f36
4642         utime $DIR/f36 || error "utime failed for MDS"
4643 }
4644 run_test 36a "MDS utime check (mknod, utime)"
4645
4646 test_36b() {
4647         echo "" > $DIR/f36
4648         utime $DIR/f36 || error "utime failed for OST"
4649 }
4650 run_test 36b "OST utime check (open, utime)"
4651
4652 test_36c() {
4653         rm -f $DIR/d36/f36
4654         test_mkdir $DIR/d36
4655         chown $RUNAS_ID $DIR/d36
4656         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4657 }
4658 run_test 36c "non-root MDS utime check (mknod, utime)"
4659
4660 test_36d() {
4661         [ ! -d $DIR/d36 ] && test_36c
4662         echo "" > $DIR/d36/f36
4663         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4664 }
4665 run_test 36d "non-root OST utime check (open, utime)"
4666
4667 test_36e() {
4668         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4669
4670         test_mkdir $DIR/$tdir
4671         touch $DIR/$tdir/$tfile
4672         $RUNAS utime $DIR/$tdir/$tfile &&
4673                 error "utime worked, expected failure" || true
4674 }
4675 run_test 36e "utime on non-owned file (should return error)"
4676
4677 subr_36fh() {
4678         local fl="$1"
4679         local LANG_SAVE=$LANG
4680         local LC_LANG_SAVE=$LC_LANG
4681         export LANG=C LC_LANG=C # for date language
4682
4683         DATESTR="Dec 20  2000"
4684         test_mkdir $DIR/$tdir
4685         lctl set_param fail_loc=$fl
4686         date; date +%s
4687         cp /etc/hosts $DIR/$tdir/$tfile
4688         sync & # write RPC generated with "current" inode timestamp, but delayed
4689         sleep 1
4690         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4691         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4692         cancel_lru_locks $OSC
4693         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4694         date; date +%s
4695         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4696                 echo "BEFORE: $LS_BEFORE" && \
4697                 echo "AFTER : $LS_AFTER" && \
4698                 echo "WANT  : $DATESTR" && \
4699                 error "$DIR/$tdir/$tfile timestamps changed" || true
4700
4701         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4702 }
4703
4704 test_36f() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4708         subr_36fh "0x80000214"
4709 }
4710 run_test 36f "utime on file racing with OST BRW write =========="
4711
4712 test_36g() {
4713         remote_ost_nodsh && skip "remote OST with nodsh"
4714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4715         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4716                 skip "Need MDS version at least 2.12.51"
4717
4718         local fmd_max_age
4719         local fmd
4720         local facet="ost1"
4721         local tgt="obdfilter"
4722
4723         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4724
4725         test_mkdir $DIR/$tdir
4726         fmd_max_age=$(do_facet $facet \
4727                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4728                 head -n 1")
4729
4730         echo "FMD max age: ${fmd_max_age}s"
4731         touch $DIR/$tdir/$tfile
4732         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4733                 gawk '{cnt=cnt+$1}  END{print cnt}')
4734         echo "FMD before: $fmd"
4735         [[ $fmd == 0 ]] &&
4736                 error "FMD wasn't create by touch"
4737         sleep $((fmd_max_age + 12))
4738         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4739                 gawk '{cnt=cnt+$1}  END{print cnt}')
4740         echo "FMD after: $fmd"
4741         [[ $fmd == 0 ]] ||
4742                 error "FMD wasn't expired by ping"
4743 }
4744 run_test 36g "FMD cache expiry ====================="
4745
4746 test_36h() {
4747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4748
4749         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4750         subr_36fh "0x80000227"
4751 }
4752 run_test 36h "utime on file racing with OST BRW write =========="
4753
4754 test_36i() {
4755         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4756
4757         test_mkdir $DIR/$tdir
4758         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4759
4760         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4761         local new_mtime=$((mtime + 200))
4762
4763         #change Modify time of striped dir
4764         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4765                         error "change mtime failed"
4766
4767         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4768
4769         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4770 }
4771 run_test 36i "change mtime on striped directory"
4772
4773 # test_37 - duplicate with tests 32q 32r
4774
4775 test_38() {
4776         local file=$DIR/$tfile
4777         touch $file
4778         openfile -f O_DIRECTORY $file
4779         local RC=$?
4780         local ENOTDIR=20
4781         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4782         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4783 }
4784 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4785
4786 test_39a() { # was test_39
4787         touch $DIR/$tfile
4788         touch $DIR/${tfile}2
4789 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4790 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4791 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4792         sleep 2
4793         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4794         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4795                 echo "mtime"
4796                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4797                 echo "atime"
4798                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4799                 echo "ctime"
4800                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4801                 error "O_TRUNC didn't change timestamps"
4802         fi
4803 }
4804 run_test 39a "mtime changed on create"
4805
4806 test_39b() {
4807         test_mkdir -c1 $DIR/$tdir
4808         cp -p /etc/passwd $DIR/$tdir/fopen
4809         cp -p /etc/passwd $DIR/$tdir/flink
4810         cp -p /etc/passwd $DIR/$tdir/funlink
4811         cp -p /etc/passwd $DIR/$tdir/frename
4812         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4813
4814         sleep 1
4815         echo "aaaaaa" >> $DIR/$tdir/fopen
4816         echo "aaaaaa" >> $DIR/$tdir/flink
4817         echo "aaaaaa" >> $DIR/$tdir/funlink
4818         echo "aaaaaa" >> $DIR/$tdir/frename
4819
4820         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4821         local link_new=`stat -c %Y $DIR/$tdir/flink`
4822         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4823         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4824
4825         cat $DIR/$tdir/fopen > /dev/null
4826         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4827         rm -f $DIR/$tdir/funlink2
4828         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4829
4830         for (( i=0; i < 2; i++ )) ; do
4831                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4832                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4833                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4834                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4835
4836                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4837                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4838                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4839                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4840
4841                 cancel_lru_locks $OSC
4842                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4843         done
4844 }
4845 run_test 39b "mtime change on open, link, unlink, rename  ======"
4846
4847 # this should be set to past
4848 TEST_39_MTIME=`date -d "1 year ago" +%s`
4849
4850 # bug 11063
4851 test_39c() {
4852         touch $DIR1/$tfile
4853         sleep 2
4854         local mtime0=`stat -c %Y $DIR1/$tfile`
4855
4856         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4857         local mtime1=`stat -c %Y $DIR1/$tfile`
4858         [ "$mtime1" = $TEST_39_MTIME ] || \
4859                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4860
4861         local d1=`date +%s`
4862         echo hello >> $DIR1/$tfile
4863         local d2=`date +%s`
4864         local mtime2=`stat -c %Y $DIR1/$tfile`
4865         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4866                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4867
4868         mv $DIR1/$tfile $DIR1/$tfile-1
4869
4870         for (( i=0; i < 2; i++ )) ; do
4871                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4872                 [ "$mtime2" = "$mtime3" ] || \
4873                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4874
4875                 cancel_lru_locks $OSC
4876                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4877         done
4878 }
4879 run_test 39c "mtime change on rename ==========================="
4880
4881 # bug 21114
4882 test_39d() {
4883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4884
4885         touch $DIR1/$tfile
4886         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4887
4888         for (( i=0; i < 2; i++ )) ; do
4889                 local mtime=`stat -c %Y $DIR1/$tfile`
4890                 [ $mtime = $TEST_39_MTIME ] || \
4891                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4892
4893                 cancel_lru_locks $OSC
4894                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4895         done
4896 }
4897 run_test 39d "create, utime, stat =============================="
4898
4899 # bug 21114
4900 test_39e() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         touch $DIR1/$tfile
4904         local mtime1=`stat -c %Y $DIR1/$tfile`
4905
4906         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4907
4908         for (( i=0; i < 2; i++ )) ; do
4909                 local mtime2=`stat -c %Y $DIR1/$tfile`
4910                 [ $mtime2 = $TEST_39_MTIME ] || \
4911                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4912
4913                 cancel_lru_locks $OSC
4914                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4915         done
4916 }
4917 run_test 39e "create, stat, utime, stat ========================"
4918
4919 # bug 21114
4920 test_39f() {
4921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4922
4923         touch $DIR1/$tfile
4924         mtime1=`stat -c %Y $DIR1/$tfile`
4925
4926         sleep 2
4927         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4928
4929         for (( i=0; i < 2; i++ )) ; do
4930                 local mtime2=`stat -c %Y $DIR1/$tfile`
4931                 [ $mtime2 = $TEST_39_MTIME ] || \
4932                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4933
4934                 cancel_lru_locks $OSC
4935                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4936         done
4937 }
4938 run_test 39f "create, stat, sleep, utime, stat ================="
4939
4940 # bug 11063
4941 test_39g() {
4942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4943
4944         echo hello >> $DIR1/$tfile
4945         local mtime1=`stat -c %Y $DIR1/$tfile`
4946
4947         sleep 2
4948         chmod o+r $DIR1/$tfile
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime2=`stat -c %Y $DIR1/$tfile`
4952                 [ "$mtime1" = "$mtime2" ] || \
4953                         error "lost mtime: $mtime2, should be $mtime1"
4954
4955                 cancel_lru_locks $OSC
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958 }
4959 run_test 39g "write, chmod, stat ==============================="
4960
4961 # bug 11063
4962 test_39h() {
4963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4964
4965         touch $DIR1/$tfile
4966         sleep 1
4967
4968         local d1=`date`
4969         echo hello >> $DIR1/$tfile
4970         local mtime1=`stat -c %Y $DIR1/$tfile`
4971
4972         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4973         local d2=`date`
4974         if [ "$d1" != "$d2" ]; then
4975                 echo "write and touch not within one second"
4976         else
4977                 for (( i=0; i < 2; i++ )) ; do
4978                         local mtime2=`stat -c %Y $DIR1/$tfile`
4979                         [ "$mtime2" = $TEST_39_MTIME ] || \
4980                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4981
4982                         cancel_lru_locks $OSC
4983                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4984                 done
4985         fi
4986 }
4987 run_test 39h "write, utime within one second, stat ============="
4988
4989 test_39i() {
4990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4991
4992         touch $DIR1/$tfile
4993         sleep 1
4994
4995         echo hello >> $DIR1/$tfile
4996         local mtime1=`stat -c %Y $DIR1/$tfile`
4997
4998         mv $DIR1/$tfile $DIR1/$tfile-1
4999
5000         for (( i=0; i < 2; i++ )) ; do
5001                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5002
5003                 [ "$mtime1" = "$mtime2" ] || \
5004                         error "lost mtime: $mtime2, should be $mtime1"
5005
5006                 cancel_lru_locks $OSC
5007                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5008         done
5009 }
5010 run_test 39i "write, rename, stat =============================="
5011
5012 test_39j() {
5013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5014
5015         start_full_debug_logging
5016         touch $DIR1/$tfile
5017         sleep 1
5018
5019         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5020         lctl set_param fail_loc=0x80000412
5021         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5022                 error "multiop failed"
5023         local multipid=$!
5024         local mtime1=`stat -c %Y $DIR1/$tfile`
5025
5026         mv $DIR1/$tfile $DIR1/$tfile-1
5027
5028         kill -USR1 $multipid
5029         wait $multipid || error "multiop close failed"
5030
5031         for (( i=0; i < 2; i++ )) ; do
5032                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5033                 [ "$mtime1" = "$mtime2" ] ||
5034                         error "mtime is lost on close: $mtime2, " \
5035                               "should be $mtime1"
5036
5037                 cancel_lru_locks
5038                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5039         done
5040         lctl set_param fail_loc=0
5041         stop_full_debug_logging
5042 }
5043 run_test 39j "write, rename, close, stat ======================="
5044
5045 test_39k() {
5046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5047
5048         touch $DIR1/$tfile
5049         sleep 1
5050
5051         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5052         local multipid=$!
5053         local mtime1=`stat -c %Y $DIR1/$tfile`
5054
5055         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5056
5057         kill -USR1 $multipid
5058         wait $multipid || error "multiop close failed"
5059
5060         for (( i=0; i < 2; i++ )) ; do
5061                 local mtime2=`stat -c %Y $DIR1/$tfile`
5062
5063                 [ "$mtime2" = $TEST_39_MTIME ] || \
5064                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5065
5066                 cancel_lru_locks
5067                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5068         done
5069 }
5070 run_test 39k "write, utime, close, stat ========================"
5071
5072 # this should be set to future
5073 TEST_39_ATIME=`date -d "1 year" +%s`
5074
5075 test_39l() {
5076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5077         remote_mds_nodsh && skip "remote MDS with nodsh"
5078
5079         local atime_diff=$(do_facet $SINGLEMDS \
5080                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5081         rm -rf $DIR/$tdir
5082         mkdir_on_mdt0 $DIR/$tdir
5083
5084         # test setting directory atime to future
5085         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5086         local atime=$(stat -c %X $DIR/$tdir)
5087         [ "$atime" = $TEST_39_ATIME ] ||
5088                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5089
5090         # test setting directory atime from future to now
5091         local now=$(date +%s)
5092         touch -a -d @$now $DIR/$tdir
5093
5094         atime=$(stat -c %X $DIR/$tdir)
5095         [ "$atime" -eq "$now"  ] ||
5096                 error "atime is not updated from future: $atime, $now"
5097
5098         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5099         sleep 3
5100
5101         # test setting directory atime when now > dir atime + atime_diff
5102         local d1=$(date +%s)
5103         ls $DIR/$tdir
5104         local d2=$(date +%s)
5105         cancel_lru_locks mdc
5106         atime=$(stat -c %X $DIR/$tdir)
5107         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5108                 error "atime is not updated  : $atime, should be $d2"
5109
5110         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5111         sleep 3
5112
5113         # test not setting directory atime when now < dir atime + atime_diff
5114         ls $DIR/$tdir
5115         cancel_lru_locks mdc
5116         atime=$(stat -c %X $DIR/$tdir)
5117         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5118                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5119
5120         do_facet $SINGLEMDS \
5121                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5122 }
5123 run_test 39l "directory atime update ==========================="
5124
5125 test_39m() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         touch $DIR1/$tfile
5129         sleep 2
5130         local far_past_mtime=$(date -d "May 29 1953" +%s)
5131         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5132
5133         touch -m -d @$far_past_mtime $DIR1/$tfile
5134         touch -a -d @$far_past_atime $DIR1/$tfile
5135
5136         for (( i=0; i < 2; i++ )) ; do
5137                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5138                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5139                         error "atime or mtime set incorrectly"
5140
5141                 cancel_lru_locks $OSC
5142                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5143         done
5144 }
5145 run_test 39m "test atime and mtime before 1970"
5146
5147 test_39n() { # LU-3832
5148         remote_mds_nodsh && skip "remote MDS with nodsh"
5149
5150         local atime_diff=$(do_facet $SINGLEMDS \
5151                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5152         local atime0
5153         local atime1
5154         local atime2
5155
5156         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5157
5158         rm -rf $DIR/$tfile
5159         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5160         atime0=$(stat -c %X $DIR/$tfile)
5161
5162         sleep 5
5163         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5164         atime1=$(stat -c %X $DIR/$tfile)
5165
5166         sleep 5
5167         cancel_lru_locks mdc
5168         cancel_lru_locks osc
5169         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5170         atime2=$(stat -c %X $DIR/$tfile)
5171
5172         do_facet $SINGLEMDS \
5173                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5174
5175         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5176         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5177 }
5178 run_test 39n "check that O_NOATIME is honored"
5179
5180 test_39o() {
5181         TESTDIR=$DIR/$tdir/$tfile
5182         [ -e $TESTDIR ] && rm -rf $TESTDIR
5183         mkdir -p $TESTDIR
5184         cd $TESTDIR
5185         links1=2
5186         ls
5187         mkdir a b
5188         ls
5189         links2=$(stat -c %h .)
5190         [ $(($links1 + 2)) != $links2 ] &&
5191                 error "wrong links count $(($links1 + 2)) != $links2"
5192         rmdir b
5193         links3=$(stat -c %h .)
5194         [ $(($links1 + 1)) != $links3 ] &&
5195                 error "wrong links count $links1 != $links3"
5196         return 0
5197 }
5198 run_test 39o "directory cached attributes updated after create"
5199
5200 test_39p() {
5201         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5202
5203         local MDTIDX=1
5204         TESTDIR=$DIR/$tdir/$tdir
5205         [ -e $TESTDIR ] && rm -rf $TESTDIR
5206         test_mkdir -p $TESTDIR
5207         cd $TESTDIR
5208         links1=2
5209         ls
5210         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5211         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5212         ls
5213         links2=$(stat -c %h .)
5214         [ $(($links1 + 2)) != $links2 ] &&
5215                 error "wrong links count $(($links1 + 2)) != $links2"
5216         rmdir remote_dir2
5217         links3=$(stat -c %h .)
5218         [ $(($links1 + 1)) != $links3 ] &&
5219                 error "wrong links count $links1 != $links3"
5220         return 0
5221 }
5222 run_test 39p "remote directory cached attributes updated after create ========"
5223
5224 test_39r() {
5225         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5226                 skip "no atime update on old OST"
5227         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5228                 skip_env "ldiskfs only test"
5229         fi
5230
5231         local saved_adiff
5232         saved_adiff=$(do_facet ost1 \
5233                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5234         stack_trap "do_facet ost1 \
5235                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5236
5237         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5238
5239         $LFS setstripe -i 0 $DIR/$tfile
5240         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5241                 error "can't write initial file"
5242         cancel_lru_locks osc
5243
5244         # exceed atime_diff and access file
5245         sleep 10
5246         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5247                 error "can't udpate atime"
5248
5249         local atime_cli=$(stat -c %X $DIR/$tfile)
5250         echo "client atime: $atime_cli"
5251         # allow atime update to be written to device
5252         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5253         sleep 5
5254
5255         local ostdev=$(ostdevname 1)
5256         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5257         local seq=${fid[3]#0x}
5258         local oid=${fid[1]}
5259         local oid_hex
5260
5261         if [ $seq == 0 ]; then
5262                 oid_hex=${fid[1]}
5263         else
5264                 oid_hex=${fid[2]#0x}
5265         fi
5266         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5267         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5268
5269         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5270         local atime_ost=$(do_facet ost1 "$cmd" |&
5271                           awk -F'[: ]' '/atime:/ { print $4 }')
5272         (( atime_cli == atime_ost )) ||
5273                 error "atime on client $atime_cli != ost $atime_ost"
5274 }
5275 run_test 39r "lazy atime update on OST"
5276
5277 test_39q() { # LU-8041
5278         local testdir=$DIR/$tdir
5279         mkdir -p $testdir
5280         multiop_bg_pause $testdir D_c || error "multiop failed"
5281         local multipid=$!
5282         cancel_lru_locks mdc
5283         kill -USR1 $multipid
5284         local atime=$(stat -c %X $testdir)
5285         [ "$atime" -ne 0 ] || error "atime is zero"
5286 }
5287 run_test 39q "close won't zero out atime"
5288
5289 test_39s() {
5290         local atime0
5291         local atime1
5292         local atime2
5293         local atime3
5294         local atime4
5295
5296         umount_client $MOUNT
5297         mount_client $MOUNT relatime
5298
5299         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5300         atime0=$(stat -c %X $DIR/$tfile)
5301
5302         # First read updates atime
5303         sleep 1
5304         cat $DIR/$tfile >/dev/null
5305         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5306
5307         # Next reads do not update atime
5308         sleep 1
5309         cat $DIR/$tfile >/dev/null
5310         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5311
5312         # If mtime is greater than atime, atime is updated
5313         sleep 1
5314         touch -m $DIR/$tfile # (mtime = now)
5315         sleep 1
5316         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5317         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5318
5319         # Next reads do not update atime
5320         sleep 1
5321         cat $DIR/$tfile >/dev/null
5322         atime4=$(stat -c %X $DIR/$tfile)
5323
5324         # Remount the client to clear 'relatime' option
5325         remount_client $MOUNT
5326
5327         (( atime0 < atime1 )) ||
5328                 error "atime $atime0 should be smaller than $atime1"
5329         (( atime1 == atime2 )) ||
5330                 error "atime $atime1 was updated to $atime2"
5331         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5332         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5333 }
5334 run_test 39s "relatime is supported"
5335
5336 test_40() {
5337         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5338         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5339                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5340         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5341                 error "$tfile is not 4096 bytes in size"
5342 }
5343 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5344
5345 test_41() {
5346         # bug 1553
5347         small_write $DIR/f41 18
5348 }
5349 run_test 41 "test small file write + fstat ====================="
5350
5351 count_ost_writes() {
5352         lctl get_param -n ${OSC}.*.stats |
5353                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5354                         END { printf("%0.0f", writes) }'
5355 }
5356
5357 # decent default
5358 WRITEBACK_SAVE=500
5359 DIRTY_RATIO_SAVE=40
5360 MAX_DIRTY_RATIO=50
5361 BG_DIRTY_RATIO_SAVE=10
5362 MAX_BG_DIRTY_RATIO=25
5363
5364 start_writeback() {
5365         trap 0
5366         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5367         # dirty_ratio, dirty_background_ratio
5368         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5369                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5370                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5371                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5372         else
5373                 # if file not here, we are a 2.4 kernel
5374                 kill -CONT `pidof kupdated`
5375         fi
5376 }
5377
5378 stop_writeback() {
5379         # setup the trap first, so someone cannot exit the test at the
5380         # exact wrong time and mess up a machine
5381         trap start_writeback EXIT
5382         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5383         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5384                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5385                 sysctl -w vm.dirty_writeback_centisecs=0
5386                 sysctl -w vm.dirty_writeback_centisecs=0
5387                 # save and increase /proc/sys/vm/dirty_ratio
5388                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5389                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5390                 # save and increase /proc/sys/vm/dirty_background_ratio
5391                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5392                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5393         else
5394                 # if file not here, we are a 2.4 kernel
5395                 kill -STOP `pidof kupdated`
5396         fi
5397 }
5398
5399 # ensure that all stripes have some grant before we test client-side cache
5400 setup_test42() {
5401         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5402                 dd if=/dev/zero of=$i bs=4k count=1
5403                 rm $i
5404         done
5405 }
5406
5407 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5408 # file truncation, and file removal.
5409 test_42a() {
5410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5411
5412         setup_test42
5413         cancel_lru_locks $OSC
5414         stop_writeback
5415         sync; sleep 1; sync # just to be safe
5416         BEFOREWRITES=`count_ost_writes`
5417         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5418         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5419         AFTERWRITES=`count_ost_writes`
5420         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5421                 error "$BEFOREWRITES < $AFTERWRITES"
5422         start_writeback
5423 }
5424 run_test 42a "ensure that we don't flush on close"
5425
5426 test_42b() {
5427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5428
5429         setup_test42
5430         cancel_lru_locks $OSC
5431         stop_writeback
5432         sync
5433         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5434         BEFOREWRITES=$(count_ost_writes)
5435         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5436         AFTERWRITES=$(count_ost_writes)
5437         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5438                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5439         fi
5440         BEFOREWRITES=$(count_ost_writes)
5441         sync || error "sync: $?"
5442         AFTERWRITES=$(count_ost_writes)
5443         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5444                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5445         fi
5446         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5447         start_writeback
5448         return 0
5449 }
5450 run_test 42b "test destroy of file with cached dirty data ======"
5451
5452 # if these tests just want to test the effect of truncation,
5453 # they have to be very careful.  consider:
5454 # - the first open gets a {0,EOF}PR lock
5455 # - the first write conflicts and gets a {0, count-1}PW
5456 # - the rest of the writes are under {count,EOF}PW
5457 # - the open for truncate tries to match a {0,EOF}PR
5458 #   for the filesize and cancels the PWs.
5459 # any number of fixes (don't get {0,EOF} on open, match
5460 # composite locks, do smarter file size management) fix
5461 # this, but for now we want these tests to verify that
5462 # the cancellation with truncate intent works, so we
5463 # start the file with a full-file pw lock to match against
5464 # until the truncate.
5465 trunc_test() {
5466         test=$1
5467         file=$DIR/$test
5468         offset=$2
5469         cancel_lru_locks $OSC
5470         stop_writeback
5471         # prime the file with 0,EOF PW to match
5472         touch $file
5473         $TRUNCATE $file 0
5474         sync; sync
5475         # now the real test..
5476         dd if=/dev/zero of=$file bs=1024 count=100
5477         BEFOREWRITES=`count_ost_writes`
5478         $TRUNCATE $file $offset
5479         cancel_lru_locks $OSC
5480         AFTERWRITES=`count_ost_writes`
5481         start_writeback
5482 }
5483
5484 test_42c() {
5485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5486
5487         trunc_test 42c 1024
5488         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5489                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5490         rm $file
5491 }
5492 run_test 42c "test partial truncate of file with cached dirty data"
5493
5494 test_42d() {
5495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5496
5497         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5498         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5499         $LCTL set_param debug=+cache
5500
5501         trunc_test 42d 0
5502         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5503                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5504         rm $file
5505 }
5506 run_test 42d "test complete truncate of file with cached dirty data"
5507
5508 test_42e() { # bug22074
5509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5510
5511         local TDIR=$DIR/${tdir}e
5512         local pages=16 # hardcoded 16 pages, don't change it.
5513         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5514         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5515         local max_dirty_mb
5516         local warmup_files
5517
5518         test_mkdir $DIR/${tdir}e
5519         $LFS setstripe -c 1 $TDIR
5520         createmany -o $TDIR/f $files
5521
5522         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5523
5524         # we assume that with $OSTCOUNT files, at least one of them will
5525         # be allocated on OST0.
5526         warmup_files=$((OSTCOUNT * max_dirty_mb))
5527         createmany -o $TDIR/w $warmup_files
5528
5529         # write a large amount of data into one file and sync, to get good
5530         # avail_grant number from OST.
5531         for ((i=0; i<$warmup_files; i++)); do
5532                 idx=$($LFS getstripe -i $TDIR/w$i)
5533                 [ $idx -ne 0 ] && continue
5534                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5535                 break
5536         done
5537         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5538         sync
5539         $LCTL get_param $proc_osc0/cur_dirty_bytes
5540         $LCTL get_param $proc_osc0/cur_grant_bytes
5541
5542         # create as much dirty pages as we can while not to trigger the actual
5543         # RPCs directly. but depends on the env, VFS may trigger flush during this
5544         # period, hopefully we are good.
5545         for ((i=0; i<$warmup_files; i++)); do
5546                 idx=$($LFS getstripe -i $TDIR/w$i)
5547                 [ $idx -ne 0 ] && continue
5548                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5549         done
5550         $LCTL get_param $proc_osc0/cur_dirty_bytes
5551         $LCTL get_param $proc_osc0/cur_grant_bytes
5552
5553         # perform the real test
5554         $LCTL set_param $proc_osc0/rpc_stats 0
5555         for ((;i<$files; i++)); do
5556                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5557                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5558         done
5559         sync
5560         $LCTL get_param $proc_osc0/rpc_stats
5561
5562         local percent=0
5563         local have_ppr=false
5564         $LCTL get_param $proc_osc0/rpc_stats |
5565                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5566                         # skip lines until we are at the RPC histogram data
5567                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5568                         $have_ppr || continue
5569
5570                         # we only want the percent stat for < 16 pages
5571                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5572
5573                         percent=$((percent + WPCT))
5574                         if [[ $percent -gt 15 ]]; then
5575                                 error "less than 16-pages write RPCs" \
5576                                       "$percent% > 15%"
5577                                 break
5578                         fi
5579                 done
5580         rm -rf $TDIR
5581 }
5582 run_test 42e "verify sub-RPC writes are not done synchronously"
5583
5584 test_43A() { # was test_43
5585         test_mkdir $DIR/$tdir
5586         cp -p /bin/ls $DIR/$tdir/$tfile
5587         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5588         pid=$!
5589         # give multiop a chance to open
5590         sleep 1
5591
5592         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5593         kill -USR1 $pid
5594         # Wait for multiop to exit
5595         wait $pid
5596 }
5597 run_test 43A "execution of file opened for write should return -ETXTBSY"
5598
5599 test_43a() {
5600         test_mkdir $DIR/$tdir
5601         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5602         $DIR/$tdir/sleep 60 &
5603         SLEEP_PID=$!
5604         # Make sure exec of $tdir/sleep wins race with truncate
5605         sleep 1
5606         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5607         kill $SLEEP_PID
5608 }
5609 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5610
5611 test_43b() {
5612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5613
5614         test_mkdir $DIR/$tdir
5615         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5616         $DIR/$tdir/sleep 60 &
5617         SLEEP_PID=$!
5618         # Make sure exec of $tdir/sleep wins race with truncate
5619         sleep 1
5620         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5621         kill $SLEEP_PID
5622 }
5623 run_test 43b "truncate of file being executed should return -ETXTBSY"
5624
5625 test_43c() {
5626         local testdir="$DIR/$tdir"
5627         test_mkdir $testdir
5628         cp $SHELL $testdir/
5629         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5630                 ( cd $testdir && md5sum -c )
5631 }
5632 run_test 43c "md5sum of copy into lustre"
5633
5634 test_44A() { # was test_44
5635         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5636
5637         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5638         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5639 }
5640 run_test 44A "zero length read from a sparse stripe"
5641
5642 test_44a() {
5643         local nstripe=$($LFS getstripe -c -d $DIR)
5644         [ -z "$nstripe" ] && skip "can't get stripe info"
5645         [[ $nstripe -gt $OSTCOUNT ]] &&
5646                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5647
5648         local stride=$($LFS getstripe -S -d $DIR)
5649         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5650                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5651         fi
5652
5653         OFFSETS="0 $((stride/2)) $((stride-1))"
5654         for offset in $OFFSETS; do
5655                 for i in $(seq 0 $((nstripe-1))); do
5656                         local GLOBALOFFSETS=""
5657                         # size in Bytes
5658                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5659                         local myfn=$DIR/d44a-$size
5660                         echo "--------writing $myfn at $size"
5661                         ll_sparseness_write $myfn $size ||
5662                                 error "ll_sparseness_write"
5663                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5664                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5665                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5666
5667                         for j in $(seq 0 $((nstripe-1))); do
5668                                 # size in Bytes
5669                                 size=$((((j + $nstripe )*$stride + $offset)))
5670                                 ll_sparseness_write $myfn $size ||
5671                                         error "ll_sparseness_write"
5672                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5673                         done
5674                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5675                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5676                         rm -f $myfn
5677                 done
5678         done
5679 }
5680 run_test 44a "test sparse pwrite ==============================="
5681
5682 dirty_osc_total() {
5683         tot=0
5684         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5685                 tot=$(($tot + $d))
5686         done
5687         echo $tot
5688 }
5689 do_dirty_record() {
5690         before=`dirty_osc_total`
5691         echo executing "\"$*\""
5692         eval $*
5693         after=`dirty_osc_total`
5694         echo before $before, after $after
5695 }
5696 test_45() {
5697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5698
5699         f="$DIR/f45"
5700         # Obtain grants from OST if it supports it
5701         echo blah > ${f}_grant
5702         stop_writeback
5703         sync
5704         do_dirty_record "echo blah > $f"
5705         [[ $before -eq $after ]] && error "write wasn't cached"
5706         do_dirty_record "> $f"
5707         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5708         do_dirty_record "echo blah > $f"
5709         [[ $before -eq $after ]] && error "write wasn't cached"
5710         do_dirty_record "sync"
5711         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5712         do_dirty_record "echo blah > $f"
5713         [[ $before -eq $after ]] && error "write wasn't cached"
5714         do_dirty_record "cancel_lru_locks osc"
5715         [[ $before -gt $after ]] ||
5716                 error "lock cancellation didn't lower dirty count"
5717         start_writeback
5718 }
5719 run_test 45 "osc io page accounting ============================"
5720
5721 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5722 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5723 # objects offset and an assert hit when an rpc was built with 1023's mapped
5724 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5725 test_46() {
5726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5727
5728         f="$DIR/f46"
5729         stop_writeback
5730         sync
5731         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5732         sync
5733         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5734         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5735         sync
5736         start_writeback
5737 }
5738 run_test 46 "dirtying a previously written page ================"
5739
5740 # test_47 is removed "Device nodes check" is moved to test_28
5741
5742 test_48a() { # bug 2399
5743         [ "$mds1_FSTYPE" = "zfs" ] &&
5744         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5745                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5746
5747         test_mkdir $DIR/$tdir
5748         cd $DIR/$tdir
5749         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5750         test_mkdir $DIR/$tdir
5751         touch foo || error "'touch foo' failed after recreating cwd"
5752         test_mkdir bar
5753         touch .foo || error "'touch .foo' failed after recreating cwd"
5754         test_mkdir .bar
5755         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5756         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5757         cd . || error "'cd .' failed after recreating cwd"
5758         mkdir . && error "'mkdir .' worked after recreating cwd"
5759         rmdir . && error "'rmdir .' worked after recreating cwd"
5760         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5761         cd .. || error "'cd ..' failed after recreating cwd"
5762 }
5763 run_test 48a "Access renamed working dir (should return errors)="
5764
5765 test_48b() { # bug 2399
5766         rm -rf $DIR/$tdir
5767         test_mkdir $DIR/$tdir
5768         cd $DIR/$tdir
5769         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5770         touch foo && error "'touch foo' worked after removing cwd"
5771         mkdir foo && error "'mkdir foo' worked after removing cwd"
5772         touch .foo && error "'touch .foo' worked after removing cwd"
5773         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5774         ls . > /dev/null && error "'ls .' worked after removing cwd"
5775         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5776         mkdir . && error "'mkdir .' worked after removing cwd"
5777         rmdir . && error "'rmdir .' worked after removing cwd"
5778         ln -s . foo && error "'ln -s .' worked after removing cwd"
5779         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5780 }
5781 run_test 48b "Access removed working dir (should return errors)="
5782
5783 test_48c() { # bug 2350
5784         #lctl set_param debug=-1
5785         #set -vx
5786         rm -rf $DIR/$tdir
5787         test_mkdir -p $DIR/$tdir/dir
5788         cd $DIR/$tdir/dir
5789         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5790         $TRACE touch foo && error "touch foo worked after removing cwd"
5791         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5792         touch .foo && error "touch .foo worked after removing cwd"
5793         mkdir .foo && error "mkdir .foo worked after removing cwd"
5794         $TRACE ls . && error "'ls .' worked after removing cwd"
5795         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5796         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5797         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5798         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5799         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5800 }
5801 run_test 48c "Access removed working subdir (should return errors)"
5802
5803 test_48d() { # bug 2350
5804         #lctl set_param debug=-1
5805         #set -vx
5806         rm -rf $DIR/$tdir
5807         test_mkdir -p $DIR/$tdir/dir
5808         cd $DIR/$tdir/dir
5809         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5810         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5811         $TRACE touch foo && error "'touch foo' worked after removing parent"
5812         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5813         touch .foo && error "'touch .foo' worked after removing parent"
5814         mkdir .foo && error "mkdir .foo worked after removing parent"
5815         $TRACE ls . && error "'ls .' worked after removing parent"
5816         $TRACE ls .. && error "'ls ..' worked after removing parent"
5817         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5818         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5819         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5820         true
5821 }
5822 run_test 48d "Access removed parent subdir (should return errors)"
5823
5824 test_48e() { # bug 4134
5825         #lctl set_param debug=-1
5826         #set -vx
5827         rm -rf $DIR/$tdir
5828         test_mkdir -p $DIR/$tdir/dir
5829         cd $DIR/$tdir/dir
5830         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5831         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5832         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5833         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5834         # On a buggy kernel addition of "touch foo" after cd .. will
5835         # produce kernel oops in lookup_hash_it
5836         touch ../foo && error "'cd ..' worked after recreate parent"
5837         cd $DIR
5838         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5839 }
5840 run_test 48e "Access to recreated parent subdir (should return errors)"
5841
5842 test_48f() {
5843         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5844                 skip "need MDS >= 2.13.55"
5845         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5846         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5847                 skip "needs different host for mdt1 mdt2"
5848         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5849
5850         $LFS mkdir -i0 $DIR/$tdir
5851         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5852
5853         for d in sub1 sub2 sub3; do
5854                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5855                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5856                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5857         done
5858
5859         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5860 }
5861 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5862
5863 test_49() { # LU-1030
5864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5865         remote_ost_nodsh && skip "remote OST with nodsh"
5866
5867         # get ost1 size - $FSNAME-OST0000
5868         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5869                 awk '{ print $4 }')
5870         # write 800M at maximum
5871         [[ $ost1_size -lt 2 ]] && ost1_size=2
5872         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5873
5874         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5875         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5876         local dd_pid=$!
5877
5878         # change max_pages_per_rpc while writing the file
5879         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5880         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5881         # loop until dd process exits
5882         while ps ax -opid | grep -wq $dd_pid; do
5883                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5884                 sleep $((RANDOM % 5 + 1))
5885         done
5886         # restore original max_pages_per_rpc
5887         $LCTL set_param $osc1_mppc=$orig_mppc
5888         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5889 }
5890 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5891
5892 test_50() {
5893         # bug 1485
5894         test_mkdir $DIR/$tdir
5895         cd $DIR/$tdir
5896         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5897 }
5898 run_test 50 "special situations: /proc symlinks  ==============="
5899
5900 test_51a() {    # was test_51
5901         # bug 1516 - create an empty entry right after ".." then split dir
5902         test_mkdir -c1 $DIR/$tdir
5903         touch $DIR/$tdir/foo
5904         $MCREATE $DIR/$tdir/bar
5905         rm $DIR/$tdir/foo
5906         createmany -m $DIR/$tdir/longfile 201
5907         FNUM=202
5908         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5909                 $MCREATE $DIR/$tdir/longfile$FNUM
5910                 FNUM=$(($FNUM + 1))
5911                 echo -n "+"
5912         done
5913         echo
5914         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5915 }
5916 run_test 51a "special situations: split htree with empty entry =="
5917
5918 cleanup_print_lfs_df () {
5919         trap 0
5920         $LFS df
5921         $LFS df -i
5922 }
5923
5924 test_51b() {
5925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5926
5927         local dir=$DIR/$tdir
5928         local nrdirs=$((65536 + 100))
5929
5930         # cleanup the directory
5931         rm -fr $dir
5932
5933         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5934
5935         $LFS df
5936         $LFS df -i
5937         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5938         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5939         [[ $numfree -lt $nrdirs ]] &&
5940                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5941
5942         # need to check free space for the directories as well
5943         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5944         numfree=$(( blkfree / $(fs_inode_ksize) ))
5945         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5946
5947         trap cleanup_print_lfs_df EXIT
5948
5949         # create files
5950         createmany -d $dir/d $nrdirs || {
5951                 unlinkmany $dir/d $nrdirs
5952                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5953         }
5954
5955         # really created :
5956         nrdirs=$(ls -U $dir | wc -l)
5957
5958         # unlink all but 100 subdirectories, then check it still works
5959         local left=100
5960         local delete=$((nrdirs - left))
5961
5962         $LFS df
5963         $LFS df -i
5964
5965         # for ldiskfs the nlink count should be 1, but this is OSD specific
5966         # and so this is listed for informational purposes only
5967         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5968         unlinkmany -d $dir/d $delete ||
5969                 error "unlink of first $delete subdirs failed"
5970
5971         echo "nlink between: $(stat -c %h $dir)"
5972         local found=$(ls -U $dir | wc -l)
5973         [ $found -ne $left ] &&
5974                 error "can't find subdirs: found only $found, expected $left"
5975
5976         unlinkmany -d $dir/d $delete $left ||
5977                 error "unlink of second $left subdirs failed"
5978         # regardless of whether the backing filesystem tracks nlink accurately
5979         # or not, the nlink count shouldn't be more than "." and ".." here
5980         local after=$(stat -c %h $dir)
5981         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5982                 echo "nlink after: $after"
5983
5984         cleanup_print_lfs_df
5985 }
5986 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5987
5988 test_51d_sub() {
5989         local stripecount=$1
5990         local nfiles=$2
5991
5992         log "create files with stripecount=$stripecount"
5993         $LFS setstripe -C $stripecount $DIR/$tdir
5994         createmany -o $DIR/$tdir/t- $nfiles
5995         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5996         for ((n = 0; n < $OSTCOUNT; n++)); do
5997                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5998                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5999                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6000                             '($1 == '$n') { objs += 1 } \
6001                             END { printf("%0.0f", objs) }')
6002                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6003         done
6004         unlinkmany $DIR/$tdir/t- $nfiles
6005         rm  -f $TMP/$tfile
6006
6007         local nlast
6008         local min=4
6009         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6010
6011         # For some combinations of stripecount and OSTCOUNT current code
6012         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6013         # than others. Rather than skipping this test entirely, check that
6014         # and keep testing to ensure imbalance does not get worse. LU-15282
6015         (( (OSTCOUNT == 6 && stripecount == 4) ||
6016            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6017            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6018         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6019                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6020                         { $LFS df && $LFS df -i &&
6021                         error "stripecount=$stripecount: " \
6022                               "OST $n has fewer objects vs. OST $nlast " \
6023                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6024                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6025                         { $LFS df && $LFS df -i &&
6026                         error "stripecount=$stripecount: " \
6027                               "OST $n has more objects vs. OST $nlast " \
6028                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6029
6030                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6031                         { $LFS df && $LFS df -i &&
6032                         error "stripecount=$stripecount: " \
6033                               "OST $n has fewer #0 objects vs. OST $nlast " \
6034                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6035                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6036                         { $LFS df && $LFS df -i &&
6037                         error "stripecount=$stripecount: " \
6038                               "OST $n has more #0 objects vs. OST $nlast " \
6039                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6040         done
6041 }
6042
6043 test_51d() {
6044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6045         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6046
6047         local stripecount
6048         local per_ost=100
6049         local nfiles=$((per_ost * OSTCOUNT))
6050         local mdts=$(comma_list $(mdts_nodes))
6051         local param="osp.*.create_count"
6052         local qos_old=$(do_facet mds1 \
6053                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6054
6055         do_nodes $mdts \
6056                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6057         stack_trap "do_nodes $mdts \
6058                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6059
6060         test_mkdir $DIR/$tdir
6061         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6062         (( dirstripes > 0 )) || dirstripes=1
6063
6064         # Ensure enough OST objects precreated for tests to pass without
6065         # running out of objects.  This is an LOV r-r OST algorithm test,
6066         # not an OST object precreation test.
6067         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6068         (( old >= nfiles )) ||
6069         {
6070                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6071
6072                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6073                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6074
6075                 # trigger precreation from all MDTs for all OSTs
6076                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6077                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6078                 done
6079         }
6080
6081         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6082                 sleep 8  # allow object precreation to catch up
6083                 test_51d_sub $stripecount $nfiles
6084         done
6085 }
6086 run_test 51d "check LOV round-robin OST object distribution"
6087
6088 test_51e() {
6089         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6090                 skip_env "ldiskfs only test"
6091         fi
6092
6093         test_mkdir -c1 $DIR/$tdir
6094         test_mkdir -c1 $DIR/$tdir/d0
6095
6096         touch $DIR/$tdir/d0/foo
6097         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6098                 error "file exceed 65000 nlink limit!"
6099         unlinkmany $DIR/$tdir/d0/f- 65001
6100         return 0
6101 }
6102 run_test 51e "check file nlink limit"
6103
6104 test_51f() {
6105         test_mkdir $DIR/$tdir
6106
6107         local max=100000
6108         local ulimit_old=$(ulimit -n)
6109         local spare=20 # number of spare fd's for scripts/libraries, etc.
6110         local mdt=$($LFS getstripe -m $DIR/$tdir)
6111         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6112
6113         echo "MDT$mdt numfree=$numfree, max=$max"
6114         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6115         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6116                 while ! ulimit -n $((numfree + spare)); do
6117                         numfree=$((numfree * 3 / 4))
6118                 done
6119                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6120         else
6121                 echo "left ulimit at $ulimit_old"
6122         fi
6123
6124         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6125                 unlinkmany $DIR/$tdir/f $numfree
6126                 error "create+open $numfree files in $DIR/$tdir failed"
6127         }
6128         ulimit -n $ulimit_old
6129
6130         # if createmany exits at 120s there will be fewer than $numfree files
6131         unlinkmany $DIR/$tdir/f $numfree || true
6132 }
6133 run_test 51f "check many open files limit"
6134
6135 test_52a() {
6136         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6137         test_mkdir $DIR/$tdir
6138         touch $DIR/$tdir/foo
6139         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6140         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6141         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6142         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6143         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6144                                         error "link worked"
6145         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6146         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6147         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6148                                                      error "lsattr"
6149         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6150         cp -r $DIR/$tdir $TMP/
6151         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6152 }
6153 run_test 52a "append-only flag test (should return errors)"
6154
6155 test_52b() {
6156         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6157         test_mkdir $DIR/$tdir
6158         touch $DIR/$tdir/foo
6159         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6160         cat test > $DIR/$tdir/foo && error "cat test worked"
6161         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6162         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6163         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6164                                         error "link worked"
6165         echo foo >> $DIR/$tdir/foo && error "echo worked"
6166         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6167         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6168         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6169         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6170                                                         error "lsattr"
6171         chattr -i $DIR/$tdir/foo || error "chattr failed"
6172
6173         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6174 }
6175 run_test 52b "immutable flag test (should return errors) ======="
6176
6177 test_53() {
6178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6179         remote_mds_nodsh && skip "remote MDS with nodsh"
6180         remote_ost_nodsh && skip "remote OST with nodsh"
6181
6182         local param
6183         local param_seq
6184         local ostname
6185         local mds_last
6186         local mds_last_seq
6187         local ost_last
6188         local ost_last_seq
6189         local ost_last_id
6190         local ostnum
6191         local node
6192         local found=false
6193         local support_last_seq=true
6194
6195         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6196                 support_last_seq=false
6197
6198         # only test MDT0000
6199         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6200         local value
6201         for value in $(do_facet $SINGLEMDS \
6202                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6203                 param=$(echo ${value[0]} | cut -d "=" -f1)
6204                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6205
6206                 if $support_last_seq; then
6207                         param_seq=$(echo $param |
6208                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6209                         mds_last_seq=$(do_facet $SINGLEMDS \
6210                                        $LCTL get_param -n $param_seq)
6211                 fi
6212                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6213
6214                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6215                 node=$(facet_active_host ost$((ostnum+1)))
6216                 param="obdfilter.$ostname.last_id"
6217                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6218                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6219                         ost_last_id=$ost_last
6220
6221                         if $support_last_seq; then
6222                                 ost_last_id=$(echo $ost_last |
6223                                               awk -F':' '{print $2}' |
6224                                               sed -e "s/^0x//g")
6225                                 ost_last_seq=$(echo $ost_last |
6226                                                awk -F':' '{print $1}')
6227                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6228                         fi
6229
6230                         if [[ $ost_last_id != $mds_last ]]; then
6231                                 error "$ost_last_id != $mds_last"
6232                         else
6233                                 found=true
6234                                 break
6235                         fi
6236                 done
6237         done
6238         $found || error "can not match last_seq/last_id for $mdtosc"
6239         return 0
6240 }
6241 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6242
6243 test_54a() {
6244         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6245
6246         LANG=C $SOCKETSERVER $DIR/socket ||
6247                 error "$SOCKETSERVER $DIR/socket failed: $?"
6248         LANG=C $SOCKETCLIENT $DIR/socket ||
6249                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6250         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6251 }
6252 run_test 54a "unix domain socket test =========================="
6253
6254 test_54b() {
6255         f="$DIR/f54b"
6256         mknod $f c 1 3
6257         chmod 0666 $f
6258         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6259 }
6260 run_test 54b "char device works in lustre ======================"
6261
6262 find_loop_dev() {
6263         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6264         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6265         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6266
6267         for i in $(seq 3 7); do
6268                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6269                 LOOPDEV=$LOOPBASE$i
6270                 LOOPNUM=$i
6271                 break
6272         done
6273 }
6274
6275 cleanup_54c() {
6276         local rc=0
6277         loopdev="$DIR/loop54c"
6278
6279         trap 0
6280         $UMOUNT $DIR/$tdir || rc=$?
6281         losetup -d $loopdev || true
6282         losetup -d $LOOPDEV || true
6283         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6284         return $rc
6285 }
6286
6287 test_54c() {
6288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6289
6290         loopdev="$DIR/loop54c"
6291
6292         find_loop_dev
6293         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6294         trap cleanup_54c EXIT
6295         mknod $loopdev b 7 $LOOPNUM
6296         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6297         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6298         losetup $loopdev $DIR/$tfile ||
6299                 error "can't set up $loopdev for $DIR/$tfile"
6300         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6301         test_mkdir $DIR/$tdir
6302         mount -t ext2 $loopdev $DIR/$tdir ||
6303                 error "error mounting $loopdev on $DIR/$tdir"
6304         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6305                 error "dd write"
6306         df $DIR/$tdir
6307         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6308                 error "dd read"
6309         cleanup_54c
6310 }
6311 run_test 54c "block device works in lustre ====================="
6312
6313 test_54d() {
6314         local pipe="$DIR/$tfile.pipe"
6315         local string="aaaaaa"
6316
6317         mknod $pipe p
6318         echo -n "$string" > $pipe &
6319         local result=$(cat $pipe)
6320         [[ "$result" == "$string" ]] || error "$result != $string"
6321 }
6322 run_test 54d "fifo device works in lustre ======================"
6323
6324 test_54e() {
6325         f="$DIR/f54e"
6326         string="aaaaaa"
6327         cp -aL /dev/console $f
6328         echo $string > $f || error "echo $string to $f failed"
6329 }
6330 run_test 54e "console/tty device works in lustre ======================"
6331
6332 test_56a() {
6333         local numfiles=3
6334         local numdirs=2
6335         local dir=$DIR/$tdir
6336
6337         rm -rf $dir
6338         test_mkdir -p $dir/dir
6339         for i in $(seq $numfiles); do
6340                 touch $dir/file$i
6341                 touch $dir/dir/file$i
6342         done
6343
6344         local numcomp=$($LFS getstripe --component-count $dir)
6345
6346         [[ $numcomp == 0 ]] && numcomp=1
6347
6348         # test lfs getstripe with --recursive
6349         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6350
6351         [[ $filenum -eq $((numfiles * 2)) ]] ||
6352                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6353         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6354         [[ $filenum -eq $numfiles ]] ||
6355                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6356         echo "$LFS getstripe showed obdidx or l_ost_idx"
6357
6358         # test lfs getstripe with file instead of dir
6359         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6360         [[ $filenum -eq 1 ]] ||
6361                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6362         echo "$LFS getstripe file1 passed"
6363
6364         #test lfs getstripe with --verbose
6365         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6366         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6367                 error "$LFS getstripe --verbose $dir: "\
6368                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6369         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6370                 error "$LFS getstripe $dir: showed lmm_magic"
6371
6372         #test lfs getstripe with -v prints lmm_fid
6373         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6374         local countfids=$((numdirs + numfiles * numcomp))
6375         [[ $filenum -eq $countfids ]] ||
6376                 error "$LFS getstripe -v $dir: "\
6377                       "got $filenum want $countfids lmm_fid"
6378         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6379                 error "$LFS getstripe $dir: showed lmm_fid by default"
6380         echo "$LFS getstripe --verbose passed"
6381
6382         #check for FID information
6383         local fid1=$($LFS getstripe --fid $dir/file1)
6384         local fid2=$($LFS getstripe --verbose $dir/file1 |
6385                      awk '/lmm_fid: / { print $2; exit; }')
6386         local fid3=$($LFS path2fid $dir/file1)
6387
6388         [ "$fid1" != "$fid2" ] &&
6389                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6390         [ "$fid1" != "$fid3" ] &&
6391                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6392         echo "$LFS getstripe --fid passed"
6393
6394         #test lfs getstripe with --obd
6395         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6396                 error "$LFS getstripe --obd wrong_uuid: should return error"
6397
6398         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6399
6400         local ostidx=1
6401         local obduuid=$(ostuuid_from_index $ostidx)
6402         local found=$($LFS getstripe -r --obd $obduuid $dir |
6403                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6404
6405         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6406         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6407                 ((filenum--))
6408         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6409                 ((filenum--))
6410
6411         [[ $found -eq $filenum ]] ||
6412                 error "$LFS getstripe --obd: found $found expect $filenum"
6413         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6414                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6415                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6416                 error "$LFS getstripe --obd: should not show file on other obd"
6417         echo "$LFS getstripe --obd passed"
6418 }
6419 run_test 56a "check $LFS getstripe"
6420
6421 test_56b() {
6422         local dir=$DIR/$tdir
6423         local numdirs=3
6424
6425         test_mkdir $dir
6426         for i in $(seq $numdirs); do
6427                 test_mkdir $dir/dir$i
6428         done
6429
6430         # test lfs getdirstripe default mode is non-recursion, which is
6431         # different from lfs getstripe
6432         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6433
6434         [[ $dircnt -eq 1 ]] ||
6435                 error "$LFS getdirstripe: found $dircnt, not 1"
6436         dircnt=$($LFS getdirstripe --recursive $dir |
6437                 grep -c lmv_stripe_count)
6438         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6439                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6440 }
6441 run_test 56b "check $LFS getdirstripe"
6442
6443 test_56bb() {
6444         verify_yaml_available || skip_env "YAML verification not installed"
6445         local output_file=$DIR/$tfile.out
6446
6447         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6448
6449         cat $output_file
6450         cat $output_file | verify_yaml || error "layout is not valid YAML"
6451 }
6452 run_test 56bb "check $LFS getdirstripe layout is YAML"
6453
6454 test_56c() {
6455         remote_ost_nodsh && skip "remote OST with nodsh"
6456
6457         local ost_idx=0
6458         local ost_name=$(ostname_from_index $ost_idx)
6459         local old_status=$(ost_dev_status $ost_idx)
6460         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6461
6462         [[ -z "$old_status" ]] ||
6463                 skip_env "OST $ost_name is in $old_status status"
6464
6465         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6466         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6467                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6468         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6469                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6470                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6471         fi
6472
6473         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6474                 error "$LFS df -v showing inactive devices"
6475         sleep_maxage
6476
6477         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6478
6479         [[ "$new_status" =~ "D" ]] ||
6480                 error "$ost_name status is '$new_status', missing 'D'"
6481         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6482                 [[ "$new_status" =~ "N" ]] ||
6483                         error "$ost_name status is '$new_status', missing 'N'"
6484         fi
6485         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6486                 [[ "$new_status" =~ "f" ]] ||
6487                         error "$ost_name status is '$new_status', missing 'f'"
6488         fi
6489
6490         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6491         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6492                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6493         [[ -z "$p" ]] && restore_lustre_params < $p || true
6494         sleep_maxage
6495
6496         new_status=$(ost_dev_status $ost_idx)
6497         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6498                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6499         # can't check 'f' as devices may actually be on flash
6500 }
6501 run_test 56c "check 'lfs df' showing device status"
6502
6503 test_56d() {
6504         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6505         local osts=$($LFS df -v $MOUNT | grep -c OST)
6506
6507         $LFS df $MOUNT
6508
6509         (( mdts == MDSCOUNT )) ||
6510                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6511         (( osts == OSTCOUNT )) ||
6512                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6513 }
6514 run_test 56d "'lfs df -v' prints only configured devices"
6515
6516 test_56e() {
6517         err_enoent=2 # No such file or directory
6518         err_eopnotsupp=95 # Operation not supported
6519
6520         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6521         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6522
6523         # Check for handling of path not exists
6524         output=$($LFS df $enoent_mnt 2>&1)
6525         ret=$?
6526
6527         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6528         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6529                 error "expect failure $err_enoent, not $ret"
6530
6531         # Check for handling of non-Lustre FS
6532         output=$($LFS df $notsup_mnt)
6533         ret=$?
6534
6535         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6536         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6537                 error "expect success $err_eopnotsupp, not $ret"
6538
6539         # Check for multiple LustreFS argument
6540         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6541         ret=$?
6542
6543         [[ $output -eq 3 && $ret -eq 0 ]] ||
6544                 error "expect success 3, not $output, rc = $ret"
6545
6546         # Check for correct non-Lustre FS handling among multiple
6547         # LustreFS argument
6548         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6549                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6550         ret=$?
6551
6552         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6553                 error "expect success 2, not $output, rc = $ret"
6554 }
6555 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6556
6557 NUMFILES=3
6558 NUMDIRS=3
6559 setup_56() {
6560         local local_tdir="$1"
6561         local local_numfiles="$2"
6562         local local_numdirs="$3"
6563         local dir_params="$4"
6564         local dir_stripe_params="$5"
6565
6566         if [ ! -d "$local_tdir" ] ; then
6567                 test_mkdir -p $dir_stripe_params $local_tdir
6568                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6569                 for i in $(seq $local_numfiles) ; do
6570                         touch $local_tdir/file$i
6571                 done
6572                 for i in $(seq $local_numdirs) ; do
6573                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6574                         for j in $(seq $local_numfiles) ; do
6575                                 touch $local_tdir/dir$i/file$j
6576                         done
6577                 done
6578         fi
6579 }
6580
6581 setup_56_special() {
6582         local local_tdir=$1
6583         local local_numfiles=$2
6584         local local_numdirs=$3
6585
6586         setup_56 $local_tdir $local_numfiles $local_numdirs
6587
6588         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6589                 for i in $(seq $local_numfiles) ; do
6590                         mknod $local_tdir/loop${i}b b 7 $i
6591                         mknod $local_tdir/null${i}c c 1 3
6592                         ln -s $local_tdir/file1 $local_tdir/link${i}
6593                 done
6594                 for i in $(seq $local_numdirs) ; do
6595                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6596                         mknod $local_tdir/dir$i/null${i}c c 1 3
6597                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6598                 done
6599         fi
6600 }
6601
6602 test_56g() {
6603         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6604         local expected=$(($NUMDIRS + 2))
6605
6606         setup_56 $dir $NUMFILES $NUMDIRS
6607
6608         # test lfs find with -name
6609         for i in $(seq $NUMFILES) ; do
6610                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6611
6612                 [ $nums -eq $expected ] ||
6613                         error "lfs find -name '*$i' $dir wrong: "\
6614                               "found $nums, expected $expected"
6615         done
6616 }
6617 run_test 56g "check lfs find -name"
6618
6619 test_56h() {
6620         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6621         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6622
6623         setup_56 $dir $NUMFILES $NUMDIRS
6624
6625         # test lfs find with ! -name
6626         for i in $(seq $NUMFILES) ; do
6627                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6628
6629                 [ $nums -eq $expected ] ||
6630                         error "lfs find ! -name '*$i' $dir wrong: "\
6631                               "found $nums, expected $expected"
6632         done
6633 }
6634 run_test 56h "check lfs find ! -name"
6635
6636 test_56i() {
6637         local dir=$DIR/$tdir
6638
6639         test_mkdir $dir
6640
6641         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6642         local out=$($cmd)
6643
6644         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6645 }
6646 run_test 56i "check 'lfs find -ost UUID' skips directories"
6647
6648 test_56j() {
6649         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6650
6651         setup_56_special $dir $NUMFILES $NUMDIRS
6652
6653         local expected=$((NUMDIRS + 1))
6654         local cmd="$LFS find -type d $dir"
6655         local nums=$($cmd | wc -l)
6656
6657         [ $nums -eq $expected ] ||
6658                 error "'$cmd' wrong: found $nums, expected $expected"
6659 }
6660 run_test 56j "check lfs find -type d"
6661
6662 test_56k() {
6663         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6664
6665         setup_56_special $dir $NUMFILES $NUMDIRS
6666
6667         local expected=$(((NUMDIRS + 1) * NUMFILES))
6668         local cmd="$LFS find -type f $dir"
6669         local nums=$($cmd | wc -l)
6670
6671         [ $nums -eq $expected ] ||
6672                 error "'$cmd' wrong: found $nums, expected $expected"
6673 }
6674 run_test 56k "check lfs find -type f"
6675
6676 test_56l() {
6677         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6678
6679         setup_56_special $dir $NUMFILES $NUMDIRS
6680
6681         local expected=$((NUMDIRS + NUMFILES))
6682         local cmd="$LFS find -type b $dir"
6683         local nums=$($cmd | wc -l)
6684
6685         [ $nums -eq $expected ] ||
6686                 error "'$cmd' wrong: found $nums, expected $expected"
6687 }
6688 run_test 56l "check lfs find -type b"
6689
6690 test_56m() {
6691         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6692
6693         setup_56_special $dir $NUMFILES $NUMDIRS
6694
6695         local expected=$((NUMDIRS + NUMFILES))
6696         local cmd="$LFS find -type c $dir"
6697         local nums=$($cmd | wc -l)
6698         [ $nums -eq $expected ] ||
6699                 error "'$cmd' wrong: found $nums, expected $expected"
6700 }
6701 run_test 56m "check lfs find -type c"
6702
6703 test_56n() {
6704         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6705         setup_56_special $dir $NUMFILES $NUMDIRS
6706
6707         local expected=$((NUMDIRS + NUMFILES))
6708         local cmd="$LFS find -type l $dir"
6709         local nums=$($cmd | wc -l)
6710
6711         [ $nums -eq $expected ] ||
6712                 error "'$cmd' wrong: found $nums, expected $expected"
6713 }
6714 run_test 56n "check lfs find -type l"
6715
6716 test_56o() {
6717         local dir=$DIR/$tdir
6718
6719         setup_56 $dir $NUMFILES $NUMDIRS
6720         utime $dir/file1 > /dev/null || error "utime (1)"
6721         utime $dir/file2 > /dev/null || error "utime (2)"
6722         utime $dir/dir1 > /dev/null || error "utime (3)"
6723         utime $dir/dir2 > /dev/null || error "utime (4)"
6724         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6725         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6726
6727         local expected=4
6728         local nums=$($LFS find -mtime +0 $dir | wc -l)
6729
6730         [ $nums -eq $expected ] ||
6731                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6732
6733         expected=12
6734         cmd="$LFS find -mtime 0 $dir"
6735         nums=$($cmd | wc -l)
6736         [ $nums -eq $expected ] ||
6737                 error "'$cmd' wrong: found $nums, expected $expected"
6738 }
6739 run_test 56o "check lfs find -mtime for old files"
6740
6741 test_56ob() {
6742         local dir=$DIR/$tdir
6743         local expected=1
6744         local count=0
6745
6746         # just to make sure there is something that won't be found
6747         test_mkdir $dir
6748         touch $dir/$tfile.now
6749
6750         for age in year week day hour min; do
6751                 count=$((count + 1))
6752
6753                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6754                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6755                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6756
6757                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6758                 local nums=$($cmd | wc -l)
6759                 [ $nums -eq $expected ] ||
6760                         error "'$cmd' wrong: found $nums, expected $expected"
6761
6762                 cmd="$LFS find $dir -atime $count${age:0:1}"
6763                 nums=$($cmd | wc -l)
6764                 [ $nums -eq $expected ] ||
6765                         error "'$cmd' wrong: found $nums, expected $expected"
6766         done
6767
6768         sleep 2
6769         cmd="$LFS find $dir -ctime +1s -type f"
6770         nums=$($cmd | wc -l)
6771         (( $nums == $count * 2 + 1)) ||
6772                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6773 }
6774 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6775
6776 test_newerXY_base() {
6777         local x=$1
6778         local y=$2
6779         local dir=$DIR/$tdir
6780         local ref
6781         local negref
6782
6783         if [ $y == "t" ]; then
6784                 if [ $x == "b" ]; then
6785                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6786                 else
6787                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6788                 fi
6789         else
6790                 ref=$DIR/$tfile.newer.$x$y
6791                 touch $ref || error "touch $ref failed"
6792         fi
6793
6794         echo "before = $ref"
6795         sleep 2
6796         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6797         sleep 2
6798         if [ $y == "t" ]; then
6799                 if [ $x == "b" ]; then
6800                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6801                 else
6802                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6803                 fi
6804         else
6805                 negref=$DIR/$tfile.negnewer.$x$y
6806                 touch $negref || error "touch $negref failed"
6807         fi
6808
6809         echo "after = $negref"
6810         local cmd="$LFS find $dir -newer$x$y $ref"
6811         local nums=$(eval $cmd | wc -l)
6812         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6813
6814         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6815                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6816
6817         cmd="$LFS find $dir ! -newer$x$y $negref"
6818         nums=$(eval $cmd | wc -l)
6819         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6820                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6821
6822         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6823         nums=$(eval $cmd | wc -l)
6824         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6825                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6826
6827         rm -rf $DIR/*
6828 }
6829
6830 test_56oc() {
6831         test_newerXY_base "a" "a"
6832         test_newerXY_base "a" "m"
6833         test_newerXY_base "a" "c"
6834         test_newerXY_base "m" "a"
6835         test_newerXY_base "m" "m"
6836         test_newerXY_base "m" "c"
6837         test_newerXY_base "c" "a"
6838         test_newerXY_base "c" "m"
6839         test_newerXY_base "c" "c"
6840
6841         test_newerXY_base "a" "t"
6842         test_newerXY_base "m" "t"
6843         test_newerXY_base "c" "t"
6844
6845         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6846            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6847                 ! btime_supported && echo "btime unsupported" && return 0
6848
6849         test_newerXY_base "b" "b"
6850         test_newerXY_base "b" "t"
6851 }
6852 run_test 56oc "check lfs find -newerXY work"
6853
6854 btime_supported() {
6855         local dir=$DIR/$tdir
6856         local rc
6857
6858         mkdir -p $dir
6859         touch $dir/$tfile
6860         $LFS find $dir -btime -1d -type f
6861         rc=$?
6862         rm -rf $dir
6863         return $rc
6864 }
6865
6866 test_56od() {
6867         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6868                 ! btime_supported && skip "btime unsupported on MDS"
6869
6870         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6871                 ! btime_supported && skip "btime unsupported on clients"
6872
6873         local dir=$DIR/$tdir
6874         local ref=$DIR/$tfile.ref
6875         local negref=$DIR/$tfile.negref
6876
6877         mkdir $dir || error "mkdir $dir failed"
6878         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6879         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6880         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6881         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6882         touch $ref || error "touch $ref failed"
6883         # sleep 3 seconds at least
6884         sleep 3
6885
6886         local before=$(do_facet mds1 date +%s)
6887         local skew=$(($(date +%s) - before + 1))
6888
6889         if (( skew < 0 && skew > -5 )); then
6890                 sleep $((0 - skew + 1))
6891                 skew=0
6892         fi
6893
6894         # Set the dir stripe params to limit files all on MDT0,
6895         # otherwise we need to calc the max clock skew between
6896         # the client and MDTs.
6897         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6898         sleep 2
6899         touch $negref || error "touch $negref failed"
6900
6901         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6902         local nums=$($cmd | wc -l)
6903         local expected=$(((NUMFILES + 1) * NUMDIRS))
6904
6905         [ $nums -eq $expected ] ||
6906                 error "'$cmd' wrong: found $nums, expected $expected"
6907
6908         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6909         nums=$($cmd | wc -l)
6910         expected=$((NUMFILES + 1))
6911         [ $nums -eq $expected ] ||
6912                 error "'$cmd' wrong: found $nums, expected $expected"
6913
6914         [ $skew -lt 0 ] && return
6915
6916         local after=$(do_facet mds1 date +%s)
6917         local age=$((after - before + 1 + skew))
6918
6919         cmd="$LFS find $dir -btime -${age}s -type f"
6920         nums=$($cmd | wc -l)
6921         expected=$(((NUMFILES + 1) * NUMDIRS))
6922
6923         echo "Clock skew between client and server: $skew, age:$age"
6924         [ $nums -eq $expected ] ||
6925                 error "'$cmd' wrong: found $nums, expected $expected"
6926
6927         expected=$(($NUMDIRS + 1))
6928         cmd="$LFS find $dir -btime -${age}s -type d"
6929         nums=$($cmd | wc -l)
6930         [ $nums -eq $expected ] ||
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932         rm -f $ref $negref || error "Failed to remove $ref $negref"
6933 }
6934 run_test 56od "check lfs find -btime with units"
6935
6936 test_56p() {
6937         [ $RUNAS_ID -eq $UID ] &&
6938                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6939
6940         local dir=$DIR/$tdir
6941
6942         setup_56 $dir $NUMFILES $NUMDIRS
6943         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6944
6945         local expected=$NUMFILES
6946         local cmd="$LFS find -uid $RUNAS_ID $dir"
6947         local nums=$($cmd | wc -l)
6948
6949         [ $nums -eq $expected ] ||
6950                 error "'$cmd' wrong: found $nums, expected $expected"
6951
6952         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6953         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6954         nums=$($cmd | wc -l)
6955         [ $nums -eq $expected ] ||
6956                 error "'$cmd' wrong: found $nums, expected $expected"
6957 }
6958 run_test 56p "check lfs find -uid and ! -uid"
6959
6960 test_56q() {
6961         [ $RUNAS_ID -eq $UID ] &&
6962                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6963
6964         local dir=$DIR/$tdir
6965
6966         setup_56 $dir $NUMFILES $NUMDIRS
6967         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6968
6969         local expected=$NUMFILES
6970         local cmd="$LFS find -gid $RUNAS_GID $dir"
6971         local nums=$($cmd | wc -l)
6972
6973         [ $nums -eq $expected ] ||
6974                 error "'$cmd' wrong: found $nums, expected $expected"
6975
6976         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6977         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6978         nums=$($cmd | wc -l)
6979         [ $nums -eq $expected ] ||
6980                 error "'$cmd' wrong: found $nums, expected $expected"
6981 }
6982 run_test 56q "check lfs find -gid and ! -gid"
6983
6984 test_56r() {
6985         local dir=$DIR/$tdir
6986
6987         setup_56 $dir $NUMFILES $NUMDIRS
6988
6989         local expected=12
6990         local cmd="$LFS find -size 0 -type f -lazy $dir"
6991         local nums=$($cmd | wc -l)
6992
6993         [ $nums -eq $expected ] ||
6994                 error "'$cmd' wrong: found $nums, expected $expected"
6995         cmd="$LFS find -size 0 -type f $dir"
6996         nums=$($cmd | wc -l)
6997         [ $nums -eq $expected ] ||
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999
7000         expected=0
7001         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7002         nums=$($cmd | wc -l)
7003         [ $nums -eq $expected ] ||
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005         cmd="$LFS find ! -size 0 -type f $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         echo "test" > $dir/$tfile
7011         echo "test2" > $dir/$tfile.2 && sync
7012         expected=1
7013         cmd="$LFS find -size 5 -type f -lazy $dir"
7014         nums=$($cmd | wc -l)
7015         [ $nums -eq $expected ] ||
7016                 error "'$cmd' wrong: found $nums, expected $expected"
7017         cmd="$LFS find -size 5 -type f $dir"
7018         nums=$($cmd | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021
7022         expected=1
7023         cmd="$LFS find -size +5 -type f -lazy $dir"
7024         nums=$($cmd | wc -l)
7025         [ $nums -eq $expected ] ||
7026                 error "'$cmd' wrong: found $nums, expected $expected"
7027         cmd="$LFS find -size +5 -type f $dir"
7028         nums=$($cmd | wc -l)
7029         [ $nums -eq $expected ] ||
7030                 error "'$cmd' wrong: found $nums, expected $expected"
7031
7032         expected=2
7033         cmd="$LFS find -size +0 -type f -lazy $dir"
7034         nums=$($cmd | wc -l)
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037         cmd="$LFS find -size +0 -type f $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041
7042         expected=2
7043         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7044         nums=$($cmd | wc -l)
7045         [ $nums -eq $expected ] ||
7046                 error "'$cmd' wrong: found $nums, expected $expected"
7047         cmd="$LFS find ! -size -5 -type f $dir"
7048         nums=$($cmd | wc -l)
7049         [ $nums -eq $expected ] ||
7050                 error "'$cmd' wrong: found $nums, expected $expected"
7051
7052         expected=12
7053         cmd="$LFS find -size -5 -type f -lazy $dir"
7054         nums=$($cmd | wc -l)
7055         [ $nums -eq $expected ] ||
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057         cmd="$LFS find -size -5 -type f $dir"
7058         nums=$($cmd | wc -l)
7059         [ $nums -eq $expected ] ||
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061 }
7062 run_test 56r "check lfs find -size works"
7063
7064 test_56ra_sub() {
7065         local expected=$1
7066         local glimpses=$2
7067         local cmd="$3"
7068
7069         cancel_lru_locks $OSC
7070
7071         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7072         local nums=$($cmd | wc -l)
7073
7074         [ $nums -eq $expected ] ||
7075                 error "'$cmd' wrong: found $nums, expected $expected"
7076
7077         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7078
7079         if (( rpcs_before + glimpses != rpcs_after )); then
7080                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7081                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7082
7083                 if [[ $glimpses == 0 ]]; then
7084                         error "'$cmd' should not send glimpse RPCs to OST"
7085                 else
7086                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7087                 fi
7088         fi
7089 }
7090
7091 test_56ra() {
7092         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7093                 skip "MDS < 2.12.58 doesn't return LSOM data"
7094         local dir=$DIR/$tdir
7095         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7096
7097         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7098
7099         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7100         $LCTL set_param -n llite.*.statahead_agl=0
7101         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7102
7103         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7104         # open and close all files to ensure LSOM is updated
7105         cancel_lru_locks $OSC
7106         find $dir -type f | xargs cat > /dev/null
7107
7108         #   expect_found  glimpse_rpcs  command_to_run
7109         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7110         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7111         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7112         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7113
7114         echo "test" > $dir/$tfile
7115         echo "test2" > $dir/$tfile.2 && sync
7116         cancel_lru_locks $OSC
7117         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7118
7119         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7120         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7121         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7122         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7123
7124         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7125         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7126         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7127         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7128         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7129         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7130 }
7131 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7132
7133 test_56rb() {
7134         local dir=$DIR/$tdir
7135         local tmp=$TMP/$tfile.log
7136         local mdt_idx;
7137
7138         test_mkdir -p $dir || error "failed to mkdir $dir"
7139         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7140                 error "failed to setstripe $dir/$tfile"
7141         mdt_idx=$($LFS getdirstripe -i $dir)
7142         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7143
7144         stack_trap "rm -f $tmp" EXIT
7145         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7146         ! grep -q obd_uuid $tmp ||
7147                 error "failed to find --size +100K --ost 0 $dir"
7148         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7149         ! grep -q obd_uuid $tmp ||
7150                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7151 }
7152 run_test 56rb "check lfs find --size --ost/--mdt works"
7153
7154 test_56rc() {
7155         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7156         local dir=$DIR/$tdir
7157         local found
7158
7159         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7160         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7161         (( $MDSCOUNT > 2 )) &&
7162                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7163         mkdir $dir/$tdir-{1..10}
7164         touch $dir/$tfile-{1..10}
7165
7166         found=$($LFS find $dir --mdt-count 2 | wc -l)
7167         expect=11
7168         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7169
7170         found=$($LFS find $dir -T +1 | wc -l)
7171         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7172         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7173
7174         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7175         expect=11
7176         (( $found == $expect )) || error "found $found all_char, expect $expect"
7177
7178         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7179         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7180         (( $found == $expect )) || error "found $found all_char, expect $expect"
7181 }
7182 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7183
7184 test_56rd() {
7185         local dir=$DIR/$tdir
7186
7187         test_mkdir $dir
7188         rm -f $dir/*
7189
7190         mkfifo $dir/fifo || error "failed to create fifo file"
7191         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7192                 error "should not fail even cannot get projid from pipe file"
7193         found=$($LFS find $dir -t p --printf "%y")
7194         [[ "p" == $found ]] || error "found $found, expect p"
7195
7196         mknod $dir/chardev c 1 5 ||
7197                 error "failed to create character device file"
7198         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7199                 error "should not fail even cannot get projid from chardev file"
7200         found=$($LFS find $dir -t c --printf "%y")
7201         [[ "c" == $found ]] || error "found $found, expect c"
7202
7203         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7204         (( found == 2 )) || error "unable to list all files"
7205 }
7206 run_test 56rd "check lfs find --printf special files"
7207
7208 test_56s() { # LU-611 #LU-9369
7209         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7210
7211         local dir=$DIR/$tdir
7212         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7213
7214         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7215         for i in $(seq $NUMDIRS); do
7216                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7217         done
7218
7219         local expected=$NUMDIRS
7220         local cmd="$LFS find -c $OSTCOUNT $dir"
7221         local nums=$($cmd | wc -l)
7222
7223         [ $nums -eq $expected ] || {
7224                 $LFS getstripe -R $dir
7225                 error "'$cmd' wrong: found $nums, expected $expected"
7226         }
7227
7228         expected=$((NUMDIRS + onestripe))
7229         cmd="$LFS find -stripe-count +0 -type f $dir"
7230         nums=$($cmd | wc -l)
7231         [ $nums -eq $expected ] || {
7232                 $LFS getstripe -R $dir
7233                 error "'$cmd' wrong: found $nums, expected $expected"
7234         }
7235
7236         expected=$onestripe
7237         cmd="$LFS find -stripe-count 1 -type f $dir"
7238         nums=$($cmd | wc -l)
7239         [ $nums -eq $expected ] || {
7240                 $LFS getstripe -R $dir
7241                 error "'$cmd' wrong: found $nums, expected $expected"
7242         }
7243
7244         cmd="$LFS find -stripe-count -2 -type f $dir"
7245         nums=$($cmd | wc -l)
7246         [ $nums -eq $expected ] || {
7247                 $LFS getstripe -R $dir
7248                 error "'$cmd' wrong: found $nums, expected $expected"
7249         }
7250
7251         expected=0
7252         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7253         nums=$($cmd | wc -l)
7254         [ $nums -eq $expected ] || {
7255                 $LFS getstripe -R $dir
7256                 error "'$cmd' wrong: found $nums, expected $expected"
7257         }
7258 }
7259 run_test 56s "check lfs find -stripe-count works"
7260
7261 test_56t() { # LU-611 #LU-9369
7262         local dir=$DIR/$tdir
7263
7264         setup_56 $dir 0 $NUMDIRS
7265         for i in $(seq $NUMDIRS); do
7266                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7267         done
7268
7269         local expected=$NUMDIRS
7270         local cmd="$LFS find -S 8M $dir"
7271         local nums=$($cmd | wc -l)
7272
7273         [ $nums -eq $expected ] || {
7274                 $LFS getstripe -R $dir
7275                 error "'$cmd' wrong: found $nums, expected $expected"
7276         }
7277         rm -rf $dir
7278
7279         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7280
7281         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7282
7283         expected=$(((NUMDIRS + 1) * NUMFILES))
7284         cmd="$LFS find -stripe-size 512k -type f $dir"
7285         nums=$($cmd | wc -l)
7286         [ $nums -eq $expected ] ||
7287                 error "'$cmd' wrong: found $nums, expected $expected"
7288
7289         cmd="$LFS find -stripe-size +320k -type f $dir"
7290         nums=$($cmd | wc -l)
7291         [ $nums -eq $expected ] ||
7292                 error "'$cmd' wrong: found $nums, expected $expected"
7293
7294         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7295         cmd="$LFS find -stripe-size +200k -type f $dir"
7296         nums=$($cmd | wc -l)
7297         [ $nums -eq $expected ] ||
7298                 error "'$cmd' wrong: found $nums, expected $expected"
7299
7300         cmd="$LFS find -stripe-size -640k -type f $dir"
7301         nums=$($cmd | wc -l)
7302         [ $nums -eq $expected ] ||
7303                 error "'$cmd' wrong: found $nums, expected $expected"
7304
7305         expected=4
7306         cmd="$LFS find -stripe-size 256k -type f $dir"
7307         nums=$($cmd | wc -l)
7308         [ $nums -eq $expected ] ||
7309                 error "'$cmd' wrong: found $nums, expected $expected"
7310
7311         cmd="$LFS find -stripe-size -320k -type f $dir"
7312         nums=$($cmd | wc -l)
7313         [ $nums -eq $expected ] ||
7314                 error "'$cmd' wrong: found $nums, expected $expected"
7315
7316         expected=0
7317         cmd="$LFS find -stripe-size 1024k -type f $dir"
7318         nums=$($cmd | wc -l)
7319         [ $nums -eq $expected ] ||
7320                 error "'$cmd' wrong: found $nums, expected $expected"
7321 }
7322 run_test 56t "check lfs find -stripe-size works"
7323
7324 test_56u() { # LU-611
7325         local dir=$DIR/$tdir
7326
7327         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7328
7329         if [[ $OSTCOUNT -gt 1 ]]; then
7330                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7331                 onestripe=4
7332         else
7333                 onestripe=0
7334         fi
7335
7336         local expected=$(((NUMDIRS + 1) * NUMFILES))
7337         local cmd="$LFS find -stripe-index 0 -type f $dir"
7338         local nums=$($cmd | wc -l)
7339
7340         [ $nums -eq $expected ] ||
7341                 error "'$cmd' wrong: found $nums, expected $expected"
7342
7343         expected=$onestripe
7344         cmd="$LFS find -stripe-index 1 -type f $dir"
7345         nums=$($cmd | wc -l)
7346         [ $nums -eq $expected ] ||
7347                 error "'$cmd' wrong: found $nums, expected $expected"
7348
7349         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7350         nums=$($cmd | wc -l)
7351         [ $nums -eq $expected ] ||
7352                 error "'$cmd' wrong: found $nums, expected $expected"
7353
7354         expected=0
7355         # This should produce an error and not return any files
7356         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7357         nums=$($cmd 2>/dev/null | wc -l)
7358         [ $nums -eq $expected ] ||
7359                 error "'$cmd' wrong: found $nums, expected $expected"
7360
7361         if [[ $OSTCOUNT -gt 1 ]]; then
7362                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7363                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7364                 nums=$($cmd | wc -l)
7365                 [ $nums -eq $expected ] ||
7366                         error "'$cmd' wrong: found $nums, expected $expected"
7367         fi
7368 }
7369 run_test 56u "check lfs find -stripe-index works"
7370
7371 test_56v() {
7372         local mdt_idx=0
7373         local dir=$DIR/$tdir
7374
7375         setup_56 $dir $NUMFILES $NUMDIRS
7376
7377         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7378         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7379
7380         for file in $($LFS find -m $UUID $dir); do
7381                 file_midx=$($LFS getstripe -m $file)
7382                 [ $file_midx -eq $mdt_idx ] ||
7383                         error "lfs find -m $UUID != getstripe -m $file_midx"
7384         done
7385 }
7386 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7387
7388 test_56wa() {
7389         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7391
7392         local dir=$DIR/$tdir
7393
7394         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7395         stack_trap "rm -rf $dir"
7396
7397         local stripe_size=$($LFS getstripe -S -d $dir) ||
7398                 error "$LFS getstripe -S -d $dir failed"
7399         stripe_size=${stripe_size%% *}
7400
7401         local file_size=$((stripe_size * OSTCOUNT))
7402         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7403         local required_space=$((file_num * file_size))
7404         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7405                            head -n1)
7406         (( free_space >= required_space / 1024 )) ||
7407                 skip_env "need $required_space, have $free_space kbytes"
7408
7409         local dd_bs=65536
7410         local dd_count=$((file_size / dd_bs))
7411
7412         # write data into the files
7413         local i
7414         local j
7415         local file
7416
7417         for ((i = 1; i <= NUMFILES; i++ )); do
7418                 file=$dir/file$i
7419                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7420                         error "write data into $file failed"
7421         done
7422         for ((i = 1; i <= NUMDIRS; i++ )); do
7423                 for ((j = 1; j <= NUMFILES; j++ )); do
7424                         file=$dir/dir$i/file$j
7425                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7426                                 error "write data into $file failed"
7427                 done
7428         done
7429
7430         # $LFS_MIGRATE will fail if hard link migration is unsupported
7431         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7432                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7433                         error "creating links to $dir/dir1/file1 failed"
7434         fi
7435
7436         local expected=-1
7437
7438         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7439
7440         # lfs_migrate file
7441         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7442
7443         echo "$cmd"
7444         eval $cmd || error "$cmd failed"
7445
7446         check_stripe_count $dir/file1 $expected
7447
7448         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7449                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7450                 # OST 1 if it is on OST 0. This file is small enough to
7451                 # be on only one stripe.
7452                 file=$dir/migr_1_ost
7453                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7454                         error "write data into $file failed"
7455                 local obdidx=$($LFS getstripe -i $file)
7456                 local oldmd5=$(md5sum $file)
7457                 local newobdidx=0
7458
7459                 (( obdidx != 0 )) || newobdidx=1
7460                 cmd="$LFS migrate -i $newobdidx $file"
7461                 echo $cmd
7462                 eval $cmd || error "$cmd failed"
7463
7464                 local realobdix=$($LFS getstripe -i $file)
7465                 local newmd5=$(md5sum $file)
7466
7467                 (( $newobdidx == $realobdix )) ||
7468                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7469                 [[ "$oldmd5" == "$newmd5" ]] ||
7470                         error "md5sum differ: $oldmd5, $newmd5"
7471         fi
7472
7473         # lfs_migrate dir
7474         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7475         echo "$cmd"
7476         eval $cmd || error "$cmd failed"
7477
7478         for (( j = 1; j <= NUMFILES; j++ )); do
7479                 check_stripe_count $dir/dir1/file$j $expected
7480         done
7481
7482         # lfs_migrate works with lfs find
7483         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7484              $LFS_MIGRATE -y -c $expected"
7485         echo "$cmd"
7486         eval $cmd || error "$cmd failed"
7487
7488         for (( i = 2; i <= NUMFILES; i++ )); do
7489                 check_stripe_count $dir/file$i $expected
7490         done
7491         for (( i = 2; i <= NUMDIRS; i++ )); do
7492                 for (( j = 1; j <= NUMFILES; j++ )); do
7493                         check_stripe_count $dir/dir$i/file$j $expected
7494                 done
7495         done
7496 }
7497 run_test 56wa "check lfs_migrate -c stripe_count works"
7498
7499 test_56wb() {
7500         local file1=$DIR/$tdir/file1
7501         local create_pool=false
7502         local initial_pool=$($LFS getstripe -p $DIR)
7503         local pool_list=()
7504         local pool=""
7505
7506         echo -n "Creating test dir..."
7507         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7508         echo "done."
7509
7510         echo -n "Creating test file..."
7511         touch $file1 || error "cannot create file"
7512         echo "done."
7513
7514         echo -n "Detecting existing pools..."
7515         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7516
7517         if [ ${#pool_list[@]} -gt 0 ]; then
7518                 echo "${pool_list[@]}"
7519                 for thispool in "${pool_list[@]}"; do
7520                         if [[ -z "$initial_pool" ||
7521                               "$initial_pool" != "$thispool" ]]; then
7522                                 pool="$thispool"
7523                                 echo "Using existing pool '$pool'"
7524                                 break
7525                         fi
7526                 done
7527         else
7528                 echo "none detected."
7529         fi
7530         if [ -z "$pool" ]; then
7531                 pool=${POOL:-testpool}
7532                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7533                 echo -n "Creating pool '$pool'..."
7534                 create_pool=true
7535                 pool_add $pool &> /dev/null ||
7536                         error "pool_add failed"
7537                 echo "done."
7538
7539                 echo -n "Adding target to pool..."
7540                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7541                         error "pool_add_targets failed"
7542                 echo "done."
7543         fi
7544
7545         echo -n "Setting pool using -p option..."
7546         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7547                 error "migrate failed rc = $?"
7548         echo "done."
7549
7550         echo -n "Verifying test file is in pool after migrating..."
7551         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7552                 error "file was not migrated to pool $pool"
7553         echo "done."
7554
7555         echo -n "Removing test file from pool '$pool'..."
7556         # "lfs migrate $file" won't remove the file from the pool
7557         # until some striping information is changed.
7558         $LFS migrate -c 1 $file1 &> /dev/null ||
7559                 error "cannot remove from pool"
7560         [ "$($LFS getstripe -p $file1)" ] &&
7561                 error "pool still set"
7562         echo "done."
7563
7564         echo -n "Setting pool using --pool option..."
7565         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7566                 error "migrate failed rc = $?"
7567         echo "done."
7568
7569         # Clean up
7570         rm -f $file1
7571         if $create_pool; then
7572                 destroy_test_pools 2> /dev/null ||
7573                         error "destroy test pools failed"
7574         fi
7575 }
7576 run_test 56wb "check lfs_migrate pool support"
7577
7578 test_56wc() {
7579         local file1="$DIR/$tdir/$tfile"
7580         local md5
7581         local parent_ssize
7582         local parent_scount
7583         local cur_ssize
7584         local cur_scount
7585         local orig_ssize
7586         local new_scount
7587         local cur_comp
7588
7589         echo -n "Creating test dir..."
7590         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7591         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7592                 error "cannot set stripe by '-S 1M -c 1'"
7593         echo "done"
7594
7595         echo -n "Setting initial stripe for test file..."
7596         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7597                 error "cannot set stripe"
7598         cur_ssize=$($LFS getstripe -S "$file1")
7599         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7600         echo "done."
7601
7602         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7603         stack_trap "rm -f $file1"
7604         md5="$(md5sum $file1)"
7605
7606         # File currently set to -S 512K -c 1
7607
7608         # Ensure -c and -S options are rejected when -R is set
7609         echo -n "Verifying incompatible options are detected..."
7610         $LFS_MIGRATE -R -c 1 "$file1" &&
7611                 error "incompatible -R and -c options not detected"
7612         $LFS_MIGRATE -R -S 1M "$file1" &&
7613                 error "incompatible -R and -S options not detected"
7614         $LFS_MIGRATE -R -p pool "$file1" &&
7615                 error "incompatible -R and -p options not detected"
7616         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7617                 error "incompatible -R and -E options not detected"
7618         $LFS_MIGRATE -R -A "$file1" &&
7619                 error "incompatible -R and -A options not detected"
7620         $LFS_MIGRATE -A -c 1 "$file1" &&
7621                 error "incompatible -A and -c options not detected"
7622         $LFS_MIGRATE -A -S 1M "$file1" &&
7623                 error "incompatible -A and -S options not detected"
7624         $LFS_MIGRATE -A -p pool "$file1" &&
7625                 error "incompatible -A and -p options not detected"
7626         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7627                 error "incompatible -A and -E options not detected"
7628         echo "done."
7629
7630         # Ensure unrecognized options are passed through to 'lfs migrate'
7631         echo -n "Verifying -S option is passed through to lfs migrate..."
7632         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7633         cur_ssize=$($LFS getstripe -S "$file1")
7634         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7635         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7636         echo "done."
7637
7638         # File currently set to -S 1M -c 1
7639
7640         # Ensure long options are supported
7641         echo -n "Verifying long options supported..."
7642         $LFS_MIGRATE --non-block "$file1" ||
7643                 error "long option without argument not supported"
7644         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7645                 error "long option with argument not supported"
7646         cur_ssize=$($LFS getstripe -S "$file1")
7647         (( cur_ssize == 524288 )) ||
7648                 error "migrate --stripe-size $cur_ssize != 524288"
7649         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7650         echo "done."
7651
7652         # File currently set to -S 512K -c 1
7653
7654         if (( OSTCOUNT > 1 )); then
7655                 echo -n "Verifying explicit stripe count can be set..."
7656                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7657                 cur_scount=$($LFS getstripe -c "$file1")
7658                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7659                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7660                         error "file data has changed (3)"
7661                 echo "done."
7662         fi
7663
7664         # File currently set to -S 512K -c 1 or -S 512K -c 2
7665
7666         # Ensure parent striping is used if -R is set, and no stripe
7667         # count or size is specified
7668         echo -n "Setting stripe for parent directory..."
7669         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7670                 error "cannot set stripe '-S 2M -c 1'"
7671         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7672         echo "done."
7673
7674         echo -n "Verifying restripe option uses parent stripe settings..."
7675         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7676         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7677         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7678         cur_ssize=$($LFS getstripe -S "$file1")
7679         (( cur_ssize == parent_ssize )) ||
7680                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7681         cur_scount=$($LFS getstripe -c "$file1")
7682         (( cur_scount == parent_scount )) ||
7683                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7684         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7685         echo "done."
7686
7687         # File currently set to -S 1M -c 1
7688
7689         # Ensure striping is preserved if -R is not set, and no stripe
7690         # count or size is specified
7691         echo -n "Verifying striping size preserved when not specified..."
7692         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7693         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7694                 error "cannot set stripe on parent directory"
7695         $LFS_MIGRATE "$file1" || error "migrate failed"
7696         cur_ssize=$($LFS getstripe -S "$file1")
7697         (( cur_ssize == orig_ssize )) ||
7698                 error "migrate by default $cur_ssize != $orig_ssize"
7699         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7700         echo "done."
7701
7702         # Ensure file name properly detected when final option has no argument
7703         echo -n "Verifying file name properly detected..."
7704         $LFS_MIGRATE "$file1" ||
7705                 error "file name interpreted as option argument"
7706         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7707         echo "done."
7708
7709         # Ensure PFL arguments are passed through properly
7710         echo -n "Verifying PFL options passed through..."
7711         new_scount=$(((OSTCOUNT + 1) / 2))
7712         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7713                 error "migrate PFL arguments failed"
7714         cur_comp=$($LFS getstripe --comp-count $file1)
7715         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7716         cur_scount=$($LFS getstripe --stripe-count $file1)
7717         (( cur_scount == new_scount)) ||
7718                 error "PFL stripe count $cur_scount != $new_scount"
7719         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7720         echo "done."
7721 }
7722 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7723
7724 test_56wd() {
7725         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7726
7727         local file1=$DIR/$tdir/$tfile
7728
7729         echo -n "Creating test dir..."
7730         test_mkdir $DIR/$tdir || error "cannot create dir"
7731         echo "done."
7732
7733         echo -n "Creating test file..."
7734         echo "$tfile" > $file1
7735         echo "done."
7736
7737         # Ensure 'lfs migrate' will fail by using a non-existent option,
7738         # and make sure rsync is not called to recover
7739         echo -n "Make sure --no-rsync option works..."
7740         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7741                 grep -q 'refusing to fall back to rsync' ||
7742                 error "rsync was called with --no-rsync set"
7743         echo "done."
7744
7745         # Ensure rsync is called without trying 'lfs migrate' first
7746         echo -n "Make sure --rsync option works..."
7747         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7748                 grep -q 'falling back to rsync' &&
7749                 error "lfs migrate was called with --rsync set"
7750         echo "done."
7751 }
7752 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7753
7754 test_56we() {
7755         local td=$DIR/$tdir
7756         local tf=$td/$tfile
7757
7758         test_mkdir $td || error "cannot create $td"
7759         touch $tf || error "cannot touch $tf"
7760
7761         echo -n "Make sure --non-direct|-D works..."
7762         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7763                 grep -q "lfs migrate --non-direct" ||
7764                 error "--non-direct option cannot work correctly"
7765         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7766                 grep -q "lfs migrate -D" ||
7767                 error "-D option cannot work correctly"
7768         echo "done."
7769 }
7770 run_test 56we "check lfs_migrate --non-direct|-D support"
7771
7772 test_56x() {
7773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7774         check_swap_layouts_support
7775
7776         local dir=$DIR/$tdir
7777         local ref1=/etc/passwd
7778         local file1=$dir/file1
7779
7780         test_mkdir $dir || error "creating dir $dir"
7781         $LFS setstripe -c 2 $file1
7782         cp $ref1 $file1
7783         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7784         stripe=$($LFS getstripe -c $file1)
7785         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7786         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7787
7788         # clean up
7789         rm -f $file1
7790 }
7791 run_test 56x "lfs migration support"
7792
7793 test_56xa() {
7794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7795         check_swap_layouts_support
7796
7797         local dir=$DIR/$tdir/$testnum
7798
7799         test_mkdir -p $dir
7800
7801         local ref1=/etc/passwd
7802         local file1=$dir/file1
7803
7804         $LFS setstripe -c 2 $file1
7805         cp $ref1 $file1
7806         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7807
7808         local stripe=$($LFS getstripe -c $file1)
7809
7810         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7811         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7812
7813         # clean up
7814         rm -f $file1
7815 }
7816 run_test 56xa "lfs migration --block support"
7817
7818 check_migrate_links() {
7819         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7820         local dir="$1"
7821         local file1="$dir/file1"
7822         local begin="$2"
7823         local count="$3"
7824         local runas="$4"
7825         local total_count=$(($begin + $count - 1))
7826         local symlink_count=10
7827         local uniq_count=10
7828
7829         if [ ! -f "$file1" ]; then
7830                 echo -n "creating initial file..."
7831                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7832                         error "cannot setstripe initial file"
7833                 echo "done"
7834
7835                 echo -n "creating symlinks..."
7836                 for s in $(seq 1 $symlink_count); do
7837                         ln -s "$file1" "$dir/slink$s" ||
7838                                 error "cannot create symlinks"
7839                 done
7840                 echo "done"
7841
7842                 echo -n "creating nonlinked files..."
7843                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7844                         error "cannot create nonlinked files"
7845                 echo "done"
7846         fi
7847
7848         # create hard links
7849         if [ ! -f "$dir/file$total_count" ]; then
7850                 echo -n "creating hard links $begin:$total_count..."
7851                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7852                         /dev/null || error "cannot create hard links"
7853                 echo "done"
7854         fi
7855
7856         echo -n "checking number of hard links listed in xattrs..."
7857         local fid=$($LFS getstripe -F "$file1")
7858         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7859
7860         echo "${#paths[*]}"
7861         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7862                         skip "hard link list has unexpected size, skipping test"
7863         fi
7864         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7865                         error "link names should exceed xattrs size"
7866         fi
7867
7868         echo -n "migrating files..."
7869         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7870         local rc=$?
7871         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7872         echo "done"
7873
7874         # make sure all links have been properly migrated
7875         echo -n "verifying files..."
7876         fid=$($LFS getstripe -F "$file1") ||
7877                 error "cannot get fid for file $file1"
7878         for i in $(seq 2 $total_count); do
7879                 local fid2=$($LFS getstripe -F $dir/file$i)
7880
7881                 [ "$fid2" == "$fid" ] ||
7882                         error "migrated hard link has mismatched FID"
7883         done
7884
7885         # make sure hard links were properly detected, and migration was
7886         # performed only once for the entire link set; nonlinked files should
7887         # also be migrated
7888         local actual=$(grep -c 'done' <<< "$migrate_out")
7889         local expected=$(($uniq_count + 1))
7890
7891         [ "$actual" -eq  "$expected" ] ||
7892                 error "hard links individually migrated ($actual != $expected)"
7893
7894         # make sure the correct number of hard links are present
7895         local hardlinks=$(stat -c '%h' "$file1")
7896
7897         [ $hardlinks -eq $total_count ] ||
7898                 error "num hard links $hardlinks != $total_count"
7899         echo "done"
7900
7901         return 0
7902 }
7903
7904 test_56xb() {
7905         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7906                 skip "Need MDS version at least 2.10.55"
7907
7908         local dir="$DIR/$tdir"
7909
7910         test_mkdir "$dir" || error "cannot create dir $dir"
7911
7912         echo "testing lfs migrate mode when all links fit within xattrs"
7913         check_migrate_links "$dir" 2 99
7914
7915         echo "testing rsync mode when all links fit within xattrs"
7916         check_migrate_links --rsync "$dir" 2 99
7917
7918         echo "testing lfs migrate mode when all links do not fit within xattrs"
7919         check_migrate_links "$dir" 101 100
7920
7921         echo "testing rsync mode when all links do not fit within xattrs"
7922         check_migrate_links --rsync "$dir" 101 100
7923
7924         chown -R $RUNAS_ID $dir
7925         echo "testing non-root lfs migrate mode when not all links are in xattr"
7926         check_migrate_links "$dir" 101 100 "$RUNAS"
7927
7928         # clean up
7929         rm -rf $dir
7930 }
7931 run_test 56xb "lfs migration hard link support"
7932
7933 test_56xc() {
7934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7935
7936         local dir="$DIR/$tdir"
7937
7938         test_mkdir "$dir" || error "cannot create dir $dir"
7939
7940         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7941         echo -n "Setting initial stripe for 20MB test file..."
7942         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7943                 error "cannot setstripe 20MB file"
7944         echo "done"
7945         echo -n "Sizing 20MB test file..."
7946         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7947         echo "done"
7948         echo -n "Verifying small file autostripe count is 1..."
7949         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7950                 error "cannot migrate 20MB file"
7951         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7952                 error "cannot get stripe for $dir/20mb"
7953         [ $stripe_count -eq 1 ] ||
7954                 error "unexpected stripe count $stripe_count for 20MB file"
7955         rm -f "$dir/20mb"
7956         echo "done"
7957
7958         # Test 2: File is small enough to fit within the available space on
7959         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7960         # have at least an additional 1KB for each desired stripe for test 3
7961         echo -n "Setting stripe for 1GB test file..."
7962         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7963         echo "done"
7964         echo -n "Sizing 1GB test file..."
7965         # File size is 1GB + 3KB
7966         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7967         echo "done"
7968
7969         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7970         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7971         if (( avail > 524288 * OSTCOUNT )); then
7972                 echo -n "Migrating 1GB file..."
7973                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7974                         error "cannot migrate 1GB file"
7975                 echo "done"
7976                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7977                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7978                         error "cannot getstripe for 1GB file"
7979                 [ $stripe_count -eq 2 ] ||
7980                         error "unexpected stripe count $stripe_count != 2"
7981                 echo "done"
7982         fi
7983
7984         # Test 3: File is too large to fit within the available space on
7985         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7986         if [ $OSTCOUNT -ge 3 ]; then
7987                 # The required available space is calculated as
7988                 # file size (1GB + 3KB) / OST count (3).
7989                 local kb_per_ost=349526
7990
7991                 echo -n "Migrating 1GB file with limit..."
7992                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7993                         error "cannot migrate 1GB file with limit"
7994                 echo "done"
7995
7996                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7997                 echo -n "Verifying 1GB autostripe count with limited space..."
7998                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7999                         error "unexpected stripe count $stripe_count (min 3)"
8000                 echo "done"
8001         fi
8002
8003         # clean up
8004         rm -rf $dir
8005 }
8006 run_test 56xc "lfs migration autostripe"
8007
8008 test_56xd() {
8009         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8010
8011         local dir=$DIR/$tdir
8012         local f_mgrt=$dir/$tfile.mgrt
8013         local f_yaml=$dir/$tfile.yaml
8014         local f_copy=$dir/$tfile.copy
8015         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8016         local layout_copy="-c 2 -S 2M -i 1"
8017         local yamlfile=$dir/yamlfile
8018         local layout_before;
8019         local layout_after;
8020
8021         test_mkdir "$dir" || error "cannot create dir $dir"
8022         stack_trap "rm -rf $dir"
8023         $LFS setstripe $layout_yaml $f_yaml ||
8024                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8025         $LFS getstripe --yaml $f_yaml > $yamlfile
8026         $LFS setstripe $layout_copy $f_copy ||
8027                 error "cannot setstripe $f_copy with layout $layout_copy"
8028         touch $f_mgrt
8029         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8030
8031         # 1. test option --yaml
8032         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8033                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8034         layout_before=$(get_layout_param $f_yaml)
8035         layout_after=$(get_layout_param $f_mgrt)
8036         [ "$layout_after" == "$layout_before" ] ||
8037                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8038
8039         # 2. test option --copy
8040         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8041                 error "cannot migrate $f_mgrt with --copy $f_copy"
8042         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8043         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8044         [ "$layout_after" == "$layout_before" ] ||
8045                 error "lfs_migrate --copy: $layout_after != $layout_before"
8046 }
8047 run_test 56xd "check lfs_migrate --yaml and --copy support"
8048
8049 test_56xe() {
8050         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8051
8052         local dir=$DIR/$tdir
8053         local f_comp=$dir/$tfile
8054         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8055         local layout_before=""
8056         local layout_after=""
8057
8058         test_mkdir "$dir" || error "cannot create dir $dir"
8059         stack_trap "rm -rf $dir"
8060         $LFS setstripe $layout $f_comp ||
8061                 error "cannot setstripe $f_comp with layout $layout"
8062         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8063         dd if=/dev/zero of=$f_comp bs=1M count=4
8064
8065         # 1. migrate a comp layout file by lfs_migrate
8066         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8067         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8068         [ "$layout_before" == "$layout_after" ] ||
8069                 error "lfs_migrate: $layout_before != $layout_after"
8070
8071         # 2. migrate a comp layout file by lfs migrate
8072         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8073         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8074         [ "$layout_before" == "$layout_after" ] ||
8075                 error "lfs migrate: $layout_before != $layout_after"
8076 }
8077 run_test 56xe "migrate a composite layout file"
8078
8079 test_56xf() {
8080         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8081
8082         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8083                 skip "Need server version at least 2.13.53"
8084
8085         local dir=$DIR/$tdir
8086         local f_comp=$dir/$tfile
8087         local layout="-E 1M -c1 -E -1 -c2"
8088         local fid_before=""
8089         local fid_after=""
8090
8091         test_mkdir "$dir" || error "cannot create dir $dir"
8092         stack_trap "rm -rf $dir"
8093         $LFS setstripe $layout $f_comp ||
8094                 error "cannot setstripe $f_comp with layout $layout"
8095         fid_before=$($LFS getstripe --fid $f_comp)
8096         dd if=/dev/zero of=$f_comp bs=1M count=4
8097
8098         # 1. migrate a comp layout file to a comp layout
8099         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8100         fid_after=$($LFS getstripe --fid $f_comp)
8101         [ "$fid_before" == "$fid_after" ] ||
8102                 error "comp-to-comp migrate: $fid_before != $fid_after"
8103
8104         # 2. migrate a comp layout file to a plain layout
8105         $LFS migrate -c2 $f_comp ||
8106                 error "cannot migrate $f_comp by lfs migrate"
8107         fid_after=$($LFS getstripe --fid $f_comp)
8108         [ "$fid_before" == "$fid_after" ] ||
8109                 error "comp-to-plain migrate: $fid_before != $fid_after"
8110
8111         # 3. migrate a plain layout file to a comp layout
8112         $LFS migrate $layout $f_comp ||
8113                 error "cannot migrate $f_comp by lfs migrate"
8114         fid_after=$($LFS getstripe --fid $f_comp)
8115         [ "$fid_before" == "$fid_after" ] ||
8116                 error "plain-to-comp migrate: $fid_before != $fid_after"
8117 }
8118 run_test 56xf "FID is not lost during migration of a composite layout file"
8119
8120 check_file_ost_range() {
8121         local file="$1"
8122         shift
8123         local range="$*"
8124         local -a file_range
8125         local idx
8126
8127         file_range=($($LFS getstripe -y "$file" |
8128                 awk '/l_ost_idx:/ { print $NF }'))
8129
8130         if [[ "${#file_range[@]}" = 0 ]]; then
8131                 echo "No osts found for $file"
8132                 return 1
8133         fi
8134
8135         for idx in "${file_range[@]}"; do
8136                 [[ " $range " =~ " $idx " ]] ||
8137                         return 1
8138         done
8139
8140         return 0
8141 }
8142
8143 sub_test_56xg() {
8144         local stripe_opt="$1"
8145         local pool="$2"
8146         shift 2
8147         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8148
8149         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8150                 error "Fail to migrate $tfile on $pool"
8151         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8152                 error "$tfile is not in pool $pool"
8153         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8154                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8155 }
8156
8157 test_56xg() {
8158         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8159         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8160         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8161                 skip "Need MDS version newer than 2.14.52"
8162
8163         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8164         local -a pool_ranges=("0 0" "1 1" "0 1")
8165
8166         # init pools
8167         for i in "${!pool_names[@]}"; do
8168                 pool_add ${pool_names[$i]} ||
8169                         error "pool_add failed (pool: ${pool_names[$i]})"
8170                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8171                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8172         done
8173
8174         # init the file to migrate
8175         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8176                 error "Unable to create $tfile on OST1"
8177         stack_trap "rm -f $DIR/$tfile"
8178         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8179                 error "Unable to write on $tfile"
8180
8181         echo "1. migrate $tfile on pool ${pool_names[0]}"
8182         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8183
8184         echo "2. migrate $tfile on pool ${pool_names[2]}"
8185         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8186
8187         echo "3. migrate $tfile on pool ${pool_names[1]}"
8188         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8189
8190         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8191         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8192         echo
8193
8194         # Clean pools
8195         destroy_test_pools ||
8196                 error "pool_destroy failed"
8197 }
8198 run_test 56xg "lfs migrate pool support"
8199
8200 test_56xh() {
8201         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8202
8203         local size_mb=25
8204         local file1=$DIR/$tfile
8205         local tmp1=$TMP/$tfile.tmp
8206
8207         $LFS setstripe -c 2 $file1
8208
8209         stack_trap "rm -f $file1 $tmp1"
8210         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8211                         error "error creating $tmp1"
8212         ls -lsh $tmp1
8213         cp $tmp1 $file1
8214
8215         local start=$SECONDS
8216
8217         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8218                 error "migrate failed rc = $?"
8219
8220         local elapsed=$((SECONDS - start))
8221
8222         # with 1MB/s, elapsed should equal size_mb
8223         (( elapsed >= size_mb * 95 / 100 )) ||
8224                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8225
8226         (( elapsed <= size_mb * 120 / 100 )) ||
8227                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8228
8229         (( elapsed <= size_mb * 350 / 100 )) ||
8230                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8231
8232         stripe=$($LFS getstripe -c $file1)
8233         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8234         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8235
8236         # Clean up file (since it is multiple MB)
8237         rm -f $file1 $tmp1
8238 }
8239 run_test 56xh "lfs migrate bandwidth limitation support"
8240
8241 test_56xi() {
8242         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8243         verify_yaml_available || skip_env "YAML verification not installed"
8244
8245         local size_mb=5
8246         local file1=$DIR/$tfile.1
8247         local file2=$DIR/$tfile.2
8248         local file3=$DIR/$tfile.3
8249         local output_file=$DIR/$tfile.out
8250         local tmp1=$TMP/$tfile.tmp
8251
8252         $LFS setstripe -c 2 $file1
8253         $LFS setstripe -c 2 $file2
8254         $LFS setstripe -c 2 $file3
8255
8256         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8257         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8258                         error "error creating $tmp1"
8259         ls -lsh $tmp1
8260         cp $tmp1 $file1
8261         cp $tmp1 $file2
8262         cp $tmp1 $file3
8263
8264         $LFS migrate --stats --stats-interval=1 \
8265                 -c 1 $file1 $file2 $file3 1> $output_file ||
8266                 error "migrate failed rc = $?"
8267
8268         cat $output_file
8269         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8270
8271         # Clean up file (since it is multiple MB)
8272         rm -f $file1 $file2 $file3 $tmp1 $output_file
8273 }
8274 run_test 56xi "lfs migrate stats support"
8275
8276 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8277         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8278
8279         local file=$DIR/$tfile
8280         local linkdir=$DIR/$tdir
8281
8282         test_mkdir $linkdir || error "fail to create $linkdir"
8283         $LFS setstripe -i 0 -c 1 -S1M $file
8284         stack_trap "rm -rf $file $linkdir"
8285         dd if=/dev/urandom of=$file bs=1M count=10 ||
8286                 error "fail to create $file"
8287
8288         # Create file links
8289         local cpts
8290         local threads_max
8291         local nlinks
8292
8293         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8294         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8295         (( nlinks = thread_max * 3 / 2 / cpts))
8296
8297         echo "create $nlinks hard links of $file"
8298         createmany -l $file $linkdir/link $nlinks
8299
8300         # Parallel migrates (should not block)
8301         local i
8302         for ((i = 0; i < nlinks; i++)); do
8303                 echo $linkdir/link$i
8304         done | xargs -n1 -P $nlinks $LFS migrate -c2
8305
8306         local stripe_count
8307         stripe_count=$($LFS getstripe -c $file) ||
8308                 error "fail to get stripe count on $file"
8309
8310         ((stripe_count == 2)) ||
8311                 error "fail to migrate $file (stripe_count = $stripe_count)"
8312 }
8313 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8314
8315 test_56y() {
8316         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8317                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8318
8319         local res=""
8320         local dir=$DIR/$tdir
8321         local f1=$dir/file1
8322         local f2=$dir/file2
8323
8324         test_mkdir -p $dir || error "creating dir $dir"
8325         touch $f1 || error "creating std file $f1"
8326         $MULTIOP $f2 H2c || error "creating released file $f2"
8327
8328         # a directory can be raid0, so ask only for files
8329         res=$($LFS find $dir -L raid0 -type f | wc -l)
8330         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8331
8332         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8333         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8334
8335         # only files can be released, so no need to force file search
8336         res=$($LFS find $dir -L released)
8337         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8338
8339         res=$($LFS find $dir -type f \! -L released)
8340         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8341 }
8342 run_test 56y "lfs find -L raid0|released"
8343
8344 test_56z() { # LU-4824
8345         # This checks to make sure 'lfs find' continues after errors
8346         # There are two classes of errors that should be caught:
8347         # - If multiple paths are provided, all should be searched even if one
8348         #   errors out
8349         # - If errors are encountered during the search, it should not terminate
8350         #   early
8351         local dir=$DIR/$tdir
8352         local i
8353
8354         test_mkdir $dir
8355         for i in d{0..9}; do
8356                 test_mkdir $dir/$i
8357                 touch $dir/$i/$tfile
8358         done
8359         $LFS find $DIR/non_existent_dir $dir &&
8360                 error "$LFS find did not return an error"
8361         # Make a directory unsearchable. This should NOT be the last entry in
8362         # directory order.  Arbitrarily pick the 6th entry
8363         chmod 700 $($LFS find $dir -type d | sed '6!d')
8364
8365         $RUNAS $LFS find $DIR/non_existent $dir
8366         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8367
8368         # The user should be able to see 10 directories and 9 files
8369         (( count == 19 )) ||
8370                 error "$LFS find found $count != 19 entries after error"
8371 }
8372 run_test 56z "lfs find should continue after an error"
8373
8374 test_56aa() { # LU-5937
8375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8376
8377         local dir=$DIR/$tdir
8378
8379         mkdir $dir
8380         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8381
8382         createmany -o $dir/striped_dir/${tfile}- 1024
8383         local dirs=$($LFS find --size +8k $dir/)
8384
8385         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8386 }
8387 run_test 56aa "lfs find --size under striped dir"
8388
8389 test_56ab() { # LU-10705
8390         test_mkdir $DIR/$tdir
8391         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8392         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8393         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8394         # Flush writes to ensure valid blocks.  Need to be more thorough for
8395         # ZFS, since blocks are not allocated/returned to client immediately.
8396         sync_all_data
8397         wait_zfs_commit ost1 2
8398         cancel_lru_locks osc
8399         ls -ls $DIR/$tdir
8400
8401         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8402
8403         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8404
8405         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8406         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8407
8408         rm -f $DIR/$tdir/$tfile.[123]
8409 }
8410 run_test 56ab "lfs find --blocks"
8411
8412 # LU-11188
8413 test_56aca() {
8414         local dir="$DIR/$tdir"
8415         local perms=(001 002 003 004 005 006 007
8416                      010 020 030 040 050 060 070
8417                      100 200 300 400 500 600 700
8418                      111 222 333 444 555 666 777)
8419         local perm_minus=(8 8 4 8 4 4 2
8420                           8 8 4 8 4 4 2
8421                           8 8 4 8 4 4 2
8422                           4 4 2 4 2 2 1)
8423         local perm_slash=(8  8 12  8 12 12 14
8424                           8  8 12  8 12 12 14
8425                           8  8 12  8 12 12 14
8426                          16 16 24 16 24 24 28)
8427
8428         test_mkdir "$dir"
8429         for perm in ${perms[*]}; do
8430                 touch "$dir/$tfile.$perm"
8431                 chmod $perm "$dir/$tfile.$perm"
8432         done
8433
8434         for ((i = 0; i < ${#perms[*]}; i++)); do
8435                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8436                 (( $num == 1 )) ||
8437                         error "lfs find -perm ${perms[i]}:"\
8438                               "$num != 1"
8439
8440                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8441                 (( $num == ${perm_minus[i]} )) ||
8442                         error "lfs find -perm -${perms[i]}:"\
8443                               "$num != ${perm_minus[i]}"
8444
8445                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8446                 (( $num == ${perm_slash[i]} )) ||
8447                         error "lfs find -perm /${perms[i]}:"\
8448                               "$num != ${perm_slash[i]}"
8449         done
8450 }
8451 run_test 56aca "check lfs find -perm with octal representation"
8452
8453 test_56acb() {
8454         local dir=$DIR/$tdir
8455         # p is the permission of write and execute for user, group and other
8456         # without the umask. It is used to test +wx.
8457         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8458         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8459         local symbolic=(+t  a+t u+t g+t o+t
8460                         g+s u+s o+s +s o+sr
8461                         o=r,ug+o,u+w
8462                         u+ g+ o+ a+ ugo+
8463                         u- g- o- a- ugo-
8464                         u= g= o= a= ugo=
8465                         o=r,ug+o,u+w u=r,a+u,u+w
8466                         g=r,ugo=g,u+w u+x,+X +X
8467                         u+x,u+X u+X u+x,g+X o+r,+X
8468                         u+x,go+X +wx +rwx)
8469
8470         test_mkdir $dir
8471         for perm in ${perms[*]}; do
8472                 touch "$dir/$tfile.$perm"
8473                 chmod $perm "$dir/$tfile.$perm"
8474         done
8475
8476         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8477                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8478
8479                 (( $num == 1 )) ||
8480                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8481         done
8482 }
8483 run_test 56acb "check lfs find -perm with symbolic representation"
8484
8485 test_56acc() {
8486         local dir=$DIR/$tdir
8487         local tests="17777 787 789 abcd
8488                 ug=uu ug=a ug=gu uo=ou urw
8489                 u+xg+x a=r,u+x,"
8490
8491         test_mkdir $dir
8492         for err in $tests; do
8493                 if $LFS find $dir -perm $err 2>/dev/null; then
8494                         error "lfs find -perm $err: parsing should have failed"
8495                 fi
8496         done
8497 }
8498 run_test 56acc "check parsing error for lfs find -perm"
8499
8500 test_56ba() {
8501         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8502                 skip "Need MDS version at least 2.10.50"
8503
8504         # Create composite files with one component
8505         local dir=$DIR/$tdir
8506
8507         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8508         # Create composite files with three components
8509         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8510         # LU-16904 Create plain layout files
8511         lfs setstripe -c 1 $dir/$tfile-{1..10}
8512
8513         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8514
8515         [[ $nfiles == 10 ]] ||
8516                 error "lfs find -E 1M found $nfiles != 10 files"
8517
8518         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8519         [[ $nfiles == 25 ]] ||
8520                 error "lfs find ! -E 1M found $nfiles != 25 files"
8521
8522         # All files have a component that starts at 0
8523         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8524         [[ $nfiles == 35 ]] ||
8525                 error "lfs find --component-start 0 - $nfiles != 35 files"
8526
8527         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8528         [[ $nfiles == 15 ]] ||
8529                 error "lfs find --component-start 2M - $nfiles != 15 files"
8530
8531         # All files created here have a componenet that does not starts at 2M
8532         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8533         [[ $nfiles == 35 ]] ||
8534                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8535
8536         # Find files with a specified number of components
8537         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8538         [[ $nfiles == 15 ]] ||
8539                 error "lfs find --component-count 3 - $nfiles != 15 files"
8540
8541         # Remember non-composite files have a component count of zero
8542         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8543         [[ $nfiles == 10 ]] ||
8544                 error "lfs find --component-count 0 - $nfiles != 10 files"
8545
8546         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8547         [[ $nfiles == 20 ]] ||
8548                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8549
8550         # All files have a flag called "init"
8551         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8552         [[ $nfiles == 35 ]] ||
8553                 error "lfs find --component-flags init - $nfiles != 35 files"
8554
8555         # Multi-component files will have a component not initialized
8556         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8557         [[ $nfiles == 15 ]] ||
8558                 error "lfs find !--component-flags init - $nfiles != 15 files"
8559
8560         rm -rf $dir
8561
8562 }
8563 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8564
8565 test_56ca() {
8566         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8567                 skip "Need MDS version at least 2.10.57"
8568
8569         local td=$DIR/$tdir
8570         local tf=$td/$tfile
8571         local dir
8572         local nfiles
8573         local cmd
8574         local i
8575         local j
8576
8577         # create mirrored directories and mirrored files
8578         mkdir $td || error "mkdir $td failed"
8579         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8580         createmany -o $tf- 10 || error "create $tf- failed"
8581
8582         for i in $(seq 2); do
8583                 dir=$td/dir$i
8584                 mkdir $dir || error "mkdir $dir failed"
8585                 $LFS mirror create -N$((3 + i)) $dir ||
8586                         error "create mirrored dir $dir failed"
8587                 createmany -o $dir/$tfile- 10 ||
8588                         error "create $dir/$tfile- failed"
8589         done
8590
8591         # change the states of some mirrored files
8592         echo foo > $tf-6
8593         for i in $(seq 2); do
8594                 dir=$td/dir$i
8595                 for j in $(seq 4 9); do
8596                         echo foo > $dir/$tfile-$j
8597                 done
8598         done
8599
8600         # find mirrored files with specific mirror count
8601         cmd="$LFS find --mirror-count 3 --type f $td"
8602         nfiles=$($cmd | wc -l)
8603         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8604
8605         cmd="$LFS find ! --mirror-count 3 --type f $td"
8606         nfiles=$($cmd | wc -l)
8607         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8608
8609         cmd="$LFS find --mirror-count +2 --type f $td"
8610         nfiles=$($cmd | wc -l)
8611         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8612
8613         cmd="$LFS find --mirror-count -6 --type f $td"
8614         nfiles=$($cmd | wc -l)
8615         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8616
8617         # find mirrored files with specific file state
8618         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8619         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8620
8621         cmd="$LFS find --mirror-state=ro --type f $td"
8622         nfiles=$($cmd | wc -l)
8623         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8624
8625         cmd="$LFS find ! --mirror-state=ro --type f $td"
8626         nfiles=$($cmd | wc -l)
8627         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8628
8629         cmd="$LFS find --mirror-state=wp --type f $td"
8630         nfiles=$($cmd | wc -l)
8631         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8632
8633         cmd="$LFS find ! --mirror-state=sp --type f $td"
8634         nfiles=$($cmd | wc -l)
8635         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8636 }
8637 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8638
8639 test_56da() { # LU-14179
8640         local path=$DIR/$tdir
8641
8642         test_mkdir $path
8643         cd $path
8644
8645         local longdir=$(str_repeat 'a' 255)
8646
8647         for i in {1..15}; do
8648                 path=$path/$longdir
8649                 test_mkdir $longdir
8650                 cd $longdir
8651         done
8652
8653         local len=${#path}
8654         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8655
8656         test_mkdir $lastdir
8657         cd $lastdir
8658         # PATH_MAX-1
8659         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8660
8661         # NAME_MAX
8662         touch $(str_repeat 'f' 255)
8663
8664         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8665                 error "lfs find reported an error"
8666
8667         rm -rf $DIR/$tdir
8668 }
8669 run_test 56da "test lfs find with long paths"
8670
8671 test_56ea() { #LU-10378
8672         local path=$DIR/$tdir
8673         local pool=$TESTNAME
8674
8675         # Create ost pool
8676         pool_add $pool || error "pool_add $pool failed"
8677         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8678                 error "adding targets to $pool failed"
8679
8680         # Set default pool on directory before creating file
8681         mkdir $path || error "mkdir $path failed"
8682         $LFS setstripe -p $pool $path ||
8683                 error "set OST pool on $pool failed"
8684         touch $path/$tfile || error "touch $path/$tfile failed"
8685
8686         # Compare basic file attributes from -printf and stat
8687         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8688         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8689
8690         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8691                 error "Attrs from lfs find and stat don't match"
8692
8693         # Compare Lustre attributes from lfs find and lfs getstripe
8694         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8695         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8696         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8697         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8698         local fpool=$($LFS getstripe --pool $path/$tfile)
8699         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8700
8701         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8702                 error "Attrs from lfs find and lfs getstripe don't match"
8703
8704         # Verify behavior for unknown escape/format sequences
8705         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8706
8707         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8708                 error "Escape/format codes don't match"
8709 }
8710 run_test 56ea "test lfs find -printf option"
8711
8712 test_56eb() {
8713         local dir=$DIR/$tdir
8714         local subdir_1=$dir/subdir_1
8715
8716         test_mkdir -p $subdir_1
8717         ln -s subdir_1 $dir/link_1
8718
8719         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8720                 error "symlink is not followed"
8721
8722         $LFS getstripe --no-follow $dir |
8723                 grep "^$dir/link_1 has no stripe info$" ||
8724                 error "symlink should not have stripe info"
8725
8726         touch $dir/testfile
8727         ln -s testfile $dir/file_link_2
8728
8729         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8730                 error "symlink is not followed"
8731
8732         $LFS getstripe --no-follow $dir |
8733                 grep "^$dir/file_link_2 has no stripe info$" ||
8734                 error "symlink should not have stripe info"
8735 }
8736 run_test 56eb "check lfs getstripe on symlink"
8737
8738 test_56ec() {
8739         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8740         local dir=$DIR/$tdir
8741         local srcfile=$dir/srcfile
8742         local srcyaml=$dir/srcyaml
8743         local destfile=$dir/destfile
8744
8745         test_mkdir -p $dir
8746
8747         $LFS setstripe -i 1 $srcfile
8748         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8749         # if the setstripe yaml parsing fails for any reason, the command can
8750         # randomly assign the correct OST index, leading to an erroneous
8751         # success. but the chance of false success is low enough that a
8752         # regression should still be quickly caught.
8753         $LFS setstripe --yaml=$srcyaml $destfile
8754
8755         local srcindex=$($LFS getstripe -i $srcfile)
8756         local destindex=$($LFS getstripe -i $destfile)
8757
8758         if [[ ! $srcindex -eq $destindex ]]; then
8759                 error "setstripe did not set OST index correctly"
8760         fi
8761 }
8762 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8763
8764 test_56eda() {
8765         local dir=$DIR/$tdir
8766         local subdir=$dir/subdir
8767         local file1=$dir/$tfile
8768         local file2=$dir/$tfile\2
8769         local link=$dir/$tfile-link
8770         local nfiles
8771
8772         test_mkdir -p $dir
8773         $LFS setdirstripe -c1 $subdir
8774         touch $file1
8775         touch $file2
8776         ln $file2 $link
8777
8778         nfiles=$($LFS find --links 1 $dir | wc -l)
8779         (( $nfiles == 1 )) ||
8780                 error "lfs find --links expected 1 file, got $nfiles"
8781
8782         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8783         (( $nfiles == 2 )) ||
8784                 error "lfs find --links expected 2 files, got $nfiles"
8785
8786         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8787         (( $nfiles == 1 )) ||
8788                 error "lfs find --links expected 1 directory, got $nfiles"
8789 }
8790 run_test 56eda "check lfs find --links"
8791
8792 test_56edb() {
8793         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8794
8795         local dir=$DIR/$tdir
8796         local stripedir=$dir/stripedir
8797         local nfiles
8798
8799         test_mkdir -p $dir
8800
8801         $LFS setdirstripe -c2 $stripedir
8802
8803         $LFS getdirstripe $stripedir
8804
8805         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8806         (( $nfiles == 1 )) ||
8807                 error "lfs find --links expected 1 directory, got $nfiles"
8808 }
8809 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8810
8811 test_56ef() {
8812         local dir=$DIR/$tdir
8813         local dir1=$dir/d1
8814         local dir2=$dir/d2
8815         local nfiles
8816
8817         test_mkdir -p $dir
8818
8819         mkdir $dir1
8820         mkdir $dir2
8821
8822         touch $dir1/f
8823         touch $dir2/f
8824
8825         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8826         (( $nfiles == 2 )) ||
8827                 error "(1) lfs find expected 2 files, got $nfiles"
8828
8829         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8830         (( $nfiles == 2 )) ||
8831                 error "(2) lfs find expected 2 files, got $nfiles"
8832
8833         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8834         (( $nfiles == 2 )) ||
8835                 error "(3) lfs find expected 2 files, got $nfiles"
8836 }
8837 run_test 56ef "lfs find with multiple paths"
8838
8839 test_57a() {
8840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8841         # note test will not do anything if MDS is not local
8842         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8843                 skip_env "ldiskfs only test"
8844         fi
8845         remote_mds_nodsh && skip "remote MDS with nodsh"
8846
8847         local MNTDEV="osd*.*MDT*.mntdev"
8848         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8849         [ -z "$DEV" ] && error "can't access $MNTDEV"
8850         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8851                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8852                         error "can't access $DEV"
8853                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8854                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8855                 rm $TMP/t57a.dump
8856         done
8857 }
8858 run_test 57a "verify MDS filesystem created with large inodes =="
8859
8860 test_57b() {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8863                 skip_env "ldiskfs only test"
8864         fi
8865         remote_mds_nodsh && skip "remote MDS with nodsh"
8866
8867         local dir=$DIR/$tdir
8868         local filecount=100
8869         local file1=$dir/f1
8870         local fileN=$dir/f$filecount
8871
8872         rm -rf $dir || error "removing $dir"
8873         test_mkdir -c1 $dir
8874         local mdtidx=$($LFS getstripe -m $dir)
8875         local mdtname=MDT$(printf %04x $mdtidx)
8876         local facet=mds$((mdtidx + 1))
8877
8878         echo "mcreating $filecount files"
8879         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8880
8881         # verify that files do not have EAs yet
8882         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8883                 error "$file1 has an EA"
8884         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8885                 error "$fileN has an EA"
8886
8887         sync
8888         sleep 1
8889         df $dir  #make sure we get new statfs data
8890         local mdsfree=$(do_facet $facet \
8891                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8892         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8893         local file
8894
8895         echo "opening files to create objects/EAs"
8896         for file in $(seq -f $dir/f%g 1 $filecount); do
8897                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8898                         error "opening $file"
8899         done
8900
8901         # verify that files have EAs now
8902         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
8903                 error "$file1 missing EA"
8904         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
8905                 error "$fileN missing EA"
8906
8907         sleep 1  #make sure we get new statfs data
8908         df $dir
8909         local mdsfree2=$(do_facet $facet \
8910                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8911         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8912
8913         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8914                 if [ "$mdsfree" != "$mdsfree2" ]; then
8915                         error "MDC before $mdcfree != after $mdcfree2"
8916                 else
8917                         echo "MDC before $mdcfree != after $mdcfree2"
8918                         echo "unable to confirm if MDS has large inodes"
8919                 fi
8920         fi
8921         rm -rf $dir
8922 }
8923 run_test 57b "default LOV EAs are stored inside large inodes ==="
8924
8925 test_58() {
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927         [ -z "$(which wiretest 2>/dev/null)" ] &&
8928                         skip_env "could not find wiretest"
8929
8930         wiretest
8931 }
8932 run_test 58 "verify cross-platform wire constants =============="
8933
8934 test_59() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         echo "touch 130 files"
8938         createmany -o $DIR/f59- 130
8939         echo "rm 130 files"
8940         unlinkmany $DIR/f59- 130
8941         sync
8942         # wait for commitment of removal
8943         wait_delete_completed
8944 }
8945 run_test 59 "verify cancellation of llog records async ========="
8946
8947 TEST60_HEAD="test_60 run $RANDOM"
8948 test_60a() {
8949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8950         remote_mgs_nodsh && skip "remote MGS with nodsh"
8951         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8952                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8953                         skip_env "missing subtest run-llog.sh"
8954
8955         log "$TEST60_HEAD - from kernel mode"
8956         do_facet mgs "$LCTL dk > /dev/null"
8957         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8958         do_facet mgs $LCTL dk > $TMP/$tfile
8959
8960         # LU-6388: test llog_reader
8961         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8962         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8963         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8964                         skip_env "missing llog_reader"
8965         local fstype=$(facet_fstype mgs)
8966         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8967                 skip_env "Only for ldiskfs or zfs type mgs"
8968
8969         local mntpt=$(facet_mntpt mgs)
8970         local mgsdev=$(mgsdevname 1)
8971         local fid_list
8972         local fid
8973         local rec_list
8974         local rec
8975         local rec_type
8976         local obj_file
8977         local path
8978         local seq
8979         local oid
8980         local pass=true
8981
8982         #get fid and record list
8983         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8984                 tail -n 4))
8985         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8986                 tail -n 4))
8987         #remount mgs as ldiskfs or zfs type
8988         stop mgs || error "stop mgs failed"
8989         mount_fstype mgs || error "remount mgs failed"
8990         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8991                 fid=${fid_list[i]}
8992                 rec=${rec_list[i]}
8993                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8994                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8995                 oid=$((16#$oid))
8996
8997                 case $fstype in
8998                         ldiskfs )
8999                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9000                         zfs )
9001                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9002                 esac
9003                 echo "obj_file is $obj_file"
9004                 do_facet mgs $llog_reader $obj_file
9005
9006                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9007                         awk '{ print $3 }' | sed -e "s/^type=//g")
9008                 if [ $rec_type != $rec ]; then
9009                         echo "FAILED test_60a wrong record type $rec_type," \
9010                               "should be $rec"
9011                         pass=false
9012                         break
9013                 fi
9014
9015                 #check obj path if record type is LLOG_LOGID_MAGIC
9016                 if [ "$rec" == "1064553b" ]; then
9017                         path=$(do_facet mgs $llog_reader $obj_file |
9018                                 grep "path=" | awk '{ print $NF }' |
9019                                 sed -e "s/^path=//g")
9020                         if [ $obj_file != $mntpt/$path ]; then
9021                                 echo "FAILED test_60a wrong obj path" \
9022                                       "$montpt/$path, should be $obj_file"
9023                                 pass=false
9024                                 break
9025                         fi
9026                 fi
9027         done
9028         rm -f $TMP/$tfile
9029         #restart mgs before "error", otherwise it will block the next test
9030         stop mgs || error "stop mgs failed"
9031         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9032         $pass || error "test failed, see FAILED test_60a messages for specifics"
9033 }
9034 run_test 60a "llog_test run from kernel module and test llog_reader"
9035
9036 test_60b() { # bug 6411
9037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9038
9039         dmesg > $DIR/$tfile
9040         LLOG_COUNT=$(do_facet mgs dmesg |
9041                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9042                           /llog_[a-z]*.c:[0-9]/ {
9043                                 if (marker)
9044                                         from_marker++
9045                                 from_begin++
9046                           }
9047                           END {
9048                                 if (marker)
9049                                         print from_marker
9050                                 else
9051                                         print from_begin
9052                           }")
9053
9054         [[ $LLOG_COUNT -gt 120 ]] &&
9055                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9056 }
9057 run_test 60b "limit repeated messages from CERROR/CWARN"
9058
9059 test_60c() {
9060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9061
9062         echo "create 5000 files"
9063         createmany -o $DIR/f60c- 5000
9064 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9065         lctl set_param fail_loc=0x80000137
9066         unlinkmany $DIR/f60c- 5000
9067         lctl set_param fail_loc=0
9068 }
9069 run_test 60c "unlink file when mds full"
9070
9071 test_60d() {
9072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9073
9074         SAVEPRINTK=$(lctl get_param -n printk)
9075         # verify "lctl mark" is even working"
9076         MESSAGE="test message ID $RANDOM $$"
9077         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9078         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9079
9080         lctl set_param printk=0 || error "set lnet.printk failed"
9081         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9082         MESSAGE="new test message ID $RANDOM $$"
9083         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9084         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9085         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9086
9087         lctl set_param -n printk="$SAVEPRINTK"
9088 }
9089 run_test 60d "test printk console message masking"
9090
9091 test_60e() {
9092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9093         remote_mds_nodsh && skip "remote MDS with nodsh"
9094
9095         touch $DIR/$tfile
9096 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9097         do_facet mds1 lctl set_param fail_loc=0x15b
9098         rm $DIR/$tfile
9099 }
9100 run_test 60e "no space while new llog is being created"
9101
9102 test_60f() {
9103         local old_path=$($LCTL get_param -n debug_path)
9104
9105         stack_trap "$LCTL set_param debug_path=$old_path"
9106         stack_trap "rm -f $TMP/$tfile*"
9107         rm -f $TMP/$tfile* 2> /dev/null
9108         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9109         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9110         test_mkdir $DIR/$tdir
9111         # retry in case the open is cached and not released
9112         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9113                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9114                 sleep 0.1
9115         done
9116         ls $TMP/$tfile*
9117         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9118 }
9119 run_test 60f "change debug_path works"
9120
9121 test_60g() {
9122         local pid
9123         local i
9124
9125         test_mkdir -c $MDSCOUNT $DIR/$tdir
9126
9127         (
9128                 local index=0
9129                 while true; do
9130                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9131                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9132                                 2>/dev/null
9133                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9134                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9135                         index=$((index + 1))
9136                 done
9137         ) &
9138
9139         pid=$!
9140
9141         for i in {0..100}; do
9142                 # define OBD_FAIL_OSD_TXN_START    0x19a
9143                 local index=$((i % MDSCOUNT + 1))
9144
9145                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9146                         > /dev/null
9147                 sleep 0.01
9148         done
9149
9150         kill -9 $pid
9151
9152         for i in $(seq $MDSCOUNT); do
9153                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9154         done
9155
9156         mkdir $DIR/$tdir/new || error "mkdir failed"
9157         rmdir $DIR/$tdir/new || error "rmdir failed"
9158
9159         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9160                 -t namespace
9161         for i in $(seq $MDSCOUNT); do
9162                 wait_update_facet mds$i "$LCTL get_param -n \
9163                         mdd.$(facet_svc mds$i).lfsck_namespace |
9164                         awk '/^status/ { print \\\$2 }'" "completed"
9165         done
9166
9167         ls -R $DIR/$tdir
9168         rm -rf $DIR/$tdir || error "rmdir failed"
9169 }
9170 run_test 60g "transaction abort won't cause MDT hung"
9171
9172 test_60h() {
9173         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9174                 skip "Need MDS version at least 2.12.52"
9175         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9176
9177         local f
9178
9179         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9180         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9181         for fail_loc in 0x80000188 0x80000189; do
9182                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9183                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9184                         error "mkdir $dir-$fail_loc failed"
9185                 for i in {0..10}; do
9186                         # create may fail on missing stripe
9187                         echo $i > $DIR/$tdir-$fail_loc/$i
9188                 done
9189                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9190                         error "getdirstripe $tdir-$fail_loc failed"
9191                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9192                         error "migrate $tdir-$fail_loc failed"
9193                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9194                         error "getdirstripe $tdir-$fail_loc failed"
9195                 pushd $DIR/$tdir-$fail_loc
9196                 for f in *; do
9197                         echo $f | cmp $f - || error "$f data mismatch"
9198                 done
9199                 popd
9200                 rm -rf $DIR/$tdir-$fail_loc
9201         done
9202 }
9203 run_test 60h "striped directory with missing stripes can be accessed"
9204
9205 function t60i_load() {
9206         mkdir $DIR/$tdir
9207         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9208         $LCTL set_param fail_loc=0x131c fail_val=1
9209         for ((i=0; i<5000; i++)); do
9210                 touch $DIR/$tdir/f$i
9211         done
9212 }
9213
9214 test_60i() {
9215         changelog_register || error "changelog_register failed"
9216         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9217         changelog_users $SINGLEMDS | grep -q $cl_user ||
9218                 error "User $cl_user not found in changelog_users"
9219         changelog_chmask "ALL"
9220         t60i_load &
9221         local PID=$!
9222         for((i=0; i<100; i++)); do
9223                 changelog_dump >/dev/null ||
9224                         error "can't read changelog"
9225         done
9226         kill $PID
9227         wait $PID
9228         changelog_deregister || error "changelog_deregister failed"
9229         $LCTL set_param fail_loc=0
9230 }
9231 run_test 60i "llog: new record vs reader race"
9232
9233 test_60j() {
9234         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9235                 skip "need MDS version at least 2.15.50"
9236         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9237         remote_mds_nodsh && skip "remote MDS with nodsh"
9238         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9239
9240         changelog_users $SINGLEMDS | grep "^cl" &&
9241                 skip "active changelog user"
9242
9243         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9244
9245         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9246                 skip_env "missing llog_reader"
9247
9248         mkdir_on_mdt0 $DIR/$tdir
9249
9250         local f=$DIR/$tdir/$tfile
9251         local mdt_dev
9252         local tmpfile
9253         local plain
9254
9255         changelog_register || error "cannot register changelog user"
9256
9257         # set changelog_mask to ALL
9258         changelog_chmask "ALL"
9259         changelog_clear
9260
9261         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9262         unlinkmany ${f}- 100 || error "unlinkmany failed"
9263
9264         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9265         mdt_dev=$(facet_device $SINGLEMDS)
9266
9267         do_facet $SINGLEMDS sync
9268         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9269                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9270                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9271
9272         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9273
9274         # if $tmpfile is not on EXT3 filesystem for some reason
9275         [[ ${plain:0:1} == 'O' ]] ||
9276                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9277
9278         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9279                 $mdt_dev; stat -c %s $tmpfile")
9280         echo "Truncate llog from $size to $((size - size % 8192))"
9281         size=$((size - size % 8192))
9282         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9283         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9284                 grep -c 'in bitmap only')
9285         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9286
9287         size=$((size - 9000))
9288         echo "Corrupt llog in the middle at $size"
9289         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9290                 count=333 conv=notrunc
9291         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9292                 grep -c 'next chunk')
9293         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9294 }
9295 run_test 60j "llog_reader reports corruptions"
9296
9297 test_61a() {
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299
9300         f="$DIR/f61"
9301         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9302         cancel_lru_locks osc
9303         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9304         sync
9305 }
9306 run_test 61a "mmap() writes don't make sync hang ================"
9307
9308 test_61b() {
9309         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9310 }
9311 run_test 61b "mmap() of unstriped file is successful"
9312
9313 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9314 # Though this test is irrelevant anymore, it helped to reveal some
9315 # other grant bugs (LU-4482), let's keep it.
9316 test_63a() {   # was test_63
9317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9318
9319         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9320
9321         for i in `seq 10` ; do
9322                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9323                 sleep 5
9324                 kill $!
9325                 sleep 1
9326         done
9327
9328         rm -f $DIR/f63 || true
9329 }
9330 run_test 63a "Verify oig_wait interruption does not crash ======="
9331
9332 # bug 2248 - async write errors didn't return to application on sync
9333 # bug 3677 - async write errors left page locked
9334 test_63b() {
9335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9336
9337         debugsave
9338         lctl set_param debug=-1
9339
9340         # ensure we have a grant to do async writes
9341         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9342         rm $DIR/$tfile
9343
9344         sync    # sync lest earlier test intercept the fail_loc
9345
9346         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9347         lctl set_param fail_loc=0x80000406
9348         $MULTIOP $DIR/$tfile Owy && \
9349                 error "sync didn't return ENOMEM"
9350         sync; sleep 2; sync     # do a real sync this time to flush page
9351         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9352                 error "locked page left in cache after async error" || true
9353         debugrestore
9354 }
9355 run_test 63b "async write errors should be returned to fsync ==="
9356
9357 test_64a () {
9358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9359
9360         lfs df $DIR
9361         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9362 }
9363 run_test 64a "verify filter grant calculations (in kernel) ====="
9364
9365 test_64b () {
9366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9367
9368         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9369 }
9370 run_test 64b "check out-of-space detection on client"
9371
9372 test_64c() {
9373         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9374 }
9375 run_test 64c "verify grant shrink"
9376
9377 import_param() {
9378         local tgt=$1
9379         local param=$2
9380
9381         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9382 }
9383
9384 # this does exactly what osc_request.c:osc_announce_cached() does in
9385 # order to calculate max amount of grants to ask from server
9386 want_grant() {
9387         local tgt=$1
9388
9389         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9390         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9391
9392         ((rpc_in_flight++));
9393         nrpages=$((nrpages * rpc_in_flight))
9394
9395         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9396
9397         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9398
9399         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9400         local undirty=$((nrpages * PAGE_SIZE))
9401
9402         local max_extent_pages
9403         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9404         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9405         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9406         local grant_extent_tax
9407         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9408
9409         undirty=$((undirty + nrextents * grant_extent_tax))
9410
9411         echo $undirty
9412 }
9413
9414 # this is size of unit for grant allocation. It should be equal to
9415 # what tgt_grant.c:tgt_grant_chunk() calculates
9416 grant_chunk() {
9417         local tgt=$1
9418         local max_brw_size
9419         local grant_extent_tax
9420
9421         max_brw_size=$(import_param $tgt max_brw_size)
9422
9423         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9424
9425         echo $(((max_brw_size + grant_extent_tax) * 2))
9426 }
9427
9428 test_64d() {
9429         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9430                 skip "OST < 2.10.55 doesn't limit grants enough"
9431
9432         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9433
9434         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9435                 skip "no grant_param connect flag"
9436
9437         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9438
9439         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9440         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9441
9442
9443         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9444         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9445
9446         $LFS setstripe $DIR/$tfile -i 0 -c 1
9447         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9448         ddpid=$!
9449
9450         while kill -0 $ddpid; do
9451                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9452
9453                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9454                         kill $ddpid
9455                         error "cur_grant $cur_grant > $max_cur_granted"
9456                 fi
9457
9458                 sleep 1
9459         done
9460 }
9461 run_test 64d "check grant limit exceed"
9462
9463 check_grants() {
9464         local tgt=$1
9465         local expected=$2
9466         local msg=$3
9467         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9468
9469         ((cur_grants == expected)) ||
9470                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9471 }
9472
9473 round_up_p2() {
9474         echo $((($1 + $2 - 1) & ~($2 - 1)))
9475 }
9476
9477 test_64e() {
9478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9479         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9480                 skip "Need OSS version at least 2.11.56"
9481
9482         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9483         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9484         $LCTL set_param debug=+cache
9485
9486         # Remount client to reset grant
9487         remount_client $MOUNT || error "failed to remount client"
9488         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9489
9490         local init_grants=$(import_param $osc_tgt initial_grant)
9491
9492         check_grants $osc_tgt $init_grants "init grants"
9493
9494         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9495         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9496         local gbs=$(import_param $osc_tgt grant_block_size)
9497
9498         # write random number of bytes from max_brw_size / 4 to max_brw_size
9499         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9500         # align for direct io
9501         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9502         # round to grant consumption unit
9503         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9504
9505         local grants=$((wb_round_up + extent_tax))
9506
9507         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9508         stack_trap "rm -f $DIR/$tfile"
9509
9510         # define OBD_FAIL_TGT_NO_GRANT 0x725
9511         # make the server not grant more back
9512         do_facet ost1 $LCTL set_param fail_loc=0x725
9513         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9514
9515         do_facet ost1 $LCTL set_param fail_loc=0
9516
9517         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9518
9519         rm -f $DIR/$tfile || error "rm failed"
9520
9521         # Remount client to reset grant
9522         remount_client $MOUNT || error "failed to remount client"
9523         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9524
9525         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9526
9527         # define OBD_FAIL_TGT_NO_GRANT 0x725
9528         # make the server not grant more back
9529         do_facet ost1 $LCTL set_param fail_loc=0x725
9530         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9531         do_facet ost1 $LCTL set_param fail_loc=0
9532
9533         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9534 }
9535 run_test 64e "check grant consumption (no grant allocation)"
9536
9537 test_64f() {
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539
9540         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9541         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9542         $LCTL set_param debug=+cache
9543
9544         # Remount client to reset grant
9545         remount_client $MOUNT || error "failed to remount client"
9546         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9547
9548         local init_grants=$(import_param $osc_tgt initial_grant)
9549         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9550         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9551         local gbs=$(import_param $osc_tgt grant_block_size)
9552         local chunk=$(grant_chunk $osc_tgt)
9553
9554         # write random number of bytes from max_brw_size / 4 to max_brw_size
9555         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9556         # align for direct io
9557         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9558         # round to grant consumption unit
9559         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9560
9561         local grants=$((wb_round_up + extent_tax))
9562
9563         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9564         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9565                 error "error writing to $DIR/$tfile"
9566
9567         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9568                 "direct io with grant allocation"
9569
9570         rm -f $DIR/$tfile || error "rm failed"
9571
9572         # Remount client to reset grant
9573         remount_client $MOUNT || error "failed to remount client"
9574         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9575
9576         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9577
9578         local cmd="oO_WRONLY:w${write_bytes}_yc"
9579
9580         $MULTIOP $DIR/$tfile $cmd &
9581         MULTIPID=$!
9582         sleep 1
9583
9584         check_grants $osc_tgt $((init_grants - grants)) \
9585                 "buffered io, not write rpc"
9586
9587         kill -USR1 $MULTIPID
9588         wait
9589
9590         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9591                 "buffered io, one RPC"
9592 }
9593 run_test 64f "check grant consumption (with grant allocation)"
9594
9595 test_64g() {
9596         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9597                 skip "Need MDS version at least 2.14.56"
9598
9599         local mdts=$(comma_list $(mdts_nodes))
9600
9601         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9602                         tr '\n' ' ')
9603         stack_trap "$LCTL set_param $old"
9604
9605         # generate dirty pages and increase dirty granted on MDT
9606         stack_trap "rm -f $DIR/$tfile-*"
9607         for (( i = 0; i < 10; i++)); do
9608                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9609                         error "can't set stripe"
9610                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9611                         error "can't dd"
9612                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9613                         $LFS getstripe $DIR/$tfile-$i
9614                         error "not DoM file"
9615                 }
9616         done
9617
9618         # flush dirty pages
9619         sync
9620
9621         # wait until grant shrink reset grant dirty on MDTs
9622         for ((i = 0; i < 120; i++)); do
9623                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9624                         awk '{sum=sum+$1} END {print sum}')
9625                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9626                 echo "$grant_dirty grants, $vm_dirty pages"
9627                 (( grant_dirty + vm_dirty == 0 )) && break
9628                 (( i == 3 )) && sync &&
9629                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9630                 sleep 1
9631         done
9632
9633         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9634                 awk '{sum=sum+$1} END {print sum}')
9635         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9636 }
9637 run_test 64g "grant shrink on MDT"
9638
9639 test_64h() {
9640         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9641                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9642
9643         local instance=$($LFS getname -i $DIR)
9644         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9645         local num_exps=$(do_facet ost1 \
9646             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9647         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9648         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9649         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9650
9651         # 10MiB is for file to be written, max_brw_size * 16 *
9652         # num_exps is space reserve so that tgt_grant_shrink() decided
9653         # to not shrink
9654         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9655         (( avail * 1024 < expect )) &&
9656                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9657
9658         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9659         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9660         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9661         $LCTL set_param osc.*OST0000*.grant_shrink=1
9662         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9663
9664         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9665         stack_trap "rm -f $DIR/$tfile"
9666         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9667
9668         # drop cache so that coming read would do rpc
9669         cancel_lru_locks osc
9670
9671         # shrink interval is set to 10, pause for 7 seconds so that
9672         # grant thread did not wake up yet but coming read entered
9673         # shrink mode for rpc (osc_should_shrink_grant())
9674         sleep 7
9675
9676         declare -a cur_grant_bytes
9677         declare -a tot_granted
9678         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9679         tot_granted[0]=$(do_facet ost1 \
9680             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9681
9682         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9683
9684         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9685         tot_granted[1]=$(do_facet ost1 \
9686             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9687
9688         # grant change should be equal on both sides
9689         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9690                 tot_granted[0] - tot_granted[1])) ||
9691                 error "grant change mismatch, "                                \
9692                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9693                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9694 }
9695 run_test 64h "grant shrink on read"
9696
9697 test_64i() {
9698         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9699                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9700
9701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9702         remote_ost_nodsh && skip "remote OSTs with nodsh"
9703
9704         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9705         stack_trap "rm -f $DIR/$tfile"
9706
9707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9708
9709         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9710         local instance=$($LFS getname -i $DIR)
9711
9712         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9713         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9714
9715         # shrink grants and simulate rpc loss
9716         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9717         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9718         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9719
9720         fail ost1
9721
9722         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9723
9724         local testid=$(echo $TESTNAME | tr '_' ' ')
9725
9726         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9727                 grep "GRANT, real grant" &&
9728                 error "client has more grants then it owns" || true
9729 }
9730 run_test 64i "shrink on reconnect"
9731
9732 # bug 1414 - set/get directories' stripe info
9733 test_65a() {
9734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9735
9736         test_mkdir $DIR/$tdir
9737         touch $DIR/$tdir/f1
9738         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9739 }
9740 run_test 65a "directory with no stripe info"
9741
9742 test_65b() {
9743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9744
9745         test_mkdir $DIR/$tdir
9746         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9747
9748         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9749                                                 error "setstripe"
9750         touch $DIR/$tdir/f2
9751         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9752 }
9753 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9754
9755 test_65c() {
9756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9757         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9758
9759         test_mkdir $DIR/$tdir
9760         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9761
9762         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9763                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9764         touch $DIR/$tdir/f3
9765         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9766 }
9767 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9768
9769 test_65d() {
9770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9771
9772         test_mkdir $DIR/$tdir
9773         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9774         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9775
9776         if [[ $STRIPECOUNT -le 0 ]]; then
9777                 sc=1
9778         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9779                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9780                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9781         else
9782                 sc=$(($STRIPECOUNT - 1))
9783         fi
9784         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9785         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9786         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9787                 error "lverify failed"
9788 }
9789 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9790
9791 test_65e() {
9792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9793
9794         # LU-16904 delete layout when root is set as PFL layout
9795         save_layout_restore_at_exit $MOUNT
9796         $LFS setstripe -d $MOUNT || error "setstripe failed"
9797
9798         test_mkdir $DIR/$tdir
9799
9800         $LFS setstripe $DIR/$tdir || error "setstripe"
9801         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9802                                         error "no stripe info failed"
9803         touch $DIR/$tdir/f6
9804         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9805 }
9806 run_test 65e "directory setstripe defaults"
9807
9808 test_65f() {
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         test_mkdir $DIR/${tdir}f
9812         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9813                 error "setstripe succeeded" || true
9814 }
9815 run_test 65f "dir setstripe permission (should return error) ==="
9816
9817 test_65g() {
9818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9819
9820         # LU-16904 delete layout when root is set as PFL layout
9821         save_layout_restore_at_exit $MOUNT
9822         $LFS setstripe -d $MOUNT || error "setstripe failed"
9823
9824         test_mkdir $DIR/$tdir
9825         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9826
9827         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9828                 error "setstripe -S failed"
9829         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9830         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9831                 error "delete default stripe failed"
9832 }
9833 run_test 65g "directory setstripe -d"
9834
9835 test_65h() {
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837
9838         test_mkdir $DIR/$tdir
9839         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9840
9841         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9842                 error "setstripe -S failed"
9843         test_mkdir $DIR/$tdir/dd1
9844         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9845                 error "stripe info inherit failed"
9846 }
9847 run_test 65h "directory stripe info inherit ===================="
9848
9849 test_65i() {
9850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9851
9852         save_layout_restore_at_exit $MOUNT
9853
9854         # bug6367: set non-default striping on root directory
9855         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9856
9857         # bug12836: getstripe on -1 default directory striping
9858         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9859
9860         # bug12836: getstripe -v on -1 default directory striping
9861         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9862
9863         # bug12836: new find on -1 default directory striping
9864         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9865 }
9866 run_test 65i "various tests to set root directory striping"
9867
9868 test_65j() { # bug6367
9869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9870
9871         sync; sleep 1
9872
9873         # if we aren't already remounting for each test, do so for this test
9874         if [ "$I_MOUNTED" = "yes" ]; then
9875                 cleanup || error "failed to unmount"
9876                 setup
9877         fi
9878
9879         save_layout_restore_at_exit $MOUNT
9880
9881         $LFS setstripe -d $MOUNT || error "setstripe failed"
9882 }
9883 run_test 65j "set default striping on root directory (bug 6367)="
9884
9885 cleanup_65k() {
9886         rm -rf $DIR/$tdir
9887         wait_delete_completed
9888         do_facet $SINGLEMDS "lctl set_param -n \
9889                 osp.$ost*MDT0000.max_create_count=$max_count"
9890         do_facet $SINGLEMDS "lctl set_param -n \
9891                 osp.$ost*MDT0000.create_count=$count"
9892         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9893         echo $INACTIVE_OSC "is Activate"
9894
9895         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9896 }
9897
9898 test_65k() { # bug11679
9899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9901         remote_mds_nodsh && skip "remote MDS with nodsh"
9902
9903         local disable_precreate=true
9904         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9905                 disable_precreate=false
9906
9907         echo "Check OST status: "
9908         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9909                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9910
9911         for OSC in $MDS_OSCS; do
9912                 echo $OSC "is active"
9913                 do_facet $SINGLEMDS lctl --device %$OSC activate
9914         done
9915
9916         for INACTIVE_OSC in $MDS_OSCS; do
9917                 local ost=$(osc_to_ost $INACTIVE_OSC)
9918                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9919                                lov.*md*.target_obd |
9920                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9921
9922                 mkdir -p $DIR/$tdir
9923                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9924                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9925
9926                 echo "Deactivate: " $INACTIVE_OSC
9927                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9928
9929                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9930                               osp.$ost*MDT0000.create_count")
9931                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9932                                   osp.$ost*MDT0000.max_create_count")
9933                 $disable_precreate &&
9934                         do_facet $SINGLEMDS "lctl set_param -n \
9935                                 osp.$ost*MDT0000.max_create_count=0"
9936
9937                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9938                         [ -f $DIR/$tdir/$idx ] && continue
9939                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9940                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9941                                 { cleanup_65k;
9942                                   error "setstripe $idx should succeed"; }
9943                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9944                 done
9945                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9946                 rmdir $DIR/$tdir
9947
9948                 do_facet $SINGLEMDS "lctl set_param -n \
9949                         osp.$ost*MDT0000.max_create_count=$max_count"
9950                 do_facet $SINGLEMDS "lctl set_param -n \
9951                         osp.$ost*MDT0000.create_count=$count"
9952                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9953                 echo $INACTIVE_OSC "is Activate"
9954
9955                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9956         done
9957 }
9958 run_test 65k "validate manual striping works properly with deactivated OSCs"
9959
9960 test_65l() { # bug 12836
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962
9963         test_mkdir -p $DIR/$tdir/test_dir
9964         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9965         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9966 }
9967 run_test 65l "lfs find on -1 stripe dir ========================"
9968
9969 test_65m() {
9970         local layout=$(save_layout $MOUNT)
9971         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9972                 restore_layout $MOUNT $layout
9973                 error "setstripe should fail by non-root users"
9974         }
9975         true
9976 }
9977 run_test 65m "normal user can't set filesystem default stripe"
9978
9979 test_65n() {
9980         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9981         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9982                 skip "Need MDS version at least 2.12.50"
9983         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9984
9985         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9986         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9987         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9988
9989         save_layout_restore_at_exit $MOUNT
9990
9991         # new subdirectory under root directory should not inherit
9992         # the default layout from root
9993         # LU-16904 check if the root is set as PFL layout
9994         local numcomp=$($LFS getstripe --component-count $MOUNT)
9995
9996         if [[ $numcomp -eq 0 ]]; then
9997                 local dir1=$MOUNT/$tdir-1
9998                 mkdir $dir1 || error "mkdir $dir1 failed"
9999                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10000                         error "$dir1 shouldn't have LOV EA"
10001         fi
10002
10003         # delete the default layout on root directory
10004         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10005
10006         local dir2=$MOUNT/$tdir-2
10007         mkdir $dir2 || error "mkdir $dir2 failed"
10008         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10009                 error "$dir2 shouldn't have LOV EA"
10010
10011         # set a new striping pattern on root directory
10012         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10013         local new_def_stripe_size=$((def_stripe_size * 2))
10014         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10015                 error "set stripe size on $MOUNT failed"
10016
10017         # new file created in $dir2 should inherit the new stripe size from
10018         # the filesystem default
10019         local file2=$dir2/$tfile-2
10020         touch $file2 || error "touch $file2 failed"
10021
10022         local file2_stripe_size=$($LFS getstripe -S $file2)
10023         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10024         {
10025                 echo "file2_stripe_size: '$file2_stripe_size'"
10026                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10027                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10028         }
10029
10030         local dir3=$MOUNT/$tdir-3
10031         mkdir $dir3 || error "mkdir $dir3 failed"
10032         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10033         # the root layout, which is the actual default layout that will be used
10034         # when new files are created in $dir3.
10035         local dir3_layout=$(get_layout_param $dir3)
10036         local root_dir_layout=$(get_layout_param $MOUNT)
10037         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10038         {
10039                 echo "dir3_layout: '$dir3_layout'"
10040                 echo "root_dir_layout: '$root_dir_layout'"
10041                 error "$dir3 should show the default layout from $MOUNT"
10042         }
10043
10044         # set OST pool on root directory
10045         local pool=$TESTNAME
10046         pool_add $pool || error "add $pool failed"
10047         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10048                 error "add targets to $pool failed"
10049
10050         $LFS setstripe -p $pool $MOUNT ||
10051                 error "set OST pool on $MOUNT failed"
10052
10053         # new file created in $dir3 should inherit the pool from
10054         # the filesystem default
10055         local file3=$dir3/$tfile-3
10056         touch $file3 || error "touch $file3 failed"
10057
10058         local file3_pool=$($LFS getstripe -p $file3)
10059         [[ "$file3_pool" = "$pool" ]] ||
10060                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10061
10062         local dir4=$MOUNT/$tdir-4
10063         mkdir $dir4 || error "mkdir $dir4 failed"
10064         local dir4_layout=$(get_layout_param $dir4)
10065         root_dir_layout=$(get_layout_param $MOUNT)
10066         echo "$LFS getstripe -d $dir4"
10067         $LFS getstripe -d $dir4
10068         echo "$LFS getstripe -d $MOUNT"
10069         $LFS getstripe -d $MOUNT
10070         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10071         {
10072                 echo "dir4_layout: '$dir4_layout'"
10073                 echo "root_dir_layout: '$root_dir_layout'"
10074                 error "$dir4 should show the default layout from $MOUNT"
10075         }
10076
10077         # new file created in $dir4 should inherit the pool from
10078         # the filesystem default
10079         local file4=$dir4/$tfile-4
10080         touch $file4 || error "touch $file4 failed"
10081
10082         local file4_pool=$($LFS getstripe -p $file4)
10083         [[ "$file4_pool" = "$pool" ]] ||
10084                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10085
10086         # new subdirectory under non-root directory should inherit
10087         # the default layout from its parent directory
10088         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10089                 error "set directory layout on $dir4 failed"
10090
10091         local dir5=$dir4/$tdir-5
10092         mkdir $dir5 || error "mkdir $dir5 failed"
10093
10094         dir4_layout=$(get_layout_param $dir4)
10095         local dir5_layout=$(get_layout_param $dir5)
10096         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10097         {
10098                 echo "dir4_layout: '$dir4_layout'"
10099                 echo "dir5_layout: '$dir5_layout'"
10100                 error "$dir5 should inherit the default layout from $dir4"
10101         }
10102
10103         # though subdir under ROOT doesn't inherit default layout, but
10104         # its sub dir/file should be created with default layout.
10105         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10106         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10107                 skip "Need MDS version at least 2.12.59"
10108
10109         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10110         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10111         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10112
10113         if [ $default_lmv_hash == "none" ]; then
10114                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10115         else
10116                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10117                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10118         fi
10119
10120         $LFS setdirstripe -D -c 2 $MOUNT ||
10121                 error "setdirstripe -D -c 2 failed"
10122         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10123         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10124         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10125
10126         # $dir4 layout includes pool
10127         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10128         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10129                 error "pool lost on setstripe"
10130         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10131         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10132                 error "pool lost on compound layout setstripe"
10133 }
10134 run_test 65n "don't inherit default layout from root for new subdirectories"
10135
10136 test_65o() {
10137         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10138                 skip "need MDS version at least 2.14.57"
10139
10140         # set OST pool on root directory
10141         local pool=$TESTNAME
10142
10143         pool_add $pool || error "add $pool failed"
10144         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10145                 error "add targets to $pool failed"
10146
10147         local dir1=$MOUNT/$tdir
10148
10149         mkdir $dir1 || error "mkdir $dir1 failed"
10150
10151         # set a new striping pattern on root directory
10152         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10153
10154         $LFS setstripe -p $pool $dir1 ||
10155                 error "set directory layout on $dir1 failed"
10156
10157         # $dir1 layout includes pool
10158         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10159         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10160                 error "pool lost on setstripe"
10161         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10162         $LFS getstripe $dir1
10163         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10164                 error "pool lost on compound layout setstripe"
10165
10166         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10167                 error "setdirstripe failed on sub-dir with inherited pool"
10168         $LFS getstripe $dir1/dir2
10169         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10170                 error "pool lost on compound layout setdirstripe"
10171
10172         $LFS setstripe -E -1 -c 1 $dir1
10173         $LFS getstripe -d $dir1
10174         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10175                 error "pool lost on setstripe"
10176 }
10177 run_test 65o "pool inheritance for mdt component"
10178
10179 test_65p () { # LU-16152
10180         local src_dir=$DIR/$tdir/src_dir
10181         local dst_dir=$DIR/$tdir/dst_dir
10182         local yaml_file=$DIR/$tdir/layout.yaml
10183         local border
10184
10185         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10186                 skip "Need at least version 2.15.51"
10187
10188         test_mkdir -p $src_dir
10189         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10190                 error "failed to setstripe"
10191         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10192                 error "failed to getstripe"
10193
10194         test_mkdir -p $dst_dir
10195         $LFS setstripe --yaml $yaml_file $dst_dir ||
10196                 error "failed to setstripe with yaml file"
10197         border=$($LFS getstripe -d $dst_dir |
10198                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10199                 error "failed to getstripe"
10200
10201         # 2048M is 0x80000000, or 2147483648
10202         (( $border == 2147483648 )) ||
10203                 error "failed to handle huge number in yaml layout"
10204 }
10205 run_test 65p "setstripe with yaml file and huge number"
10206
10207 # bug 2543 - update blocks count on client
10208 test_66() {
10209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10210
10211         local COUNT=${COUNT:-8}
10212         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10213         sync; sync_all_data; sync; sync_all_data
10214         cancel_lru_locks osc
10215         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10216         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10217 }
10218 run_test 66 "update inode blocks count on client ==============="
10219
10220 meminfo() {
10221         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10222 }
10223
10224 swap_used() {
10225         swapon -s | awk '($1 == "'$1'") { print $4 }'
10226 }
10227
10228 # bug5265, obdfilter oa2dentry return -ENOENT
10229 # #define OBD_FAIL_SRV_ENOENT 0x217
10230 test_69() {
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232         remote_ost_nodsh && skip "remote OST with nodsh"
10233
10234         f="$DIR/$tfile"
10235         $LFS setstripe -c 1 -i 0 $f
10236         stack_trap "rm -f $f ${f}.2"
10237
10238         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10239
10240         do_facet ost1 lctl set_param fail_loc=0x217
10241         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10242         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10243
10244         do_facet ost1 lctl set_param fail_loc=0
10245         $DIRECTIO write $f 0 2 || error "write error"
10246
10247         cancel_lru_locks osc
10248         $DIRECTIO read $f 0 1 || error "read error"
10249
10250         do_facet ost1 lctl set_param fail_loc=0x217
10251         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10252
10253         do_facet ost1 lctl set_param fail_loc=0
10254 }
10255 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10256
10257 test_71() {
10258         test_mkdir $DIR/$tdir
10259         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10260         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10261 }
10262 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10263
10264 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266         [ "$RUNAS_ID" = "$UID" ] &&
10267                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10268         # Check that testing environment is properly set up. Skip if not
10269         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10270                 skip_env "User $RUNAS_ID does not exist - skipping"
10271
10272         touch $DIR/$tfile
10273         chmod 777 $DIR/$tfile
10274         chmod ug+s $DIR/$tfile
10275         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10276                 error "$RUNAS dd $DIR/$tfile failed"
10277         # See if we are still setuid/sgid
10278         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10279                 error "S/gid is not dropped on write"
10280         # Now test that MDS is updated too
10281         cancel_lru_locks mdc
10282         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10283                 error "S/gid is not dropped on MDS"
10284         rm -f $DIR/$tfile
10285 }
10286 run_test 72a "Test that remove suid works properly (bug5695) ===="
10287
10288 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10289         local perm
10290
10291         [ "$RUNAS_ID" = "$UID" ] &&
10292                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10293         [ "$RUNAS_ID" -eq 0 ] &&
10294                 skip_env "RUNAS_ID = 0 -- skipping"
10295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10296         # Check that testing environment is properly set up. Skip if not
10297         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10298                 skip_env "User $RUNAS_ID does not exist - skipping"
10299
10300         touch $DIR/${tfile}-f{g,u}
10301         test_mkdir $DIR/${tfile}-dg
10302         test_mkdir $DIR/${tfile}-du
10303         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10304         chmod g+s $DIR/${tfile}-{f,d}g
10305         chmod u+s $DIR/${tfile}-{f,d}u
10306         for perm in 777 2777 4777; do
10307                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10308                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10309                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10310                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10311         done
10312         true
10313 }
10314 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10315
10316 # bug 3462 - multiple simultaneous MDC requests
10317 test_73() {
10318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10319
10320         test_mkdir $DIR/d73-1
10321         test_mkdir $DIR/d73-2
10322         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10323         pid1=$!
10324
10325         lctl set_param fail_loc=0x80000129
10326         $MULTIOP $DIR/d73-1/f73-2 Oc &
10327         sleep 1
10328         lctl set_param fail_loc=0
10329
10330         $MULTIOP $DIR/d73-2/f73-3 Oc &
10331         pid3=$!
10332
10333         kill -USR1 $pid1
10334         wait $pid1 || return 1
10335
10336         sleep 25
10337
10338         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10339         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10340         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10341
10342         rm -rf $DIR/d73-*
10343 }
10344 run_test 73 "multiple MDC requests (should not deadlock)"
10345
10346 test_74a() { # bug 6149, 6184
10347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10348
10349         touch $DIR/f74a
10350         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10351         #
10352         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10353         # will spin in a tight reconnection loop
10354         $LCTL set_param fail_loc=0x8000030e
10355         # get any lock that won't be difficult - lookup works.
10356         ls $DIR/f74a
10357         $LCTL set_param fail_loc=0
10358         rm -f $DIR/f74a
10359         true
10360 }
10361 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10362
10363 test_74b() { # bug 13310
10364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10365
10366         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10367         #
10368         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10369         # will spin in a tight reconnection loop
10370         $LCTL set_param fail_loc=0x8000030e
10371         # get a "difficult" lock
10372         touch $DIR/f74b
10373         $LCTL set_param fail_loc=0
10374         rm -f $DIR/f74b
10375         true
10376 }
10377 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10378
10379 test_74c() {
10380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10381
10382         #define OBD_FAIL_LDLM_NEW_LOCK
10383         $LCTL set_param fail_loc=0x319
10384         touch $DIR/$tfile && error "touch successful"
10385         $LCTL set_param fail_loc=0
10386         true
10387 }
10388 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10389
10390 slab_lic=/sys/kernel/slab/lustre_inode_cache
10391 num_objects() {
10392         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10393         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10394                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10395 }
10396
10397 test_76a() { # Now for b=20433, added originally in b=1443
10398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10399
10400         cancel_lru_locks osc
10401         # there may be some slab objects cached per core
10402         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10403         local before=$(num_objects)
10404         local count=$((512 * cpus))
10405         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10406         local margin=$((count / 10))
10407         if [[ -f $slab_lic/aliases ]]; then
10408                 local aliases=$(cat $slab_lic/aliases)
10409                 (( aliases > 0 )) && margin=$((margin * aliases))
10410         fi
10411
10412         echo "before slab objects: $before"
10413         for i in $(seq $count); do
10414                 touch $DIR/$tfile
10415                 rm -f $DIR/$tfile
10416         done
10417         cancel_lru_locks osc
10418         local after=$(num_objects)
10419         echo "created: $count, after slab objects: $after"
10420         # shared slab counts are not very accurate, allow significant margin
10421         # the main goal is that the cache growth is not permanently > $count
10422         while (( after > before + margin )); do
10423                 sleep 1
10424                 after=$(num_objects)
10425                 wait=$((wait + 1))
10426                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10427                 if (( wait > 60 )); then
10428                         error "inode slab grew from $before+$margin to $after"
10429                 fi
10430         done
10431 }
10432 run_test 76a "confirm clients recycle inodes properly ===="
10433
10434 test_76b() {
10435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10436         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10437
10438         local count=512
10439         local before=$(num_objects)
10440
10441         for i in $(seq $count); do
10442                 mkdir $DIR/$tdir
10443                 rmdir $DIR/$tdir
10444         done
10445
10446         local after=$(num_objects)
10447         local wait=0
10448
10449         while (( after > before )); do
10450                 sleep 1
10451                 after=$(num_objects)
10452                 wait=$((wait + 1))
10453                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10454                 if (( wait > 60 )); then
10455                         error "inode slab grew from $before to $after"
10456                 fi
10457         done
10458
10459         echo "slab objects before: $before, after: $after"
10460 }
10461 run_test 76b "confirm clients recycle directory inodes properly ===="
10462
10463 export ORIG_CSUM=""
10464 set_checksums()
10465 {
10466         # Note: in sptlrpc modes which enable its own bulk checksum, the
10467         # original crc32_le bulk checksum will be automatically disabled,
10468         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10469         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10470         # In this case set_checksums() will not be no-op, because sptlrpc
10471         # bulk checksum will be enabled all through the test.
10472
10473         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10474         lctl set_param -n osc.*.checksums $1
10475         return 0
10476 }
10477
10478 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10479                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10480 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10481                              tr -d [] | head -n1)}
10482 set_checksum_type()
10483 {
10484         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10485         rc=$?
10486         log "set checksum type to $1, rc = $rc"
10487         return $rc
10488 }
10489
10490 get_osc_checksum_type()
10491 {
10492         # arugment 1: OST name, like OST0000
10493         ost=$1
10494         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10495                         sed 's/.*\[\(.*\)\].*/\1/g')
10496         rc=$?
10497         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10498         echo $checksum_type
10499 }
10500
10501 F77_TMP=$TMP/f77-temp
10502 F77SZ=8
10503 setup_f77() {
10504         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10505                 error "error writing to $F77_TMP"
10506 }
10507
10508 test_77a() { # bug 10889
10509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10510         $GSS && skip_env "could not run with gss"
10511
10512         [ ! -f $F77_TMP ] && setup_f77
10513         set_checksums 1
10514         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10515         set_checksums 0
10516         rm -f $DIR/$tfile
10517 }
10518 run_test 77a "normal checksum read/write operation"
10519
10520 test_77b() { # bug 10889
10521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10522         $GSS && skip_env "could not run with gss"
10523
10524         [ ! -f $F77_TMP ] && setup_f77
10525         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10526         $LCTL set_param fail_loc=0x80000409
10527         set_checksums 1
10528
10529         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10530                 error "dd error: $?"
10531         $LCTL set_param fail_loc=0
10532
10533         for algo in $CKSUM_TYPES; do
10534                 cancel_lru_locks osc
10535                 set_checksum_type $algo
10536                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10537                 $LCTL set_param fail_loc=0x80000408
10538                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10539                 $LCTL set_param fail_loc=0
10540         done
10541         set_checksums 0
10542         set_checksum_type $ORIG_CSUM_TYPE
10543         rm -f $DIR/$tfile
10544 }
10545 run_test 77b "checksum error on client write, read"
10546
10547 cleanup_77c() {
10548         trap 0
10549         set_checksums 0
10550         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10551         $check_ost &&
10552                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10553         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10554         $check_ost && [ -n "$ost_file_prefix" ] &&
10555                 do_facet ost1 rm -f ${ost_file_prefix}\*
10556 }
10557
10558 test_77c() {
10559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10560         $GSS && skip_env "could not run with gss"
10561         remote_ost_nodsh && skip "remote OST with nodsh"
10562
10563         local bad1
10564         local osc_file_prefix
10565         local osc_file
10566         local check_ost=false
10567         local ost_file_prefix
10568         local ost_file
10569         local orig_cksum
10570         local dump_cksum
10571         local fid
10572
10573         # ensure corruption will occur on first OSS/OST
10574         $LFS setstripe -i 0 $DIR/$tfile
10575
10576         [ ! -f $F77_TMP ] && setup_f77
10577         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10578                 error "dd write error: $?"
10579         fid=$($LFS path2fid $DIR/$tfile)
10580
10581         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10582         then
10583                 check_ost=true
10584                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10585                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10586         else
10587                 echo "OSS do not support bulk pages dump upon error"
10588         fi
10589
10590         osc_file_prefix=$($LCTL get_param -n debug_path)
10591         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10592
10593         trap cleanup_77c EXIT
10594
10595         set_checksums 1
10596         # enable bulk pages dump upon error on Client
10597         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10598         # enable bulk pages dump upon error on OSS
10599         $check_ost &&
10600                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10601
10602         # flush Client cache to allow next read to reach OSS
10603         cancel_lru_locks osc
10604
10605         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10606         $LCTL set_param fail_loc=0x80000408
10607         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10608         $LCTL set_param fail_loc=0
10609
10610         rm -f $DIR/$tfile
10611
10612         # check cksum dump on Client
10613         osc_file=$(ls ${osc_file_prefix}*)
10614         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10615         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10616         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10617         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10618         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10619                      cksum)
10620         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10621         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10622                 error "dump content does not match on Client"
10623
10624         $check_ost || skip "No need to check cksum dump on OSS"
10625
10626         # check cksum dump on OSS
10627         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10628         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10629         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10630         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10631         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10632                 error "dump content does not match on OSS"
10633
10634         cleanup_77c
10635 }
10636 run_test 77c "checksum error on client read with debug"
10637
10638 test_77d() { # bug 10889
10639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10640         $GSS && skip_env "could not run with gss"
10641
10642         stack_trap "rm -f $DIR/$tfile"
10643         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10644         $LCTL set_param fail_loc=0x80000409
10645         set_checksums 1
10646         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10647                 error "direct write: rc=$?"
10648         $LCTL set_param fail_loc=0
10649         set_checksums 0
10650
10651         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10652         $LCTL set_param fail_loc=0x80000408
10653         set_checksums 1
10654         cancel_lru_locks osc
10655         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10656                 error "direct read: rc=$?"
10657         $LCTL set_param fail_loc=0
10658         set_checksums 0
10659 }
10660 run_test 77d "checksum error on OST direct write, read"
10661
10662 test_77f() { # bug 10889
10663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10664         $GSS && skip_env "could not run with gss"
10665
10666         set_checksums 1
10667         stack_trap "rm -f $DIR/$tfile"
10668         for algo in $CKSUM_TYPES; do
10669                 cancel_lru_locks osc
10670                 set_checksum_type $algo
10671                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10672                 $LCTL set_param fail_loc=0x409
10673                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10674                         error "direct write succeeded"
10675                 $LCTL set_param fail_loc=0
10676         done
10677         set_checksum_type $ORIG_CSUM_TYPE
10678         set_checksums 0
10679 }
10680 run_test 77f "repeat checksum error on write (expect error)"
10681
10682 test_77g() { # bug 10889
10683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10684         $GSS && skip_env "could not run with gss"
10685         remote_ost_nodsh && skip "remote OST with nodsh"
10686
10687         [ ! -f $F77_TMP ] && setup_f77
10688
10689         local file=$DIR/$tfile
10690         stack_trap "rm -f $file" EXIT
10691
10692         $LFS setstripe -c 1 -i 0 $file
10693         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10694         do_facet ost1 lctl set_param fail_loc=0x8000021a
10695         set_checksums 1
10696         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10697                 error "write error: rc=$?"
10698         do_facet ost1 lctl set_param fail_loc=0
10699         set_checksums 0
10700
10701         cancel_lru_locks osc
10702         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10703         do_facet ost1 lctl set_param fail_loc=0x8000021b
10704         set_checksums 1
10705         cmp $F77_TMP $file || error "file compare failed"
10706         do_facet ost1 lctl set_param fail_loc=0
10707         set_checksums 0
10708 }
10709 run_test 77g "checksum error on OST write, read"
10710
10711 test_77k() { # LU-10906
10712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10713         $GSS && skip_env "could not run with gss"
10714
10715         local cksum_param="osc.$FSNAME*.checksums"
10716         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10717         local checksum
10718         local i
10719
10720         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10721         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10722         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10723
10724         for i in 0 1; do
10725                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10726                         error "failed to set checksum=$i on MGS"
10727                 wait_update $HOSTNAME "$get_checksum" $i
10728                 #remount
10729                 echo "remount client, checksum should be $i"
10730                 remount_client $MOUNT || error "failed to remount client"
10731                 checksum=$(eval $get_checksum)
10732                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10733         done
10734         # remove persistent param to avoid races with checksum mountopt below
10735         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10736                 error "failed to delete checksum on MGS"
10737
10738         for opt in "checksum" "nochecksum"; do
10739                 #remount with mount option
10740                 echo "remount client with option $opt, checksum should be $i"
10741                 umount_client $MOUNT || error "failed to umount client"
10742                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10743                         error "failed to mount client with option '$opt'"
10744                 checksum=$(eval $get_checksum)
10745                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10746                 i=$((i - 1))
10747         done
10748
10749         remount_client $MOUNT || error "failed to remount client"
10750 }
10751 run_test 77k "enable/disable checksum correctly"
10752
10753 test_77l() {
10754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10755         $GSS && skip_env "could not run with gss"
10756
10757         set_checksums 1
10758         stack_trap "set_checksums $ORIG_CSUM" EXIT
10759         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10760
10761         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10762
10763         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10764         for algo in $CKSUM_TYPES; do
10765                 set_checksum_type $algo || error "fail to set checksum type $algo"
10766                 osc_algo=$(get_osc_checksum_type OST0000)
10767                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10768
10769                 # no locks, no reqs to let the connection idle
10770                 cancel_lru_locks osc
10771                 lru_resize_disable osc
10772                 wait_osc_import_state client ost1 IDLE
10773
10774                 # ensure ost1 is connected
10775                 stat $DIR/$tfile >/dev/null || error "can't stat"
10776                 wait_osc_import_state client ost1 FULL
10777
10778                 osc_algo=$(get_osc_checksum_type OST0000)
10779                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10780         done
10781         return 0
10782 }
10783 run_test 77l "preferred checksum type is remembered after reconnected"
10784
10785 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10786 rm -f $F77_TMP
10787 unset F77_TMP
10788
10789 test_77m() {
10790         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10791                 skip "Need at least version 2.14.52"
10792         local param=checksum_speed
10793
10794         $LCTL get_param $param || error "reading $param failed"
10795
10796         csum_speeds=$($LCTL get_param -n $param)
10797
10798         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10799                 error "known checksum types are missing"
10800 }
10801 run_test 77m "Verify checksum_speed is correctly read"
10802
10803 check_filefrag_77n() {
10804         local nr_ext=0
10805         local starts=()
10806         local ends=()
10807
10808         while read extidx a b start end rest; do
10809                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10810                         nr_ext=$(( $nr_ext + 1 ))
10811                         starts+=( ${start%..} )
10812                         ends+=( ${end%:} )
10813                 fi
10814         done < <( filefrag -sv $1 )
10815
10816         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10817         return 1
10818 }
10819
10820 test_77n() {
10821         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10822
10823         touch $DIR/$tfile
10824         $TRUNCATE $DIR/$tfile 0
10825         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10826         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10827         check_filefrag_77n $DIR/$tfile ||
10828                 skip "$tfile blocks not contiguous around hole"
10829
10830         set_checksums 1
10831         stack_trap "set_checksums $ORIG_CSUM" EXIT
10832         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10833         stack_trap "rm -f $DIR/$tfile"
10834
10835         for algo in $CKSUM_TYPES; do
10836                 if [[ "$algo" =~ ^t10 ]]; then
10837                         set_checksum_type $algo ||
10838                                 error "fail to set checksum type $algo"
10839                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10840                                 error "fail to read $tfile with $algo"
10841                 fi
10842         done
10843         rm -f $DIR/$tfile
10844         return 0
10845 }
10846 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10847
10848 test_77o() {
10849         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10850                 skip "Need MDS version at least 2.14.55"
10851         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10852                 skip "Need OST version at least 2.14.55"
10853         local ofd=obdfilter
10854         local mdt=mdt
10855
10856         # print OST checksum_type
10857         echo "$ofd.$FSNAME-*.checksum_type:"
10858         do_nodes $(comma_list $(osts_nodes)) \
10859                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10860
10861         # print MDT checksum_type
10862         echo "$mdt.$FSNAME-*.checksum_type:"
10863         do_nodes $(comma_list $(mdts_nodes)) \
10864                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10865
10866         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10867                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10868
10869         (( $o_count == $OSTCOUNT )) ||
10870                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10871
10872         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10873                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10874
10875         (( $m_count == $MDSCOUNT )) ||
10876                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10877 }
10878 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10879
10880 cleanup_test_78() {
10881         trap 0
10882         rm -f $DIR/$tfile
10883 }
10884
10885 test_78() { # bug 10901
10886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10887         remote_ost || skip_env "local OST"
10888
10889         NSEQ=5
10890         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10891         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10892         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10893         echo "MemTotal: $MEMTOTAL"
10894
10895         # reserve 256MB of memory for the kernel and other running processes,
10896         # and then take 1/2 of the remaining memory for the read/write buffers.
10897         if [ $MEMTOTAL -gt 512 ] ;then
10898                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10899         else
10900                 # for those poor memory-starved high-end clusters...
10901                 MEMTOTAL=$((MEMTOTAL / 2))
10902         fi
10903         echo "Mem to use for directio: $MEMTOTAL"
10904
10905         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10906         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10907         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10908         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10909                 head -n1)
10910         echo "Smallest OST: $SMALLESTOST"
10911         [[ $SMALLESTOST -lt 10240 ]] &&
10912                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10913
10914         trap cleanup_test_78 EXIT
10915
10916         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10917                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10918
10919         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10920         echo "File size: $F78SIZE"
10921         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10922         for i in $(seq 1 $NSEQ); do
10923                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10924                 echo directIO rdwr round $i of $NSEQ
10925                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10926         done
10927
10928         cleanup_test_78
10929 }
10930 run_test 78 "handle large O_DIRECT writes correctly ============"
10931
10932 test_79() { # bug 12743
10933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10934
10935         wait_delete_completed
10936
10937         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10938         BKFREE=$(calc_osc_kbytes kbytesfree)
10939         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10940
10941         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10942         DFTOTAL=`echo $STRING | cut -d, -f1`
10943         DFUSED=`echo $STRING  | cut -d, -f2`
10944         DFAVAIL=`echo $STRING | cut -d, -f3`
10945         DFFREE=$(($DFTOTAL - $DFUSED))
10946
10947         ALLOWANCE=$((64 * $OSTCOUNT))
10948
10949         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10950            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10951                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10952         fi
10953         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10954            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10955                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10956         fi
10957         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10958            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10959                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10960         fi
10961 }
10962 run_test 79 "df report consistency check ======================="
10963
10964 test_80() { # bug 10718
10965         remote_ost_nodsh && skip "remote OST with nodsh"
10966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10967
10968         # relax strong synchronous semantics for slow backends like ZFS
10969         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10970                 local soc="obdfilter.*.sync_lock_cancel"
10971                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10972
10973                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10974                 if [ -z "$save" ]; then
10975                         soc="obdfilter.*.sync_on_lock_cancel"
10976                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10977                 fi
10978
10979                 if [ "$save" != "never" ]; then
10980                         local hosts=$(comma_list $(osts_nodes))
10981
10982                         do_nodes $hosts $LCTL set_param $soc=never
10983                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10984                 fi
10985         fi
10986
10987         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10988         sync; sleep 1; sync
10989         local before=$(date +%s)
10990         cancel_lru_locks osc
10991         local after=$(date +%s)
10992         local diff=$((after - before))
10993         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10994
10995         rm -f $DIR/$tfile
10996 }
10997 run_test 80 "Page eviction is equally fast at high offsets too"
10998
10999 test_81a() { # LU-456
11000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11001         remote_ost_nodsh && skip "remote OST with nodsh"
11002
11003         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11004         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11005         do_facet ost1 lctl set_param fail_loc=0x80000228
11006
11007         # write should trigger a retry and success
11008         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11009         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11010         RC=$?
11011         if [ $RC -ne 0 ] ; then
11012                 error "write should success, but failed for $RC"
11013         fi
11014 }
11015 run_test 81a "OST should retry write when get -ENOSPC ==============="
11016
11017 test_81b() { # LU-456
11018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11019         remote_ost_nodsh && skip "remote OST with nodsh"
11020
11021         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11022         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11023         do_facet ost1 lctl set_param fail_loc=0x228
11024
11025         # write should retry several times and return -ENOSPC finally
11026         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11027         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11028         RC=$?
11029         ENOSPC=28
11030         if [ $RC -ne $ENOSPC ] ; then
11031                 error "dd should fail for -ENOSPC, but succeed."
11032         fi
11033 }
11034 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11035
11036 test_99() {
11037         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11038
11039         test_mkdir $DIR/$tdir.cvsroot
11040         chown $RUNAS_ID $DIR/$tdir.cvsroot
11041
11042         cd $TMP
11043         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11044
11045         cd /etc/init.d
11046         # some versions of cvs import exit(1) when asked to import links or
11047         # files they can't read.  ignore those files.
11048         local toignore=$(find . -type l -printf '-I %f\n' -o \
11049                          ! -perm /4 -printf '-I %f\n')
11050         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11051                 $tdir.reposname vtag rtag
11052
11053         cd $DIR
11054         test_mkdir $DIR/$tdir.reposname
11055         chown $RUNAS_ID $DIR/$tdir.reposname
11056         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11057
11058         cd $DIR/$tdir.reposname
11059         $RUNAS touch foo99
11060         $RUNAS cvs add -m 'addmsg' foo99
11061         $RUNAS cvs update
11062         $RUNAS cvs commit -m 'nomsg' foo99
11063         rm -fr $DIR/$tdir.cvsroot
11064 }
11065 run_test 99 "cvs strange file/directory operations"
11066
11067 test_100() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069         [[ "$NETTYPE" =~ tcp ]] ||
11070                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11071         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11072         remote_ost_nodsh && skip "remote OST with nodsh"
11073         remote_mds_nodsh && skip "remote MDS with nodsh"
11074         remote_servers || skip "useless for local single node setup"
11075
11076         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11077                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11078
11079                 rc=0
11080                 if (( ${LOCAL/*:/} >= 1024 )); then
11081                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11082                         ss -tna
11083                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11084                 fi
11085         done
11086         (( $rc == 0 )) || error "privileged port not found" )
11087 }
11088 run_test 100 "check local port using privileged port"
11089
11090 function get_named_value()
11091 {
11092     local tag=$1
11093
11094     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11095 }
11096
11097 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11098                    awk '/^max_cached_mb/ { print $2 }')
11099
11100 cleanup_101a() {
11101         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11102         trap 0
11103 }
11104
11105 test_101a() {
11106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11107
11108         local s
11109         local discard
11110         local nreads=10000
11111         local cache_limit=32
11112
11113         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11114         trap cleanup_101a EXIT
11115         $LCTL set_param -n llite.*.read_ahead_stats=0
11116         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11117
11118         #
11119         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11120         #
11121         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11122         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11123
11124         discard=0
11125         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11126                    get_named_value 'read.but.discarded'); do
11127                         discard=$(($discard + $s))
11128         done
11129         cleanup_101a
11130
11131         $LCTL get_param osc.*-osc*.rpc_stats
11132         $LCTL get_param llite.*.read_ahead_stats
11133
11134         # Discard is generally zero, but sometimes a few random reads line up
11135         # and trigger larger readahead, which is wasted & leads to discards.
11136         if [[ $(($discard)) -gt $nreads ]]; then
11137                 error "too many ($discard) discarded pages"
11138         fi
11139         rm -f $DIR/$tfile || true
11140 }
11141 run_test 101a "check read-ahead for random reads"
11142
11143 setup_test101bc() {
11144         test_mkdir $DIR/$tdir
11145         local ssize=$1
11146         local FILE_LENGTH=$2
11147         STRIPE_OFFSET=0
11148
11149         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11150
11151         local list=$(comma_list $(osts_nodes))
11152         set_osd_param $list '' read_cache_enable 0
11153         set_osd_param $list '' writethrough_cache_enable 0
11154
11155         trap cleanup_test101bc EXIT
11156         # prepare the read-ahead file
11157         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11158
11159         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11160                                 count=$FILE_SIZE_MB 2> /dev/null
11161
11162 }
11163
11164 cleanup_test101bc() {
11165         trap 0
11166         rm -rf $DIR/$tdir
11167         rm -f $DIR/$tfile
11168
11169         local list=$(comma_list $(osts_nodes))
11170         set_osd_param $list '' read_cache_enable 1
11171         set_osd_param $list '' writethrough_cache_enable 1
11172 }
11173
11174 calc_total() {
11175         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11176 }
11177
11178 ra_check_101() {
11179         local read_size=$1
11180         local stripe_size=$2
11181         local stride_length=$((stripe_size / read_size))
11182         local stride_width=$((stride_length * OSTCOUNT))
11183         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11184                                 (stride_width - stride_length) ))
11185         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11186                   get_named_value 'read.but.discarded' | calc_total)
11187
11188         if [[ $discard -gt $discard_limit ]]; then
11189                 $LCTL get_param llite.*.read_ahead_stats
11190                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11191         else
11192                 echo "Read-ahead success for size ${read_size}"
11193         fi
11194 }
11195
11196 test_101b() {
11197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11198         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11199
11200         local STRIPE_SIZE=1048576
11201         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11202
11203         if [ $SLOW == "yes" ]; then
11204                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11205         else
11206                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11207         fi
11208
11209         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11210
11211         # prepare the read-ahead file
11212         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11213         cancel_lru_locks osc
11214         for BIDX in 2 4 8 16 32 64 128 256
11215         do
11216                 local BSIZE=$((BIDX*4096))
11217                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11218                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11219                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11220                 $LCTL set_param -n llite.*.read_ahead_stats=0
11221                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11222                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11223                 cancel_lru_locks osc
11224                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11225         done
11226         cleanup_test101bc
11227         true
11228 }
11229 run_test 101b "check stride-io mode read-ahead ================="
11230
11231 test_101c() {
11232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11233
11234         local STRIPE_SIZE=1048576
11235         local FILE_LENGTH=$((STRIPE_SIZE*100))
11236         local nreads=10000
11237         local rsize=65536
11238         local osc_rpc_stats
11239
11240         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11241
11242         cancel_lru_locks osc
11243         $LCTL set_param osc.*.rpc_stats=0
11244         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11245         $LCTL get_param osc.*.rpc_stats
11246         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11247                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11248                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11249                 local size
11250
11251                 if [ $lines -le 20 ]; then
11252                         echo "continue debug"
11253                         continue
11254                 fi
11255                 for size in 1 2 4 8; do
11256                         local rpc=$(echo "$stats" |
11257                                     awk '($1 == "'$size':") {print $2; exit; }')
11258                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11259                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11260                 done
11261                 echo "$osc_rpc_stats check passed!"
11262         done
11263         cleanup_test101bc
11264         true
11265 }
11266 run_test 101c "check stripe_size aligned read-ahead"
11267
11268 test_101d() {
11269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11270
11271         local file=$DIR/$tfile
11272         local sz_MB=${FILESIZE_101d:-80}
11273         local ra_MB=${READAHEAD_MB:-40}
11274
11275         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11276         [ $free_MB -lt $sz_MB ] &&
11277                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11278
11279         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11280         $LFS setstripe -c -1 $file || error "setstripe failed"
11281
11282         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11283         echo Cancel LRU locks on lustre client to flush the client cache
11284         cancel_lru_locks osc
11285
11286         echo Disable read-ahead
11287         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11288         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11289         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11290         $LCTL get_param -n llite.*.max_read_ahead_mb
11291
11292         echo "Reading the test file $file with read-ahead disabled"
11293         local sz_KB=$((sz_MB * 1024 / 4))
11294         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11295         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11296         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11297                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11298
11299         echo "Cancel LRU locks on lustre client to flush the client cache"
11300         cancel_lru_locks osc
11301         echo Enable read-ahead with ${ra_MB}MB
11302         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11303
11304         echo "Reading the test file $file with read-ahead enabled"
11305         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11306                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11307
11308         echo "read-ahead disabled time read $raOFF"
11309         echo "read-ahead enabled time read $raON"
11310
11311         rm -f $file
11312         wait_delete_completed
11313
11314         # use awk for this check instead of bash because it handles decimals
11315         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11316                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11317 }
11318 run_test 101d "file read with and without read-ahead enabled"
11319
11320 test_101e() {
11321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11322
11323         local file=$DIR/$tfile
11324         local size_KB=500  #KB
11325         local count=100
11326         local bsize=1024
11327
11328         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11329         local need_KB=$((count * size_KB))
11330         [[ $free_KB -le $need_KB ]] &&
11331                 skip_env "Need free space $need_KB, have $free_KB"
11332
11333         echo "Creating $count ${size_KB}K test files"
11334         for ((i = 0; i < $count; i++)); do
11335                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11336         done
11337
11338         echo "Cancel LRU locks on lustre client to flush the client cache"
11339         cancel_lru_locks $OSC
11340
11341         echo "Reset readahead stats"
11342         $LCTL set_param -n llite.*.read_ahead_stats=0
11343
11344         for ((i = 0; i < $count; i++)); do
11345                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11346         done
11347
11348         $LCTL get_param llite.*.max_cached_mb
11349         $LCTL get_param llite.*.read_ahead_stats
11350         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11351                      get_named_value 'misses' | calc_total)
11352
11353         for ((i = 0; i < $count; i++)); do
11354                 rm -rf $file.$i 2>/dev/null
11355         done
11356
11357         #10000 means 20% reads are missing in readahead
11358         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11359 }
11360 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11361
11362 test_101f() {
11363         which iozone || skip_env "no iozone installed"
11364
11365         local old_debug=$($LCTL get_param debug)
11366         old_debug=${old_debug#*=}
11367         $LCTL set_param debug="reada mmap"
11368
11369         # create a test file
11370         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11371
11372         echo Cancel LRU locks on lustre client to flush the client cache
11373         cancel_lru_locks osc
11374
11375         echo Reset readahead stats
11376         $LCTL set_param -n llite.*.read_ahead_stats=0
11377
11378         echo mmap read the file with small block size
11379         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11380                 > /dev/null 2>&1
11381
11382         echo checking missing pages
11383         $LCTL get_param llite.*.read_ahead_stats
11384         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11385                         get_named_value 'misses' | calc_total)
11386
11387         $LCTL set_param debug="$old_debug"
11388         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11389         rm -f $DIR/$tfile
11390 }
11391 run_test 101f "check mmap read performance"
11392
11393 test_101g_brw_size_test() {
11394         local mb=$1
11395         local pages=$((mb * 1048576 / PAGE_SIZE))
11396         local file=$DIR/$tfile
11397
11398         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11399                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11400         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11401                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11402                         return 2
11403         done
11404
11405         stack_trap "rm -f $file" EXIT
11406         $LCTL set_param -n osc.*.rpc_stats=0
11407
11408         # 10 RPCs should be enough for the test
11409         local count=10
11410         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11411                 { error "dd write ${mb} MB blocks failed"; return 3; }
11412         cancel_lru_locks osc
11413         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11414                 { error "dd write ${mb} MB blocks failed"; return 4; }
11415
11416         # calculate number of full-sized read and write RPCs
11417         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11418                 sed -n '/pages per rpc/,/^$/p' |
11419                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11420                 END { print reads,writes }'))
11421         # allow one extra full-sized read RPC for async readahead
11422         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11423                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11424         [[ ${rpcs[1]} == $count ]] ||
11425                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11426 }
11427
11428 test_101g() {
11429         remote_ost_nodsh && skip "remote OST with nodsh"
11430
11431         local rpcs
11432         local osts=$(get_facets OST)
11433         local list=$(comma_list $(osts_nodes))
11434         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11435         local brw_size="obdfilter.*.brw_size"
11436
11437         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11438
11439         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11440
11441         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11442                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11443                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11444            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11445                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11446                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11447
11448                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11449                         suffix="M"
11450
11451                 if [[ $orig_mb -lt 16 ]]; then
11452                         save_lustre_params $osts "$brw_size" > $p
11453                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11454                                 error "set 16MB RPC size failed"
11455
11456                         echo "remount client to enable new RPC size"
11457                         remount_client $MOUNT || error "remount_client failed"
11458                 fi
11459
11460                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11461                 # should be able to set brw_size=12, but no rpc_stats for that
11462                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11463         fi
11464
11465         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11466
11467         if [[ $orig_mb -lt 16 ]]; then
11468                 restore_lustre_params < $p
11469                 remount_client $MOUNT || error "remount_client restore failed"
11470         fi
11471
11472         rm -f $p $DIR/$tfile
11473 }
11474 run_test 101g "Big bulk(4/16 MiB) readahead"
11475
11476 test_101h() {
11477         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11478
11479         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11480                 error "dd 70M file failed"
11481         echo Cancel LRU locks on lustre client to flush the client cache
11482         cancel_lru_locks osc
11483
11484         echo "Reset readahead stats"
11485         $LCTL set_param -n llite.*.read_ahead_stats 0
11486
11487         echo "Read 10M of data but cross 64M bundary"
11488         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11489         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11490                      get_named_value 'misses' | calc_total)
11491         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11492         rm -f $p $DIR/$tfile
11493 }
11494 run_test 101h "Readahead should cover current read window"
11495
11496 test_101i() {
11497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11498                 error "dd 10M file failed"
11499
11500         local max_per_file_mb=$($LCTL get_param -n \
11501                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11502         cancel_lru_locks osc
11503         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11504         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11505                 error "set max_read_ahead_per_file_mb to 1 failed"
11506
11507         echo "Reset readahead stats"
11508         $LCTL set_param llite.*.read_ahead_stats=0
11509
11510         dd if=$DIR/$tfile of=/dev/null bs=2M
11511
11512         $LCTL get_param llite.*.read_ahead_stats
11513         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11514                      awk '/misses/ { print $2 }')
11515         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11516         rm -f $DIR/$tfile
11517 }
11518 run_test 101i "allow current readahead to exceed reservation"
11519
11520 test_101j() {
11521         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11522                 error "setstripe $DIR/$tfile failed"
11523         local file_size=$((1048576 * 16))
11524         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11525         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11526
11527         echo Disable read-ahead
11528         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11529
11530         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11531         for blk in $PAGE_SIZE 1048576 $file_size; do
11532                 cancel_lru_locks osc
11533                 echo "Reset readahead stats"
11534                 $LCTL set_param -n llite.*.read_ahead_stats=0
11535                 local count=$(($file_size / $blk))
11536                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11537                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11538                              get_named_value 'failed.to.fast.read' | calc_total)
11539                 $LCTL get_param -n llite.*.read_ahead_stats
11540                 [ $miss -eq $count ] || error "expected $count got $miss"
11541         done
11542
11543         rm -f $p $DIR/$tfile
11544 }
11545 run_test 101j "A complete read block should be submitted when no RA"
11546
11547 test_readahead_base() {
11548         local file=$DIR/$tfile
11549         local size=$1
11550         local iosz
11551         local ramax
11552         local ranum
11553
11554         $LCTL set_param -n llite.*.read_ahead_stats=0
11555         # The first page is not accounted into readahead
11556         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11557         iosz=$(((size + 1048575) / 1048576 * 1048576))
11558         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11559
11560         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11561         fallocate -l $size $file || error "failed to fallocate $file"
11562         cancel_lru_locks osc
11563         $MULTIOP $file or${iosz}c || error "failed to read $file"
11564         $LCTL get_param -n llite.*.read_ahead_stats
11565         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11566                 awk '/readahead.pages/ { print $7 }' | calc_total)
11567         (( $ranum <= $ramax )) ||
11568                 error "read-ahead pages is $ranum more than $ramax"
11569         rm -rf $file || error "failed to remove $file"
11570 }
11571
11572 test_101m()
11573 {
11574         local file=$DIR/$tfile
11575         local ramax
11576         local ranum
11577         local size
11578         local iosz
11579
11580         check_set_fallocate_or_skip
11581         stack_trap "rm -f $file" EXIT
11582
11583         test_readahead_base 4096
11584
11585         # file size: 16K = 16384
11586         test_readahead_base 16384
11587         test_readahead_base 16385
11588         test_readahead_base 16383
11589
11590         # file size: 1M + 1 = 1048576 + 1
11591         test_readahead_base 1048577
11592         # file size: 1M + 16K
11593         test_readahead_base $((1048576 + 16384))
11594
11595         # file size: stripe_size * (stripe_count - 1) + 16K
11596         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11597         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11598         # file size: stripe_size * stripe_count + 16K
11599         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11600         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11601         # file size: 2 * stripe_size * stripe_count + 16K
11602         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11603         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11604 }
11605 run_test 101m "read ahead for small file and last stripe of the file"
11606
11607 setup_test102() {
11608         test_mkdir $DIR/$tdir
11609         chown $RUNAS_ID $DIR/$tdir
11610         STRIPE_SIZE=65536
11611         STRIPE_OFFSET=1
11612         STRIPE_COUNT=$OSTCOUNT
11613         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11614
11615         trap cleanup_test102 EXIT
11616         cd $DIR
11617         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11618         cd $DIR/$tdir
11619         for num in 1 2 3 4; do
11620                 for count in $(seq 1 $STRIPE_COUNT); do
11621                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11622                                 local size=`expr $STRIPE_SIZE \* $num`
11623                                 local file=file"$num-$idx-$count"
11624                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11625                         done
11626                 done
11627         done
11628
11629         cd $DIR
11630         $1 tar cf $TMP/f102.tar $tdir --xattrs
11631 }
11632
11633 cleanup_test102() {
11634         trap 0
11635         rm -f $TMP/f102.tar
11636         rm -rf $DIR/d0.sanity/d102
11637 }
11638
11639 test_102a() {
11640         [ "$UID" != 0 ] && skip "must run as root"
11641         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11642                 skip_env "must have user_xattr"
11643
11644         [ -z "$(which setfattr 2>/dev/null)" ] &&
11645                 skip_env "could not find setfattr"
11646
11647         local testfile=$DIR/$tfile
11648
11649         touch $testfile
11650         echo "set/get xattr..."
11651         setfattr -n trusted.name1 -v value1 $testfile ||
11652                 error "setfattr -n trusted.name1=value1 $testfile failed"
11653         getfattr -n trusted.name1 $testfile 2> /dev/null |
11654           grep "trusted.name1=.value1" ||
11655                 error "$testfile missing trusted.name1=value1"
11656
11657         setfattr -n user.author1 -v author1 $testfile ||
11658                 error "setfattr -n user.author1=author1 $testfile failed"
11659         getfattr -n user.author1 $testfile 2> /dev/null |
11660           grep "user.author1=.author1" ||
11661                 error "$testfile missing trusted.author1=author1"
11662
11663         echo "listxattr..."
11664         setfattr -n trusted.name2 -v value2 $testfile ||
11665                 error "$testfile unable to set trusted.name2"
11666         setfattr -n trusted.name3 -v value3 $testfile ||
11667                 error "$testfile unable to set trusted.name3"
11668         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11669             grep "trusted.name" | wc -l) -eq 3 ] ||
11670                 error "$testfile missing 3 trusted.name xattrs"
11671
11672         setfattr -n user.author2 -v author2 $testfile ||
11673                 error "$testfile unable to set user.author2"
11674         setfattr -n user.author3 -v author3 $testfile ||
11675                 error "$testfile unable to set user.author3"
11676         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11677             grep "user.author" | wc -l) -eq 3 ] ||
11678                 error "$testfile missing 3 user.author xattrs"
11679
11680         echo "remove xattr..."
11681         setfattr -x trusted.name1 $testfile ||
11682                 error "$testfile error deleting trusted.name1"
11683         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11684                 error "$testfile did not delete trusted.name1 xattr"
11685
11686         setfattr -x user.author1 $testfile ||
11687                 error "$testfile error deleting user.author1"
11688         echo "set lustre special xattr ..."
11689         $LFS setstripe -c1 $testfile
11690         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11691                 awk -F "=" '/trusted.lov/ { print $2 }' )
11692         setfattr -n "trusted.lov" -v $lovea $testfile ||
11693                 error "$testfile doesn't ignore setting trusted.lov again"
11694         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11695                 error "$testfile allow setting invalid trusted.lov"
11696         rm -f $testfile
11697 }
11698 run_test 102a "user xattr test =================================="
11699
11700 check_102b_layout() {
11701         local layout="$*"
11702         local testfile=$DIR/$tfile
11703
11704         echo "test layout '$layout'"
11705         $LFS setstripe $layout $testfile || error "setstripe failed"
11706         $LFS getstripe -y $testfile
11707
11708         echo "get/set/list trusted.lov xattr ..." # b=10930
11709         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11710         [[ "$value" =~ "trusted.lov" ]] ||
11711                 error "can't get trusted.lov from $testfile"
11712         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11713                 error "getstripe failed"
11714
11715         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11716
11717         value=$(cut -d= -f2 <<<$value)
11718         # LU-13168: truncated xattr should fail if short lov_user_md header
11719         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11720                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11721         for len in $lens; do
11722                 echo "setfattr $len $testfile.2"
11723                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11724                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11725         done
11726         local stripe_size=$($LFS getstripe -S $testfile.2)
11727         local stripe_count=$($LFS getstripe -c $testfile.2)
11728         [[ $stripe_size -eq 65536 ]] ||
11729                 error "stripe size $stripe_size != 65536"
11730         [[ $stripe_count -eq $stripe_count_orig ]] ||
11731                 error "stripe count $stripe_count != $stripe_count_orig"
11732         rm $testfile $testfile.2
11733 }
11734
11735 test_102b() {
11736         [ -z "$(which setfattr 2>/dev/null)" ] &&
11737                 skip_env "could not find setfattr"
11738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11739
11740         # check plain layout
11741         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11742
11743         # and also check composite layout
11744         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11745
11746 }
11747 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11748
11749 test_102c() {
11750         [ -z "$(which setfattr 2>/dev/null)" ] &&
11751                 skip_env "could not find setfattr"
11752         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11753
11754         # b10930: get/set/list lustre.lov xattr
11755         echo "get/set/list lustre.lov xattr ..."
11756         test_mkdir $DIR/$tdir
11757         chown $RUNAS_ID $DIR/$tdir
11758         local testfile=$DIR/$tdir/$tfile
11759         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11760                 error "setstripe failed"
11761         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11762                 error "getstripe failed"
11763         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11764         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11765
11766         local testfile2=${testfile}2
11767         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11768                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11769
11770         $RUNAS $MCREATE $testfile2
11771         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11772         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11773         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11774         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11775         [ $stripe_count -eq $STRIPECOUNT ] ||
11776                 error "stripe count $stripe_count != $STRIPECOUNT"
11777 }
11778 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11779
11780 compare_stripe_info1() {
11781         local stripe_index_all_zero=true
11782
11783         for num in 1 2 3 4; do
11784                 for count in $(seq 1 $STRIPE_COUNT); do
11785                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11786                                 local size=$((STRIPE_SIZE * num))
11787                                 local file=file"$num-$offset-$count"
11788                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11789                                 [[ $stripe_size -ne $size ]] &&
11790                                     error "$file: size $stripe_size != $size"
11791                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11792                                 # allow fewer stripes to be created, ORI-601
11793                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11794                                     error "$file: count $stripe_count != $count"
11795                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11796                                 [[ $stripe_index -ne 0 ]] &&
11797                                         stripe_index_all_zero=false
11798                         done
11799                 done
11800         done
11801         $stripe_index_all_zero &&
11802                 error "all files are being extracted starting from OST index 0"
11803         return 0
11804 }
11805
11806 have_xattrs_include() {
11807         tar --help | grep -q xattrs-include &&
11808                 echo --xattrs-include="lustre.*"
11809 }
11810
11811 test_102d() {
11812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11813         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11814
11815         XINC=$(have_xattrs_include)
11816         setup_test102
11817         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11818         cd $DIR/$tdir/$tdir
11819         compare_stripe_info1
11820 }
11821 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11822
11823 test_102f() {
11824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11825         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11826
11827         XINC=$(have_xattrs_include)
11828         setup_test102
11829         test_mkdir $DIR/$tdir.restore
11830         cd $DIR
11831         tar cf - --xattrs $tdir | tar xf - \
11832                 -C $DIR/$tdir.restore --xattrs $XINC
11833         cd $DIR/$tdir.restore/$tdir
11834         compare_stripe_info1
11835 }
11836 run_test 102f "tar copy files, not keep osts"
11837
11838 grow_xattr() {
11839         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11840                 skip "must have user_xattr"
11841         [ -z "$(which setfattr 2>/dev/null)" ] &&
11842                 skip_env "could not find setfattr"
11843         [ -z "$(which getfattr 2>/dev/null)" ] &&
11844                 skip_env "could not find getfattr"
11845
11846         local xsize=${1:-1024}  # in bytes
11847         local file=$DIR/$tfile
11848         local value="$(generate_string $xsize)"
11849         local xbig=trusted.big
11850         local toobig=$2
11851
11852         touch $file
11853         log "save $xbig on $file"
11854         if [ -z "$toobig" ]
11855         then
11856                 setfattr -n $xbig -v $value $file ||
11857                         error "saving $xbig on $file failed"
11858         else
11859                 setfattr -n $xbig -v $value $file &&
11860                         error "saving $xbig on $file succeeded"
11861                 return 0
11862         fi
11863
11864         local orig=$(get_xattr_value $xbig $file)
11865         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11866
11867         local xsml=trusted.sml
11868         log "save $xsml on $file"
11869         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11870
11871         local new=$(get_xattr_value $xbig $file)
11872         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11873
11874         log "grow $xsml on $file"
11875         setfattr -n $xsml -v "$value" $file ||
11876                 error "growing $xsml on $file failed"
11877
11878         new=$(get_xattr_value $xbig $file)
11879         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11880         log "$xbig still valid after growing $xsml"
11881
11882         rm -f $file
11883 }
11884
11885 test_102h() { # bug 15777
11886         grow_xattr 1024
11887 }
11888 run_test 102h "grow xattr from inside inode to external block"
11889
11890 test_102ha() {
11891         large_xattr_enabled || skip_env "ea_inode feature disabled"
11892
11893         echo "setting xattr of max xattr size: $(max_xattr_size)"
11894         grow_xattr $(max_xattr_size)
11895
11896         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11897         echo "This should fail:"
11898         grow_xattr $(($(max_xattr_size) + 10)) 1
11899 }
11900 run_test 102ha "grow xattr from inside inode to external inode"
11901
11902 test_102i() { # bug 17038
11903         [ -z "$(which getfattr 2>/dev/null)" ] &&
11904                 skip "could not find getfattr"
11905
11906         touch $DIR/$tfile
11907         ln -s $DIR/$tfile $DIR/${tfile}link
11908         getfattr -n trusted.lov $DIR/$tfile ||
11909                 error "lgetxattr on $DIR/$tfile failed"
11910         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11911                 grep -i "no such attr" ||
11912                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11913         rm -f $DIR/$tfile $DIR/${tfile}link
11914 }
11915 run_test 102i "lgetxattr test on symbolic link ============"
11916
11917 test_102j() {
11918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11919         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11920
11921         XINC=$(have_xattrs_include)
11922         setup_test102 "$RUNAS"
11923         chown $RUNAS_ID $DIR/$tdir
11924         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11925         cd $DIR/$tdir/$tdir
11926         compare_stripe_info1 "$RUNAS"
11927 }
11928 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11929
11930 test_102k() {
11931         [ -z "$(which setfattr 2>/dev/null)" ] &&
11932                 skip "could not find setfattr"
11933
11934         touch $DIR/$tfile
11935         # b22187 just check that does not crash for regular file.
11936         setfattr -n trusted.lov $DIR/$tfile
11937         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11938         local test_kdir=$DIR/$tdir
11939         test_mkdir $test_kdir
11940         local default_size=$($LFS getstripe -S $test_kdir)
11941         local default_count=$($LFS getstripe -c $test_kdir)
11942         local default_offset=$($LFS getstripe -i $test_kdir)
11943         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11944                 error 'dir setstripe failed'
11945         setfattr -n trusted.lov $test_kdir
11946         local stripe_size=$($LFS getstripe -S $test_kdir)
11947         local stripe_count=$($LFS getstripe -c $test_kdir)
11948         local stripe_offset=$($LFS getstripe -i $test_kdir)
11949         [ $stripe_size -eq $default_size ] ||
11950                 error "stripe size $stripe_size != $default_size"
11951         [ $stripe_count -eq $default_count ] ||
11952                 error "stripe count $stripe_count != $default_count"
11953         [ $stripe_offset -eq $default_offset ] ||
11954                 error "stripe offset $stripe_offset != $default_offset"
11955         rm -rf $DIR/$tfile $test_kdir
11956 }
11957 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11958
11959 test_102l() {
11960         [ -z "$(which getfattr 2>/dev/null)" ] &&
11961                 skip "could not find getfattr"
11962
11963         # LU-532 trusted. xattr is invisible to non-root
11964         local testfile=$DIR/$tfile
11965
11966         touch $testfile
11967
11968         echo "listxattr as user..."
11969         chown $RUNAS_ID $testfile
11970         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11971             grep -q "trusted" &&
11972                 error "$testfile trusted xattrs are user visible"
11973
11974         return 0;
11975 }
11976 run_test 102l "listxattr size test =================================="
11977
11978 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11979         local path=$DIR/$tfile
11980         touch $path
11981
11982         listxattr_size_check $path || error "listattr_size_check $path failed"
11983 }
11984 run_test 102m "Ensure listxattr fails on small bufffer ========"
11985
11986 cleanup_test102
11987
11988 getxattr() { # getxattr path name
11989         # Return the base64 encoding of the value of xattr name on path.
11990         local path=$1
11991         local name=$2
11992
11993         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11994         # file: $path
11995         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11996         #
11997         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11998
11999         getfattr --absolute-names --encoding=base64 --name=$name $path |
12000                 awk -F= -v name=$name '$1 == name {
12001                         print substr($0, index($0, "=") + 1);
12002         }'
12003 }
12004
12005 test_102n() { # LU-4101 mdt: protect internal xattrs
12006         [ -z "$(which setfattr 2>/dev/null)" ] &&
12007                 skip "could not find setfattr"
12008         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12009         then
12010                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12011         fi
12012
12013         local file0=$DIR/$tfile.0
12014         local file1=$DIR/$tfile.1
12015         local xattr0=$TMP/$tfile.0
12016         local xattr1=$TMP/$tfile.1
12017         local namelist="lov lma lmv link fid version som hsm"
12018         local name
12019         local value
12020
12021         rm -rf $file0 $file1 $xattr0 $xattr1
12022         touch $file0 $file1
12023
12024         # Get 'before' xattrs of $file1.
12025         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12026
12027         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12028                 namelist+=" lfsck_namespace"
12029         for name in $namelist; do
12030                 # Try to copy xattr from $file0 to $file1.
12031                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12032
12033                 setfattr --name=trusted.$name --value="$value" $file1 ||
12034                         error "setxattr 'trusted.$name' failed"
12035
12036                 # Try to set a garbage xattr.
12037                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12038
12039                 if [[ x$name == "xlov" ]]; then
12040                         setfattr --name=trusted.lov --value="$value" $file1 &&
12041                         error "setxattr invalid 'trusted.lov' success"
12042                 else
12043                         setfattr --name=trusted.$name --value="$value" $file1 ||
12044                                 error "setxattr invalid 'trusted.$name' failed"
12045                 fi
12046
12047                 # Try to remove the xattr from $file1. We don't care if this
12048                 # appears to succeed or fail, we just don't want there to be
12049                 # any changes or crashes.
12050                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12051         done
12052
12053         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12054         then
12055                 name="lfsck_ns"
12056                 # Try to copy xattr from $file0 to $file1.
12057                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12058
12059                 setfattr --name=trusted.$name --value="$value" $file1 ||
12060                         error "setxattr 'trusted.$name' failed"
12061
12062                 # Try to set a garbage xattr.
12063                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12064
12065                 setfattr --name=trusted.$name --value="$value" $file1 ||
12066                         error "setxattr 'trusted.$name' failed"
12067
12068                 # Try to remove the xattr from $file1. We don't care if this
12069                 # appears to succeed or fail, we just don't want there to be
12070                 # any changes or crashes.
12071                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12072         fi
12073
12074         # Get 'after' xattrs of file1.
12075         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12076
12077         if ! diff $xattr0 $xattr1; then
12078                 error "before and after xattrs of '$file1' differ"
12079         fi
12080
12081         rm -rf $file0 $file1 $xattr0 $xattr1
12082
12083         return 0
12084 }
12085 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12086
12087 test_102p() { # LU-4703 setxattr did not check ownership
12088         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12089                 skip "MDS needs to be at least 2.5.56"
12090
12091         local testfile=$DIR/$tfile
12092
12093         touch $testfile
12094
12095         echo "setfacl as user..."
12096         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12097         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12098
12099         echo "setfattr as user..."
12100         setfacl -m "u:$RUNAS_ID:---" $testfile
12101         $RUNAS setfattr -x system.posix_acl_access $testfile
12102         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12103 }
12104 run_test 102p "check setxattr(2) correctly fails without permission"
12105
12106 test_102q() {
12107         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12108                 skip "MDS needs to be at least 2.6.92"
12109
12110         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12111 }
12112 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12113
12114 test_102r() {
12115         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12116                 skip "MDS needs to be at least 2.6.93"
12117
12118         touch $DIR/$tfile || error "touch"
12119         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12120         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12121         rm $DIR/$tfile || error "rm"
12122
12123         #normal directory
12124         mkdir -p $DIR/$tdir || error "mkdir"
12125         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12126         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12127         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12128                 error "$testfile error deleting user.author1"
12129         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12130                 grep "user.$(basename $tdir)" &&
12131                 error "$tdir did not delete user.$(basename $tdir)"
12132         rmdir $DIR/$tdir || error "rmdir"
12133
12134         #striped directory
12135         test_mkdir $DIR/$tdir
12136         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12137         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12138         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12139                 error "$testfile error deleting user.author1"
12140         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12141                 grep "user.$(basename $tdir)" &&
12142                 error "$tdir did not delete user.$(basename $tdir)"
12143         rmdir $DIR/$tdir || error "rm striped dir"
12144 }
12145 run_test 102r "set EAs with empty values"
12146
12147 test_102s() {
12148         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12149                 skip "MDS needs to be at least 2.11.52"
12150
12151         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12152
12153         save_lustre_params client "llite.*.xattr_cache" > $save
12154
12155         for cache in 0 1; do
12156                 lctl set_param llite.*.xattr_cache=$cache
12157
12158                 rm -f $DIR/$tfile
12159                 touch $DIR/$tfile || error "touch"
12160                 for prefix in lustre security system trusted user; do
12161                         # Note getxattr() may fail with 'Operation not
12162                         # supported' or 'No such attribute' depending
12163                         # on prefix and cache.
12164                         getfattr -n $prefix.n102s $DIR/$tfile &&
12165                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12166                 done
12167         done
12168
12169         restore_lustre_params < $save
12170 }
12171 run_test 102s "getting nonexistent xattrs should fail"
12172
12173 test_102t() {
12174         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12175                 skip "MDS needs to be at least 2.11.52"
12176
12177         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12178
12179         save_lustre_params client "llite.*.xattr_cache" > $save
12180
12181         for cache in 0 1; do
12182                 lctl set_param llite.*.xattr_cache=$cache
12183
12184                 for buf_size in 0 256; do
12185                         rm -f $DIR/$tfile
12186                         touch $DIR/$tfile || error "touch"
12187                         setfattr -n user.multiop $DIR/$tfile
12188                         $MULTIOP $DIR/$tfile oa$buf_size ||
12189                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12190                 done
12191         done
12192
12193         restore_lustre_params < $save
12194 }
12195 run_test 102t "zero length xattr values handled correctly"
12196
12197 run_acl_subtest()
12198 {
12199         local test=$LUSTRE/tests/acl/$1.test
12200         local tmp=$(mktemp -t $1-XXXXXX).test
12201         local bin=$2
12202         local dmn=$3
12203         local grp=$4
12204         local nbd=$5
12205         export LANG=C
12206
12207
12208         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12209         local sedgroups="-e s/:users/:$grp/g"
12210         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12211
12212         sed $sedusers $sedgroups < $test > $tmp
12213         stack_trap "rm -f $tmp"
12214         [[ -s $tmp ]] || error "sed failed to create test script"
12215
12216         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12217         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12218 }
12219
12220 test_103a() {
12221         [ "$UID" != 0 ] && skip "must run as root"
12222         $GSS && skip_env "could not run under gss"
12223         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12224                 skip_env "must have acl enabled"
12225         which setfacl || skip_env "could not find setfacl"
12226         remote_mds_nodsh && skip "remote MDS with nodsh"
12227
12228         local mdts=$(comma_list $(mdts_nodes))
12229         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12230
12231         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12232         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12233
12234         ACLBIN=${ACLBIN:-"bin"}
12235         ACLDMN=${ACLDMN:-"daemon"}
12236         ACLGRP=${ACLGRP:-"users"}
12237         ACLNBD=${ACLNBD:-"nobody"}
12238
12239         if ! id $ACLBIN ||
12240            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12241                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12242                 ACLBIN=$USER0
12243                 if ! id $ACLBIN ; then
12244                         cat /etc/passwd
12245                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12246                 fi
12247         fi
12248         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12249            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12250                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12251                 ACLDMN=$USER1
12252                 if ! id $ACLDMN ; then
12253                         cat /etc/passwd
12254                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12255                 fi
12256         fi
12257         if ! getent group $ACLGRP; then
12258                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12259                 ACLGRP="$TSTUSR"
12260                 if ! getent group $ACLGRP; then
12261                         echo "cannot find group '$ACLGRP', adding it"
12262                         cat /etc/group
12263                         add_group 60000 $ACLGRP
12264                 fi
12265         fi
12266
12267         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12268         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12269         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12270
12271         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12272                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12273                 ACLGRP="$TSTUSR"
12274                 if ! getent group $ACLGRP; then
12275                         echo "cannot find group '$ACLGRP', adding it"
12276                         cat /etc/group
12277                         add_group 60000 $ACLGRP
12278                 fi
12279                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12280                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12281                         cat /etc/group
12282                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12283                 fi
12284         fi
12285
12286         gpasswd -a $ACLDMN $ACLBIN ||
12287                 error "setting client group failed"             # LU-5641
12288         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12289                 error "setting MDS group failed"                # LU-5641
12290
12291         declare -a identity_old
12292
12293         for num in $(seq $MDSCOUNT); do
12294                 switch_identity $num true || identity_old[$num]=$?
12295         done
12296
12297         SAVE_UMASK=$(umask)
12298         umask 0022
12299         mkdir -p $DIR/$tdir
12300         cd $DIR/$tdir
12301
12302         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12303         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12304         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12305         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12306         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12307         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12308         if ! id -u $ACLNBD ||
12309            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12310                 ACLNBD="nfsnobody"
12311                 if ! id -u $ACLNBD; then
12312                         ACLNBD=""
12313                 fi
12314         fi
12315         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12316                 add_group $(id -u $ACLNBD) $ACLNBD
12317                 if ! getent group $ACLNBD; then
12318                         ACLNBD=""
12319                 fi
12320         fi
12321         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12322            [[ -n "$ACLNBD" ]] && which setfattr; then
12323                 run_acl_subtest permissions_xattr \
12324                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12325         elif [[ -z "$ACLNBD" ]]; then
12326                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12327         else
12328                 echo "skip 'permission_xattr' test - missing setfattr command"
12329         fi
12330         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12331
12332         # inheritance test got from HP
12333         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12334         chmod +x make-tree || error "chmod +x failed"
12335         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12336         rm -f make-tree
12337
12338         echo "LU-974 ignore umask when acl is enabled..."
12339         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12340         if [ $MDSCOUNT -ge 2 ]; then
12341                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12342         fi
12343
12344         echo "LU-2561 newly created file is same size as directory..."
12345         if [ "$mds1_FSTYPE" != "zfs" ]; then
12346                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12347         else
12348                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12349         fi
12350
12351         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12352
12353         cd $SAVE_PWD
12354         umask $SAVE_UMASK
12355
12356         for num in $(seq $MDSCOUNT); do
12357                 if [ "${identity_old[$num]}" = 1 ]; then
12358                         switch_identity $num false || identity_old[$num]=$?
12359                 fi
12360         done
12361 }
12362 run_test 103a "acl test"
12363
12364 test_103b() {
12365         declare -a pids
12366         local U
12367
12368         stack_trap "rm -f $DIR/$tfile.*"
12369         for U in {0..511}; do
12370                 {
12371                 local O=$(printf "%04o" $U)
12372
12373                 umask $(printf "%04o" $((511 ^ $O)))
12374                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12375                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12376
12377                 (( $S == ($O & 0666) )) ||
12378                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12379
12380                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12381                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12382                 (( $S == ($O & 0666) )) ||
12383                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12384
12385                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12386                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12387                 (( $S == ($O & 0666) )) ||
12388                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12389                 rm -f $DIR/$tfile.[smp]$0
12390                 } &
12391                 local pid=$!
12392
12393                 # limit the concurrently running threads to 64. LU-11878
12394                 local idx=$((U % 64))
12395                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12396                 pids[idx]=$pid
12397         done
12398         wait
12399 }
12400 run_test 103b "umask lfs setstripe"
12401
12402 test_103c() {
12403         mkdir -p $DIR/$tdir
12404         cp -rp $DIR/$tdir $DIR/$tdir.bak
12405
12406         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12407                 error "$DIR/$tdir shouldn't contain default ACL"
12408         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12409                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12410         true
12411 }
12412 run_test 103c "'cp -rp' won't set empty acl"
12413
12414 test_103e() {
12415         local numacl
12416         local fileacl
12417         local saved_debug=$($LCTL get_param -n debug)
12418
12419         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12420                 skip "MDS needs to be at least 2.14.52"
12421
12422         large_xattr_enabled || skip_env "ea_inode feature disabled"
12423
12424         mkdir -p $DIR/$tdir
12425         # add big LOV EA to cause reply buffer overflow earlier
12426         $LFS setstripe -C 1000 $DIR/$tdir
12427         lctl set_param mdc.*-mdc*.stats=clear
12428
12429         $LCTL set_param debug=0
12430         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12431         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12432
12433         # add a large number of default ACLs (expect 8000+ for 2.13+)
12434         for U in {2..7000}; do
12435                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12436                         error "Able to add just $U default ACLs"
12437         done
12438         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12439         echo "$numacl default ACLs created"
12440
12441         stat $DIR/$tdir || error "Cannot stat directory"
12442         # check file creation
12443         touch $DIR/$tdir/$tfile ||
12444                 error "failed to create $tfile with $numacl default ACLs"
12445         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12446         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12447         echo "$fileacl ACLs were inherited"
12448         (( $fileacl == $numacl )) ||
12449                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12450         # check that new ACLs creation adds new ACLs to inherited ACLs
12451         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12452                 error "Cannot set new ACL"
12453         numacl=$((numacl + 1))
12454         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12455         (( $fileacl == $numacl )) ||
12456                 error "failed to add new ACL: $fileacl != $numacl as expected"
12457         # adds more ACLs to a file to reach their maximum at 8000+
12458         numacl=0
12459         for U in {20000..25000}; do
12460                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12461                 numacl=$((numacl + 1))
12462         done
12463         echo "Added $numacl more ACLs to the file"
12464         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12465         echo "Total $fileacl ACLs in file"
12466         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12467         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12468         rmdir $DIR/$tdir || error "Cannot remove directory"
12469 }
12470 run_test 103e "inheritance of big amount of default ACLs"
12471
12472 test_103f() {
12473         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12474                 skip "MDS needs to be at least 2.14.51"
12475
12476         large_xattr_enabled || skip_env "ea_inode feature disabled"
12477
12478         # enable changelog to consume more internal MDD buffers
12479         changelog_register
12480
12481         mkdir -p $DIR/$tdir
12482         # add big LOV EA
12483         $LFS setstripe -C 1000 $DIR/$tdir
12484         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12485         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12486         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12487         rmdir $DIR/$tdir || error "Cannot remove directory"
12488 }
12489 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12490
12491 test_104a() {
12492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12493
12494         touch $DIR/$tfile
12495         lfs df || error "lfs df failed"
12496         lfs df -ih || error "lfs df -ih failed"
12497         lfs df -h $DIR || error "lfs df -h $DIR failed"
12498         lfs df -i $DIR || error "lfs df -i $DIR failed"
12499         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12500         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12501
12502         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12503         lctl --device %$OSC deactivate
12504         lfs df || error "lfs df with deactivated OSC failed"
12505         lctl --device %$OSC activate
12506         # wait the osc back to normal
12507         wait_osc_import_ready client ost
12508
12509         lfs df || error "lfs df with reactivated OSC failed"
12510         rm -f $DIR/$tfile
12511 }
12512 run_test 104a "lfs df [-ih] [path] test ========================="
12513
12514 test_104b() {
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516         [ $RUNAS_ID -eq $UID ] &&
12517                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12518
12519         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12520                         grep "Permission denied" | wc -l)))
12521         if [ $denied_cnt -ne 0 ]; then
12522                 error "lfs check servers test failed"
12523         fi
12524 }
12525 run_test 104b "$RUNAS lfs check servers test ===================="
12526
12527 #
12528 # Verify $1 is within range of $2.
12529 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12530 # $1 is <= 2% of $2. Else Fail.
12531 #
12532 value_in_range() {
12533         # Strip all units (M, G, T)
12534         actual=$(echo $1 | tr -d A-Z)
12535         expect=$(echo $2 | tr -d A-Z)
12536
12537         expect_lo=$(($expect * 98 / 100)) # 2% below
12538         expect_hi=$(($expect * 102 / 100)) # 2% above
12539
12540         # permit 2% drift above and below
12541         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12542 }
12543
12544 test_104c() {
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12547
12548         local ost_param="osd-zfs.$FSNAME-OST0000."
12549         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12550         local ofacets=$(get_facets OST)
12551         local mfacets=$(get_facets MDS)
12552         local saved_ost_blocks=
12553         local saved_mdt_blocks=
12554
12555         echo "Before recordsize change"
12556         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12557         df=($(df -h | grep "$MOUNT"$))
12558
12559         # For checking.
12560         echo "lfs output : ${lfs_df[*]}"
12561         echo "df  output : ${df[*]}"
12562
12563         for facet in ${ofacets//,/ }; do
12564                 if [ -z $saved_ost_blocks ]; then
12565                         saved_ost_blocks=$(do_facet $facet \
12566                                 lctl get_param -n $ost_param.blocksize)
12567                         echo "OST Blocksize: $saved_ost_blocks"
12568                 fi
12569                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12570                 do_facet $facet zfs set recordsize=32768 $ost
12571         done
12572
12573         # BS too small. Sufficient for functional testing.
12574         for facet in ${mfacets//,/ }; do
12575                 if [ -z $saved_mdt_blocks ]; then
12576                         saved_mdt_blocks=$(do_facet $facet \
12577                                 lctl get_param -n $mdt_param.blocksize)
12578                         echo "MDT Blocksize: $saved_mdt_blocks"
12579                 fi
12580                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12581                 do_facet $facet zfs set recordsize=32768 $mdt
12582         done
12583
12584         # Give new values chance to reflect change
12585         sleep 2
12586
12587         echo "After recordsize change"
12588         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12589         df_after=($(df -h | grep "$MOUNT"$))
12590
12591         # For checking.
12592         echo "lfs output : ${lfs_df_after[*]}"
12593         echo "df  output : ${df_after[*]}"
12594
12595         # Verify lfs df
12596         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12597                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12598         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12599                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12600         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12601                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12602
12603         # Verify df
12604         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12605                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12606         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12607                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12608         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12609                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12610
12611         # Restore MDT recordize back to original
12612         for facet in ${mfacets//,/ }; do
12613                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12614                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12615         done
12616
12617         # Restore OST recordize back to original
12618         for facet in ${ofacets//,/ }; do
12619                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12620                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12621         done
12622
12623         return 0
12624 }
12625 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12626
12627 test_104d() {
12628         (( $RUNAS_ID != $UID )) ||
12629                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12630
12631         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12632                 skip "lustre version doesn't support lctl dl with non-root"
12633
12634         # debugfs only allows root users to access files, so the
12635         # previous move of the "devices" file to debugfs broke
12636         # "lctl dl" for non-root users. The LU-9680 Netlink
12637         # interface again allows non-root users to list devices.
12638         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12639                 error "lctl dl doesn't work for non root"
12640
12641         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12642         [ "$ost_count" -eq $OSTCOUNT ]  ||
12643                 error "lctl dl reports wrong number of OST devices"
12644
12645         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12646         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12647                 error "lctl dl reports wrong number of MDT devices"
12648 }
12649 run_test 104d "$RUNAS lctl dl test"
12650
12651 test_105a() {
12652         # doesn't work on 2.4 kernels
12653         touch $DIR/$tfile
12654         if $(flock_is_enabled); then
12655                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12656         else
12657                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12658         fi
12659         rm -f $DIR/$tfile
12660 }
12661 run_test 105a "flock when mounted without -o flock test ========"
12662
12663 test_105b() {
12664         touch $DIR/$tfile
12665         if $(flock_is_enabled); then
12666                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12667         else
12668                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12669         fi
12670         rm -f $DIR/$tfile
12671 }
12672 run_test 105b "fcntl when mounted without -o flock test ========"
12673
12674 test_105c() {
12675         touch $DIR/$tfile
12676         if $(flock_is_enabled); then
12677                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12678         else
12679                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12680         fi
12681         rm -f $DIR/$tfile
12682 }
12683 run_test 105c "lockf when mounted without -o flock test"
12684
12685 test_105d() { # bug 15924
12686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12687
12688         test_mkdir $DIR/$tdir
12689         flock_is_enabled || skip_env "mount w/o flock enabled"
12690         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12691         $LCTL set_param fail_loc=0x80000315
12692         flocks_test 2 $DIR/$tdir
12693 }
12694 run_test 105d "flock race (should not freeze) ========"
12695
12696 test_105e() { # bug 22660 && 22040
12697         flock_is_enabled || skip_env "mount w/o flock enabled"
12698
12699         touch $DIR/$tfile
12700         flocks_test 3 $DIR/$tfile
12701 }
12702 run_test 105e "Two conflicting flocks from same process"
12703
12704 test_106() { #bug 10921
12705         test_mkdir $DIR/$tdir
12706         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12707         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12708 }
12709 run_test 106 "attempt exec of dir followed by chown of that dir"
12710
12711 test_107() {
12712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12713
12714         CDIR=`pwd`
12715         local file=core
12716
12717         cd $DIR
12718         rm -f $file
12719
12720         local save_pattern=$(sysctl -n kernel.core_pattern)
12721         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12722         sysctl -w kernel.core_pattern=$file
12723         sysctl -w kernel.core_uses_pid=0
12724
12725         ulimit -c unlimited
12726         sleep 60 &
12727         SLEEPPID=$!
12728
12729         sleep 1
12730
12731         kill -s 11 $SLEEPPID
12732         wait $SLEEPPID
12733         if [ -e $file ]; then
12734                 size=`stat -c%s $file`
12735                 [ $size -eq 0 ] && error "Fail to create core file $file"
12736         else
12737                 error "Fail to create core file $file"
12738         fi
12739         rm -f $file
12740         sysctl -w kernel.core_pattern=$save_pattern
12741         sysctl -w kernel.core_uses_pid=$save_uses_pid
12742         cd $CDIR
12743 }
12744 run_test 107 "Coredump on SIG"
12745
12746 test_110() {
12747         test_mkdir $DIR/$tdir
12748         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12749         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12750                 error "mkdir with 256 char should fail, but did not"
12751         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12752                 error "create with 255 char failed"
12753         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12754                 error "create with 256 char should fail, but did not"
12755
12756         ls -l $DIR/$tdir
12757         rm -rf $DIR/$tdir
12758 }
12759 run_test 110 "filename length checking"
12760
12761 test_116a() { # was previously test_116()
12762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12763         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12764         remote_mds_nodsh && skip "remote MDS with nodsh"
12765
12766         echo -n "Free space priority "
12767         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12768                 head -n1
12769         declare -a AVAIL
12770         free_min_max
12771
12772         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12773         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12774         stack_trap simple_cleanup_common
12775
12776         # Check if we need to generate uneven OSTs
12777         test_mkdir -p $DIR/$tdir/OST${MINI}
12778         local FILL=$((MINV / 4))
12779         local DIFF=$((MAXV - MINV))
12780         local DIFF2=$((DIFF * 100 / MINV))
12781
12782         local threshold=$(do_facet $SINGLEMDS \
12783                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12784         threshold=${threshold%%%}
12785         echo -n "Check for uneven OSTs: "
12786         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12787
12788         if [[ $DIFF2 -gt $threshold ]]; then
12789                 echo "ok"
12790                 echo "Don't need to fill OST$MINI"
12791         else
12792                 # generate uneven OSTs. Write 2% over the QOS threshold value
12793                 echo "no"
12794                 DIFF=$((threshold - DIFF2 + 2))
12795                 DIFF2=$((MINV * DIFF / 100))
12796                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12797                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12798                         error "setstripe failed"
12799                 DIFF=$((DIFF2 / 2048))
12800                 i=0
12801                 while [ $i -lt $DIFF ]; do
12802                         i=$((i + 1))
12803                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12804                                 bs=2M count=1 2>/dev/null
12805                         echo -n .
12806                 done
12807                 echo .
12808                 sync
12809                 sleep_maxage
12810                 free_min_max
12811         fi
12812
12813         DIFF=$((MAXV - MINV))
12814         DIFF2=$((DIFF * 100 / MINV))
12815         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12816         if [ $DIFF2 -gt $threshold ]; then
12817                 echo "ok"
12818         else
12819                 skip "QOS imbalance criteria not met"
12820         fi
12821
12822         MINI1=$MINI
12823         MINV1=$MINV
12824         MAXI1=$MAXI
12825         MAXV1=$MAXV
12826
12827         # now fill using QOS
12828         $LFS setstripe -c 1 $DIR/$tdir
12829         FILL=$((FILL / 200))
12830         if [ $FILL -gt 600 ]; then
12831                 FILL=600
12832         fi
12833         echo "writing $FILL files to QOS-assigned OSTs"
12834         i=0
12835         while [ $i -lt $FILL ]; do
12836                 i=$((i + 1))
12837                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12838                         count=1 2>/dev/null
12839                 echo -n .
12840         done
12841         echo "wrote $i 200k files"
12842         sync
12843         sleep_maxage
12844
12845         echo "Note: free space may not be updated, so measurements might be off"
12846         free_min_max
12847         DIFF2=$((MAXV - MINV))
12848         echo "free space delta: orig $DIFF final $DIFF2"
12849         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12850         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12851         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12852         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12853         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12854         if [[ $DIFF -gt 0 ]]; then
12855                 FILL=$((DIFF2 * 100 / DIFF - 100))
12856                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12857         fi
12858
12859         # Figure out which files were written where
12860         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12861                awk '/'$MINI1': / {print $2; exit}')
12862         echo $UUID
12863         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12864         echo "$MINC files created on smaller OST $MINI1"
12865         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12866                awk '/'$MAXI1': / {print $2; exit}')
12867         echo $UUID
12868         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12869         echo "$MAXC files created on larger OST $MAXI1"
12870         if [[ $MINC -gt 0 ]]; then
12871                 FILL=$((MAXC * 100 / MINC - 100))
12872                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12873         fi
12874         [[ $MAXC -gt $MINC ]] ||
12875                 error_ignore LU-9 "stripe QOS didn't balance free space"
12876 }
12877 run_test 116a "stripe QOS: free space balance ==================="
12878
12879 test_116b() { # LU-2093
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_mds_nodsh && skip "remote MDS with nodsh"
12882
12883 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12884         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12885                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12886         [ -z "$old_rr" ] && skip "no QOS"
12887         do_facet $SINGLEMDS lctl set_param \
12888                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12889         mkdir -p $DIR/$tdir
12890         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12891         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12892         do_facet $SINGLEMDS lctl set_param fail_loc=0
12893         rm -rf $DIR/$tdir
12894         do_facet $SINGLEMDS lctl set_param \
12895                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12896 }
12897 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12898
12899 test_117() # bug 10891
12900 {
12901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12902
12903         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12904         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12905         lctl set_param fail_loc=0x21e
12906         > $DIR/$tfile || error "truncate failed"
12907         lctl set_param fail_loc=0
12908         echo "Truncate succeeded."
12909         rm -f $DIR/$tfile
12910 }
12911 run_test 117 "verify osd extend =========="
12912
12913 NO_SLOW_RESENDCOUNT=4
12914 export OLD_RESENDCOUNT=""
12915 set_resend_count () {
12916         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12917         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12918         lctl set_param -n $PROC_RESENDCOUNT $1
12919         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12920 }
12921
12922 # for reduce test_118* time (b=14842)
12923 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12924
12925 # Reset async IO behavior after error case
12926 reset_async() {
12927         FILE=$DIR/reset_async
12928
12929         # Ensure all OSCs are cleared
12930         $LFS setstripe -c -1 $FILE
12931         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12932         sync
12933         rm $FILE
12934 }
12935
12936 test_118a() #bug 11710
12937 {
12938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12939
12940         reset_async
12941
12942         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12943         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12944         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12945
12946         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12947                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12948                 return 1;
12949         fi
12950         rm -f $DIR/$tfile
12951 }
12952 run_test 118a "verify O_SYNC works =========="
12953
12954 test_118b()
12955 {
12956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12957         remote_ost_nodsh && skip "remote OST with nodsh"
12958
12959         reset_async
12960
12961         #define OBD_FAIL_SRV_ENOENT 0x217
12962         set_nodes_failloc "$(osts_nodes)" 0x217
12963         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12964         RC=$?
12965         set_nodes_failloc "$(osts_nodes)" 0
12966         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12967         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12968                     grep -c writeback)
12969
12970         if [[ $RC -eq 0 ]]; then
12971                 error "Must return error due to dropped pages, rc=$RC"
12972                 return 1;
12973         fi
12974
12975         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12976                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12977                 return 1;
12978         fi
12979
12980         echo "Dirty pages not leaked on ENOENT"
12981
12982         # Due to the above error the OSC will issue all RPCs syncronously
12983         # until a subsequent RPC completes successfully without error.
12984         $MULTIOP $DIR/$tfile Ow4096yc
12985         rm -f $DIR/$tfile
12986
12987         return 0
12988 }
12989 run_test 118b "Reclaim dirty pages on fatal error =========="
12990
12991 test_118c()
12992 {
12993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12994
12995         # for 118c, restore the original resend count, LU-1940
12996         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12997                                 set_resend_count $OLD_RESENDCOUNT
12998         remote_ost_nodsh && skip "remote OST with nodsh"
12999
13000         reset_async
13001
13002         #define OBD_FAIL_OST_EROFS               0x216
13003         set_nodes_failloc "$(osts_nodes)" 0x216
13004
13005         # multiop should block due to fsync until pages are written
13006         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13007         MULTIPID=$!
13008         sleep 1
13009
13010         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13011                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13012         fi
13013
13014         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13015                     grep -c writeback)
13016         if [[ $WRITEBACK -eq 0 ]]; then
13017                 error "No page in writeback, writeback=$WRITEBACK"
13018         fi
13019
13020         set_nodes_failloc "$(osts_nodes)" 0
13021         wait $MULTIPID
13022         RC=$?
13023         if [[ $RC -ne 0 ]]; then
13024                 error "Multiop fsync failed, rc=$RC"
13025         fi
13026
13027         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13028         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13029                     grep -c writeback)
13030         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13031                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13032         fi
13033
13034         rm -f $DIR/$tfile
13035         echo "Dirty pages flushed via fsync on EROFS"
13036         return 0
13037 }
13038 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13039
13040 # continue to use small resend count to reduce test_118* time (b=14842)
13041 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13042
13043 test_118d()
13044 {
13045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13046         remote_ost_nodsh && skip "remote OST with nodsh"
13047
13048         reset_async
13049
13050         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13051         set_nodes_failloc "$(osts_nodes)" 0x214
13052         # multiop should block due to fsync until pages are written
13053         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13054         MULTIPID=$!
13055         sleep 1
13056
13057         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13058                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13059         fi
13060
13061         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13062                     grep -c writeback)
13063         if [[ $WRITEBACK -eq 0 ]]; then
13064                 error "No page in writeback, writeback=$WRITEBACK"
13065         fi
13066
13067         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13068         set_nodes_failloc "$(osts_nodes)" 0
13069
13070         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13071         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13072                     grep -c writeback)
13073         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13074                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13075         fi
13076
13077         rm -f $DIR/$tfile
13078         echo "Dirty pages gaurenteed flushed via fsync"
13079         return 0
13080 }
13081 run_test 118d "Fsync validation inject a delay of the bulk =========="
13082
13083 test_118f() {
13084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13085
13086         reset_async
13087
13088         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13089         lctl set_param fail_loc=0x8000040a
13090
13091         # Should simulate EINVAL error which is fatal
13092         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13093         RC=$?
13094         if [[ $RC -eq 0 ]]; then
13095                 error "Must return error due to dropped pages, rc=$RC"
13096         fi
13097
13098         lctl set_param fail_loc=0x0
13099
13100         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13101         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13102         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13103                     grep -c writeback)
13104         if [[ $LOCKED -ne 0 ]]; then
13105                 error "Locked pages remain in cache, locked=$LOCKED"
13106         fi
13107
13108         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13109                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13110         fi
13111
13112         rm -f $DIR/$tfile
13113         echo "No pages locked after fsync"
13114
13115         reset_async
13116         return 0
13117 }
13118 run_test 118f "Simulate unrecoverable OSC side error =========="
13119
13120 test_118g() {
13121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13122
13123         reset_async
13124
13125         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13126         lctl set_param fail_loc=0x406
13127
13128         # simulate local -ENOMEM
13129         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13130         RC=$?
13131
13132         lctl set_param fail_loc=0
13133         if [[ $RC -eq 0 ]]; then
13134                 error "Must return error due to dropped pages, rc=$RC"
13135         fi
13136
13137         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13138         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13139         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13140                         grep -c writeback)
13141         if [[ $LOCKED -ne 0 ]]; then
13142                 error "Locked pages remain in cache, locked=$LOCKED"
13143         fi
13144
13145         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13146                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13147         fi
13148
13149         rm -f $DIR/$tfile
13150         echo "No pages locked after fsync"
13151
13152         reset_async
13153         return 0
13154 }
13155 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13156
13157 test_118h() {
13158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13159         remote_ost_nodsh && skip "remote OST with nodsh"
13160
13161         reset_async
13162
13163         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13164         set_nodes_failloc "$(osts_nodes)" 0x20e
13165         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13167         RC=$?
13168
13169         set_nodes_failloc "$(osts_nodes)" 0
13170         if [[ $RC -eq 0 ]]; then
13171                 error "Must return error due to dropped pages, rc=$RC"
13172         fi
13173
13174         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13175         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13176         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13177                     grep -c writeback)
13178         if [[ $LOCKED -ne 0 ]]; then
13179                 error "Locked pages remain in cache, locked=$LOCKED"
13180         fi
13181
13182         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13183                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13184         fi
13185
13186         rm -f $DIR/$tfile
13187         echo "No pages locked after fsync"
13188
13189         return 0
13190 }
13191 run_test 118h "Verify timeout in handling recoverables errors  =========="
13192
13193 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13194
13195 test_118i() {
13196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13197         remote_ost_nodsh && skip "remote OST with nodsh"
13198
13199         reset_async
13200
13201         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13202         set_nodes_failloc "$(osts_nodes)" 0x20e
13203
13204         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13205         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13206         PID=$!
13207         sleep 5
13208         set_nodes_failloc "$(osts_nodes)" 0
13209
13210         wait $PID
13211         RC=$?
13212         if [[ $RC -ne 0 ]]; then
13213                 error "got error, but should be not, rc=$RC"
13214         fi
13215
13216         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13217         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13218         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13219         if [[ $LOCKED -ne 0 ]]; then
13220                 error "Locked pages remain in cache, locked=$LOCKED"
13221         fi
13222
13223         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13224                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13225         fi
13226
13227         rm -f $DIR/$tfile
13228         echo "No pages locked after fsync"
13229
13230         return 0
13231 }
13232 run_test 118i "Fix error before timeout in recoverable error  =========="
13233
13234 [ "$SLOW" = "no" ] && set_resend_count 4
13235
13236 test_118j() {
13237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13238         remote_ost_nodsh && skip "remote OST with nodsh"
13239
13240         reset_async
13241
13242         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13243         set_nodes_failloc "$(osts_nodes)" 0x220
13244
13245         # return -EIO from OST
13246         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13247         RC=$?
13248         set_nodes_failloc "$(osts_nodes)" 0x0
13249         if [[ $RC -eq 0 ]]; then
13250                 error "Must return error due to dropped pages, rc=$RC"
13251         fi
13252
13253         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13254         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13255         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13256         if [[ $LOCKED -ne 0 ]]; then
13257                 error "Locked pages remain in cache, locked=$LOCKED"
13258         fi
13259
13260         # in recoverable error on OST we want resend and stay until it finished
13261         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13262                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13263         fi
13264
13265         rm -f $DIR/$tfile
13266         echo "No pages locked after fsync"
13267
13268         return 0
13269 }
13270 run_test 118j "Simulate unrecoverable OST side error =========="
13271
13272 test_118k()
13273 {
13274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13275         remote_ost_nodsh && skip "remote OSTs with nodsh"
13276
13277         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13278         set_nodes_failloc "$(osts_nodes)" 0x20e
13279         test_mkdir $DIR/$tdir
13280
13281         for ((i=0;i<10;i++)); do
13282                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13283                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13284                 SLEEPPID=$!
13285                 sleep 0.500s
13286                 kill $SLEEPPID
13287                 wait $SLEEPPID
13288         done
13289
13290         set_nodes_failloc "$(osts_nodes)" 0
13291         rm -rf $DIR/$tdir
13292 }
13293 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13294
13295 test_118l() # LU-646
13296 {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298
13299         test_mkdir $DIR/$tdir
13300         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13301         rm -rf $DIR/$tdir
13302 }
13303 run_test 118l "fsync dir"
13304
13305 test_118m() # LU-3066
13306 {
13307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13308
13309         test_mkdir $DIR/$tdir
13310         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13311         rm -rf $DIR/$tdir
13312 }
13313 run_test 118m "fdatasync dir ========="
13314
13315 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13316
13317 test_118n()
13318 {
13319         local begin
13320         local end
13321
13322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13323         remote_ost_nodsh && skip "remote OSTs with nodsh"
13324
13325         # Sleep to avoid a cached response.
13326         #define OBD_STATFS_CACHE_SECONDS 1
13327         sleep 2
13328
13329         # Inject a 10 second delay in the OST_STATFS handler.
13330         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13331         set_nodes_failloc "$(osts_nodes)" 0x242
13332
13333         begin=$SECONDS
13334         stat --file-system $MOUNT > /dev/null
13335         end=$SECONDS
13336
13337         set_nodes_failloc "$(osts_nodes)" 0
13338
13339         if ((end - begin > 20)); then
13340             error "statfs took $((end - begin)) seconds, expected 10"
13341         fi
13342 }
13343 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13344
13345 test_119a() # bug 11737
13346 {
13347         BSIZE=$((512 * 1024))
13348         directio write $DIR/$tfile 0 1 $BSIZE
13349         # We ask to read two blocks, which is more than a file size.
13350         # directio will indicate an error when requested and actual
13351         # sizes aren't equeal (a normal situation in this case) and
13352         # print actual read amount.
13353         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13354         if [ "$NOB" != "$BSIZE" ]; then
13355                 error "read $NOB bytes instead of $BSIZE"
13356         fi
13357         rm -f $DIR/$tfile
13358 }
13359 run_test 119a "Short directIO read must return actual read amount"
13360
13361 test_119b() # bug 11737
13362 {
13363         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13364
13365         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13367         sync
13368         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13369                 error "direct read failed"
13370         rm -f $DIR/$tfile
13371 }
13372 run_test 119b "Sparse directIO read must return actual read amount"
13373
13374 test_119c() # bug 13099
13375 {
13376         BSIZE=1048576
13377         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13378         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13379         rm -f $DIR/$tfile
13380 }
13381 run_test 119c "Testing for direct read hitting hole"
13382
13383 test_120a() {
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13385         remote_mds_nodsh && skip "remote MDS with nodsh"
13386         test_mkdir -i0 -c1 $DIR/$tdir
13387         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13388                 skip_env "no early lock cancel on server"
13389
13390         lru_resize_disable mdc
13391         lru_resize_disable osc
13392         cancel_lru_locks mdc
13393         # asynchronous object destroy at MDT could cause bl ast to client
13394         cancel_lru_locks osc
13395
13396         stat $DIR/$tdir > /dev/null
13397         can1=$(do_facet mds1 \
13398                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13399                awk '/ldlm_cancel/ {print $2}')
13400         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13401                awk '/ldlm_bl_callback/ {print $2}')
13402         test_mkdir -i0 -c1 $DIR/$tdir/d1
13403         can2=$(do_facet mds1 \
13404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13405                awk '/ldlm_cancel/ {print $2}')
13406         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13407                awk '/ldlm_bl_callback/ {print $2}')
13408         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13409         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13410         lru_resize_enable mdc
13411         lru_resize_enable osc
13412 }
13413 run_test 120a "Early Lock Cancel: mkdir test"
13414
13415 test_120b() {
13416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13417         remote_mds_nodsh && skip "remote MDS with nodsh"
13418         test_mkdir $DIR/$tdir
13419         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13420                 skip_env "no early lock cancel on server"
13421
13422         lru_resize_disable mdc
13423         lru_resize_disable osc
13424         cancel_lru_locks mdc
13425         stat $DIR/$tdir > /dev/null
13426         can1=$(do_facet $SINGLEMDS \
13427                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13428                awk '/ldlm_cancel/ {print $2}')
13429         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13430                awk '/ldlm_bl_callback/ {print $2}')
13431         touch $DIR/$tdir/f1
13432         can2=$(do_facet $SINGLEMDS \
13433                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13434                awk '/ldlm_cancel/ {print $2}')
13435         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13436                awk '/ldlm_bl_callback/ {print $2}')
13437         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13438         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13439         lru_resize_enable mdc
13440         lru_resize_enable osc
13441 }
13442 run_test 120b "Early Lock Cancel: create test"
13443
13444 test_120c() {
13445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13446         remote_mds_nodsh && skip "remote MDS with nodsh"
13447         test_mkdir -i0 -c1 $DIR/$tdir
13448         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13449                 skip "no early lock cancel on server"
13450
13451         lru_resize_disable mdc
13452         lru_resize_disable osc
13453         test_mkdir -i0 -c1 $DIR/$tdir/d1
13454         test_mkdir -i0 -c1 $DIR/$tdir/d2
13455         touch $DIR/$tdir/d1/f1
13456         cancel_lru_locks mdc
13457         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13458         can1=$(do_facet mds1 \
13459                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13460                awk '/ldlm_cancel/ {print $2}')
13461         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13462                awk '/ldlm_bl_callback/ {print $2}')
13463         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13464         can2=$(do_facet mds1 \
13465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13466                awk '/ldlm_cancel/ {print $2}')
13467         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13468                awk '/ldlm_bl_callback/ {print $2}')
13469         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13470         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13471         lru_resize_enable mdc
13472         lru_resize_enable osc
13473 }
13474 run_test 120c "Early Lock Cancel: link test"
13475
13476 test_120d() {
13477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13478         remote_mds_nodsh && skip "remote MDS with nodsh"
13479         test_mkdir -i0 -c1 $DIR/$tdir
13480         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13481                 skip_env "no early lock cancel on server"
13482
13483         lru_resize_disable mdc
13484         lru_resize_disable osc
13485         touch $DIR/$tdir
13486         cancel_lru_locks mdc
13487         stat $DIR/$tdir > /dev/null
13488         can1=$(do_facet mds1 \
13489                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13490                awk '/ldlm_cancel/ {print $2}')
13491         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13492                awk '/ldlm_bl_callback/ {print $2}')
13493         chmod a+x $DIR/$tdir
13494         can2=$(do_facet mds1 \
13495                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13496                awk '/ldlm_cancel/ {print $2}')
13497         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13498                awk '/ldlm_bl_callback/ {print $2}')
13499         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13500         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13501         lru_resize_enable mdc
13502         lru_resize_enable osc
13503 }
13504 run_test 120d "Early Lock Cancel: setattr test"
13505
13506 test_120e() {
13507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13508         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13509                 skip_env "no early lock cancel on server"
13510         remote_mds_nodsh && skip "remote MDS with nodsh"
13511
13512         local dlmtrace_set=false
13513
13514         test_mkdir -i0 -c1 $DIR/$tdir
13515         lru_resize_disable mdc
13516         lru_resize_disable osc
13517         ! $LCTL get_param debug | grep -q dlmtrace &&
13518                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13519         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13520         cancel_lru_locks mdc
13521         cancel_lru_locks osc
13522         dd if=$DIR/$tdir/f1 of=/dev/null
13523         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13524         # XXX client can not do early lock cancel of OST lock
13525         # during unlink (LU-4206), so cancel osc lock now.
13526         sleep 2
13527         cancel_lru_locks osc
13528         can1=$(do_facet mds1 \
13529                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13530                awk '/ldlm_cancel/ {print $2}')
13531         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13532                awk '/ldlm_bl_callback/ {print $2}')
13533         unlink $DIR/$tdir/f1
13534         sleep 5
13535         can2=$(do_facet mds1 \
13536                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13537                awk '/ldlm_cancel/ {print $2}')
13538         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13539                awk '/ldlm_bl_callback/ {print $2}')
13540         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13541                 $LCTL dk $TMP/cancel.debug.txt
13542         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13543                 $LCTL dk $TMP/blocking.debug.txt
13544         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13545         lru_resize_enable mdc
13546         lru_resize_enable osc
13547 }
13548 run_test 120e "Early Lock Cancel: unlink test"
13549
13550 test_120f() {
13551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13552         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13553                 skip_env "no early lock cancel on server"
13554         remote_mds_nodsh && skip "remote MDS with nodsh"
13555
13556         test_mkdir -i0 -c1 $DIR/$tdir
13557         lru_resize_disable mdc
13558         lru_resize_disable osc
13559         test_mkdir -i0 -c1 $DIR/$tdir/d1
13560         test_mkdir -i0 -c1 $DIR/$tdir/d2
13561         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13562         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13563         cancel_lru_locks mdc
13564         cancel_lru_locks osc
13565         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13566         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13567         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13568         # XXX client can not do early lock cancel of OST lock
13569         # during rename (LU-4206), so cancel osc lock now.
13570         sleep 2
13571         cancel_lru_locks osc
13572         can1=$(do_facet mds1 \
13573                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13574                awk '/ldlm_cancel/ {print $2}')
13575         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13576                awk '/ldlm_bl_callback/ {print $2}')
13577         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13578         sleep 5
13579         can2=$(do_facet mds1 \
13580                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13581                awk '/ldlm_cancel/ {print $2}')
13582         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13583                awk '/ldlm_bl_callback/ {print $2}')
13584         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13585         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13586         lru_resize_enable mdc
13587         lru_resize_enable osc
13588 }
13589 run_test 120f "Early Lock Cancel: rename test"
13590
13591 test_120g() {
13592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13593         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13594                 skip_env "no early lock cancel on server"
13595         remote_mds_nodsh && skip "remote MDS with nodsh"
13596
13597         lru_resize_disable mdc
13598         lru_resize_disable osc
13599         count=10000
13600         echo create $count files
13601         test_mkdir $DIR/$tdir
13602         cancel_lru_locks mdc
13603         cancel_lru_locks osc
13604         t0=$(date +%s)
13605
13606         can0=$(do_facet $SINGLEMDS \
13607                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13608                awk '/ldlm_cancel/ {print $2}')
13609         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13610                awk '/ldlm_bl_callback/ {print $2}')
13611         createmany -o $DIR/$tdir/f $count
13612         sync
13613         can1=$(do_facet $SINGLEMDS \
13614                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13615                awk '/ldlm_cancel/ {print $2}')
13616         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13617                awk '/ldlm_bl_callback/ {print $2}')
13618         t1=$(date +%s)
13619         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13620         echo rm $count files
13621         rm -r $DIR/$tdir
13622         sync
13623         can2=$(do_facet $SINGLEMDS \
13624                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13625                awk '/ldlm_cancel/ {print $2}')
13626         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13627                awk '/ldlm_bl_callback/ {print $2}')
13628         t2=$(date +%s)
13629         echo total: $count removes in $((t2-t1))
13630         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13631         sleep 2
13632         # wait for commitment of removal
13633         lru_resize_enable mdc
13634         lru_resize_enable osc
13635 }
13636 run_test 120g "Early Lock Cancel: performance test"
13637
13638 test_121() { #bug #10589
13639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13640
13641         rm -rf $DIR/$tfile
13642         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13643 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13644         lctl set_param fail_loc=0x310
13645         cancel_lru_locks osc > /dev/null
13646         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13647         lctl set_param fail_loc=0
13648         [[ $reads -eq $writes ]] ||
13649                 error "read $reads blocks, must be $writes blocks"
13650 }
13651 run_test 121 "read cancel race ========="
13652
13653 test_123a_base() { # was test 123, statahead(bug 11401)
13654         local lsx="$1"
13655
13656         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13657
13658         SLOWOK=0
13659         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13660                 log "testing UP system. Performance may be lower than expected."
13661                 SLOWOK=1
13662         fi
13663         running_in_vm && SLOWOK=1
13664
13665         $LCTL set_param mdc.*.batch_stats=0
13666
13667         rm -rf $DIR/$tdir
13668         test_mkdir $DIR/$tdir
13669         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13670         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13671         MULT=10
13672         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13673                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13674
13675                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13676                 lctl set_param -n llite.*.statahead_max 0
13677                 lctl get_param llite.*.statahead_max
13678                 cancel_lru_locks mdc
13679                 cancel_lru_locks osc
13680                 stime=$(date +%s)
13681                 time $lsx $DIR/$tdir | wc -l
13682                 etime=$(date +%s)
13683                 delta=$((etime - stime))
13684                 log "$lsx $i files without statahead: $delta sec"
13685                 lctl set_param llite.*.statahead_max=$max
13686
13687                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13688                          awk '/statahead.wrong:/ { print $NF }')
13689                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13690                 cancel_lru_locks mdc
13691                 cancel_lru_locks osc
13692                 stime=$(date +%s)
13693                 time $lsx $DIR/$tdir | wc -l
13694                 etime=$(date +%s)
13695                 delta_sa=$((etime - stime))
13696                 log "$lsx $i files with statahead: $delta_sa sec"
13697                 lctl get_param -n llite.*.statahead_stats
13698                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13699                          awk '/statahead.wrong:/ { print $NF }')
13700
13701                 [[ $swrong -lt $ewrong ]] &&
13702                         log "statahead was stopped, maybe too many locks held!"
13703                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13704
13705                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13706                         max=$(lctl get_param -n llite.*.statahead_max |
13707                                 head -n 1)
13708                         lctl set_param -n llite.*.statahead_max 0
13709                         lctl get_param llite.*.statahead_max
13710                         cancel_lru_locks mdc
13711                         cancel_lru_locks osc
13712                         stime=$(date +%s)
13713                         time $lsx $DIR/$tdir | wc -l
13714                         etime=$(date +%s)
13715                         delta=$((etime - stime))
13716                         log "$lsx $i files again without statahead: $delta sec"
13717                         lctl set_param llite.*.statahead_max=$max
13718                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13719                                 if [ $SLOWOK -eq 0 ]; then
13720                                         error "$lsx $i files is slower with statahead!"
13721                                 else
13722                                         log "$lsx $i files is slower with statahead!"
13723                                 fi
13724                                 break
13725                         fi
13726                 fi
13727
13728                 [ $delta -gt 20 ] && break
13729                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13730                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13731         done
13732         log "$lsx done"
13733
13734         stime=$(date +%s)
13735         rm -r $DIR/$tdir
13736         sync
13737         etime=$(date +%s)
13738         delta=$((etime - stime))
13739         log "rm -r $DIR/$tdir/: $delta seconds"
13740         log "rm done"
13741         lctl get_param -n llite.*.statahead_stats
13742         $LCTL get_param mdc.*.batch_stats
13743 }
13744
13745 test_123aa() {
13746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13747
13748         test_123a_base "ls -l"
13749 }
13750 run_test 123aa "verify statahead work"
13751
13752 test_123ab() {
13753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13754
13755         statx_supported || skip_env "Test must be statx() syscall supported"
13756
13757         test_123a_base "$STATX -l"
13758 }
13759 run_test 123ab "verify statahead work by using statx"
13760
13761 test_123ac() {
13762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13763
13764         statx_supported || skip_env "Test must be statx() syscall supported"
13765
13766         local rpcs_before
13767         local rpcs_after
13768         local agl_before
13769         local agl_after
13770
13771         cancel_lru_locks $OSC
13772         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13773         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13774                      awk '/agl.total:/ { print $NF }')
13775         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13776         test_123a_base "$STATX --cached=always -D"
13777         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13778                     awk '/agl.total:/ { print $NF }')
13779         [ $agl_before -eq $agl_after ] ||
13780                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13781         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13782         [ $rpcs_after -eq $rpcs_before ] ||
13783                 error "$STATX should not send glimpse RPCs to $OSC"
13784 }
13785 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13786
13787 test_batch_statahead() {
13788         local max=$1
13789         local batch_max=$2
13790         local num=10000
13791         local batch_rpcs
13792         local unbatch_rpcs
13793         local hit_total
13794
13795         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13796         $LCTL set_param mdc.*.batch_stats=0
13797         $LCTL set_param llite.*.statahead_max=$max
13798         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13799         # Verify that batched statahead is faster than one without statahead
13800         test_123a_base "ls -l"
13801
13802         stack_trap "rm -rf $DIR/$tdir" EXIT
13803         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13804         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13805
13806         # unbatched statahead
13807         $LCTL set_param llite.*.statahead_batch_max=0
13808         $LCTL set_param llite.*.statahead_stats=clear
13809         $LCTL set_param mdc.*.stats=clear
13810         cancel_lru_locks mdc
13811         cancel_lru_locks osc
13812         time ls -l $DIR/$tdir | wc -l
13813         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13814         sleep 2
13815         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13816                     awk '/hit.total:/ { print $NF }')
13817         # hit ratio should be larger than 75% (7500).
13818         (( $hit_total > 7500 )) ||
13819                 error "unbatched statahead hit count ($hit_total) is too low"
13820
13821         # batched statahead
13822         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13823         $LCTL set_param llite.*.statahead_stats=clear
13824         $LCTL set_param mdc.*.batch_stats=clear
13825         $LCTL set_param mdc.*.stats=clear
13826         cancel_lru_locks mdc
13827         cancel_lru_locks osc
13828         time ls -l $DIR/$tdir | wc -l
13829         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13830         # wait for statahead thread to quit and update statahead stats
13831         sleep 2
13832         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13833                     awk '/hit.total:/ { print $NF }')
13834         # hit ratio should be larger than 75% (7500).
13835         (( $hit_total > 7500 )) ||
13836                 error "batched statahead hit count ($hit_total) is too low"
13837
13838         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13839         (( $unbatch_rpcs > $batch_rpcs )) ||
13840                 error "batched statahead does not reduce RPC count"
13841         $LCTL get_param mdc.*.batch_stats
13842 }
13843
13844 test_123ad() {
13845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13846
13847         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13848                 skip "Need server version at least 2.15.53"
13849
13850         local max
13851         local batch_max
13852
13853         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13854         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13855
13856         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13857         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13858
13859         test_batch_statahead 32 32
13860         test_batch_statahead 2048 256
13861 }
13862 run_test 123ad "Verify batching statahead works correctly"
13863
13864 test_123b () { # statahead(bug 15027)
13865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13866
13867         test_mkdir $DIR/$tdir
13868         createmany -o $DIR/$tdir/$tfile-%d 1000
13869
13870         cancel_lru_locks mdc
13871         cancel_lru_locks osc
13872
13873 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13874         lctl set_param fail_loc=0x80000803
13875         ls -lR $DIR/$tdir > /dev/null
13876         log "ls done"
13877         lctl set_param fail_loc=0x0
13878         lctl get_param -n llite.*.statahead_stats
13879         rm -r $DIR/$tdir
13880         sync
13881
13882 }
13883 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13884
13885 test_123c() {
13886         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13887
13888         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13889         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13890         touch $DIR/$tdir.1/{1..3}
13891         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13892
13893         remount_client $MOUNT
13894
13895         $MULTIOP $DIR/$tdir.0 Q
13896
13897         # let statahead to complete
13898         ls -l $DIR/$tdir.0 > /dev/null
13899
13900         testid=$(echo $TESTNAME | tr '_' ' ')
13901         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13902                 error "statahead warning" || true
13903 }
13904 run_test 123c "Can not initialize inode warning on DNE statahead"
13905
13906 test_123d() {
13907         local num=100
13908         local swrong
13909         local ewrong
13910
13911         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13912         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13913                 error "setdirstripe $DIR/$tdir failed"
13914         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13915         remount_client $MOUNT
13916         $LCTL get_param llite.*.statahead_max
13917         $LCTL set_param llite.*.statahead_stats=0 ||
13918                 error "clear statahead_stats failed"
13919         swrong=$(lctl get_param -n llite.*.statahead_stats |
13920                  awk '/statahead.wrong:/ { print $NF }')
13921         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13922         # wait for statahead thread finished to update hit/miss stats.
13923         sleep 1
13924         $LCTL get_param -n llite.*.statahead_stats
13925         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13926                  awk '/statahead.wrong:/ { print $NF }')
13927         (( $swrong == $ewrong )) ||
13928                 log "statahead was stopped, maybe too many locks held!"
13929 }
13930 run_test 123d "Statahead on striped directories works correctly"
13931
13932 test_123e() {
13933         local max
13934         local batch_max
13935         local dir=$DIR/$tdir
13936
13937         mkdir $dir || error "mkdir $dir failed"
13938         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13939         stack_trap "rm -rf $dir"
13940
13941         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13942
13943         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13944         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13945         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13946         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13947
13948         $LCTL set_param llite.*.statahead_max=2048
13949         $LCTL set_param llite.*.statahead_batch_max=1024
13950
13951         ls -l $dir
13952         $LCTL get_param mdc.*.batch_stats
13953         $LCTL get_param llite.*.statahead_*
13954 }
13955 run_test 123e "statahead with large wide striping"
13956
13957 test_123f() {
13958         local max
13959         local batch_max
13960         local dir=$DIR/$tdir
13961
13962         mkdir $dir || error "mkdir $dir failed"
13963         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13964         stack_trap "rm -rf $dir"
13965
13966         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13967
13968         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13969         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13970
13971         $LCTL set_param llite.*.statahead_max=64
13972         $LCTL set_param llite.*.statahead_batch_max=64
13973
13974         ls -l $dir
13975         lctl get_param mdc.*.batch_stats
13976         lctl get_param llite.*.statahead_*
13977
13978         $LCTL set_param llite.*.statahead_max=$max
13979         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13980 }
13981 run_test 123f "Retry mechanism with large wide striping files"
13982
13983 test_124a() {
13984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13985         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13986                 skip_env "no lru resize on server"
13987
13988         local NR=2000
13989
13990         test_mkdir $DIR/$tdir
13991
13992         log "create $NR files at $DIR/$tdir"
13993         createmany -o $DIR/$tdir/f $NR ||
13994                 error "failed to create $NR files in $DIR/$tdir"
13995
13996         cancel_lru_locks mdc
13997         ls -l $DIR/$tdir > /dev/null
13998
13999         local NSDIR=""
14000         local LRU_SIZE=0
14001         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14002                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14003                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14004                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14005                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14006                         log "NSDIR=$NSDIR"
14007                         log "NS=$(basename $NSDIR)"
14008                         break
14009                 fi
14010         done
14011
14012         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14013                 skip "Not enough cached locks created!"
14014         fi
14015         log "LRU=$LRU_SIZE"
14016
14017         local SLEEP=30
14018
14019         # We know that lru resize allows one client to hold $LIMIT locks
14020         # for 10h. After that locks begin to be killed by client.
14021         local MAX_HRS=10
14022         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14023         log "LIMIT=$LIMIT"
14024         if [ $LIMIT -lt $LRU_SIZE ]; then
14025                 skip "Limit is too small $LIMIT"
14026         fi
14027
14028         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14029         # killing locks. Some time was spent for creating locks. This means
14030         # that up to the moment of sleep finish we must have killed some of
14031         # them (10-100 locks). This depends on how fast ther were created.
14032         # Many of them were touched in almost the same moment and thus will
14033         # be killed in groups.
14034         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14035
14036         # Use $LRU_SIZE_B here to take into account real number of locks
14037         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14038         local LRU_SIZE_B=$LRU_SIZE
14039         log "LVF=$LVF"
14040         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14041         log "OLD_LVF=$OLD_LVF"
14042         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14043
14044         # Let's make sure that we really have some margin. Client checks
14045         # cached locks every 10 sec.
14046         SLEEP=$((SLEEP+20))
14047         log "Sleep ${SLEEP} sec"
14048         local SEC=0
14049         while ((SEC<$SLEEP)); do
14050                 echo -n "..."
14051                 sleep 5
14052                 SEC=$((SEC+5))
14053                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14054                 echo -n "$LRU_SIZE"
14055         done
14056         echo ""
14057         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14058         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14059
14060         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14061                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14062                 unlinkmany $DIR/$tdir/f $NR
14063                 return
14064         }
14065
14066         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14067         log "unlink $NR files at $DIR/$tdir"
14068         unlinkmany $DIR/$tdir/f $NR
14069 }
14070 run_test 124a "lru resize ======================================="
14071
14072 get_max_pool_limit()
14073 {
14074         local limit=$($LCTL get_param \
14075                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14076         local max=0
14077         for l in $limit; do
14078                 if [[ $l -gt $max ]]; then
14079                         max=$l
14080                 fi
14081         done
14082         echo $max
14083 }
14084
14085 test_124b() {
14086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14087         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14088                 skip_env "no lru resize on server"
14089
14090         LIMIT=$(get_max_pool_limit)
14091
14092         NR=$(($(default_lru_size)*20))
14093         if [[ $NR -gt $LIMIT ]]; then
14094                 log "Limit lock number by $LIMIT locks"
14095                 NR=$LIMIT
14096         fi
14097
14098         IFree=$(mdsrate_inodes_available)
14099         if [ $IFree -lt $NR ]; then
14100                 log "Limit lock number by $IFree inodes"
14101                 NR=$IFree
14102         fi
14103
14104         lru_resize_disable mdc
14105         test_mkdir -p $DIR/$tdir/disable_lru_resize
14106
14107         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14108         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14109         cancel_lru_locks mdc
14110         stime=`date +%s`
14111         PID=""
14112         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14113         PID="$PID $!"
14114         sleep 2
14115         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14116         PID="$PID $!"
14117         sleep 2
14118         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14119         PID="$PID $!"
14120         wait $PID
14121         etime=`date +%s`
14122         nolruresize_delta=$((etime-stime))
14123         log "ls -la time: $nolruresize_delta seconds"
14124         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14125         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14126
14127         lru_resize_enable mdc
14128         test_mkdir -p $DIR/$tdir/enable_lru_resize
14129
14130         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14131         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14132         cancel_lru_locks mdc
14133         stime=`date +%s`
14134         PID=""
14135         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14136         PID="$PID $!"
14137         sleep 2
14138         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14139         PID="$PID $!"
14140         sleep 2
14141         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14142         PID="$PID $!"
14143         wait $PID
14144         etime=`date +%s`
14145         lruresize_delta=$((etime-stime))
14146         log "ls -la time: $lruresize_delta seconds"
14147         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14148
14149         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14150                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14151         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14152                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14153         else
14154                 log "lru resize performs the same with no lru resize"
14155         fi
14156         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14157 }
14158 run_test 124b "lru resize (performance test) ======================="
14159
14160 test_124c() {
14161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14162         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14163                 skip_env "no lru resize on server"
14164
14165         # cache ununsed locks on client
14166         local nr=100
14167         cancel_lru_locks mdc
14168         test_mkdir $DIR/$tdir
14169         createmany -o $DIR/$tdir/f $nr ||
14170                 error "failed to create $nr files in $DIR/$tdir"
14171         ls -l $DIR/$tdir > /dev/null
14172
14173         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14174         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14175         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14176         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14177         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14178
14179         # set lru_max_age to 1 sec
14180         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14181         echo "sleep $((recalc_p * 2)) seconds..."
14182         sleep $((recalc_p * 2))
14183
14184         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14185         # restore lru_max_age
14186         $LCTL set_param -n $nsdir.lru_max_age $max_age
14187         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14188         unlinkmany $DIR/$tdir/f $nr
14189 }
14190 run_test 124c "LRUR cancel very aged locks"
14191
14192 test_124d() {
14193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14194         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14195                 skip_env "no lru resize on server"
14196
14197         # cache ununsed locks on client
14198         local nr=100
14199
14200         lru_resize_disable mdc
14201         stack_trap "lru_resize_enable mdc" EXIT
14202
14203         cancel_lru_locks mdc
14204
14205         # asynchronous object destroy at MDT could cause bl ast to client
14206         test_mkdir $DIR/$tdir
14207         createmany -o $DIR/$tdir/f $nr ||
14208                 error "failed to create $nr files in $DIR/$tdir"
14209         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14210
14211         ls -l $DIR/$tdir > /dev/null
14212
14213         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14214         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14215         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14216         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14217
14218         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14219
14220         # set lru_max_age to 1 sec
14221         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14222         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14223
14224         echo "sleep $((recalc_p * 2)) seconds..."
14225         sleep $((recalc_p * 2))
14226
14227         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14228
14229         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14230 }
14231 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14232
14233 test_125() { # 13358
14234         $LCTL get_param -n llite.*.client_type | grep -q local ||
14235                 skip "must run as local client"
14236         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14237                 skip_env "must have acl enabled"
14238         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14239
14240         test_mkdir $DIR/$tdir
14241         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14242         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14243                 error "setfacl $DIR/$tdir failed"
14244         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14245 }
14246 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14247
14248 test_126() { # bug 12829/13455
14249         $GSS && skip_env "must run as gss disabled"
14250         $LCTL get_param -n llite.*.client_type | grep -q local ||
14251                 skip "must run as local client"
14252         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14253
14254         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14255         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14256         rm -f $DIR/$tfile
14257         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14258 }
14259 run_test 126 "check that the fsgid provided by the client is taken into account"
14260
14261 test_127a() { # bug 15521
14262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14263         local name count samp unit min max sum sumsq
14264         local tmpfile=$TMP/$tfile.tmp
14265
14266         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14267         echo "stats before reset"
14268         stack_trap "rm -f $tmpfile"
14269         local now=$(date +%s)
14270
14271         $LCTL get_param osc.*.stats | tee $tmpfile
14272
14273         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14274         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14275         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14276         local uptime=$(awk '{ print $1 }' /proc/uptime)
14277
14278         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14279         (( ${snapshot_time%\.*} >= $now - 5 &&
14280            ${snapshot_time%\.*} <= $now + 5 )) ||
14281                 error "snapshot_time=$snapshot_time != now=$now"
14282         # elapsed _should_ be from mount, but at least less than uptime
14283         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14284                 error "elapsed=$elapsed > uptime=$uptime"
14285         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14286            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14287                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14288
14289         $LCTL set_param osc.*.stats=0
14290         local reset=$(date +%s)
14291         local fsize=$((2048 * 1024))
14292
14293         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14294         cancel_lru_locks osc
14295         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14296
14297         now=$(date +%s)
14298         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14299         while read name count samp unit min max sum sumsq; do
14300                 [[ "$samp" == "samples" ]] || continue
14301
14302                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14303                 [ ! $min ] && error "Missing min value for $name proc entry"
14304                 eval $name=$count || error "Wrong proc format"
14305
14306                 case $name in
14307                 read_bytes|write_bytes)
14308                         [[ "$unit" =~ "bytes" ]] ||
14309                                 error "unit is not 'bytes': $unit"
14310                         (( $min >= 4096 )) || error "min is too small: $min"
14311                         (( $min <= $fsize )) || error "min is too big: $min"
14312                         (( $max >= 4096 )) || error "max is too small: $max"
14313                         (( $max <= $fsize )) || error "max is too big: $max"
14314                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14315                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14316                                 error "sumsquare is too small: $sumsq"
14317                         (( $sumsq <= $fsize * $fsize )) ||
14318                                 error "sumsquare is too big: $sumsq"
14319                         ;;
14320                 ost_read|ost_write)
14321                         [[ "$unit" =~ "usec" ]] ||
14322                                 error "unit is not 'usec': $unit"
14323                         ;;
14324                 *)      ;;
14325                 esac
14326         done < $tmpfile
14327
14328         #check that we actually got some stats
14329         [ "$read_bytes" ] || error "Missing read_bytes stats"
14330         [ "$write_bytes" ] || error "Missing write_bytes stats"
14331         [ "$read_bytes" != 0 ] || error "no read done"
14332         [ "$write_bytes" != 0 ] || error "no write done"
14333
14334         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14335         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14336         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14337
14338         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14339         (( ${snapshot_time%\.*} >= $now - 5 &&
14340            ${snapshot_time%\.*} <= $now + 5 )) ||
14341                 error "reset snapshot_time=$snapshot_time != now=$now"
14342         # elapsed should be from time of stats reset
14343         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14344            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14345                 error "reset elapsed=$elapsed > $now - $reset"
14346         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14347            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14348                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14349 }
14350 run_test 127a "verify the client stats are sane"
14351
14352 test_127b() { # bug LU-333
14353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14354         local name count samp unit min max sum sumsq
14355
14356         echo "stats before reset"
14357         $LCTL get_param llite.*.stats
14358         $LCTL set_param llite.*.stats=0
14359
14360         # perform 2 reads and writes so MAX is different from SUM.
14361         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14362         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14363         cancel_lru_locks osc
14364         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14365         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14366
14367         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14368         stack_trap "rm -f $TMP/$tfile.tmp"
14369         while read name count samp unit min max sum sumsq; do
14370                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14371                 eval $name=$count || error "Wrong proc format"
14372
14373                 case $name in
14374                 read_bytes|write_bytes)
14375                         [[ "$unit" =~ "bytes" ]] ||
14376                                 error "unit is not 'bytes': $unit"
14377                         (( $count == 2 )) || error "count is not 2: $count"
14378                         (( $min == $PAGE_SIZE )) ||
14379                                 error "min is not $PAGE_SIZE: $min"
14380                         (( $max == $PAGE_SIZE )) ||
14381                                 error "max is not $PAGE_SIZE: $max"
14382                         (( $sum == $PAGE_SIZE * 2 )) ||
14383                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14384                         ;;
14385                 read|write)
14386                         [[ "$unit" =~ "usec" ]] ||
14387                                 error "unit is not 'usec': $unit"
14388                         ;;
14389                 *)      ;;
14390                 esac
14391         done < $TMP/$tfile.tmp
14392
14393         #check that we actually got some stats
14394         [ "$read_bytes" ] || error "Missing read_bytes stats"
14395         [ "$write_bytes" ] || error "Missing write_bytes stats"
14396         [ "$read_bytes" != 0 ] || error "no read done"
14397         [ "$write_bytes" != 0 ] || error "no write done"
14398 }
14399 run_test 127b "verify the llite client stats are sane"
14400
14401 test_127c() { # LU-12394
14402         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14403         local size
14404         local bsize
14405         local reads
14406         local writes
14407         local count
14408
14409         $LCTL set_param llite.*.extents_stats=1
14410         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14411
14412         # Use two stripes so there is enough space in default config
14413         $LFS setstripe -c 2 $DIR/$tfile
14414
14415         # Extent stats start at 0-4K and go in power of two buckets
14416         # LL_HIST_START = 12 --> 2^12 = 4K
14417         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14418         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14419         # small configs
14420         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14421                 do
14422                 # Write and read, 2x each, second time at a non-zero offset
14423                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14424                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14425                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14426                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14427                 rm -f $DIR/$tfile
14428         done
14429
14430         $LCTL get_param llite.*.extents_stats
14431
14432         count=2
14433         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14434                 do
14435                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14436                                 grep -m 1 $bsize)
14437                 reads=$(echo $bucket | awk '{print $5}')
14438                 writes=$(echo $bucket | awk '{print $9}')
14439                 [ "$reads" -eq $count ] ||
14440                         error "$reads reads in < $bsize bucket, expect $count"
14441                 [ "$writes" -eq $count ] ||
14442                         error "$writes writes in < $bsize bucket, expect $count"
14443         done
14444
14445         # Test mmap write and read
14446         $LCTL set_param llite.*.extents_stats=c
14447         size=512
14448         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14449         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14450         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14451
14452         $LCTL get_param llite.*.extents_stats
14453
14454         count=$(((size*1024) / PAGE_SIZE))
14455
14456         bsize=$((2 * PAGE_SIZE / 1024))K
14457
14458         bucket=$($LCTL get_param -n llite.*.extents_stats |
14459                         grep -m 1 $bsize)
14460         reads=$(echo $bucket | awk '{print $5}')
14461         writes=$(echo $bucket | awk '{print $9}')
14462         # mmap writes fault in the page first, creating an additonal read
14463         [ "$reads" -eq $((2 * count)) ] ||
14464                 error "$reads reads in < $bsize bucket, expect $count"
14465         [ "$writes" -eq $count ] ||
14466                 error "$writes writes in < $bsize bucket, expect $count"
14467 }
14468 run_test 127c "test llite extent stats with regular & mmap i/o"
14469
14470 test_128() { # bug 15212
14471         touch $DIR/$tfile
14472         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14473                 find $DIR/$tfile
14474                 find $DIR/$tfile
14475         EOF
14476
14477         result=$(grep error $TMP/$tfile.log)
14478         rm -f $DIR/$tfile $TMP/$tfile.log
14479         [ -z "$result" ] ||
14480                 error "consecutive find's under interactive lfs failed"
14481 }
14482 run_test 128 "interactive lfs for 2 consecutive find's"
14483
14484 set_dir_limits () {
14485         local mntdev
14486         local canondev
14487         local node
14488
14489         local ldproc=/proc/fs/ldiskfs
14490         local facets=$(get_facets MDS)
14491
14492         for facet in ${facets//,/ }; do
14493                 canondev=$(ldiskfs_canon \
14494                            *.$(convert_facet2label $facet).mntdev $facet)
14495                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14496                         ldproc=/sys/fs/ldiskfs
14497                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14498                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14499         done
14500 }
14501
14502 check_mds_dmesg() {
14503         local facets=$(get_facets MDS)
14504         for facet in ${facets//,/ }; do
14505                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14506         done
14507         return 1
14508 }
14509
14510 test_129() {
14511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14512         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14513                 skip "Need MDS version with at least 2.5.56"
14514         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14515                 skip_env "ldiskfs only test"
14516         fi
14517         remote_mds_nodsh && skip "remote MDS with nodsh"
14518
14519         local ENOSPC=28
14520         local has_warning=false
14521
14522         rm -rf $DIR/$tdir
14523         mkdir -p $DIR/$tdir
14524
14525         # block size of mds1
14526         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14527         set_dir_limits $maxsize $((maxsize * 6 / 8))
14528         stack_trap "set_dir_limits 0 0"
14529         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14530         local dirsize=$(stat -c%s "$DIR/$tdir")
14531         local nfiles=0
14532         while (( $dirsize <= $maxsize )); do
14533                 $MCREATE $DIR/$tdir/file_base_$nfiles
14534                 rc=$?
14535                 # check two errors:
14536                 # ENOSPC for ext4 max_dir_size, which has been used since
14537                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14538                 if (( rc == ENOSPC )); then
14539                         set_dir_limits 0 0
14540                         echo "rc=$rc returned as expected after $nfiles files"
14541
14542                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14543                                 error "create failed w/o dir size limit"
14544
14545                         # messages may be rate limited if test is run repeatedly
14546                         check_mds_dmesg '"is approaching max"' ||
14547                                 echo "warning message should be output"
14548                         check_mds_dmesg '"has reached max"' ||
14549                                 echo "reached message should be output"
14550
14551                         dirsize=$(stat -c%s "$DIR/$tdir")
14552
14553                         [[ $dirsize -ge $maxsize ]] && return 0
14554                         error "dirsize $dirsize < $maxsize after $nfiles files"
14555                 elif (( rc != 0 )); then
14556                         break
14557                 fi
14558                 nfiles=$((nfiles + 1))
14559                 dirsize=$(stat -c%s "$DIR/$tdir")
14560         done
14561
14562         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14563 }
14564 run_test 129 "test directory size limit ========================"
14565
14566 OLDIFS="$IFS"
14567 cleanup_130() {
14568         trap 0
14569         IFS="$OLDIFS"
14570         rm -f $DIR/$tfile
14571 }
14572
14573 test_130a() {
14574         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14575         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14576
14577         trap cleanup_130 EXIT RETURN
14578
14579         local fm_file=$DIR/$tfile
14580         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14581         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14582                 error "dd failed for $fm_file"
14583
14584         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14585         filefrag -ves $fm_file
14586         local rc=$?
14587         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14588                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14589         (( $rc == 0 )) || error "filefrag $fm_file failed"
14590
14591         filefrag_op=$(filefrag -ve -k $fm_file |
14592                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14593         local lun=$($LFS getstripe -i $fm_file)
14594
14595         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14596         IFS=$'\n'
14597         local tot_len=0
14598         for line in $filefrag_op; do
14599                 local frag_lun=$(echo $line | cut -d: -f5)
14600                 local ext_len=$(echo $line | cut -d: -f4)
14601
14602                 if (( $frag_lun != $lun )); then
14603                         error "FIEMAP on 1-stripe file($fm_file) failed"
14604                         return
14605                 fi
14606                 (( tot_len += ext_len ))
14607         done
14608
14609         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14610                 error "FIEMAP on 1-stripe file($fm_file) failed"
14611                 return
14612         fi
14613
14614         echo "FIEMAP on single striped file succeeded"
14615 }
14616 run_test 130a "FIEMAP (1-stripe file)"
14617
14618 test_130b() {
14619         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14620
14621         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14622         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14623         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14624                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14625
14626         trap cleanup_130 EXIT RETURN
14627
14628         local fm_file=$DIR/$tfile
14629         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14630                 error "setstripe on $fm_file"
14631
14632         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14633                 error "dd failed on $fm_file"
14634
14635         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14636         filefrag_op=$(filefrag -ve -k $fm_file |
14637                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14638
14639         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14640                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14641
14642         IFS=$'\n'
14643         local tot_len=0
14644         local num_luns=1
14645
14646         for line in $filefrag_op; do
14647                 local frag_lun=$(echo $line | cut -d: -f5 |
14648                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14649                 local ext_len=$(echo $line | cut -d: -f4)
14650                 if (( $frag_lun != $last_lun )); then
14651                         if (( tot_len != 1024 )); then
14652                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14653                                 return
14654                         else
14655                                 (( num_luns += 1 ))
14656                                 tot_len=0
14657                         fi
14658                 fi
14659                 (( tot_len += ext_len ))
14660                 last_lun=$frag_lun
14661         done
14662         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14663                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14664                 return
14665         fi
14666
14667         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14668 }
14669 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14670
14671 test_130c() {
14672         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14673
14674         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14675         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14676         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14677                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14678
14679         trap cleanup_130 EXIT RETURN
14680
14681         local fm_file=$DIR/$tfile
14682         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14683
14684         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14685                 error "dd failed on $fm_file"
14686
14687         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14688         filefrag_op=$(filefrag -ve -k $fm_file |
14689                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14690
14691         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14692                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14693
14694         IFS=$'\n'
14695         local tot_len=0
14696         local num_luns=1
14697         for line in $filefrag_op; do
14698                 local frag_lun=$(echo $line | cut -d: -f5 |
14699                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14700                 local ext_len=$(echo $line | cut -d: -f4)
14701                 if (( $frag_lun != $last_lun )); then
14702                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14703                         if (( logical != 512 )); then
14704                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14705                                 return
14706                         fi
14707                         if (( tot_len != 512 )); then
14708                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14709                                 return
14710                         else
14711                                 (( num_luns += 1 ))
14712                                 tot_len=0
14713                         fi
14714                 fi
14715                 (( tot_len += ext_len ))
14716                 last_lun=$frag_lun
14717         done
14718         if (( num_luns != 2 || tot_len != 512 )); then
14719                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14720                 return
14721         fi
14722
14723         echo "FIEMAP on 2-stripe file with hole succeeded"
14724 }
14725 run_test 130c "FIEMAP (2-stripe file with hole)"
14726
14727 test_130d() {
14728         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14729
14730         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14731         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14732         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14733                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14734
14735         trap cleanup_130 EXIT RETURN
14736
14737         local fm_file=$DIR/$tfile
14738         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14739                         error "setstripe on $fm_file"
14740
14741         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14742         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14743                 error "dd failed on $fm_file"
14744
14745         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14746         filefrag_op=$(filefrag -ve -k $fm_file |
14747                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14748
14749         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14750                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14751
14752         IFS=$'\n'
14753         local tot_len=0
14754         local num_luns=1
14755         for line in $filefrag_op; do
14756                 local frag_lun=$(echo $line | cut -d: -f5 |
14757                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14758                 local ext_len=$(echo $line | cut -d: -f4)
14759                 if (( $frag_lun != $last_lun )); then
14760                         if (( tot_len != 1024 )); then
14761                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14762                                 return
14763                         else
14764                                 (( num_luns += 1 ))
14765                                 local tot_len=0
14766                         fi
14767                 fi
14768                 (( tot_len += ext_len ))
14769                 last_lun=$frag_lun
14770         done
14771         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14772                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14773                 return
14774         fi
14775
14776         echo "FIEMAP on N-stripe file succeeded"
14777 }
14778 run_test 130d "FIEMAP (N-stripe file)"
14779
14780 test_130e() {
14781         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14782
14783         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14784         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14785         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14786                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14787
14788         trap cleanup_130 EXIT RETURN
14789
14790         local fm_file=$DIR/$tfile
14791         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14792         stack_trap "rm -f $fm_file"
14793
14794         local num_blks=512
14795         local expected_len=$(( (num_blks / 2) * 64 ))
14796         for ((i = 0; i < $num_blks; i++)); do
14797                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14798                         conv=notrunc > /dev/null 2>&1
14799         done
14800
14801         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14802         filefrag_op=$(filefrag -ve -k $fm_file |
14803                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14804
14805         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14806
14807         IFS=$'\n'
14808         local tot_len=0
14809         local num_luns=1
14810         for line in $filefrag_op; do
14811                 local frag_lun=$(echo $line | cut -d: -f5)
14812                 local ext_len=$(echo $line | cut -d: -f4)
14813                 if (( $frag_lun != $last_lun )); then
14814                         if (( tot_len != $expected_len )); then
14815                                 error "OST$last_lun $tot_len != $expected_len"
14816                         else
14817                                 (( num_luns += 1 ))
14818                                 tot_len=0
14819                         fi
14820                 fi
14821                 (( tot_len += ext_len ))
14822                 last_lun=$frag_lun
14823         done
14824         if (( num_luns != 2 || tot_len != $expected_len )); then
14825                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14826         fi
14827
14828         echo "FIEMAP with continuation calls succeeded"
14829 }
14830 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14831
14832 test_130f() {
14833         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14834         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14835         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14836                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14837
14838         local fm_file=$DIR/$tfile
14839         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14840                 error "multiop create with lov_delay_create on $fm_file"
14841
14842         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14843         filefrag_extents=$(filefrag -vek $fm_file |
14844                            awk '/extents? found/ { print $2 }')
14845         if (( $filefrag_extents != 0 )); then
14846                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14847         fi
14848
14849         rm -f $fm_file
14850 }
14851 run_test 130f "FIEMAP (unstriped file)"
14852
14853 test_130g() {
14854         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14855                 skip "Need MDS version with at least 2.12.53 for overstriping"
14856         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14857         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14858         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14859                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14860
14861         local file=$DIR/$tfile
14862         local nr=$((OSTCOUNT * 100))
14863
14864         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14865
14866         stack_trap "rm -f $file"
14867         dd if=/dev/zero of=$file count=$nr bs=1M
14868         sync
14869         nr=$($LFS getstripe -c $file)
14870
14871         local extents=$(filefrag -v $file |
14872                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14873
14874         echo "filefrag list $extents extents in file with stripecount $nr"
14875         if (( extents < nr )); then
14876                 $LFS getstripe $file
14877                 filefrag -v $file
14878                 error "filefrag printed $extents < $nr extents"
14879         fi
14880 }
14881 run_test 130g "FIEMAP (overstripe file)"
14882
14883 # Test for writev/readv
14884 test_131a() {
14885         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14886                 error "writev test failed"
14887         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14888                 error "readv failed"
14889         rm -f $DIR/$tfile
14890 }
14891 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14892
14893 test_131b() {
14894         local fsize=$((524288 + 1048576 + 1572864))
14895         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14896                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14897                         error "append writev test failed"
14898
14899         ((fsize += 1572864 + 1048576))
14900         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14901                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14902                         error "append writev test failed"
14903         rm -f $DIR/$tfile
14904 }
14905 run_test 131b "test append writev"
14906
14907 test_131c() {
14908         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14909         error "NOT PASS"
14910 }
14911 run_test 131c "test read/write on file w/o objects"
14912
14913 test_131d() {
14914         rwv -f $DIR/$tfile -w -n 1 1572864
14915         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14916         if [ "$NOB" != 1572864 ]; then
14917                 error "Short read filed: read $NOB bytes instead of 1572864"
14918         fi
14919         rm -f $DIR/$tfile
14920 }
14921 run_test 131d "test short read"
14922
14923 test_131e() {
14924         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14925         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14926         error "read hitting hole failed"
14927         rm -f $DIR/$tfile
14928 }
14929 run_test 131e "test read hitting hole"
14930
14931 check_stats() {
14932         local facet=$1
14933         local op=$2
14934         local want=${3:-0}
14935         local res
14936
14937         # open             11 samples [usecs] 468 4793 13658 35791898
14938         case $facet in
14939         mds*) res=($(do_facet $facet \
14940                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14941                  ;;
14942         ost*) res=($(do_facet $facet \
14943                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14944                  ;;
14945         *) error "Wrong facet '$facet'" ;;
14946         esac
14947         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14948         # if $want is zero, it means any stat increment is ok.
14949         if (( $want > 0 )); then
14950                 local count=${res[1]}
14951
14952                 if (( $count != $want )); then
14953                         if [[ $facet =~ "mds" ]]; then
14954                                 do_nodes $(comma_list $(mdts_nodes)) \
14955                                         $LCTL get_param mdt.*.md_stats
14956                         else
14957                                 do_nodes $(comma_list $(osts-nodes)) \
14958                                         $LCTL get_param obdfilter.*.stats
14959                         fi
14960                         error "The $op counter on $facet is $count, not $want"
14961                 fi
14962         fi
14963 }
14964
14965 test_133a() {
14966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14967         remote_ost_nodsh && skip "remote OST with nodsh"
14968         remote_mds_nodsh && skip "remote MDS with nodsh"
14969         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14970                 skip_env "MDS doesn't support rename stats"
14971
14972         local testdir=$DIR/${tdir}/stats_testdir
14973
14974         mkdir -p $DIR/${tdir}
14975
14976         # clear stats.
14977         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14978         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14979
14980         # verify mdt stats first.
14981         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14982         check_stats $SINGLEMDS "mkdir" 1
14983
14984         # clear "open" from "lfs mkdir" above
14985         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14986         touch ${testdir}/${tfile} || error "touch failed"
14987         check_stats $SINGLEMDS "open" 1
14988         check_stats $SINGLEMDS "close" 1
14989         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14990                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14991                 check_stats $SINGLEMDS "mknod" 2
14992         }
14993         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14994         check_stats $SINGLEMDS "unlink" 1
14995         rm -f ${testdir}/${tfile} || error "file remove failed"
14996         check_stats $SINGLEMDS "unlink" 2
14997
14998         # remove working dir and check mdt stats again.
14999         rmdir ${testdir} || error "rmdir failed"
15000         check_stats $SINGLEMDS "rmdir" 1
15001
15002         local testdir1=$DIR/${tdir}/stats_testdir1
15003         mkdir_on_mdt0 -p ${testdir}
15004         mkdir_on_mdt0 -p ${testdir1}
15005         touch ${testdir1}/test1
15006         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15007         check_stats $SINGLEMDS "crossdir_rename" 1
15008
15009         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15010         check_stats $SINGLEMDS "samedir_rename" 1
15011
15012         rm -rf $DIR/${tdir}
15013 }
15014 run_test 133a "Verifying MDT stats ========================================"
15015
15016 test_133b() {
15017         local res
15018
15019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15020         remote_ost_nodsh && skip "remote OST with nodsh"
15021         remote_mds_nodsh && skip "remote MDS with nodsh"
15022
15023         local testdir=$DIR/${tdir}/stats_testdir
15024
15025         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15026         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15027         touch ${testdir}/${tfile} || error "touch failed"
15028         cancel_lru_locks mdc
15029
15030         # clear stats.
15031         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15032         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15033
15034         # extra mdt stats verification.
15035         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15036         check_stats $SINGLEMDS "setattr" 1
15037         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15038         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15039         then            # LU-1740
15040                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15041                 check_stats $SINGLEMDS "getattr" 1
15042         fi
15043         rm -rf $DIR/${tdir}
15044
15045         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15046         # so the check below is not reliable
15047         [ $MDSCOUNT -eq 1 ] || return 0
15048
15049         # Sleep to avoid a cached response.
15050         #define OBD_STATFS_CACHE_SECONDS 1
15051         sleep 2
15052         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15053         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15054         $LFS df || error "lfs failed"
15055         check_stats $SINGLEMDS "statfs" 1
15056
15057         # check aggregated statfs (LU-10018)
15058         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15059                 return 0
15060         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15061                 return 0
15062         sleep 2
15063         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15064         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15065         df $DIR
15066         check_stats $SINGLEMDS "statfs" 1
15067
15068         # We want to check that the client didn't send OST_STATFS to
15069         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15070         # extra care is needed here.
15071         if remote_mds; then
15072                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15073                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15074
15075                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15076                 [ "$res" ] && error "OST got STATFS"
15077         fi
15078
15079         return 0
15080 }
15081 run_test 133b "Verifying extra MDT stats =================================="
15082
15083 test_133c() {
15084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15085         remote_ost_nodsh && skip "remote OST with nodsh"
15086         remote_mds_nodsh && skip "remote MDS with nodsh"
15087
15088         local testdir=$DIR/$tdir/stats_testdir
15089
15090         test_mkdir -p $testdir
15091
15092         # verify obdfilter stats.
15093         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15094         sync
15095         cancel_lru_locks osc
15096         wait_delete_completed
15097
15098         # clear stats.
15099         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15100         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15101
15102         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15103                 error "dd failed"
15104         sync
15105         cancel_lru_locks osc
15106         check_stats ost1 "write" 1
15107
15108         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15109         check_stats ost1 "read" 1
15110
15111         > $testdir/$tfile || error "truncate failed"
15112         check_stats ost1 "punch" 1
15113
15114         rm -f $testdir/$tfile || error "file remove failed"
15115         wait_delete_completed
15116         check_stats ost1 "destroy" 1
15117
15118         rm -rf $DIR/$tdir
15119 }
15120 run_test 133c "Verifying OST stats ========================================"
15121
15122 order_2() {
15123         local value=$1
15124         local orig=$value
15125         local order=1
15126
15127         while [ $value -ge 2 ]; do
15128                 order=$((order*2))
15129                 value=$((value/2))
15130         done
15131
15132         if [ $orig -gt $order ]; then
15133                 order=$((order*2))
15134         fi
15135         echo $order
15136 }
15137
15138 size_in_KMGT() {
15139     local value=$1
15140     local size=('K' 'M' 'G' 'T');
15141     local i=0
15142     local size_string=$value
15143
15144     while [ $value -ge 1024 ]; do
15145         if [ $i -gt 3 ]; then
15146             #T is the biggest unit we get here, if that is bigger,
15147             #just return XXXT
15148             size_string=${value}T
15149             break
15150         fi
15151         value=$((value >> 10))
15152         if [ $value -lt 1024 ]; then
15153             size_string=${value}${size[$i]}
15154             break
15155         fi
15156         i=$((i + 1))
15157     done
15158
15159     echo $size_string
15160 }
15161
15162 get_rename_size() {
15163         local size=$1
15164         local context=${2:-.}
15165         local sample=$(do_facet $SINGLEMDS $LCTL \
15166                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15167                 grep -A1 $context |
15168                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15169         echo $sample
15170 }
15171
15172 test_133d() {
15173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15174         remote_ost_nodsh && skip "remote OST with nodsh"
15175         remote_mds_nodsh && skip "remote MDS with nodsh"
15176         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15177                 skip_env "MDS doesn't support rename stats"
15178
15179         local testdir1=$DIR/${tdir}/stats_testdir1
15180         local testdir2=$DIR/${tdir}/stats_testdir2
15181         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15182
15183         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15184
15185         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15186         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15187
15188         createmany -o $testdir1/test 512 || error "createmany failed"
15189
15190         # check samedir rename size
15191         mv ${testdir1}/test0 ${testdir1}/test_0
15192
15193         local testdir1_size=$(ls -l $DIR/${tdir} |
15194                 awk '/stats_testdir1/ {print $5}')
15195         local testdir2_size=$(ls -l $DIR/${tdir} |
15196                 awk '/stats_testdir2/ {print $5}')
15197
15198         testdir1_size=$(order_2 $testdir1_size)
15199         testdir2_size=$(order_2 $testdir2_size)
15200
15201         testdir1_size=$(size_in_KMGT $testdir1_size)
15202         testdir2_size=$(size_in_KMGT $testdir2_size)
15203
15204         echo "source rename dir size: ${testdir1_size}"
15205         echo "target rename dir size: ${testdir2_size}"
15206
15207         local cmd="do_facet $SINGLEMDS $LCTL "
15208         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15209
15210         eval $cmd || error "$cmd failed"
15211         local samedir=$($cmd | grep 'same_dir')
15212         local same_sample=$(get_rename_size $testdir1_size)
15213         [ -z "$samedir" ] && error "samedir_rename_size count error"
15214         [[ $same_sample -eq 1 ]] ||
15215                 error "samedir_rename_size error $same_sample"
15216         echo "Check same dir rename stats success"
15217
15218         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15219
15220         # check crossdir rename size
15221         mv ${testdir1}/test_0 ${testdir2}/test_0
15222
15223         testdir1_size=$(ls -l $DIR/${tdir} |
15224                 awk '/stats_testdir1/ {print $5}')
15225         testdir2_size=$(ls -l $DIR/${tdir} |
15226                 awk '/stats_testdir2/ {print $5}')
15227
15228         testdir1_size=$(order_2 $testdir1_size)
15229         testdir2_size=$(order_2 $testdir2_size)
15230
15231         testdir1_size=$(size_in_KMGT $testdir1_size)
15232         testdir2_size=$(size_in_KMGT $testdir2_size)
15233
15234         echo "source rename dir size: ${testdir1_size}"
15235         echo "target rename dir size: ${testdir2_size}"
15236
15237         eval $cmd || error "$cmd failed"
15238         local crossdir=$($cmd | grep 'crossdir')
15239         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15240         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15241         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15242         [[ $src_sample -eq 1 ]] ||
15243                 error "crossdir_rename_size error $src_sample"
15244         [[ $tgt_sample -eq 1 ]] ||
15245                 error "crossdir_rename_size error $tgt_sample"
15246         echo "Check cross dir rename stats success"
15247         rm -rf $DIR/${tdir}
15248 }
15249 run_test 133d "Verifying rename_stats ========================================"
15250
15251 test_133e() {
15252         remote_mds_nodsh && skip "remote MDS with nodsh"
15253         remote_ost_nodsh && skip "remote OST with nodsh"
15254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15255
15256         local testdir=$DIR/${tdir}/stats_testdir
15257         local ctr f0 f1 bs=32768 count=42 sum
15258
15259         mkdir -p ${testdir} || error "mkdir failed"
15260
15261         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15262
15263         for ctr in {write,read}_bytes; do
15264                 sync
15265                 cancel_lru_locks osc
15266
15267                 do_facet ost1 $LCTL set_param -n \
15268                         "obdfilter.*.exports.clear=clear"
15269
15270                 if [ $ctr = write_bytes ]; then
15271                         f0=/dev/zero
15272                         f1=${testdir}/${tfile}
15273                 else
15274                         f0=${testdir}/${tfile}
15275                         f1=/dev/null
15276                 fi
15277
15278                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15279                         error "dd failed"
15280                 sync
15281                 cancel_lru_locks osc
15282
15283                 sum=$(do_facet ost1 $LCTL get_param \
15284                         "obdfilter.*.exports.*.stats" |
15285                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15286                                 $1 == ctr { sum += $7 }
15287                                 END { printf("%0.0f", sum) }')
15288
15289                 if ((sum != bs * count)); then
15290                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15291                 fi
15292         done
15293
15294         rm -rf $DIR/${tdir}
15295 }
15296 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15297
15298 test_133f() {
15299         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15300                 skip "too old lustre for get_param -R ($facet_ver)"
15301
15302         # verifying readability.
15303         $LCTL get_param -R '*' &> /dev/null
15304
15305         # Verifing writability with badarea_io.
15306         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15307         local skipped_params='force_lbug|changelog_mask|daemon_file'
15308         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15309                 egrep -v "$skipped_params" |
15310                 xargs -n 1 find $proc_dirs -name |
15311                 xargs -n 1 badarea_io ||
15312                 error "client badarea_io failed"
15313
15314         # remount the FS in case writes/reads /proc break the FS
15315         cleanup || error "failed to unmount"
15316         setup || error "failed to setup"
15317 }
15318 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15319
15320 test_133g() {
15321         remote_mds_nodsh && skip "remote MDS with nodsh"
15322         remote_ost_nodsh && skip "remote OST with nodsh"
15323
15324         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15325         local proc_dirs_str=$(eval echo $proc_dirs)
15326         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15327         local facet
15328         for facet in mds1 ost1; do
15329                 local facet_ver=$(lustre_version_code $facet)
15330                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15331                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15332                 else
15333                         log "$facet: too old lustre for get_param -R"
15334                 fi
15335                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15336                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15337                                 tr -d = | egrep -v $skipped_params |
15338                                 xargs -n 1 find $proc_dirs_str -name |
15339                                 xargs -n 1 badarea_io" ||
15340                                         error "$facet badarea_io failed"
15341                 else
15342                         skip_noexit "$facet: too old lustre for get_param -R"
15343                 fi
15344         done
15345
15346         # remount the FS in case writes/reads /proc break the FS
15347         cleanup || error "failed to unmount"
15348         setup || error "failed to setup"
15349 }
15350 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15351
15352 test_133h() {
15353         remote_mds_nodsh && skip "remote MDS with nodsh"
15354         remote_ost_nodsh && skip "remote OST with nodsh"
15355         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15356                 skip "Need MDS version at least 2.9.54"
15357
15358         local facet
15359         for facet in client mds1 ost1; do
15360                 # Get the list of files that are missing the terminating newline
15361                 local plist=$(do_facet $facet
15362                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15363                 local ent
15364                 for ent in $plist; do
15365                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15366                                 awk -v FS='\v' -v RS='\v\v' \
15367                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15368                                         print FILENAME}'" 2>/dev/null)
15369                         [ -z $missing ] || {
15370                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15371                                 error "file does not end with newline: $facet-$ent"
15372                         }
15373                 done
15374         done
15375 }
15376 run_test 133h "Proc files should end with newlines"
15377
15378 test_134a() {
15379         remote_mds_nodsh && skip "remote MDS with nodsh"
15380         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15381                 skip "Need MDS version at least 2.7.54"
15382
15383         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15384         cancel_lru_locks mdc
15385
15386         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15387         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15388         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15389
15390         local nr=1000
15391         createmany -o $DIR/$tdir/f $nr ||
15392                 error "failed to create $nr files in $DIR/$tdir"
15393         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15394
15395         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15396         do_facet mds1 $LCTL set_param fail_loc=0x327
15397         do_facet mds1 $LCTL set_param fail_val=500
15398         touch $DIR/$tdir/m
15399
15400         echo "sleep 10 seconds ..."
15401         sleep 10
15402         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15403
15404         do_facet mds1 $LCTL set_param fail_loc=0
15405         do_facet mds1 $LCTL set_param fail_val=0
15406         [ $lck_cnt -lt $unused ] ||
15407                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15408
15409         rm $DIR/$tdir/m
15410         unlinkmany $DIR/$tdir/f $nr
15411 }
15412 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15413
15414 test_134b() {
15415         remote_mds_nodsh && skip "remote MDS with nodsh"
15416         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15417                 skip "Need MDS version at least 2.7.54"
15418
15419         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15420         cancel_lru_locks mdc
15421
15422         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15423                         ldlm.lock_reclaim_threshold_mb)
15424         # disable reclaim temporarily
15425         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15426
15427         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15428         do_facet mds1 $LCTL set_param fail_loc=0x328
15429         do_facet mds1 $LCTL set_param fail_val=500
15430
15431         $LCTL set_param debug=+trace
15432
15433         local nr=600
15434         createmany -o $DIR/$tdir/f $nr &
15435         local create_pid=$!
15436
15437         echo "Sleep $TIMEOUT seconds ..."
15438         sleep $TIMEOUT
15439         if ! ps -p $create_pid  > /dev/null 2>&1; then
15440                 do_facet mds1 $LCTL set_param fail_loc=0
15441                 do_facet mds1 $LCTL set_param fail_val=0
15442                 do_facet mds1 $LCTL set_param \
15443                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15444                 error "createmany finished incorrectly!"
15445         fi
15446         do_facet mds1 $LCTL set_param fail_loc=0
15447         do_facet mds1 $LCTL set_param fail_val=0
15448         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15449         wait $create_pid || return 1
15450
15451         unlinkmany $DIR/$tdir/f $nr
15452 }
15453 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15454
15455 test_135() {
15456         remote_mds_nodsh && skip "remote MDS with nodsh"
15457         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15458                 skip "Need MDS version at least 2.13.50"
15459         local fname
15460
15461         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15462
15463 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15464         #set only one record at plain llog
15465         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15466
15467         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15468
15469         #fill already existed plain llog each 64767
15470         #wrapping whole catalog
15471         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15472
15473         createmany -o $DIR/$tdir/$tfile_ 64700
15474         for (( i = 0; i < 64700; i = i + 2 ))
15475         do
15476                 rm $DIR/$tdir/$tfile_$i &
15477                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15478                 local pid=$!
15479                 wait $pid
15480         done
15481
15482         #waiting osp synchronization
15483         wait_delete_completed
15484 }
15485 run_test 135 "Race catalog processing"
15486
15487 test_136() {
15488         remote_mds_nodsh && skip "remote MDS with nodsh"
15489         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15490                 skip "Need MDS version at least 2.13.50"
15491         local fname
15492
15493         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15494         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15495         #set only one record at plain llog
15496 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15497         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15498
15499         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15500
15501         #fill already existed 2 plain llogs each 64767
15502         #wrapping whole catalog
15503         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15504         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15505         wait_delete_completed
15506
15507         createmany -o $DIR/$tdir/$tfile_ 10
15508         sleep 25
15509
15510         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15511         for (( i = 0; i < 10; i = i + 3 ))
15512         do
15513                 rm $DIR/$tdir/$tfile_$i &
15514                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15515                 local pid=$!
15516                 wait $pid
15517                 sleep 7
15518                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15519         done
15520
15521         #waiting osp synchronization
15522         wait_delete_completed
15523 }
15524 run_test 136 "Race catalog processing 2"
15525
15526 test_140() { #bug-17379
15527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15528
15529         test_mkdir $DIR/$tdir
15530         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15531         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15532
15533         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15534         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15535         local i=0
15536         while i=$((i + 1)); do
15537                 test_mkdir $i
15538                 cd $i || error "Changing to $i"
15539                 ln -s ../stat stat || error "Creating stat symlink"
15540                 # Read the symlink until ELOOP present,
15541                 # not LBUGing the system is considered success,
15542                 # we didn't overrun the stack.
15543                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15544                 if [ $ret -ne 0 ]; then
15545                         if [ $ret -eq 40 ]; then
15546                                 break  # -ELOOP
15547                         else
15548                                 error "Open stat symlink"
15549                                         return
15550                         fi
15551                 fi
15552         done
15553         i=$((i - 1))
15554         echo "The symlink depth = $i"
15555         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15556                 error "Invalid symlink depth"
15557
15558         # Test recursive symlink
15559         ln -s symlink_self symlink_self
15560         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15561         echo "open symlink_self returns $ret"
15562         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15563 }
15564 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15565
15566 test_150a() {
15567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15568
15569         local TF="$TMP/$tfile"
15570
15571         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15572         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15573         cp $TF $DIR/$tfile
15574         cancel_lru_locks $OSC
15575         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15576         remount_client $MOUNT
15577         df -P $MOUNT
15578         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15579
15580         $TRUNCATE $TF 6000
15581         $TRUNCATE $DIR/$tfile 6000
15582         cancel_lru_locks $OSC
15583         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15584
15585         echo "12345" >>$TF
15586         echo "12345" >>$DIR/$tfile
15587         cancel_lru_locks $OSC
15588         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15589
15590         echo "12345" >>$TF
15591         echo "12345" >>$DIR/$tfile
15592         cancel_lru_locks $OSC
15593         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15594 }
15595 run_test 150a "truncate/append tests"
15596
15597 test_150b() {
15598         check_set_fallocate_or_skip
15599         local out
15600
15601         touch $DIR/$tfile
15602         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15603         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15604                 skip_eopnotsupp "$out|check_fallocate failed"
15605 }
15606 run_test 150b "Verify fallocate (prealloc) functionality"
15607
15608 test_150bb() {
15609         check_set_fallocate_or_skip
15610
15611         touch $DIR/$tfile
15612         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15613         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15614         > $DIR/$tfile
15615         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15616         # precomputed md5sum for 20MB of zeroes
15617         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15618         local sum=($(md5sum $DIR/$tfile))
15619
15620         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15621
15622         check_set_fallocate 1
15623
15624         > $DIR/$tfile
15625         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15626         sum=($(md5sum $DIR/$tfile))
15627
15628         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15629 }
15630 run_test 150bb "Verify fallocate modes both zero space"
15631
15632 test_150c() {
15633         check_set_fallocate_or_skip
15634         local striping="-c2"
15635
15636         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15637         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15638         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15639         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15640         local want=$((OSTCOUNT * 1048576))
15641
15642         # Must allocate all requested space, not more than 5% extra
15643         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15644                 error "bytes $bytes is not $want"
15645
15646         rm -f $DIR/$tfile
15647
15648         echo "verify fallocate on PFL file"
15649
15650         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15651
15652         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15653                 error "Create $DIR/$tfile failed"
15654         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15655         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15656         want=$((512 * 1048576))
15657
15658         # Must allocate all requested space, not more than 5% extra
15659         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15660                 error "bytes $bytes is not $want"
15661 }
15662 run_test 150c "Verify fallocate Size and Blocks"
15663
15664 test_150d() {
15665         check_set_fallocate_or_skip
15666         local striping="-c2"
15667
15668         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15669
15670         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15671         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15672                 error "setstripe failed"
15673         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15674         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15675         local want=$((OSTCOUNT * 1048576))
15676
15677         # Must allocate all requested space, not more than 5% extra
15678         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15679                 error "bytes $bytes is not $want"
15680 }
15681 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15682
15683 test_150e() {
15684         check_set_fallocate_or_skip
15685
15686         echo "df before:"
15687         $LFS df
15688         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15689         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15690                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15691
15692         # Find OST with Minimum Size
15693         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15694                        sort -un | head -1)
15695
15696         # Get 100MB per OST of the available space to reduce run time
15697         # else 60% of the available space if we are running SLOW tests
15698         if [ $SLOW == "no" ]; then
15699                 local space=$((1024 * 100 * OSTCOUNT))
15700         else
15701                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15702         fi
15703
15704         fallocate -l${space}k $DIR/$tfile ||
15705                 error "fallocate ${space}k $DIR/$tfile failed"
15706         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15707
15708         # get size immediately after fallocate. This should be correctly
15709         # updated
15710         local size=$(stat -c '%s' $DIR/$tfile)
15711         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15712
15713         # Sleep for a while for statfs to get updated. And not pull from cache.
15714         sleep 2
15715
15716         echo "df after fallocate:"
15717         $LFS df
15718
15719         (( size / 1024 == space )) || error "size $size != requested $space"
15720         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15721                 error "used $used < space $space"
15722
15723         rm $DIR/$tfile || error "rm failed"
15724         sync
15725         wait_delete_completed
15726
15727         echo "df after unlink:"
15728         $LFS df
15729 }
15730 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15731
15732 test_150f() {
15733         local size
15734         local blocks
15735         local want_size_before=20480 # in bytes
15736         local want_blocks_before=40 # 512 sized blocks
15737         local want_blocks_after=24  # 512 sized blocks
15738         local length=$(((want_blocks_before - want_blocks_after) * 512))
15739
15740         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15741                 skip "need at least 2.14.0 for fallocate punch"
15742
15743         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15744                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15745         fi
15746
15747         check_set_fallocate_or_skip
15748         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15749
15750         [[ "x$DOM" == "xyes" ]] &&
15751                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15752
15753         echo "Verify fallocate punch: Range within the file range"
15754         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15755                 error "dd failed for bs 4096 and count 5"
15756
15757         # Call fallocate with punch range which is within the file range
15758         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15759                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15760         # client must see changes immediately after fallocate
15761         size=$(stat -c '%s' $DIR/$tfile)
15762         blocks=$(stat -c '%b' $DIR/$tfile)
15763
15764         # Verify punch worked.
15765         (( blocks == want_blocks_after )) ||
15766                 error "punch failed: blocks $blocks != $want_blocks_after"
15767
15768         (( size == want_size_before )) ||
15769                 error "punch failed: size $size != $want_size_before"
15770
15771         # Verify there is hole in file
15772         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15773         # precomputed md5sum
15774         local expect="4a9a834a2db02452929c0a348273b4aa"
15775
15776         cksum=($(md5sum $DIR/$tfile))
15777         [[ "${cksum[0]}" == "$expect" ]] ||
15778                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15779
15780         # Start second sub-case for fallocate punch.
15781         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15782         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15783                 error "dd failed for bs 4096 and count 5"
15784
15785         # Punch range less than block size will have no change in block count
15786         want_blocks_after=40  # 512 sized blocks
15787
15788         # Punch overlaps two blocks and less than blocksize
15789         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15790                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15791         size=$(stat -c '%s' $DIR/$tfile)
15792         blocks=$(stat -c '%b' $DIR/$tfile)
15793
15794         # Verify punch worked.
15795         (( blocks == want_blocks_after )) ||
15796                 error "punch failed: blocks $blocks != $want_blocks_after"
15797
15798         (( size == want_size_before )) ||
15799                 error "punch failed: size $size != $want_size_before"
15800
15801         # Verify if range is really zero'ed out. We expect Zeros.
15802         # precomputed md5sum
15803         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15804         cksum=($(md5sum $DIR/$tfile))
15805         [[ "${cksum[0]}" == "$expect" ]] ||
15806                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15807 }
15808 run_test 150f "Verify fallocate punch functionality"
15809
15810 test_150g() {
15811         local space
15812         local size
15813         local blocks
15814         local blocks_after
15815         local size_after
15816         local BS=4096 # Block size in bytes
15817
15818         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15819                 skip "need at least 2.14.0 for fallocate punch"
15820
15821         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15822                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15823         fi
15824
15825         check_set_fallocate_or_skip
15826         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15827
15828         if [[ "x$DOM" == "xyes" ]]; then
15829                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15830                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15831         else
15832                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15833                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15834         fi
15835
15836         # Get 100MB per OST of the available space to reduce run time
15837         # else 60% of the available space if we are running SLOW tests
15838         if [ $SLOW == "no" ]; then
15839                 space=$((1024 * 100 * OSTCOUNT))
15840         else
15841                 # Find OST with Minimum Size
15842                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15843                         sort -un | head -1)
15844                 echo "min size OST: $space"
15845                 space=$(((space * 60)/100 * OSTCOUNT))
15846         fi
15847         # space in 1k units, round to 4k blocks
15848         local blkcount=$((space * 1024 / $BS))
15849
15850         echo "Verify fallocate punch: Very large Range"
15851         fallocate -l${space}k $DIR/$tfile ||
15852                 error "fallocate ${space}k $DIR/$tfile failed"
15853         # write 1M at the end, start and in the middle
15854         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15855                 error "dd failed: bs $BS count 256"
15856         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15857                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15858         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15859                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15860
15861         # Gather stats.
15862         size=$(stat -c '%s' $DIR/$tfile)
15863
15864         # gather punch length.
15865         local punch_size=$((size - (BS * 2)))
15866
15867         echo "punch_size = $punch_size"
15868         echo "size - punch_size: $((size - punch_size))"
15869         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15870
15871         # Call fallocate to punch all except 2 blocks. We leave the
15872         # first and the last block
15873         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15874         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15875                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15876
15877         size_after=$(stat -c '%s' $DIR/$tfile)
15878         blocks_after=$(stat -c '%b' $DIR/$tfile)
15879
15880         # Verify punch worked.
15881         # Size should be kept
15882         (( size == size_after )) ||
15883                 error "punch failed: size $size != $size_after"
15884
15885         # two 4k data blocks to remain plus possible 1 extra extent block
15886         (( blocks_after <= ((BS / 512) * 3) )) ||
15887                 error "too many blocks remains: $blocks_after"
15888
15889         # Verify that file has hole between the first and the last blocks
15890         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15891         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15892
15893         echo "Hole at [$hole_start, $hole_end)"
15894         (( hole_start == BS )) ||
15895                 error "no hole at offset $BS after punch"
15896
15897         (( hole_end == BS + punch_size )) ||
15898                 error "data at offset $hole_end < $((BS + punch_size))"
15899 }
15900 run_test 150g "Verify fallocate punch on large range"
15901
15902 test_150h() {
15903         local file=$DIR/$tfile
15904         local size
15905
15906         check_set_fallocate_or_skip
15907         statx_supported || skip_env "Test must be statx() syscall supported"
15908
15909         # fallocate() does not update the size information on the MDT
15910         fallocate -l 16K $file || error "failed to fallocate $file"
15911         cancel_lru_locks $OSC
15912         # STATX with cached-always mode will not send glimpse RPCs to OST,
15913         # it uses the caching attrs on the client side as much as possible.
15914         size=$($STATX --cached=always -c %s $file)
15915         [ $size == 16384 ] ||
15916                 error "size after fallocate() is $size, expected 16384"
15917 }
15918 run_test 150h "Verify extend fallocate updates the file size"
15919
15920 #LU-2902 roc_hit was not able to read all values from lproc
15921 function roc_hit_init() {
15922         local list=$(comma_list $(osts_nodes))
15923         local dir=$DIR/$tdir-check
15924         local file=$dir/$tfile
15925         local BEFORE
15926         local AFTER
15927         local idx
15928
15929         test_mkdir $dir
15930         #use setstripe to do a write to every ost
15931         for i in $(seq 0 $((OSTCOUNT-1))); do
15932                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15933                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15934                 idx=$(printf %04x $i)
15935                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15936                         awk '$1 == "cache_access" {sum += $7}
15937                                 END { printf("%0.0f", sum) }')
15938
15939                 cancel_lru_locks osc
15940                 cat $file >/dev/null
15941
15942                 AFTER=$(get_osd_param $list *OST*$idx stats |
15943                         awk '$1 == "cache_access" {sum += $7}
15944                                 END { printf("%0.0f", sum) }')
15945
15946                 echo BEFORE:$BEFORE AFTER:$AFTER
15947                 if ! let "AFTER - BEFORE == 4"; then
15948                         rm -rf $dir
15949                         error "roc_hit is not safe to use"
15950                 fi
15951                 rm $file
15952         done
15953
15954         rm -rf $dir
15955 }
15956
15957 function roc_hit() {
15958         local list=$(comma_list $(osts_nodes))
15959         echo $(get_osd_param $list '' stats |
15960                 awk '$1 == "cache_hit" {sum += $7}
15961                         END { printf("%0.0f", sum) }')
15962 }
15963
15964 function set_cache() {
15965         local on=1
15966
15967         if [ "$2" == "off" ]; then
15968                 on=0;
15969         fi
15970         local list=$(comma_list $(osts_nodes))
15971         set_osd_param $list '' $1_cache_enable $on
15972
15973         cancel_lru_locks osc
15974 }
15975
15976 test_151() {
15977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15978         remote_ost_nodsh && skip "remote OST with nodsh"
15979         (( CLIENT_VERSION == OST1_VERSION )) ||
15980                 skip "LU-13081: no interop testing for OSS cache"
15981
15982         local CPAGES=3
15983         local list=$(comma_list $(osts_nodes))
15984
15985         # check whether obdfilter is cache capable at all
15986         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15987                 skip "not cache-capable obdfilter"
15988         fi
15989
15990         # check cache is enabled on all obdfilters
15991         if get_osd_param $list '' read_cache_enable | grep 0; then
15992                 skip "oss cache is disabled"
15993         fi
15994
15995         set_osd_param $list '' writethrough_cache_enable 1
15996
15997         # check write cache is enabled on all obdfilters
15998         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15999                 skip "oss write cache is NOT enabled"
16000         fi
16001
16002         roc_hit_init
16003
16004         #define OBD_FAIL_OBD_NO_LRU  0x609
16005         do_nodes $list $LCTL set_param fail_loc=0x609
16006
16007         # pages should be in the case right after write
16008         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16009                 error "dd failed"
16010
16011         local BEFORE=$(roc_hit)
16012         cancel_lru_locks osc
16013         cat $DIR/$tfile >/dev/null
16014         local AFTER=$(roc_hit)
16015
16016         do_nodes $list $LCTL set_param fail_loc=0
16017
16018         if ! let "AFTER - BEFORE == CPAGES"; then
16019                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16020         fi
16021
16022         cancel_lru_locks osc
16023         # invalidates OST cache
16024         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16025         set_osd_param $list '' read_cache_enable 0
16026         cat $DIR/$tfile >/dev/null
16027
16028         # now data shouldn't be found in the cache
16029         BEFORE=$(roc_hit)
16030         cancel_lru_locks osc
16031         cat $DIR/$tfile >/dev/null
16032         AFTER=$(roc_hit)
16033         if let "AFTER - BEFORE != 0"; then
16034                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16035         fi
16036
16037         set_osd_param $list '' read_cache_enable 1
16038         rm -f $DIR/$tfile
16039 }
16040 run_test 151 "test cache on oss and controls ==============================="
16041
16042 test_152() {
16043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16044
16045         local TF="$TMP/$tfile"
16046
16047         # simulate ENOMEM during write
16048 #define OBD_FAIL_OST_NOMEM      0x226
16049         lctl set_param fail_loc=0x80000226
16050         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16051         cp $TF $DIR/$tfile
16052         sync || error "sync failed"
16053         lctl set_param fail_loc=0
16054
16055         # discard client's cache
16056         cancel_lru_locks osc
16057
16058         # simulate ENOMEM during read
16059         lctl set_param fail_loc=0x80000226
16060         cmp $TF $DIR/$tfile || error "cmp failed"
16061         lctl set_param fail_loc=0
16062
16063         rm -f $TF
16064 }
16065 run_test 152 "test read/write with enomem ============================"
16066
16067 test_153() {
16068         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16069 }
16070 run_test 153 "test if fdatasync does not crash ======================="
16071
16072 dot_lustre_fid_permission_check() {
16073         local fid=$1
16074         local ffid=$MOUNT/.lustre/fid/$fid
16075         local test_dir=$2
16076
16077         echo "stat fid $fid"
16078         stat $ffid || error "stat $ffid failed."
16079         echo "touch fid $fid"
16080         touch $ffid || error "touch $ffid failed."
16081         echo "write to fid $fid"
16082         cat /etc/hosts > $ffid || error "write $ffid failed."
16083         echo "read fid $fid"
16084         diff /etc/hosts $ffid || error "read $ffid failed."
16085         echo "append write to fid $fid"
16086         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16087         echo "rename fid $fid"
16088         mv $ffid $test_dir/$tfile.1 &&
16089                 error "rename $ffid to $tfile.1 should fail."
16090         touch $test_dir/$tfile.1
16091         mv $test_dir/$tfile.1 $ffid &&
16092                 error "rename $tfile.1 to $ffid should fail."
16093         rm -f $test_dir/$tfile.1
16094         echo "truncate fid $fid"
16095         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16096         echo "link fid $fid"
16097         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16098         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16099                 echo "setfacl fid $fid"
16100                 setfacl -R -m u:$USER0:rwx $ffid ||
16101                         error "setfacl $ffid failed"
16102                 echo "getfacl fid $fid"
16103                 getfacl $ffid || error "getfacl $ffid failed."
16104         fi
16105         echo "unlink fid $fid"
16106         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16107         echo "mknod fid $fid"
16108         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16109
16110         fid=[0xf00000400:0x1:0x0]
16111         ffid=$MOUNT/.lustre/fid/$fid
16112
16113         echo "stat non-exist fid $fid"
16114         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16115         echo "write to non-exist fid $fid"
16116         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16117         echo "link new fid $fid"
16118         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16119
16120         mkdir -p $test_dir/$tdir
16121         touch $test_dir/$tdir/$tfile
16122         fid=$($LFS path2fid $test_dir/$tdir)
16123         rc=$?
16124         [ $rc -ne 0 ] &&
16125                 error "error: could not get fid for $test_dir/$dir/$tfile."
16126
16127         ffid=$MOUNT/.lustre/fid/$fid
16128
16129         echo "ls $fid"
16130         ls $ffid || error "ls $ffid failed."
16131         echo "touch $fid/$tfile.1"
16132         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16133
16134         echo "touch $MOUNT/.lustre/fid/$tfile"
16135         touch $MOUNT/.lustre/fid/$tfile && \
16136                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16137
16138         echo "setxattr to $MOUNT/.lustre/fid"
16139         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16140
16141         echo "listxattr for $MOUNT/.lustre/fid"
16142         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16143
16144         echo "delxattr from $MOUNT/.lustre/fid"
16145         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16146
16147         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16148         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16149                 error "touch invalid fid should fail."
16150
16151         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16152         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16153                 error "touch non-normal fid should fail."
16154
16155         echo "rename $tdir to $MOUNT/.lustre/fid"
16156         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16157                 error "rename to $MOUNT/.lustre/fid should fail."
16158
16159         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16160         then            # LU-3547
16161                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16162                 local new_obf_mode=777
16163
16164                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16165                 chmod $new_obf_mode $DIR/.lustre/fid ||
16166                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16167
16168                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16169                 [ $obf_mode -eq $new_obf_mode ] ||
16170                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16171
16172                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16173                 chmod $old_obf_mode $DIR/.lustre/fid ||
16174                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16175         fi
16176
16177         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16178         fid=$($LFS path2fid $test_dir/$tfile-2)
16179
16180         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16181         then # LU-5424
16182                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16183                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16184                         error "create lov data thru .lustre failed"
16185         fi
16186         echo "cp /etc/passwd $test_dir/$tfile-2"
16187         cp /etc/passwd $test_dir/$tfile-2 ||
16188                 error "copy to $test_dir/$tfile-2 failed."
16189         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16190         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16191                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16192
16193         rm -rf $test_dir/tfile.lnk
16194         rm -rf $test_dir/$tfile-2
16195 }
16196
16197 test_154A() {
16198         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16199                 skip "Need MDS version at least 2.4.1"
16200
16201         local tf=$DIR/$tfile
16202         touch $tf
16203
16204         local fid=$($LFS path2fid $tf)
16205         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16206
16207         # check that we get the same pathname back
16208         local rootpath
16209         local found
16210         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16211                 echo "$rootpath $fid"
16212                 found=$($LFS fid2path $rootpath "$fid")
16213                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16214                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16215         done
16216
16217         # check wrong root path format
16218         rootpath=$MOUNT"_wrong"
16219         found=$($LFS fid2path $rootpath "$fid")
16220         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16221 }
16222 run_test 154A "lfs path2fid and fid2path basic checks"
16223
16224 test_154B() {
16225         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16226                 skip "Need MDS version at least 2.4.1"
16227
16228         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16229         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16230         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16231         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16232
16233         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16234         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16235
16236         # check that we get the same pathname
16237         echo "PFID: $PFID, name: $name"
16238         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16239         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16240         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16241                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16242
16243         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16244 }
16245 run_test 154B "verify the ll_decode_linkea tool"
16246
16247 test_154a() {
16248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16249         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16250         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16251                 skip "Need MDS version at least 2.2.51"
16252         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16253
16254         cp /etc/hosts $DIR/$tfile
16255
16256         fid=$($LFS path2fid $DIR/$tfile)
16257         rc=$?
16258         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16259
16260         dot_lustre_fid_permission_check "$fid" $DIR ||
16261                 error "dot lustre permission check $fid failed"
16262
16263         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16264
16265         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16266
16267         touch $MOUNT/.lustre/file &&
16268                 error "creation is not allowed under .lustre"
16269
16270         mkdir $MOUNT/.lustre/dir &&
16271                 error "mkdir is not allowed under .lustre"
16272
16273         rm -rf $DIR/$tfile
16274 }
16275 run_test 154a "Open-by-FID"
16276
16277 test_154b() {
16278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16279         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16281         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16282                 skip "Need MDS version at least 2.2.51"
16283
16284         local remote_dir=$DIR/$tdir/remote_dir
16285         local MDTIDX=1
16286         local rc=0
16287
16288         mkdir -p $DIR/$tdir
16289         $LFS mkdir -i $MDTIDX $remote_dir ||
16290                 error "create remote directory failed"
16291
16292         cp /etc/hosts $remote_dir/$tfile
16293
16294         fid=$($LFS path2fid $remote_dir/$tfile)
16295         rc=$?
16296         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16297
16298         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16299                 error "dot lustre permission check $fid failed"
16300         rm -rf $DIR/$tdir
16301 }
16302 run_test 154b "Open-by-FID for remote directory"
16303
16304 test_154c() {
16305         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16306                 skip "Need MDS version at least 2.4.1"
16307
16308         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16309         local FID1=$($LFS path2fid $DIR/$tfile.1)
16310         local FID2=$($LFS path2fid $DIR/$tfile.2)
16311         local FID3=$($LFS path2fid $DIR/$tfile.3)
16312
16313         local N=1
16314         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16315                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16316                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16317                 local want=FID$N
16318                 [ "$FID" = "${!want}" ] ||
16319                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16320                 N=$((N + 1))
16321         done
16322
16323         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16324         do
16325                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16326                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16327                 N=$((N + 1))
16328         done
16329 }
16330 run_test 154c "lfs path2fid and fid2path multiple arguments"
16331
16332 test_154d() {
16333         remote_mds_nodsh && skip "remote MDS with nodsh"
16334         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16335                 skip "Need MDS version at least 2.5.53"
16336
16337         if remote_mds; then
16338                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16339         else
16340                 nid="0@lo"
16341         fi
16342         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16343         local fd
16344         local cmd
16345
16346         rm -f $DIR/$tfile
16347         touch $DIR/$tfile
16348
16349         local fid=$($LFS path2fid $DIR/$tfile)
16350         # Open the file
16351         fd=$(free_fd)
16352         cmd="exec $fd<$DIR/$tfile"
16353         eval $cmd
16354         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16355         echo "$fid_list" | grep "$fid"
16356         rc=$?
16357
16358         cmd="exec $fd>/dev/null"
16359         eval $cmd
16360         if [ $rc -ne 0 ]; then
16361                 error "FID $fid not found in open files list $fid_list"
16362         fi
16363 }
16364 run_test 154d "Verify open file fid"
16365
16366 test_154e()
16367 {
16368         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16369                 skip "Need MDS version at least 2.6.50"
16370
16371         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16372                 error ".lustre returned by readdir"
16373         fi
16374 }
16375 run_test 154e ".lustre is not returned by readdir"
16376
16377 test_154f() {
16378         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16379
16380         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16381         mkdir_on_mdt0 $DIR/$tdir
16382         # test dirs inherit from its stripe
16383         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16384         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16385         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16386         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16387         touch $DIR/f
16388
16389         # get fid of parents
16390         local FID0=$($LFS path2fid $DIR/$tdir)
16391         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16392         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16393         local FID3=$($LFS path2fid $DIR)
16394
16395         # check that path2fid --parents returns expected <parent_fid>/name
16396         # 1) test for a directory (single parent)
16397         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16398         [ "$parent" == "$FID0/foo1" ] ||
16399                 error "expected parent: $FID0/foo1, got: $parent"
16400
16401         # 2) test for a file with nlink > 1 (multiple parents)
16402         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16403         echo "$parent" | grep -F "$FID1/$tfile" ||
16404                 error "$FID1/$tfile not returned in parent list"
16405         echo "$parent" | grep -F "$FID2/link" ||
16406                 error "$FID2/link not returned in parent list"
16407
16408         # 3) get parent by fid
16409         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16410         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16411         echo "$parent" | grep -F "$FID1/$tfile" ||
16412                 error "$FID1/$tfile not returned in parent list (by fid)"
16413         echo "$parent" | grep -F "$FID2/link" ||
16414                 error "$FID2/link not returned in parent list (by fid)"
16415
16416         # 4) test for entry in root directory
16417         parent=$($LFS path2fid --parents $DIR/f)
16418         echo "$parent" | grep -F "$FID3/f" ||
16419                 error "$FID3/f not returned in parent list"
16420
16421         # 5) test it on root directory
16422         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16423                 error "$MOUNT should not have parents"
16424
16425         # enable xattr caching and check that linkea is correctly updated
16426         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16427         save_lustre_params client "llite.*.xattr_cache" > $save
16428         lctl set_param llite.*.xattr_cache 1
16429
16430         # 6.1) linkea update on rename
16431         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16432
16433         # get parents by fid
16434         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16435         # foo1 should no longer be returned in parent list
16436         echo "$parent" | grep -F "$FID1" &&
16437                 error "$FID1 should no longer be in parent list"
16438         # the new path should appear
16439         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16440                 error "$FID2/$tfile.moved is not in parent list"
16441
16442         # 6.2) linkea update on unlink
16443         rm -f $DIR/$tdir/foo2/link
16444         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16445         # foo2/link should no longer be returned in parent list
16446         echo "$parent" | grep -F "$FID2/link" &&
16447                 error "$FID2/link should no longer be in parent list"
16448         true
16449
16450         rm -f $DIR/f
16451         restore_lustre_params < $save
16452         rm -f $save
16453 }
16454 run_test 154f "get parent fids by reading link ea"
16455
16456 test_154g()
16457 {
16458         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16459            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16460                 skip "Need MDS version at least 2.6.92"
16461
16462         mkdir_on_mdt0 $DIR/$tdir
16463         llapi_fid_test -d $DIR/$tdir
16464 }
16465 run_test 154g "various llapi FID tests"
16466
16467 test_154h()
16468 {
16469         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16470                 skip "Need client at least version 2.15.55.1"
16471
16472         # Create an empty file
16473         touch $DIR/$tfile
16474
16475         # Get FID (interactive mode) and save under $TMP/$tfile.log
16476         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16477                 path2fid $DIR/$tfile
16478         EOF
16479
16480         fid=$(cat $TMP/$tfile.log)
16481         # $fid should not be empty
16482         [[ ! -z $fid ]] || error "FID is empty"
16483         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16484 }
16485 run_test 154h "Verify interactive path2fid"
16486
16487 test_155_small_load() {
16488     local temp=$TMP/$tfile
16489     local file=$DIR/$tfile
16490
16491     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16492         error "dd of=$temp bs=6096 count=1 failed"
16493     cp $temp $file
16494     cancel_lru_locks $OSC
16495     cmp $temp $file || error "$temp $file differ"
16496
16497     $TRUNCATE $temp 6000
16498     $TRUNCATE $file 6000
16499     cmp $temp $file || error "$temp $file differ (truncate1)"
16500
16501     echo "12345" >>$temp
16502     echo "12345" >>$file
16503     cmp $temp $file || error "$temp $file differ (append1)"
16504
16505     echo "12345" >>$temp
16506     echo "12345" >>$file
16507     cmp $temp $file || error "$temp $file differ (append2)"
16508
16509     rm -f $temp $file
16510     true
16511 }
16512
16513 test_155_big_load() {
16514         remote_ost_nodsh && skip "remote OST with nodsh"
16515
16516         local temp=$TMP/$tfile
16517         local file=$DIR/$tfile
16518
16519         free_min_max
16520         local cache_size=$(do_facet ost$((MAXI+1)) \
16521                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16522
16523         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16524         # pre-set value
16525         if [ -z "$cache_size" ]; then
16526                 cache_size=256
16527         fi
16528         local large_file_size=$((cache_size * 2))
16529
16530         echo "OSS cache size: $cache_size KB"
16531         echo "Large file size: $large_file_size KB"
16532
16533         [ $MAXV -le $large_file_size ] &&
16534                 skip_env "max available OST size needs > $large_file_size KB"
16535
16536         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16537
16538         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16539                 error "dd of=$temp bs=$large_file_size count=1k failed"
16540         cp $temp $file
16541         ls -lh $temp $file
16542         cancel_lru_locks osc
16543         cmp $temp $file || error "$temp $file differ"
16544
16545         rm -f $temp $file
16546         true
16547 }
16548
16549 save_writethrough() {
16550         local facets=$(get_facets OST)
16551
16552         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16553 }
16554
16555 test_155a() {
16556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16557
16558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16559
16560         save_writethrough $p
16561
16562         set_cache read on
16563         set_cache writethrough on
16564         test_155_small_load
16565         restore_lustre_params < $p
16566         rm -f $p
16567 }
16568 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16569
16570 test_155b() {
16571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16572
16573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16574
16575         save_writethrough $p
16576
16577         set_cache read on
16578         set_cache writethrough off
16579         test_155_small_load
16580         restore_lustre_params < $p
16581         rm -f $p
16582 }
16583 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16584
16585 test_155c() {
16586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16587
16588         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16589
16590         save_writethrough $p
16591
16592         set_cache read off
16593         set_cache writethrough on
16594         test_155_small_load
16595         restore_lustre_params < $p
16596         rm -f $p
16597 }
16598 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16599
16600 test_155d() {
16601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16602
16603         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16604
16605         save_writethrough $p
16606
16607         set_cache read off
16608         set_cache writethrough off
16609         test_155_small_load
16610         restore_lustre_params < $p
16611         rm -f $p
16612 }
16613 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16614
16615 test_155e() {
16616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16617
16618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16619
16620         save_writethrough $p
16621
16622         set_cache read on
16623         set_cache writethrough on
16624         test_155_big_load
16625         restore_lustre_params < $p
16626         rm -f $p
16627 }
16628 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16629
16630 test_155f() {
16631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16632
16633         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16634
16635         save_writethrough $p
16636
16637         set_cache read on
16638         set_cache writethrough off
16639         test_155_big_load
16640         restore_lustre_params < $p
16641         rm -f $p
16642 }
16643 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16644
16645 test_155g() {
16646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16647
16648         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16649
16650         save_writethrough $p
16651
16652         set_cache read off
16653         set_cache writethrough on
16654         test_155_big_load
16655         restore_lustre_params < $p
16656         rm -f $p
16657 }
16658 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16659
16660 test_155h() {
16661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16662
16663         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16664
16665         save_writethrough $p
16666
16667         set_cache read off
16668         set_cache writethrough off
16669         test_155_big_load
16670         restore_lustre_params < $p
16671         rm -f $p
16672 }
16673 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16674
16675 test_156() {
16676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16677         remote_ost_nodsh && skip "remote OST with nodsh"
16678         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16679                 skip "stats not implemented on old servers"
16680         [ "$ost1_FSTYPE" = "zfs" ] &&
16681                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16682         (( CLIENT_VERSION == OST1_VERSION )) ||
16683                 skip "LU-13081: no interop testing for OSS cache"
16684
16685         local CPAGES=3
16686         local BEFORE
16687         local AFTER
16688         local file="$DIR/$tfile"
16689         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16690
16691         save_writethrough $p
16692         roc_hit_init
16693
16694         log "Turn on read and write cache"
16695         set_cache read on
16696         set_cache writethrough on
16697
16698         log "Write data and read it back."
16699         log "Read should be satisfied from the cache."
16700         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16701         BEFORE=$(roc_hit)
16702         cancel_lru_locks osc
16703         cat $file >/dev/null
16704         AFTER=$(roc_hit)
16705         if ! let "AFTER - BEFORE == CPAGES"; then
16706                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16707         else
16708                 log "cache hits: before: $BEFORE, after: $AFTER"
16709         fi
16710
16711         log "Read again; it should be satisfied from the cache."
16712         BEFORE=$AFTER
16713         cancel_lru_locks osc
16714         cat $file >/dev/null
16715         AFTER=$(roc_hit)
16716         if ! let "AFTER - BEFORE == CPAGES"; then
16717                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16718         else
16719                 log "cache hits:: before: $BEFORE, after: $AFTER"
16720         fi
16721
16722         log "Turn off the read cache and turn on the write cache"
16723         set_cache read off
16724         set_cache writethrough on
16725
16726         log "Read again; it should be satisfied from the cache."
16727         BEFORE=$(roc_hit)
16728         cancel_lru_locks osc
16729         cat $file >/dev/null
16730         AFTER=$(roc_hit)
16731         if ! let "AFTER - BEFORE == CPAGES"; then
16732                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16733         else
16734                 log "cache hits:: before: $BEFORE, after: $AFTER"
16735         fi
16736
16737         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16738                 # > 2.12.56 uses pagecache if cached
16739                 log "Read again; it should not be satisfied from the cache."
16740                 BEFORE=$AFTER
16741                 cancel_lru_locks osc
16742                 cat $file >/dev/null
16743                 AFTER=$(roc_hit)
16744                 if ! let "AFTER - BEFORE == 0"; then
16745                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16746                 else
16747                         log "cache hits:: before: $BEFORE, after: $AFTER"
16748                 fi
16749         fi
16750
16751         log "Write data and read it back."
16752         log "Read should be satisfied from the cache."
16753         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16754         BEFORE=$(roc_hit)
16755         cancel_lru_locks osc
16756         cat $file >/dev/null
16757         AFTER=$(roc_hit)
16758         if ! let "AFTER - BEFORE == CPAGES"; then
16759                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16760         else
16761                 log "cache hits:: before: $BEFORE, after: $AFTER"
16762         fi
16763
16764         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16765                 # > 2.12.56 uses pagecache if cached
16766                 log "Read again; it should not be satisfied from the cache."
16767                 BEFORE=$AFTER
16768                 cancel_lru_locks osc
16769                 cat $file >/dev/null
16770                 AFTER=$(roc_hit)
16771                 if ! let "AFTER - BEFORE == 0"; then
16772                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16773                 else
16774                         log "cache hits:: before: $BEFORE, after: $AFTER"
16775                 fi
16776         fi
16777
16778         log "Turn off read and write cache"
16779         set_cache read off
16780         set_cache writethrough off
16781
16782         log "Write data and read it back"
16783         log "It should not be satisfied from the cache."
16784         rm -f $file
16785         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16786         cancel_lru_locks osc
16787         BEFORE=$(roc_hit)
16788         cat $file >/dev/null
16789         AFTER=$(roc_hit)
16790         if ! let "AFTER - BEFORE == 0"; then
16791                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16792         else
16793                 log "cache hits:: before: $BEFORE, after: $AFTER"
16794         fi
16795
16796         log "Turn on the read cache and turn off the write cache"
16797         set_cache read on
16798         set_cache writethrough off
16799
16800         log "Write data and read it back"
16801         log "It should not be satisfied from the cache."
16802         rm -f $file
16803         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16804         BEFORE=$(roc_hit)
16805         cancel_lru_locks osc
16806         cat $file >/dev/null
16807         AFTER=$(roc_hit)
16808         if ! let "AFTER - BEFORE == 0"; then
16809                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16810         else
16811                 log "cache hits:: before: $BEFORE, after: $AFTER"
16812         fi
16813
16814         log "Read again; it should be satisfied from the cache."
16815         BEFORE=$(roc_hit)
16816         cancel_lru_locks osc
16817         cat $file >/dev/null
16818         AFTER=$(roc_hit)
16819         if ! let "AFTER - BEFORE == CPAGES"; then
16820                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16821         else
16822                 log "cache hits:: before: $BEFORE, after: $AFTER"
16823         fi
16824
16825         restore_lustre_params < $p
16826         rm -f $p $file
16827 }
16828 run_test 156 "Verification of tunables"
16829
16830 test_160a() {
16831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16832         remote_mds_nodsh && skip "remote MDS with nodsh"
16833         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16834                 skip "Need MDS version at least 2.2.0"
16835
16836         changelog_register || error "changelog_register failed"
16837         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16838         changelog_users $SINGLEMDS | grep -q $cl_user ||
16839                 error "User $cl_user not found in changelog_users"
16840
16841         mkdir_on_mdt0 $DIR/$tdir
16842
16843         # change something
16844         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16845         changelog_clear 0 || error "changelog_clear failed"
16846         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16847         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16848         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16849         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16850         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16851         rm $DIR/$tdir/pics/desktop.jpg
16852
16853         echo "verifying changelog mask"
16854         changelog_chmask "-MKDIR"
16855         changelog_chmask "-CLOSE"
16856
16857         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16858         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16859
16860         changelog_chmask "+MKDIR"
16861         changelog_chmask "+CLOSE"
16862
16863         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16864         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16865
16866         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16867         CLOSES=$(changelog_dump | grep -c "CLOSE")
16868         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16869         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16870
16871         # verify contents
16872         echo "verifying target fid"
16873         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16874         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16875         [ "$fidc" == "$fidf" ] ||
16876                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16877         echo "verifying parent fid"
16878         # The FID returned from the Changelog may be the directory shard on
16879         # a different MDT, and not the FID returned by path2fid on the parent.
16880         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16881         # since this is what will matter when recreating this file in the tree.
16882         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16883         local pathp=$($LFS fid2path $MOUNT "$fidp")
16884         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16885                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16886
16887         echo "getting records for $cl_user"
16888         changelog_users $SINGLEMDS
16889         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16890         local nclr=3
16891         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16892                 error "changelog_clear failed"
16893         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16894         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16895         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16896                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16897
16898         local min0_rec=$(changelog_users $SINGLEMDS |
16899                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16900         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16901                           awk '{ print $1; exit; }')
16902
16903         changelog_dump | tail -n 5
16904         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16905         [ $first_rec == $((min0_rec + 1)) ] ||
16906                 error "first index should be $min0_rec + 1 not $first_rec"
16907
16908         # LU-3446 changelog index reset on MDT restart
16909         local cur_rec1=$(changelog_users $SINGLEMDS |
16910                          awk '/^current.index:/ { print $NF }')
16911         changelog_clear 0 ||
16912                 error "clear all changelog records for $cl_user failed"
16913         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16914         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16915                 error "Fail to start $SINGLEMDS"
16916         local cur_rec2=$(changelog_users $SINGLEMDS |
16917                          awk '/^current.index:/ { print $NF }')
16918         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16919         [ $cur_rec1 == $cur_rec2 ] ||
16920                 error "current index should be $cur_rec1 not $cur_rec2"
16921
16922         echo "verifying users from this test are deregistered"
16923         changelog_deregister || error "changelog_deregister failed"
16924         changelog_users $SINGLEMDS | grep -q $cl_user &&
16925                 error "User '$cl_user' still in changelog_users"
16926
16927         # lctl get_param -n mdd.*.changelog_users
16928         # current_index: 144
16929         # ID    index (idle seconds)
16930         # cl3   144   (2) mask=<list>
16931         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16932                 # this is the normal case where all users were deregistered
16933                 # make sure no new records are added when no users are present
16934                 local last_rec1=$(changelog_users $SINGLEMDS |
16935                                   awk '/^current.index:/ { print $NF }')
16936                 touch $DIR/$tdir/chloe
16937                 local last_rec2=$(changelog_users $SINGLEMDS |
16938                                   awk '/^current.index:/ { print $NF }')
16939                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16940                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16941         else
16942                 # any changelog users must be leftovers from a previous test
16943                 changelog_users $SINGLEMDS
16944                 echo "other changelog users; can't verify off"
16945         fi
16946 }
16947 run_test 160a "changelog sanity"
16948
16949 test_160b() { # LU-3587
16950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16951         remote_mds_nodsh && skip "remote MDS with nodsh"
16952         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16953                 skip "Need MDS version at least 2.2.0"
16954
16955         changelog_register || error "changelog_register failed"
16956         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16957         changelog_users $SINGLEMDS | grep -q $cl_user ||
16958                 error "User '$cl_user' not found in changelog_users"
16959
16960         local longname1=$(str_repeat a 255)
16961         local longname2=$(str_repeat b 255)
16962
16963         cd $DIR
16964         echo "creating very long named file"
16965         touch $longname1 || error "create of '$longname1' failed"
16966         echo "renaming very long named file"
16967         mv $longname1 $longname2
16968
16969         changelog_dump | grep RENME | tail -n 5
16970         rm -f $longname2
16971 }
16972 run_test 160b "Verify that very long rename doesn't crash in changelog"
16973
16974 test_160c() {
16975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16976         remote_mds_nodsh && skip "remote MDS with nodsh"
16977
16978         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16979                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16980                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16981                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16982
16983         local rc=0
16984
16985         # Registration step
16986         changelog_register || error "changelog_register failed"
16987
16988         rm -rf $DIR/$tdir
16989         mkdir -p $DIR/$tdir
16990         $MCREATE $DIR/$tdir/foo_160c
16991         changelog_chmask "-TRUNC"
16992         $TRUNCATE $DIR/$tdir/foo_160c 200
16993         changelog_chmask "+TRUNC"
16994         $TRUNCATE $DIR/$tdir/foo_160c 199
16995         changelog_dump | tail -n 5
16996         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16997         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16998 }
16999 run_test 160c "verify that changelog log catch the truncate event"
17000
17001 test_160d() {
17002         remote_mds_nodsh && skip "remote MDS with nodsh"
17003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17005         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17006                 skip "Need MDS version at least 2.7.60"
17007
17008         # Registration step
17009         changelog_register || error "changelog_register failed"
17010
17011         mkdir -p $DIR/$tdir/migrate_dir
17012         changelog_clear 0 || error "changelog_clear failed"
17013
17014         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17015         changelog_dump | tail -n 5
17016         local migrates=$(changelog_dump | grep -c "MIGRT")
17017         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17018 }
17019 run_test 160d "verify that changelog log catch the migrate event"
17020
17021 test_160e() {
17022         remote_mds_nodsh && skip "remote MDS with nodsh"
17023
17024         # Create a user
17025         changelog_register || error "changelog_register failed"
17026
17027         local MDT0=$(facet_svc $SINGLEMDS)
17028         local rc
17029
17030         # No user (expect fail)
17031         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17032         rc=$?
17033         if [ $rc -eq 0 ]; then
17034                 error "Should fail without user"
17035         elif [ $rc -ne 4 ]; then
17036                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17037         fi
17038
17039         # Delete a future user (expect fail)
17040         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17041         rc=$?
17042         if [ $rc -eq 0 ]; then
17043                 error "Deleted non-existant user cl77"
17044         elif [ $rc -ne 2 ]; then
17045                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17046         fi
17047
17048         # Clear to a bad index (1 billion should be safe)
17049         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17050         rc=$?
17051
17052         if [ $rc -eq 0 ]; then
17053                 error "Successfully cleared to invalid CL index"
17054         elif [ $rc -ne 22 ]; then
17055                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17056         fi
17057 }
17058 run_test 160e "changelog negative testing (should return errors)"
17059
17060 test_160f() {
17061         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17062         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17063                 skip "Need MDS version at least 2.10.56"
17064
17065         local mdts=$(comma_list $(mdts_nodes))
17066
17067         # Create a user
17068         changelog_register || error "first changelog_register failed"
17069         changelog_register || error "second changelog_register failed"
17070         local cl_users
17071         declare -A cl_user1
17072         declare -A cl_user2
17073         local user_rec1
17074         local user_rec2
17075         local i
17076
17077         # generate some changelog records to accumulate on each MDT
17078         # use all_char because created files should be evenly distributed
17079         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17080                 error "test_mkdir $tdir failed"
17081         log "$(date +%s): creating first files"
17082         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17083                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17084                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17085         done
17086
17087         # check changelogs have been generated
17088         local start=$SECONDS
17089         local idle_time=$((MDSCOUNT * 5 + 5))
17090         local nbcl=$(changelog_dump | wc -l)
17091         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17092
17093         for param in "changelog_max_idle_time=$idle_time" \
17094                      "changelog_gc=1" \
17095                      "changelog_min_gc_interval=2" \
17096                      "changelog_min_free_cat_entries=3"; do
17097                 local MDT0=$(facet_svc $SINGLEMDS)
17098                 local var="${param%=*}"
17099                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17100
17101                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17102                 do_nodes $mdts $LCTL set_param mdd.*.$param
17103         done
17104
17105         # force cl_user2 to be idle (1st part), but also cancel the
17106         # cl_user1 records so that it is not evicted later in the test.
17107         local sleep1=$((idle_time / 2))
17108         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17109         sleep $sleep1
17110
17111         # simulate changelog catalog almost full
17112         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17113         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17114
17115         for i in $(seq $MDSCOUNT); do
17116                 cl_users=(${CL_USERS[mds$i]})
17117                 cl_user1[mds$i]="${cl_users[0]}"
17118                 cl_user2[mds$i]="${cl_users[1]}"
17119
17120                 [ -n "${cl_user1[mds$i]}" ] ||
17121                         error "mds$i: no user registered"
17122                 [ -n "${cl_user2[mds$i]}" ] ||
17123                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17124
17125                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17126                 [ -n "$user_rec1" ] ||
17127                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17128                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17129                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17130                 [ -n "$user_rec2" ] ||
17131                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17132                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17133                      "$user_rec1 + 2 == $user_rec2"
17134                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17135                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17136                               "$user_rec1 + 2, but is $user_rec2"
17137                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17138                 [ -n "$user_rec2" ] ||
17139                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17140                 [ $user_rec1 == $user_rec2 ] ||
17141                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17142                               "$user_rec1, but is $user_rec2"
17143         done
17144
17145         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17146         local sleep2=$((idle_time - (SECONDS - start) + 1))
17147         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17148         sleep $sleep2
17149
17150         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17151         # cl_user1 should be OK because it recently processed records.
17152         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17153         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17154                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17155                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17156         done
17157
17158         # ensure gc thread is done
17159         for i in $(mdts_nodes); do
17160                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17161                         error "$i: GC-thread not done"
17162         done
17163
17164         local first_rec
17165         for (( i = 1; i <= MDSCOUNT; i++ )); do
17166                 # check cl_user1 still registered
17167                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17168                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17169                 # check cl_user2 unregistered
17170                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17171                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17172
17173                 # check changelogs are present and starting at $user_rec1 + 1
17174                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17175                 [ -n "$user_rec1" ] ||
17176                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17177                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17178                             awk '{ print $1; exit; }')
17179
17180                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17181                 [ $((user_rec1 + 1)) == $first_rec ] ||
17182                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17183         done
17184 }
17185 run_test 160f "changelog garbage collect (timestamped users)"
17186
17187 test_160g() {
17188         remote_mds_nodsh && skip "remote MDS with nodsh"
17189         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17190                 skip "Need MDS version at least 2.14.55"
17191
17192         local mdts=$(comma_list $(mdts_nodes))
17193
17194         # Create a user
17195         changelog_register || error "first changelog_register failed"
17196         changelog_register || error "second changelog_register failed"
17197         local cl_users
17198         declare -A cl_user1
17199         declare -A cl_user2
17200         local user_rec1
17201         local user_rec2
17202         local i
17203
17204         # generate some changelog records to accumulate on each MDT
17205         # use all_char because created files should be evenly distributed
17206         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17207                 error "test_mkdir $tdir failed"
17208         for ((i = 0; i < MDSCOUNT; i++)); do
17209                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17210                         error "create $DIR/$tdir/d$i.1 failed"
17211         done
17212
17213         # check changelogs have been generated
17214         local nbcl=$(changelog_dump | wc -l)
17215         (( $nbcl > 0 )) || error "no changelogs found"
17216
17217         # reduce the max_idle_indexes value to make sure we exceed it
17218         for param in "changelog_max_idle_indexes=2" \
17219                      "changelog_gc=1" \
17220                      "changelog_min_gc_interval=2"; do
17221                 local MDT0=$(facet_svc $SINGLEMDS)
17222                 local var="${param%=*}"
17223                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17224
17225                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17226                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17227                         error "unable to set mdd.*.$param"
17228         done
17229
17230         local start=$SECONDS
17231         for i in $(seq $MDSCOUNT); do
17232                 cl_users=(${CL_USERS[mds$i]})
17233                 cl_user1[mds$i]="${cl_users[0]}"
17234                 cl_user2[mds$i]="${cl_users[1]}"
17235
17236                 [ -n "${cl_user1[mds$i]}" ] ||
17237                         error "mds$i: user1 is not registered"
17238                 [ -n "${cl_user2[mds$i]}" ] ||
17239                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17240
17241                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17242                 [ -n "$user_rec1" ] ||
17243                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17244                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17245                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17246                 [ -n "$user_rec2" ] ||
17247                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17248                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17249                      "$user_rec1 + 2 == $user_rec2"
17250                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17251                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17252                               "expected $user_rec1 + 2, but is $user_rec2"
17253                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17254                 [ -n "$user_rec2" ] ||
17255                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17256                 [ $user_rec1 == $user_rec2 ] ||
17257                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17258                               "expected $user_rec1, but is $user_rec2"
17259         done
17260
17261         # ensure we are past the previous changelog_min_gc_interval set above
17262         local sleep2=$((start + 2 - SECONDS))
17263         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17264         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17265         # cl_user1 should be OK because it recently processed records.
17266         for ((i = 0; i < MDSCOUNT; i++)); do
17267                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17268                         error "create $DIR/$tdir/d$i.3 failed"
17269         done
17270
17271         # ensure gc thread is done
17272         for i in $(mdts_nodes); do
17273                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17274                         error "$i: GC-thread not done"
17275         done
17276
17277         local first_rec
17278         for (( i = 1; i <= MDSCOUNT; i++ )); do
17279                 # check cl_user1 still registered
17280                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17281                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17282                 # check cl_user2 unregistered
17283                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17284                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17285
17286                 # check changelogs are present and starting at $user_rec1 + 1
17287                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17288                 [ -n "$user_rec1" ] ||
17289                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17290                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17291                             awk '{ print $1; exit; }')
17292
17293                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17294                 [ $((user_rec1 + 1)) == $first_rec ] ||
17295                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17296         done
17297 }
17298 run_test 160g "changelog garbage collect on idle records"
17299
17300 test_160h() {
17301         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17302         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17303                 skip "Need MDS version at least 2.10.56"
17304
17305         local mdts=$(comma_list $(mdts_nodes))
17306
17307         # Create a user
17308         changelog_register || error "first changelog_register failed"
17309         changelog_register || error "second changelog_register failed"
17310         local cl_users
17311         declare -A cl_user1
17312         declare -A cl_user2
17313         local user_rec1
17314         local user_rec2
17315         local i
17316
17317         # generate some changelog records to accumulate on each MDT
17318         # use all_char because created files should be evenly distributed
17319         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17320                 error "test_mkdir $tdir failed"
17321         for ((i = 0; i < MDSCOUNT; i++)); do
17322                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17323                         error "create $DIR/$tdir/d$i.1 failed"
17324         done
17325
17326         # check changelogs have been generated
17327         local nbcl=$(changelog_dump | wc -l)
17328         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17329
17330         for param in "changelog_max_idle_time=10" \
17331                      "changelog_gc=1" \
17332                      "changelog_min_gc_interval=2"; do
17333                 local MDT0=$(facet_svc $SINGLEMDS)
17334                 local var="${param%=*}"
17335                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17336
17337                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17338                 do_nodes $mdts $LCTL set_param mdd.*.$param
17339         done
17340
17341         # force cl_user2 to be idle (1st part)
17342         sleep 9
17343
17344         for i in $(seq $MDSCOUNT); do
17345                 cl_users=(${CL_USERS[mds$i]})
17346                 cl_user1[mds$i]="${cl_users[0]}"
17347                 cl_user2[mds$i]="${cl_users[1]}"
17348
17349                 [ -n "${cl_user1[mds$i]}" ] ||
17350                         error "mds$i: no user registered"
17351                 [ -n "${cl_user2[mds$i]}" ] ||
17352                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17353
17354                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17355                 [ -n "$user_rec1" ] ||
17356                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17357                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17358                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17359                 [ -n "$user_rec2" ] ||
17360                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17361                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17362                      "$user_rec1 + 2 == $user_rec2"
17363                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17364                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17365                               "$user_rec1 + 2, but is $user_rec2"
17366                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17367                 [ -n "$user_rec2" ] ||
17368                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17369                 [ $user_rec1 == $user_rec2 ] ||
17370                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17371                               "$user_rec1, but is $user_rec2"
17372         done
17373
17374         # force cl_user2 to be idle (2nd part) and to reach
17375         # changelog_max_idle_time
17376         sleep 2
17377
17378         # force each GC-thread start and block then
17379         # one per MDT/MDD, set fail_val accordingly
17380         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17381         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17382
17383         # generate more changelogs to trigger fail_loc
17384         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17385                 error "create $DIR/$tdir/${tfile}bis failed"
17386
17387         # stop MDT to stop GC-thread, should be done in back-ground as it will
17388         # block waiting for the thread to be released and exit
17389         declare -A stop_pids
17390         for i in $(seq $MDSCOUNT); do
17391                 stop mds$i &
17392                 stop_pids[mds$i]=$!
17393         done
17394
17395         for i in $(mdts_nodes); do
17396                 local facet
17397                 local nb=0
17398                 local facets=$(facets_up_on_host $i)
17399
17400                 for facet in ${facets//,/ }; do
17401                         if [[ $facet == mds* ]]; then
17402                                 nb=$((nb + 1))
17403                         fi
17404                 done
17405                 # ensure each MDS's gc threads are still present and all in "R"
17406                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17407                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17408                         error "$i: expected $nb GC-thread"
17409                 wait_update $i \
17410                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17411                         "R" 20 ||
17412                         error "$i: GC-thread not found in R-state"
17413                 # check umounts of each MDT on MDS have reached kthread_stop()
17414                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17415                         error "$i: expected $nb umount"
17416                 wait_update $i \
17417                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17418                         error "$i: umount not found in D-state"
17419         done
17420
17421         # release all GC-threads
17422         do_nodes $mdts $LCTL set_param fail_loc=0
17423
17424         # wait for MDT stop to complete
17425         for i in $(seq $MDSCOUNT); do
17426                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17427         done
17428
17429         # XXX
17430         # may try to check if any orphan changelog records are present
17431         # via ldiskfs/zfs and llog_reader...
17432
17433         # re-start/mount MDTs
17434         for i in $(seq $MDSCOUNT); do
17435                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17436                         error "Fail to start mds$i"
17437         done
17438
17439         local first_rec
17440         for i in $(seq $MDSCOUNT); do
17441                 # check cl_user1 still registered
17442                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17443                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17444                 # check cl_user2 unregistered
17445                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17446                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17447
17448                 # check changelogs are present and starting at $user_rec1 + 1
17449                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17450                 [ -n "$user_rec1" ] ||
17451                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17452                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17453                             awk '{ print $1; exit; }')
17454
17455                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17456                 [ $((user_rec1 + 1)) == $first_rec ] ||
17457                         error "mds$i: first index should be $user_rec1 + 1, " \
17458                               "but is $first_rec"
17459         done
17460 }
17461 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17462               "during mount"
17463
17464 test_160i() {
17465
17466         local mdts=$(comma_list $(mdts_nodes))
17467
17468         changelog_register || error "first changelog_register failed"
17469
17470         # generate some changelog records to accumulate on each MDT
17471         # use all_char because created files should be evenly distributed
17472         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17473                 error "test_mkdir $tdir failed"
17474         for ((i = 0; i < MDSCOUNT; i++)); do
17475                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17476                         error "create $DIR/$tdir/d$i.1 failed"
17477         done
17478
17479         # check changelogs have been generated
17480         local nbcl=$(changelog_dump | wc -l)
17481         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17482
17483         # simulate race between register and unregister
17484         # XXX as fail_loc is set per-MDS, with DNE configs the race
17485         # simulation will only occur for one MDT per MDS and for the
17486         # others the normal race scenario will take place
17487         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17488         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17489         do_nodes $mdts $LCTL set_param fail_val=1
17490
17491         # unregister 1st user
17492         changelog_deregister &
17493         local pid1=$!
17494         # wait some time for deregister work to reach race rdv
17495         sleep 2
17496         # register 2nd user
17497         changelog_register || error "2nd user register failed"
17498
17499         wait $pid1 || error "1st user deregister failed"
17500
17501         local i
17502         local last_rec
17503         declare -A LAST_REC
17504         for i in $(seq $MDSCOUNT); do
17505                 if changelog_users mds$i | grep "^cl"; then
17506                         # make sure new records are added with one user present
17507                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17508                                           awk '/^current.index:/ { print $NF }')
17509                 else
17510                         error "mds$i has no user registered"
17511                 fi
17512         done
17513
17514         # generate more changelog records to accumulate on each MDT
17515         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17516                 error "create $DIR/$tdir/${tfile}bis failed"
17517
17518         for i in $(seq $MDSCOUNT); do
17519                 last_rec=$(changelog_users $SINGLEMDS |
17520                            awk '/^current.index:/ { print $NF }')
17521                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17522                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17523                         error "changelogs are off on mds$i"
17524         done
17525 }
17526 run_test 160i "changelog user register/unregister race"
17527
17528 test_160j() {
17529         remote_mds_nodsh && skip "remote MDS with nodsh"
17530         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17531                 skip "Need MDS version at least 2.12.56"
17532
17533         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17534         stack_trap "umount $MOUNT2" EXIT
17535
17536         changelog_register || error "first changelog_register failed"
17537         stack_trap "changelog_deregister" EXIT
17538
17539         # generate some changelog
17540         # use all_char because created files should be evenly distributed
17541         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17542                 error "mkdir $tdir failed"
17543         for ((i = 0; i < MDSCOUNT; i++)); do
17544                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17545                         error "create $DIR/$tdir/d$i.1 failed"
17546         done
17547
17548         # open the changelog device
17549         exec 3>/dev/changelog-$FSNAME-MDT0000
17550         stack_trap "exec 3>&-" EXIT
17551         exec 4</dev/changelog-$FSNAME-MDT0000
17552         stack_trap "exec 4<&-" EXIT
17553
17554         # umount the first lustre mount
17555         umount $MOUNT
17556         stack_trap "mount_client $MOUNT" EXIT
17557
17558         # read changelog, which may or may not fail, but should not crash
17559         cat <&4 >/dev/null
17560
17561         # clear changelog
17562         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17563         changelog_users $SINGLEMDS | grep -q $cl_user ||
17564                 error "User $cl_user not found in changelog_users"
17565
17566         printf 'clear:'$cl_user':0' >&3
17567 }
17568 run_test 160j "client can be umounted while its chanangelog is being used"
17569
17570 test_160k() {
17571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17572         remote_mds_nodsh && skip "remote MDS with nodsh"
17573
17574         mkdir -p $DIR/$tdir/1/1
17575
17576         changelog_register || error "changelog_register failed"
17577         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17578
17579         changelog_users $SINGLEMDS | grep -q $cl_user ||
17580                 error "User '$cl_user' not found in changelog_users"
17581 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17582         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17583         rmdir $DIR/$tdir/1/1 & sleep 1
17584         mkdir $DIR/$tdir/2
17585         touch $DIR/$tdir/2/2
17586         rm -rf $DIR/$tdir/2
17587
17588         wait
17589         sleep 4
17590
17591         changelog_dump | grep rmdir || error "rmdir not recorded"
17592 }
17593 run_test 160k "Verify that changelog records are not lost"
17594
17595 # Verifies that a file passed as a parameter has recently had an operation
17596 # performed on it that has generated an MTIME changelog which contains the
17597 # correct parent FID. As files might reside on a different MDT from the
17598 # parent directory in DNE configurations, the FIDs are translated to paths
17599 # before being compared, which should be identical
17600 compare_mtime_changelog() {
17601         local file="${1}"
17602         local mdtidx
17603         local mtime
17604         local cl_fid
17605         local pdir
17606         local dir
17607
17608         mdtidx=$($LFS getstripe --mdt-index $file)
17609         mdtidx=$(printf "%04x" $mdtidx)
17610
17611         # Obtain the parent FID from the MTIME changelog
17612         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17613         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17614
17615         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17616         [ -z "$cl_fid" ] && error "parent FID not present"
17617
17618         # Verify that the path for the parent FID is the same as the path for
17619         # the test directory
17620         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17621
17622         dir=$(dirname $1)
17623
17624         [[ "${pdir%/}" == "$dir" ]] ||
17625                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17626 }
17627
17628 test_160l() {
17629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17630
17631         remote_mds_nodsh && skip "remote MDS with nodsh"
17632         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17633                 skip "Need MDS version at least 2.13.55"
17634
17635         local cl_user
17636
17637         changelog_register || error "changelog_register failed"
17638         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17639
17640         changelog_users $SINGLEMDS | grep -q $cl_user ||
17641                 error "User '$cl_user' not found in changelog_users"
17642
17643         # Clear some types so that MTIME changelogs are generated
17644         changelog_chmask "-CREAT"
17645         changelog_chmask "-CLOSE"
17646
17647         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17648
17649         # Test CL_MTIME during setattr
17650         touch $DIR/$tdir/$tfile
17651         compare_mtime_changelog $DIR/$tdir/$tfile
17652
17653         # Test CL_MTIME during close
17654         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17655         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17656 }
17657 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17658
17659 test_160m() {
17660         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17661         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17662                 skip "Need MDS version at least 2.14.51"
17663         local cl_users
17664         local cl_user1
17665         local cl_user2
17666         local pid1
17667
17668         # Create a user
17669         changelog_register || error "first changelog_register failed"
17670         changelog_register || error "second changelog_register failed"
17671
17672         cl_users=(${CL_USERS[mds1]})
17673         cl_user1="${cl_users[0]}"
17674         cl_user2="${cl_users[1]}"
17675         # generate some changelog records to accumulate on MDT0
17676         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17677         createmany -m $DIR/$tdir/$tfile 50 ||
17678                 error "create $DIR/$tdir/$tfile failed"
17679         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17680         rm -f $DIR/$tdir
17681
17682         # check changelogs have been generated
17683         local nbcl=$(changelog_dump | wc -l)
17684         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17685
17686 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17687         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17688
17689         __changelog_clear mds1 $cl_user1 +10
17690         __changelog_clear mds1 $cl_user2 0 &
17691         pid1=$!
17692         sleep 2
17693         __changelog_clear mds1 $cl_user1 0 ||
17694                 error "fail to cancel record for $cl_user1"
17695         wait $pid1
17696         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17697 }
17698 run_test 160m "Changelog clear race"
17699
17700 test_160n() {
17701         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17702         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17703                 skip "Need MDS version at least 2.14.51"
17704         local cl_users
17705         local cl_user1
17706         local cl_user2
17707         local pid1
17708         local first_rec
17709         local last_rec=0
17710
17711         # Create a user
17712         changelog_register || error "first changelog_register failed"
17713
17714         cl_users=(${CL_USERS[mds1]})
17715         cl_user1="${cl_users[0]}"
17716
17717         # generate some changelog records to accumulate on MDT0
17718         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17719         first_rec=$(changelog_users $SINGLEMDS |
17720                         awk '/^current.index:/ { print $NF }')
17721         while (( last_rec < (( first_rec + 65000)) )); do
17722                 createmany -m $DIR/$tdir/$tfile 10000 ||
17723                         error "create $DIR/$tdir/$tfile failed"
17724
17725                 for i in $(seq 0 10000); do
17726                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17727                                 > /dev/null
17728                 done
17729
17730                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17731                         error "unlinkmany failed unlink"
17732                 last_rec=$(changelog_users $SINGLEMDS |
17733                         awk '/^current.index:/ { print $NF }')
17734                 echo last record $last_rec
17735                 (( last_rec == 0 )) && error "no changelog found"
17736         done
17737
17738 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17739         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17740
17741         __changelog_clear mds1 $cl_user1 0 &
17742         pid1=$!
17743         sleep 2
17744         __changelog_clear mds1 $cl_user1 0 ||
17745                 error "fail to cancel record for $cl_user1"
17746         wait $pid1
17747         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17748 }
17749 run_test 160n "Changelog destroy race"
17750
17751 test_160o() {
17752         local mdt="$(facet_svc $SINGLEMDS)"
17753
17754         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17755         remote_mds_nodsh && skip "remote MDS with nodsh"
17756         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17757                 skip "Need MDS version at least 2.14.52"
17758
17759         changelog_register --user test_160o -m unlnk+close+open ||
17760                 error "changelog_register failed"
17761
17762         do_facet $SINGLEMDS $LCTL --device $mdt \
17763                                 changelog_register -u "Tt3_-#" &&
17764                 error "bad symbols in name should fail"
17765
17766         do_facet $SINGLEMDS $LCTL --device $mdt \
17767                                 changelog_register -u test_160o &&
17768                 error "the same name registration should fail"
17769
17770         do_facet $SINGLEMDS $LCTL --device $mdt \
17771                         changelog_register -u test_160toolongname &&
17772                 error "too long name registration should fail"
17773
17774         changelog_chmask "MARK+HSM"
17775         lctl get_param mdd.*.changelog*mask
17776         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17777         changelog_users $SINGLEMDS | grep -q $cl_user ||
17778                 error "User $cl_user not found in changelog_users"
17779         #verify username
17780         echo $cl_user | grep -q test_160o ||
17781                 error "User $cl_user has no specific name 'test160o'"
17782
17783         # change something
17784         changelog_clear 0 || error "changelog_clear failed"
17785         # generate some changelog records to accumulate on MDT0
17786         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17787         touch $DIR/$tdir/$tfile                 # open 1
17788
17789         OPENS=$(changelog_dump | grep -c "OPEN")
17790         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17791
17792         # must be no MKDIR it wasn't set as user mask
17793         MKDIR=$(changelog_dump | grep -c "MKDIR")
17794         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17795
17796         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17797                                 mdd.$mdt.changelog_current_mask -n)
17798         # register maskless user
17799         changelog_register || error "changelog_register failed"
17800         # effective mask should be not changed because it is not minimal
17801         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17802                                 mdd.$mdt.changelog_current_mask -n)
17803         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17804         # set server mask to minimal value
17805         changelog_chmask "MARK"
17806         # check effective mask again, should be treated as DEFMASK now
17807         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17808                                 mdd.$mdt.changelog_current_mask -n)
17809         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17810
17811         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17812                 # set server mask back to some value
17813                 changelog_chmask "CLOSE,UNLNK"
17814                 # check effective mask again, should not remain as DEFMASK
17815                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17816                                 mdd.$mdt.changelog_current_mask -n)
17817                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17818         fi
17819
17820         do_facet $SINGLEMDS $LCTL --device $mdt \
17821                                 changelog_deregister -u test_160o ||
17822                 error "cannot deregister by name"
17823 }
17824 run_test 160o "changelog user name and mask"
17825
17826 test_160p() {
17827         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17828         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17829                 skip "Need MDS version at least 2.14.51"
17830         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17831         local cl_users
17832         local cl_user1
17833         local entry_count
17834
17835         # Create a user
17836         changelog_register || error "first changelog_register failed"
17837
17838         cl_users=(${CL_USERS[mds1]})
17839         cl_user1="${cl_users[0]}"
17840
17841         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17842         createmany -m $DIR/$tdir/$tfile 50 ||
17843                 error "create $DIR/$tdir/$tfile failed"
17844         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17845         rm -rf $DIR/$tdir
17846
17847         # check changelogs have been generated
17848         entry_count=$(changelog_dump | wc -l)
17849         ((entry_count != 0)) || error "no changelog entries found"
17850
17851         # remove changelog_users and check that orphan entries are removed
17852         stop mds1
17853         local dev=$(mdsdevname 1)
17854         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17855         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17856         entry_count=$(changelog_dump | wc -l)
17857         ((entry_count == 0)) ||
17858                 error "found $entry_count changelog entries, expected none"
17859 }
17860 run_test 160p "Changelog orphan cleanup with no users"
17861
17862 test_160q() {
17863         local mdt="$(facet_svc $SINGLEMDS)"
17864         local clu
17865
17866         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17867         remote_mds_nodsh && skip "remote MDS with nodsh"
17868         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17869                 skip "Need MDS version at least 2.14.54"
17870
17871         # set server mask to minimal value like server init does
17872         changelog_chmask "MARK"
17873         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17874                 error "changelog_register failed"
17875         # check effective mask again, should be treated as DEFMASK now
17876         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17877                                 mdd.$mdt.changelog_current_mask -n)
17878         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17879                 error "changelog_deregister failed"
17880         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17881 }
17882 run_test 160q "changelog effective mask is DEFMASK if not set"
17883
17884 test_160s() {
17885         remote_mds_nodsh && skip "remote MDS with nodsh"
17886         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17887                 skip "Need MDS version at least 2.14.55"
17888
17889         local mdts=$(comma_list $(mdts_nodes))
17890
17891         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17892         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17893                                        fail_val=$((24 * 3600 * 10))
17894
17895         # Create a user which is 10 days old
17896         changelog_register || error "first changelog_register failed"
17897         local cl_users
17898         declare -A cl_user1
17899         local i
17900
17901         # generate some changelog records to accumulate on each MDT
17902         # use all_char because created files should be evenly distributed
17903         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17904                 error "test_mkdir $tdir failed"
17905         for ((i = 0; i < MDSCOUNT; i++)); do
17906                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17907                         error "create $DIR/$tdir/d$i.1 failed"
17908         done
17909
17910         # check changelogs have been generated
17911         local nbcl=$(changelog_dump | wc -l)
17912         (( nbcl > 0 )) || error "no changelogs found"
17913
17914         # reduce the max_idle_indexes value to make sure we exceed it
17915         for param in "changelog_max_idle_indexes=2097446912" \
17916                      "changelog_max_idle_time=2592000" \
17917                      "changelog_gc=1" \
17918                      "changelog_min_gc_interval=2"; do
17919                 local MDT0=$(facet_svc $SINGLEMDS)
17920                 local var="${param%=*}"
17921                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17922
17923                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17924                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17925                         error "unable to set mdd.*.$param"
17926         done
17927
17928         local start=$SECONDS
17929         for i in $(seq $MDSCOUNT); do
17930                 cl_users=(${CL_USERS[mds$i]})
17931                 cl_user1[mds$i]="${cl_users[0]}"
17932
17933                 [[ -n "${cl_user1[mds$i]}" ]] ||
17934                         error "mds$i: no user registered"
17935         done
17936
17937         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17938         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17939
17940         # ensure we are past the previous changelog_min_gc_interval set above
17941         local sleep2=$((start + 2 - SECONDS))
17942         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17943
17944         # Generate one more changelog to trigger GC
17945         for ((i = 0; i < MDSCOUNT; i++)); do
17946                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17947                         error "create $DIR/$tdir/d$i.3 failed"
17948         done
17949
17950         # ensure gc thread is done
17951         for node in $(mdts_nodes); do
17952                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17953                         error "$node: GC-thread not done"
17954         done
17955
17956         do_nodes $mdts $LCTL set_param fail_loc=0
17957
17958         for (( i = 1; i <= MDSCOUNT; i++ )); do
17959                 # check cl_user1 is purged
17960                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17961                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17962         done
17963         return 0
17964 }
17965 run_test 160s "changelog garbage collect on idle records * time"
17966
17967 test_160t() {
17968         remote_mds_nodsh && skip "remote MDS with nodsh"
17969         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17970                 skip "Need MDS version at least 2.15.50"
17971
17972         local MDT0=$(facet_svc $SINGLEMDS)
17973         local cl_users
17974         local cl_user1
17975         local cl_user2
17976         local start
17977
17978         changelog_register --user user1 -m all ||
17979                 error "user1 failed to register"
17980
17981         mkdir_on_mdt0 $DIR/$tdir
17982         # create default overstripe to maximize changelog size
17983         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17984         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17985         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17986
17987         # user2 consumes less records so less space
17988         changelog_register --user user2 || error "user2 failed to register"
17989         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17990         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17991
17992         # check changelogs have been generated
17993         local nbcl=$(changelog_dump | wc -l)
17994         (( nbcl > 0 )) || error "no changelogs found"
17995
17996         # reduce the changelog_min_gc_interval to force check
17997         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17998                 local var="${param%=*}"
17999                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18000
18001                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18002                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18003                         error "unable to set mdd.*.$param"
18004         done
18005
18006         start=$SECONDS
18007         cl_users=(${CL_USERS[mds1]})
18008         cl_user1="${cl_users[0]}"
18009         cl_user2="${cl_users[1]}"
18010
18011         [[ -n $cl_user1 ]] ||
18012                 error "mds1: user #1 isn't registered"
18013         [[ -n $cl_user2 ]] ||
18014                 error "mds1: user #2 isn't registered"
18015
18016         # ensure we are past the previous changelog_min_gc_interval set above
18017         local sleep2=$((start + 2 - SECONDS))
18018         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18019
18020         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18021         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18022                         fail_val=$(((llog_size1 + llog_size2) / 2))
18023
18024         # Generate more changelog to trigger GC
18025         createmany -o $DIR/$tdir/u3_ 4 ||
18026                 error "create failed for more files"
18027
18028         # ensure gc thread is done
18029         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18030                 error "mds1: GC-thread not done"
18031
18032         do_facet mds1 $LCTL set_param fail_loc=0
18033
18034         # check cl_user1 is purged
18035         changelog_users mds1 | grep -q "$cl_user1" &&
18036                 error "User $cl_user1 is registered"
18037         # check cl_user2 is not purged
18038         changelog_users mds1 | grep -q "$cl_user2" ||
18039                 error "User $cl_user2 is not registered"
18040 }
18041 run_test 160t "changelog garbage collect on lack of space"
18042
18043 test_161a() {
18044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18045
18046         test_mkdir -c1 $DIR/$tdir
18047         cp /etc/hosts $DIR/$tdir/$tfile
18048         test_mkdir -c1 $DIR/$tdir/foo1
18049         test_mkdir -c1 $DIR/$tdir/foo2
18050         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18051         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18052         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18053         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18054         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18055         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18056                 $LFS fid2path $DIR $FID
18057                 error "bad link ea"
18058         fi
18059         # middle
18060         rm $DIR/$tdir/foo2/zachary
18061         # last
18062         rm $DIR/$tdir/foo2/thor
18063         # first
18064         rm $DIR/$tdir/$tfile
18065         # rename
18066         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18067         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18068                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18069         rm $DIR/$tdir/foo2/maggie
18070
18071         # overflow the EA
18072         local longname=$tfile.avg_len_is_thirty_two_
18073         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18074                 error_noexit 'failed to unlink many hardlinks'" EXIT
18075         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18076                 error "failed to hardlink many files"
18077         links=$($LFS fid2path $DIR $FID | wc -l)
18078         echo -n "${links}/1000 links in link EA"
18079         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18080 }
18081 run_test 161a "link ea sanity"
18082
18083 test_161b() {
18084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18085         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18086
18087         local MDTIDX=1
18088         local remote_dir=$DIR/$tdir/remote_dir
18089
18090         mkdir -p $DIR/$tdir
18091         $LFS mkdir -i $MDTIDX $remote_dir ||
18092                 error "create remote directory failed"
18093
18094         cp /etc/hosts $remote_dir/$tfile
18095         mkdir -p $remote_dir/foo1
18096         mkdir -p $remote_dir/foo2
18097         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18098         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18099         ln $remote_dir/$tfile $remote_dir/foo1/luna
18100         ln $remote_dir/$tfile $remote_dir/foo2/thor
18101
18102         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18103                      tr -d ']')
18104         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18105                 $LFS fid2path $DIR $FID
18106                 error "bad link ea"
18107         fi
18108         # middle
18109         rm $remote_dir/foo2/zachary
18110         # last
18111         rm $remote_dir/foo2/thor
18112         # first
18113         rm $remote_dir/$tfile
18114         # rename
18115         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18116         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18117         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18118                 $LFS fid2path $DIR $FID
18119                 error "bad link rename"
18120         fi
18121         rm $remote_dir/foo2/maggie
18122
18123         # overflow the EA
18124         local longname=filename_avg_len_is_thirty_two_
18125         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18126                 error "failed to hardlink many files"
18127         links=$($LFS fid2path $DIR $FID | wc -l)
18128         echo -n "${links}/1000 links in link EA"
18129         [[ ${links} -gt 60 ]] ||
18130                 error "expected at least 60 links in link EA"
18131         unlinkmany $remote_dir/foo2/$longname 1000 ||
18132         error "failed to unlink many hardlinks"
18133 }
18134 run_test 161b "link ea sanity under remote directory"
18135
18136 test_161c() {
18137         remote_mds_nodsh && skip "remote MDS with nodsh"
18138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18139         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18140                 skip "Need MDS version at least 2.1.5"
18141
18142         # define CLF_RENAME_LAST 0x0001
18143         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18144         changelog_register || error "changelog_register failed"
18145
18146         rm -rf $DIR/$tdir
18147         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18148         touch $DIR/$tdir/foo_161c
18149         touch $DIR/$tdir/bar_161c
18150         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18151         changelog_dump | grep RENME | tail -n 5
18152         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18153         changelog_clear 0 || error "changelog_clear failed"
18154         if [ x$flags != "x0x1" ]; then
18155                 error "flag $flags is not 0x1"
18156         fi
18157
18158         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18159         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18160         touch $DIR/$tdir/foo_161c
18161         touch $DIR/$tdir/bar_161c
18162         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18163         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18164         changelog_dump | grep RENME | tail -n 5
18165         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18166         changelog_clear 0 || error "changelog_clear failed"
18167         if [ x$flags != "x0x0" ]; then
18168                 error "flag $flags is not 0x0"
18169         fi
18170         echo "rename overwrite a target having nlink > 1," \
18171                 "changelog record has flags of $flags"
18172
18173         # rename doesn't overwrite a target (changelog flag 0x0)
18174         touch $DIR/$tdir/foo_161c
18175         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18176         changelog_dump | grep RENME | tail -n 5
18177         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18178         changelog_clear 0 || error "changelog_clear failed"
18179         if [ x$flags != "x0x0" ]; then
18180                 error "flag $flags is not 0x0"
18181         fi
18182         echo "rename doesn't overwrite a target," \
18183                 "changelog record has flags of $flags"
18184
18185         # define CLF_UNLINK_LAST 0x0001
18186         # unlink a file having nlink = 1 (changelog flag 0x1)
18187         rm -f $DIR/$tdir/foo2_161c
18188         changelog_dump | grep UNLNK | tail -n 5
18189         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18190         changelog_clear 0 || error "changelog_clear failed"
18191         if [ x$flags != "x0x1" ]; then
18192                 error "flag $flags is not 0x1"
18193         fi
18194         echo "unlink a file having nlink = 1," \
18195                 "changelog record has flags of $flags"
18196
18197         # unlink a file having nlink > 1 (changelog flag 0x0)
18198         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18199         rm -f $DIR/$tdir/foobar_161c
18200         changelog_dump | grep UNLNK | tail -n 5
18201         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18202         changelog_clear 0 || error "changelog_clear failed"
18203         if [ x$flags != "x0x0" ]; then
18204                 error "flag $flags is not 0x0"
18205         fi
18206         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18207 }
18208 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18209
18210 test_161d() {
18211         remote_mds_nodsh && skip "remote MDS with nodsh"
18212         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18213
18214         local pid
18215         local fid
18216
18217         changelog_register || error "changelog_register failed"
18218
18219         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18220         # interfer with $MOUNT/.lustre/fid/ access
18221         mkdir $DIR/$tdir
18222         [[ $? -eq 0 ]] || error "mkdir failed"
18223
18224         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18225         $LCTL set_param fail_loc=0x8000140c
18226         # 5s pause
18227         $LCTL set_param fail_val=5
18228
18229         # create file
18230         echo foofoo > $DIR/$tdir/$tfile &
18231         pid=$!
18232
18233         # wait for create to be delayed
18234         sleep 2
18235
18236         ps -p $pid
18237         [[ $? -eq 0 ]] || error "create should be blocked"
18238
18239         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18240         stack_trap "rm -f $tempfile"
18241         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18242         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18243         # some delay may occur during ChangeLog publishing and file read just
18244         # above, that could allow file write to happen finally
18245         [[ -s $tempfile ]] && echo "file should be empty"
18246
18247         $LCTL set_param fail_loc=0
18248
18249         wait $pid
18250         [[ $? -eq 0 ]] || error "create failed"
18251 }
18252 run_test 161d "create with concurrent .lustre/fid access"
18253
18254 check_path() {
18255         local expected="$1"
18256         shift
18257         local fid="$2"
18258
18259         local path
18260         path=$($LFS fid2path "$@")
18261         local rc=$?
18262
18263         if [ $rc -ne 0 ]; then
18264                 error "path looked up of '$expected' failed: rc=$rc"
18265         elif [ "$path" != "$expected" ]; then
18266                 error "path looked up '$path' instead of '$expected'"
18267         else
18268                 echo "FID '$fid' resolves to path '$path' as expected"
18269         fi
18270 }
18271
18272 test_162a() { # was test_162
18273         test_mkdir -p -c1 $DIR/$tdir/d2
18274         touch $DIR/$tdir/d2/$tfile
18275         touch $DIR/$tdir/d2/x1
18276         touch $DIR/$tdir/d2/x2
18277         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18278         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18279         # regular file
18280         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18281         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18282
18283         # softlink
18284         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18285         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18286         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18287
18288         # softlink to wrong file
18289         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18290         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18291         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18292
18293         # hardlink
18294         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18295         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18296         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18297         # fid2path dir/fsname should both work
18298         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18299         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18300
18301         # hardlink count: check that there are 2 links
18302         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18303         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18304
18305         # hardlink indexing: remove the first link
18306         rm $DIR/$tdir/d2/p/q/r/hlink
18307         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18308 }
18309 run_test 162a "path lookup sanity"
18310
18311 test_162b() {
18312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18313         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18314
18315         mkdir $DIR/$tdir
18316         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18317                                 error "create striped dir failed"
18318
18319         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18320                                         tail -n 1 | awk '{print $2}')
18321         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18322
18323         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18324         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18325
18326         # regular file
18327         for ((i=0;i<5;i++)); do
18328                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18329                         error "get fid for f$i failed"
18330                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18331
18332                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18333                         error "get fid for d$i failed"
18334                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18335         done
18336
18337         return 0
18338 }
18339 run_test 162b "striped directory path lookup sanity"
18340
18341 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18342 test_162c() {
18343         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18344                 skip "Need MDS version at least 2.7.51"
18345
18346         local lpath=$tdir.local
18347         local rpath=$tdir.remote
18348
18349         test_mkdir $DIR/$lpath
18350         test_mkdir $DIR/$rpath
18351
18352         for ((i = 0; i <= 101; i++)); do
18353                 lpath="$lpath/$i"
18354                 mkdir $DIR/$lpath
18355                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18356                         error "get fid for local directory $DIR/$lpath failed"
18357                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18358
18359                 rpath="$rpath/$i"
18360                 test_mkdir $DIR/$rpath
18361                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18362                         error "get fid for remote directory $DIR/$rpath failed"
18363                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18364         done
18365
18366         return 0
18367 }
18368 run_test 162c "fid2path works with paths 100 or more directories deep"
18369
18370 oalr_event_count() {
18371         local event="${1}"
18372         local trace="${2}"
18373
18374         awk -v name="${FSNAME}-OST0000" \
18375             -v event="${event}" \
18376             '$1 == "TRACE" && $2 == event && $3 == name' \
18377             "${trace}" |
18378         wc -l
18379 }
18380
18381 oalr_expect_event_count() {
18382         local event="${1}"
18383         local trace="${2}"
18384         local expect="${3}"
18385         local count
18386
18387         count=$(oalr_event_count "${event}" "${trace}")
18388         if ((count == expect)); then
18389                 return 0
18390         fi
18391
18392         error_noexit "${event} event count was '${count}', expected ${expect}"
18393         cat "${trace}" >&2
18394         exit 1
18395 }
18396
18397 cleanup_165() {
18398         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18399         stop ost1
18400         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18401 }
18402
18403 setup_165() {
18404         sync # Flush previous IOs so we can count log entries.
18405         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18406         stack_trap cleanup_165 EXIT
18407 }
18408
18409 test_165a() {
18410         local trace="/tmp/${tfile}.trace"
18411         local rc
18412         local count
18413
18414         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18415                 skip "OFD access log unsupported"
18416
18417         setup_165
18418         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18419         sleep 5
18420
18421         do_facet ost1 ofd_access_log_reader --list
18422         stop ost1
18423
18424         do_facet ost1 killall -TERM ofd_access_log_reader
18425         wait
18426         rc=$?
18427
18428         if ((rc != 0)); then
18429                 error "ofd_access_log_reader exited with rc = '${rc}'"
18430         fi
18431
18432         # Parse trace file for discovery events:
18433         oalr_expect_event_count alr_log_add "${trace}" 1
18434         oalr_expect_event_count alr_log_eof "${trace}" 1
18435         oalr_expect_event_count alr_log_free "${trace}" 1
18436 }
18437 run_test 165a "ofd access log discovery"
18438
18439 test_165b() {
18440         local trace="/tmp/${tfile}.trace"
18441         local file="${DIR}/${tfile}"
18442         local pfid1
18443         local pfid2
18444         local -a entry
18445         local rc
18446         local count
18447         local size
18448         local flags
18449
18450         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18451                 skip "OFD access log unsupported"
18452
18453         setup_165
18454         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18455         sleep 5
18456
18457         do_facet ost1 ofd_access_log_reader --list
18458
18459         lfs setstripe -c 1 -i 0 "${file}"
18460         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18461                 error "cannot create '${file}'"
18462
18463         sleep 5
18464         do_facet ost1 killall -TERM ofd_access_log_reader
18465         wait
18466         rc=$?
18467
18468         if ((rc != 0)); then
18469                 error "ofd_access_log_reader exited with rc = '${rc}'"
18470         fi
18471
18472         oalr_expect_event_count alr_log_entry "${trace}" 1
18473
18474         pfid1=$($LFS path2fid "${file}")
18475
18476         # 1     2             3   4    5     6   7    8    9     10
18477         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18478         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18479
18480         echo "entry = '${entry[*]}'" >&2
18481
18482         pfid2=${entry[4]}
18483         if [[ "${pfid1}" != "${pfid2}" ]]; then
18484                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18485         fi
18486
18487         size=${entry[8]}
18488         if ((size != 1048576)); then
18489                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18490         fi
18491
18492         flags=${entry[10]}
18493         if [[ "${flags}" != "w" ]]; then
18494                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18495         fi
18496
18497         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18498         sleep 5
18499
18500         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18501                 error "cannot read '${file}'"
18502         sleep 5
18503
18504         do_facet ost1 killall -TERM ofd_access_log_reader
18505         wait
18506         rc=$?
18507
18508         if ((rc != 0)); then
18509                 error "ofd_access_log_reader exited with rc = '${rc}'"
18510         fi
18511
18512         oalr_expect_event_count alr_log_entry "${trace}" 1
18513
18514         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18515         echo "entry = '${entry[*]}'" >&2
18516
18517         pfid2=${entry[4]}
18518         if [[ "${pfid1}" != "${pfid2}" ]]; then
18519                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18520         fi
18521
18522         size=${entry[8]}
18523         if ((size != 524288)); then
18524                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18525         fi
18526
18527         flags=${entry[10]}
18528         if [[ "${flags}" != "r" ]]; then
18529                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18530         fi
18531 }
18532 run_test 165b "ofd access log entries are produced and consumed"
18533
18534 test_165c() {
18535         local trace="/tmp/${tfile}.trace"
18536         local file="${DIR}/${tdir}/${tfile}"
18537
18538         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18539                 skip "OFD access log unsupported"
18540
18541         test_mkdir "${DIR}/${tdir}"
18542
18543         setup_165
18544         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18545         sleep 5
18546
18547         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18548
18549         # 4096 / 64 = 64. Create twice as many entries.
18550         for ((i = 0; i < 128; i++)); do
18551                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18552                         error "cannot create file"
18553         done
18554
18555         sync
18556
18557         do_facet ost1 killall -TERM ofd_access_log_reader
18558         wait
18559         rc=$?
18560         if ((rc != 0)); then
18561                 error "ofd_access_log_reader exited with rc = '${rc}'"
18562         fi
18563
18564         unlinkmany  "${file}-%d" 128
18565 }
18566 run_test 165c "full ofd access logs do not block IOs"
18567
18568 oal_get_read_count() {
18569         local stats="$1"
18570
18571         # STATS lustre-OST0001 alr_read_count 1
18572
18573         do_facet ost1 cat "${stats}" |
18574         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18575              END { print count; }'
18576 }
18577
18578 oal_expect_read_count() {
18579         local stats="$1"
18580         local count
18581         local expect="$2"
18582
18583         # Ask ofd_access_log_reader to write stats.
18584         do_facet ost1 killall -USR1 ofd_access_log_reader
18585
18586         # Allow some time for things to happen.
18587         sleep 1
18588
18589         count=$(oal_get_read_count "${stats}")
18590         if ((count == expect)); then
18591                 return 0
18592         fi
18593
18594         error_noexit "bad read count, got ${count}, expected ${expect}"
18595         do_facet ost1 cat "${stats}" >&2
18596         exit 1
18597 }
18598
18599 test_165d() {
18600         local stats="/tmp/${tfile}.stats"
18601         local file="${DIR}/${tdir}/${tfile}"
18602         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18603
18604         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18605                 skip "OFD access log unsupported"
18606
18607         test_mkdir "${DIR}/${tdir}"
18608
18609         setup_165
18610         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18611         sleep 5
18612
18613         lfs setstripe -c 1 -i 0 "${file}"
18614
18615         do_facet ost1 lctl set_param "${param}=rw"
18616         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18617                 error "cannot create '${file}'"
18618         oal_expect_read_count "${stats}" 1
18619
18620         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18621                 error "cannot read '${file}'"
18622         oal_expect_read_count "${stats}" 2
18623
18624         do_facet ost1 lctl set_param "${param}=r"
18625         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18626                 error "cannot create '${file}'"
18627         oal_expect_read_count "${stats}" 2
18628
18629         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18630                 error "cannot read '${file}'"
18631         oal_expect_read_count "${stats}" 3
18632
18633         do_facet ost1 lctl set_param "${param}=w"
18634         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18635                 error "cannot create '${file}'"
18636         oal_expect_read_count "${stats}" 4
18637
18638         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18639                 error "cannot read '${file}'"
18640         oal_expect_read_count "${stats}" 4
18641
18642         do_facet ost1 lctl set_param "${param}=0"
18643         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18644                 error "cannot create '${file}'"
18645         oal_expect_read_count "${stats}" 4
18646
18647         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18648                 error "cannot read '${file}'"
18649         oal_expect_read_count "${stats}" 4
18650
18651         do_facet ost1 killall -TERM ofd_access_log_reader
18652         wait
18653         rc=$?
18654         if ((rc != 0)); then
18655                 error "ofd_access_log_reader exited with rc = '${rc}'"
18656         fi
18657 }
18658 run_test 165d "ofd_access_log mask works"
18659
18660 test_165e() {
18661         local stats="/tmp/${tfile}.stats"
18662         local file0="${DIR}/${tdir}-0/${tfile}"
18663         local file1="${DIR}/${tdir}-1/${tfile}"
18664
18665         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18666                 skip "OFD access log unsupported"
18667
18668         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18669
18670         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18671         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18672
18673         lfs setstripe -c 1 -i 0 "${file0}"
18674         lfs setstripe -c 1 -i 0 "${file1}"
18675
18676         setup_165
18677         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18678         sleep 5
18679
18680         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18681                 error "cannot create '${file0}'"
18682         sync
18683         oal_expect_read_count "${stats}" 0
18684
18685         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18686                 error "cannot create '${file1}'"
18687         sync
18688         oal_expect_read_count "${stats}" 1
18689
18690         do_facet ost1 killall -TERM ofd_access_log_reader
18691         wait
18692         rc=$?
18693         if ((rc != 0)); then
18694                 error "ofd_access_log_reader exited with rc = '${rc}'"
18695         fi
18696 }
18697 run_test 165e "ofd_access_log MDT index filter works"
18698
18699 test_165f() {
18700         local trace="/tmp/${tfile}.trace"
18701         local rc
18702         local count
18703
18704         setup_165
18705         do_facet ost1 timeout 60 ofd_access_log_reader \
18706                 --exit-on-close --debug=- --trace=- > "${trace}" &
18707         sleep 5
18708         stop ost1
18709
18710         wait
18711         rc=$?
18712
18713         if ((rc != 0)); then
18714                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18715                 cat "${trace}"
18716                 exit 1
18717         fi
18718 }
18719 run_test 165f "ofd_access_log_reader --exit-on-close works"
18720
18721 test_169() {
18722         # do directio so as not to populate the page cache
18723         log "creating a 10 Mb file"
18724         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18725                 error "multiop failed while creating a file"
18726         log "starting reads"
18727         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18728         log "truncating the file"
18729         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18730                 error "multiop failed while truncating the file"
18731         log "killing dd"
18732         kill %+ || true # reads might have finished
18733         echo "wait until dd is finished"
18734         wait
18735         log "removing the temporary file"
18736         rm -rf $DIR/$tfile || error "tmp file removal failed"
18737 }
18738 run_test 169 "parallel read and truncate should not deadlock"
18739
18740 test_170() {
18741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18742
18743         $LCTL clear     # bug 18514
18744         $LCTL debug_daemon start $TMP/${tfile}_log_good
18745         touch $DIR/$tfile
18746         $LCTL debug_daemon stop
18747         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18748                 error "sed failed to read log_good"
18749
18750         $LCTL debug_daemon start $TMP/${tfile}_log_good
18751         rm -rf $DIR/$tfile
18752         $LCTL debug_daemon stop
18753
18754         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18755                error "lctl df log_bad failed"
18756
18757         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18758         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18759
18760         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18761         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18762
18763         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18764                 error "bad_line good_line1 good_line2 are empty"
18765
18766         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18767         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18768         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18769
18770         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18771         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18772         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18773
18774         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18775                 error "bad_line_new good_line_new are empty"
18776
18777         local expected_good=$((good_line1 + good_line2*2))
18778
18779         rm -f $TMP/${tfile}*
18780         # LU-231, short malformed line may not be counted into bad lines
18781         if [ $bad_line -ne $bad_line_new ] &&
18782                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18783                 error "expected $bad_line bad lines, but got $bad_line_new"
18784                 return 1
18785         fi
18786
18787         if [ $expected_good -ne $good_line_new ]; then
18788                 error "expected $expected_good good lines, but got $good_line_new"
18789                 return 2
18790         fi
18791         true
18792 }
18793 run_test 170 "test lctl df to handle corrupted log ====================="
18794
18795 test_171() { # bug20592
18796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18797
18798         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18799         $LCTL set_param fail_loc=0x50e
18800         $LCTL set_param fail_val=3000
18801         multiop_bg_pause $DIR/$tfile O_s || true
18802         local MULTIPID=$!
18803         kill -USR1 $MULTIPID
18804         # cause log dump
18805         sleep 3
18806         wait $MULTIPID
18807         if dmesg | grep "recursive fault"; then
18808                 error "caught a recursive fault"
18809         fi
18810         $LCTL set_param fail_loc=0
18811         true
18812 }
18813 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18814
18815 test_172() {
18816
18817         #define OBD_FAIL_OBD_CLEANUP  0x60e
18818         $LCTL set_param fail_loc=0x60e
18819         umount $MOUNT || error "umount $MOUNT failed"
18820         stack_trap "mount_client $MOUNT"
18821
18822         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18823                 error "no client OBDs are remained"
18824
18825         $LCTL dl | while read devno state type name foo; do
18826                 case $type in
18827                 lov|osc|lmv|mdc)
18828                         $LCTL --device $name cleanup
18829                         $LCTL --device $name detach
18830                         ;;
18831                 *)
18832                         # skip server devices
18833                         ;;
18834                 esac
18835         done
18836
18837         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18838                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18839                 error "some client OBDs are still remained"
18840         fi
18841
18842 }
18843 run_test 172 "manual device removal with lctl cleanup/detach ======"
18844
18845 # it would be good to share it with obdfilter-survey/iokit-libecho code
18846 setup_obdecho_osc () {
18847         local rc=0
18848         local ost_nid=$1
18849         local obdfilter_name=$2
18850         echo "Creating new osc for $obdfilter_name on $ost_nid"
18851         # make sure we can find loopback nid
18852         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18853
18854         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18855                            ${obdfilter_name}_osc_UUID || rc=2; }
18856         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18857                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18858         return $rc
18859 }
18860
18861 cleanup_obdecho_osc () {
18862         local obdfilter_name=$1
18863         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18864         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18865         return 0
18866 }
18867
18868 obdecho_test() {
18869         local OBD=$1
18870         local node=$2
18871         local pages=${3:-64}
18872         local rc=0
18873         local id
18874
18875         local count=10
18876         local obd_size=$(get_obd_size $node $OBD)
18877         local page_size=$(get_page_size $node)
18878         if [[ -n "$obd_size" ]]; then
18879                 local new_count=$((obd_size / (pages * page_size / 1024)))
18880                 [[ $new_count -ge $count ]] || count=$new_count
18881         fi
18882
18883         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18884         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18885                            rc=2; }
18886         if [ $rc -eq 0 ]; then
18887             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18888             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18889         fi
18890         echo "New object id is $id"
18891         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18892                            rc=4; }
18893         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18894                            "test_brw $count w v $pages $id" || rc=4; }
18895         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18896                            rc=4; }
18897         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18898                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18899         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18900                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18901         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18902         return $rc
18903 }
18904
18905 test_180a() {
18906         skip "obdecho on osc is no longer supported"
18907 }
18908 run_test 180a "test obdecho on osc"
18909
18910 test_180b() {
18911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18912         remote_ost_nodsh && skip "remote OST with nodsh"
18913
18914         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18915                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18916                 error "failed to load module obdecho"
18917
18918         local target=$(do_facet ost1 $LCTL dl |
18919                        awk '/obdfilter/ { print $4; exit; }')
18920
18921         if [ -n "$target" ]; then
18922                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18923         else
18924                 do_facet ost1 $LCTL dl
18925                 error "there is no obdfilter target on ost1"
18926         fi
18927 }
18928 run_test 180b "test obdecho directly on obdfilter"
18929
18930 test_180c() { # LU-2598
18931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18932         remote_ost_nodsh && skip "remote OST with nodsh"
18933         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18934                 skip "Need MDS version at least 2.4.0"
18935
18936         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18937                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18938                 error "failed to load module obdecho"
18939
18940         local target=$(do_facet ost1 $LCTL dl |
18941                        awk '/obdfilter/ { print $4; exit; }')
18942
18943         if [ -n "$target" ]; then
18944                 local pages=16384 # 64MB bulk I/O RPC size
18945
18946                 obdecho_test "$target" ost1 "$pages" ||
18947                         error "obdecho_test with pages=$pages failed with $?"
18948         else
18949                 do_facet ost1 $LCTL dl
18950                 error "there is no obdfilter target on ost1"
18951         fi
18952 }
18953 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18954
18955 test_181() { # bug 22177
18956         test_mkdir $DIR/$tdir
18957         # create enough files to index the directory
18958         createmany -o $DIR/$tdir/foobar 4000
18959         # print attributes for debug purpose
18960         lsattr -d .
18961         # open dir
18962         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18963         MULTIPID=$!
18964         # remove the files & current working dir
18965         unlinkmany $DIR/$tdir/foobar 4000
18966         rmdir $DIR/$tdir
18967         kill -USR1 $MULTIPID
18968         wait $MULTIPID
18969         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18970         return 0
18971 }
18972 run_test 181 "Test open-unlinked dir ========================"
18973
18974 test_182a() {
18975         local fcount=1000
18976         local tcount=10
18977
18978         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18979
18980         $LCTL set_param mdc.*.rpc_stats=clear
18981
18982         for (( i = 0; i < $tcount; i++ )) ; do
18983                 mkdir $DIR/$tdir/$i
18984         done
18985
18986         for (( i = 0; i < $tcount; i++ )) ; do
18987                 createmany -o $DIR/$tdir/$i/f- $fcount &
18988         done
18989         wait
18990
18991         for (( i = 0; i < $tcount; i++ )) ; do
18992                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18993         done
18994         wait
18995
18996         $LCTL get_param mdc.*.rpc_stats
18997
18998         rm -rf $DIR/$tdir
18999 }
19000 run_test 182a "Test parallel modify metadata operations from mdc"
19001
19002 test_182b() {
19003         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19004         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19005         local dcount=1000
19006         local tcount=10
19007         local stime
19008         local etime
19009         local delta
19010
19011         do_facet mds1 $LCTL list_param \
19012                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19013                 skip "MDS lacks parallel RPC handling"
19014
19015         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19016
19017         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19018                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19019
19020         stime=$(date +%s)
19021         createmany -i 0 -d $DIR/$tdir/t- $tcount
19022
19023         for (( i = 0; i < $tcount; i++ )) ; do
19024                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19025         done
19026         wait
19027         etime=$(date +%s)
19028         delta=$((etime - stime))
19029         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19030
19031         stime=$(date +%s)
19032         for (( i = 0; i < $tcount; i++ )) ; do
19033                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19034         done
19035         wait
19036         etime=$(date +%s)
19037         delta=$((etime - stime))
19038         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19039
19040         rm -rf $DIR/$tdir
19041
19042         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19043
19044         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19045
19046         stime=$(date +%s)
19047         createmany -i 0 -d $DIR/$tdir/t- $tcount
19048
19049         for (( i = 0; i < $tcount; i++ )) ; do
19050                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19051         done
19052         wait
19053         etime=$(date +%s)
19054         delta=$((etime - stime))
19055         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19056
19057         stime=$(date +%s)
19058         for (( i = 0; i < $tcount; i++ )) ; do
19059                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19060         done
19061         wait
19062         etime=$(date +%s)
19063         delta=$((etime - stime))
19064         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19065
19066         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19067 }
19068 run_test 182b "Test parallel modify metadata operations from osp"
19069
19070 test_183() { # LU-2275
19071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19072         remote_mds_nodsh && skip "remote MDS with nodsh"
19073         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19074                 skip "Need MDS version at least 2.3.56"
19075
19076         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19077         echo aaa > $DIR/$tdir/$tfile
19078
19079 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19080         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19081
19082         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19083         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19084
19085         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19086
19087         # Flush negative dentry cache
19088         touch $DIR/$tdir/$tfile
19089
19090         # We are not checking for any leaked references here, they'll
19091         # become evident next time we do cleanup with module unload.
19092         rm -rf $DIR/$tdir
19093 }
19094 run_test 183 "No crash or request leak in case of strange dispositions ========"
19095
19096 # test suite 184 is for LU-2016, LU-2017
19097 test_184a() {
19098         check_swap_layouts_support
19099
19100         dir0=$DIR/$tdir/$testnum
19101         test_mkdir -p -c1 $dir0
19102         ref1=/etc/passwd
19103         ref2=/etc/group
19104         file1=$dir0/f1
19105         file2=$dir0/f2
19106         $LFS setstripe -c1 $file1
19107         cp $ref1 $file1
19108         $LFS setstripe -c2 $file2
19109         cp $ref2 $file2
19110         gen1=$($LFS getstripe -g $file1)
19111         gen2=$($LFS getstripe -g $file2)
19112
19113         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19114         gen=$($LFS getstripe -g $file1)
19115         [[ $gen1 != $gen ]] ||
19116                 error "Layout generation on $file1 does not change"
19117         gen=$($LFS getstripe -g $file2)
19118         [[ $gen2 != $gen ]] ||
19119                 error "Layout generation on $file2 does not change"
19120
19121         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19122         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19123
19124         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19125 }
19126 run_test 184a "Basic layout swap"
19127
19128 test_184b() {
19129         check_swap_layouts_support
19130
19131         dir0=$DIR/$tdir/$testnum
19132         mkdir -p $dir0 || error "creating dir $dir0"
19133         file1=$dir0/f1
19134         file2=$dir0/f2
19135         file3=$dir0/f3
19136         dir1=$dir0/d1
19137         dir2=$dir0/d2
19138         mkdir $dir1 $dir2
19139         $LFS setstripe -c1 $file1
19140         $LFS setstripe -c2 $file2
19141         $LFS setstripe -c1 $file3
19142         chown $RUNAS_ID $file3
19143         gen1=$($LFS getstripe -g $file1)
19144         gen2=$($LFS getstripe -g $file2)
19145
19146         $LFS swap_layouts $dir1 $dir2 &&
19147                 error "swap of directories layouts should fail"
19148         $LFS swap_layouts $dir1 $file1 &&
19149                 error "swap of directory and file layouts should fail"
19150         $RUNAS $LFS swap_layouts $file1 $file2 &&
19151                 error "swap of file we cannot write should fail"
19152         $LFS swap_layouts $file1 $file3 &&
19153                 error "swap of file with different owner should fail"
19154         /bin/true # to clear error code
19155 }
19156 run_test 184b "Forbidden layout swap (will generate errors)"
19157
19158 test_184c() {
19159         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19160         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19161         check_swap_layouts_support
19162         check_swap_layout_no_dom $DIR
19163
19164         local dir0=$DIR/$tdir/$testnum
19165         mkdir -p $dir0 || error "creating dir $dir0"
19166
19167         local ref1=$dir0/ref1
19168         local ref2=$dir0/ref2
19169         local file1=$dir0/file1
19170         local file2=$dir0/file2
19171         # create a file large enough for the concurrent test
19172         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19173         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19174         echo "ref file size: ref1($(stat -c %s $ref1))," \
19175              "ref2($(stat -c %s $ref2))"
19176
19177         cp $ref2 $file2
19178         dd if=$ref1 of=$file1 bs=16k &
19179         local DD_PID=$!
19180
19181         # Make sure dd starts to copy file, but wait at most 5 seconds
19182         local loops=0
19183         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19184
19185         $LFS swap_layouts $file1 $file2
19186         local rc=$?
19187         wait $DD_PID
19188         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19189         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19190
19191         # how many bytes copied before swapping layout
19192         local copied=$(stat -c %s $file2)
19193         local remaining=$(stat -c %s $ref1)
19194         remaining=$((remaining - copied))
19195         echo "Copied $copied bytes before swapping layout..."
19196
19197         cmp -n $copied $file1 $ref2 | grep differ &&
19198                 error "Content mismatch [0, $copied) of ref2 and file1"
19199         cmp -n $copied $file2 $ref1 ||
19200                 error "Content mismatch [0, $copied) of ref1 and file2"
19201         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19202                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19203
19204         # clean up
19205         rm -f $ref1 $ref2 $file1 $file2
19206 }
19207 run_test 184c "Concurrent write and layout swap"
19208
19209 test_184d() {
19210         check_swap_layouts_support
19211         check_swap_layout_no_dom $DIR
19212         [ -z "$(which getfattr 2>/dev/null)" ] &&
19213                 skip_env "no getfattr command"
19214
19215         local file1=$DIR/$tdir/$tfile-1
19216         local file2=$DIR/$tdir/$tfile-2
19217         local file3=$DIR/$tdir/$tfile-3
19218         local lovea1
19219         local lovea2
19220
19221         mkdir -p $DIR/$tdir
19222         touch $file1 || error "create $file1 failed"
19223         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19224                 error "create $file2 failed"
19225         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19226                 error "create $file3 failed"
19227         lovea1=$(get_layout_param $file1)
19228
19229         $LFS swap_layouts $file2 $file3 ||
19230                 error "swap $file2 $file3 layouts failed"
19231         $LFS swap_layouts $file1 $file2 ||
19232                 error "swap $file1 $file2 layouts failed"
19233
19234         lovea2=$(get_layout_param $file2)
19235         echo "$lovea1"
19236         echo "$lovea2"
19237         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19238
19239         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19240         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19241 }
19242 run_test 184d "allow stripeless layouts swap"
19243
19244 test_184e() {
19245         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19246                 skip "Need MDS version at least 2.6.94"
19247         check_swap_layouts_support
19248         check_swap_layout_no_dom $DIR
19249         [ -z "$(which getfattr 2>/dev/null)" ] &&
19250                 skip_env "no getfattr command"
19251
19252         local file1=$DIR/$tdir/$tfile-1
19253         local file2=$DIR/$tdir/$tfile-2
19254         local file3=$DIR/$tdir/$tfile-3
19255         local lovea
19256
19257         mkdir -p $DIR/$tdir
19258         touch $file1 || error "create $file1 failed"
19259         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19260                 error "create $file2 failed"
19261         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19262                 error "create $file3 failed"
19263
19264         $LFS swap_layouts $file1 $file2 ||
19265                 error "swap $file1 $file2 layouts failed"
19266
19267         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19268         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19269
19270         echo 123 > $file1 || error "Should be able to write into $file1"
19271
19272         $LFS swap_layouts $file1 $file3 ||
19273                 error "swap $file1 $file3 layouts failed"
19274
19275         echo 123 > $file1 || error "Should be able to write into $file1"
19276
19277         rm -rf $file1 $file2 $file3
19278 }
19279 run_test 184e "Recreate layout after stripeless layout swaps"
19280
19281 test_184f() {
19282         # Create a file with name longer than sizeof(struct stat) ==
19283         # 144 to see if we can get chars from the file name to appear
19284         # in the returned striping. Note that 'f' == 0x66.
19285         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19286
19287         mkdir -p $DIR/$tdir
19288         mcreate $DIR/$tdir/$file
19289         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19290                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19291         fi
19292 }
19293 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19294
19295 test_185() { # LU-2441
19296         # LU-3553 - no volatile file support in old servers
19297         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19298                 skip "Need MDS version at least 2.3.60"
19299
19300         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19301         touch $DIR/$tdir/spoo
19302         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19303         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19304                 error "cannot create/write a volatile file"
19305         [ "$FILESET" == "" ] &&
19306         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19307                 error "FID is still valid after close"
19308
19309         multiop_bg_pause $DIR/$tdir vVw4096_c
19310         local multi_pid=$!
19311
19312         local OLD_IFS=$IFS
19313         IFS=":"
19314         local fidv=($fid)
19315         IFS=$OLD_IFS
19316         # assume that the next FID for this client is sequential, since stdout
19317         # is unfortunately eaten by multiop_bg_pause
19318         local n=$((${fidv[1]} + 1))
19319         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19320         if [ "$FILESET" == "" ]; then
19321                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19322                         error "FID is missing before close"
19323         fi
19324         kill -USR1 $multi_pid
19325         # 1 second delay, so if mtime change we will see it
19326         sleep 1
19327         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19328         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19329 }
19330 run_test 185 "Volatile file support"
19331
19332 function create_check_volatile() {
19333         local idx=$1
19334         local tgt
19335
19336         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19337         local PID=$!
19338         sleep 1
19339         local FID=$(cat /tmp/${tfile}.fid)
19340         [ "$FID" == "" ] && error "can't get FID for volatile"
19341         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19342         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19343         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19344         kill -USR1 $PID
19345         wait
19346         sleep 1
19347         cancel_lru_locks mdc # flush opencache
19348         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19349         return 0
19350 }
19351
19352 test_185a(){
19353         # LU-12516 - volatile creation via .lustre
19354         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19355                 skip "Need MDS version at least 2.3.55"
19356
19357         create_check_volatile 0
19358         [ $MDSCOUNT -lt 2 ] && return 0
19359
19360         # DNE case
19361         create_check_volatile 1
19362
19363         return 0
19364 }
19365 run_test 185a "Volatile file creation in .lustre/fid/"
19366
19367 test_187a() {
19368         remote_mds_nodsh && skip "remote MDS with nodsh"
19369         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19370                 skip "Need MDS version at least 2.3.0"
19371
19372         local dir0=$DIR/$tdir/$testnum
19373         mkdir -p $dir0 || error "creating dir $dir0"
19374
19375         local file=$dir0/file1
19376         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19377         stack_trap "rm -f $file"
19378         local dv1=$($LFS data_version $file)
19379         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19380         local dv2=$($LFS data_version $file)
19381         [[ $dv1 != $dv2 ]] ||
19382                 error "data version did not change on write $dv1 == $dv2"
19383 }
19384 run_test 187a "Test data version change"
19385
19386 test_187b() {
19387         remote_mds_nodsh && skip "remote MDS with nodsh"
19388         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19389                 skip "Need MDS version at least 2.3.0"
19390
19391         local dir0=$DIR/$tdir/$testnum
19392         mkdir -p $dir0 || error "creating dir $dir0"
19393
19394         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19395         [[ ${DV[0]} != ${DV[1]} ]] ||
19396                 error "data version did not change on write"\
19397                       " ${DV[0]} == ${DV[1]}"
19398
19399         # clean up
19400         rm -f $file1
19401 }
19402 run_test 187b "Test data version change on volatile file"
19403
19404 test_200() {
19405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19406         remote_mgs_nodsh && skip "remote MGS with nodsh"
19407         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19408
19409         local POOL=${POOL:-cea1}
19410         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19411         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19412         # Pool OST targets
19413         local first_ost=0
19414         local last_ost=$(($OSTCOUNT - 1))
19415         local ost_step=2
19416         local ost_list=$(seq $first_ost $ost_step $last_ost)
19417         local ost_range="$first_ost $last_ost $ost_step"
19418         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19419         local file_dir=$POOL_ROOT/file_tst
19420         local subdir=$test_path/subdir
19421         local rc=0
19422
19423         while : ; do
19424                 # former test_200a test_200b
19425                 pool_add $POOL                          || { rc=$? ; break; }
19426                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19427                 # former test_200c test_200d
19428                 mkdir -p $test_path
19429                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19430                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19431                 mkdir -p $subdir
19432                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19433                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19434                                                         || { rc=$? ; break; }
19435                 # former test_200e test_200f
19436                 local files=$((OSTCOUNT*3))
19437                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19438                                                         || { rc=$? ; break; }
19439                 pool_create_files $POOL $file_dir $files "$ost_list" \
19440                                                         || { rc=$? ; break; }
19441                 # former test_200g test_200h
19442                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19443                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19444
19445                 # former test_201a test_201b test_201c
19446                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19447
19448                 local f=$test_path/$tfile
19449                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19450                 pool_remove $POOL $f                    || { rc=$? ; break; }
19451                 break
19452         done
19453
19454         destroy_test_pools
19455
19456         return $rc
19457 }
19458 run_test 200 "OST pools"
19459
19460 # usage: default_attr <count | size | offset>
19461 default_attr() {
19462         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19463 }
19464
19465 # usage: check_default_stripe_attr
19466 check_default_stripe_attr() {
19467         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19468         case $1 in
19469         --stripe-count|-c)
19470                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19471         --stripe-size|-S)
19472                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19473         --stripe-index|-i)
19474                 EXPECTED=-1;;
19475         *)
19476                 error "unknown getstripe attr '$1'"
19477         esac
19478
19479         [ $ACTUAL == $EXPECTED ] ||
19480                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19481 }
19482
19483 test_204a() {
19484         test_mkdir $DIR/$tdir
19485         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19486
19487         check_default_stripe_attr --stripe-count
19488         check_default_stripe_attr --stripe-size
19489         check_default_stripe_attr --stripe-index
19490 }
19491 run_test 204a "Print default stripe attributes"
19492
19493 test_204b() {
19494         test_mkdir $DIR/$tdir
19495         $LFS setstripe --stripe-count 1 $DIR/$tdir
19496
19497         check_default_stripe_attr --stripe-size
19498         check_default_stripe_attr --stripe-index
19499 }
19500 run_test 204b "Print default stripe size and offset"
19501
19502 test_204c() {
19503         test_mkdir $DIR/$tdir
19504         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19505
19506         check_default_stripe_attr --stripe-count
19507         check_default_stripe_attr --stripe-index
19508 }
19509 run_test 204c "Print default stripe count and offset"
19510
19511 test_204d() {
19512         test_mkdir $DIR/$tdir
19513         $LFS setstripe --stripe-index 0 $DIR/$tdir
19514
19515         check_default_stripe_attr --stripe-count
19516         check_default_stripe_attr --stripe-size
19517 }
19518 run_test 204d "Print default stripe count and size"
19519
19520 test_204e() {
19521         test_mkdir $DIR/$tdir
19522         $LFS setstripe -d $DIR/$tdir
19523
19524         # LU-16904 check if root is set as PFL layout
19525         local numcomp=$($LFS getstripe --component-count $MOUNT)
19526
19527         if [[ $numcomp -gt 0 ]]; then
19528                 check_default_stripe_attr --stripe-count
19529         else
19530                 check_default_stripe_attr --stripe-count --raw
19531         fi
19532         check_default_stripe_attr --stripe-size --raw
19533         check_default_stripe_attr --stripe-index --raw
19534 }
19535 run_test 204e "Print raw stripe attributes"
19536
19537 test_204f() {
19538         test_mkdir $DIR/$tdir
19539         $LFS setstripe --stripe-count 1 $DIR/$tdir
19540
19541         check_default_stripe_attr --stripe-size --raw
19542         check_default_stripe_attr --stripe-index --raw
19543 }
19544 run_test 204f "Print raw stripe size and offset"
19545
19546 test_204g() {
19547         test_mkdir $DIR/$tdir
19548         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19549
19550         check_default_stripe_attr --stripe-count --raw
19551         check_default_stripe_attr --stripe-index --raw
19552 }
19553 run_test 204g "Print raw stripe count and offset"
19554
19555 test_204h() {
19556         test_mkdir $DIR/$tdir
19557         $LFS setstripe --stripe-index 0 $DIR/$tdir
19558
19559         check_default_stripe_attr --stripe-count --raw
19560         check_default_stripe_attr --stripe-size --raw
19561 }
19562 run_test 204h "Print raw stripe count and size"
19563
19564 # Figure out which job scheduler is being used, if any,
19565 # or use a fake one
19566 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19567         JOBENV=SLURM_JOB_ID
19568 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19569         JOBENV=LSB_JOBID
19570 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19571         JOBENV=PBS_JOBID
19572 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19573         JOBENV=LOADL_STEP_ID
19574 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19575         JOBENV=JOB_ID
19576 else
19577         $LCTL list_param jobid_name > /dev/null 2>&1
19578         if [ $? -eq 0 ]; then
19579                 JOBENV=nodelocal
19580         else
19581                 JOBENV=FAKE_JOBID
19582         fi
19583 fi
19584 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19585
19586 verify_jobstats() {
19587         local cmd=($1)
19588         shift
19589         local facets="$@"
19590
19591 # we don't really need to clear the stats for this test to work, since each
19592 # command has a unique jobid, but it makes debugging easier if needed.
19593 #       for facet in $facets; do
19594 #               local dev=$(convert_facet2label $facet)
19595 #               # clear old jobstats
19596 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19597 #       done
19598
19599         # use a new JobID for each test, or we might see an old one
19600         [ "$JOBENV" = "FAKE_JOBID" ] &&
19601                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19602
19603         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19604
19605         [ "$JOBENV" = "nodelocal" ] && {
19606                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19607                 $LCTL set_param jobid_name=$FAKE_JOBID
19608                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19609         }
19610
19611         log "Test: ${cmd[*]}"
19612         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19613
19614         if [ $JOBENV = "FAKE_JOBID" ]; then
19615                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19616         else
19617                 ${cmd[*]}
19618         fi
19619
19620         # all files are created on OST0000
19621         for facet in $facets; do
19622                 local stats="*.$(convert_facet2label $facet).job_stats"
19623
19624                 # strip out libtool wrappers for in-tree executables
19625                 if (( $(do_facet $facet lctl get_param $stats |
19626                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19627                         do_facet $facet lctl get_param $stats
19628                         error "No jobstats for $JOBVAL found on $facet::$stats"
19629                 fi
19630         done
19631 }
19632
19633 jobstats_set() {
19634         local new_jobenv=$1
19635
19636         set_persistent_param_and_check client "jobid_var" \
19637                 "$FSNAME.sys.jobid_var" $new_jobenv
19638 }
19639
19640 test_205a() { # Job stats
19641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19642         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19643                 skip "Need MDS version with at least 2.7.1"
19644         remote_mgs_nodsh && skip "remote MGS with nodsh"
19645         remote_mds_nodsh && skip "remote MDS with nodsh"
19646         remote_ost_nodsh && skip "remote OST with nodsh"
19647         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19648                 skip "Server doesn't support jobstats"
19649         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19650
19651         local old_jobenv=$($LCTL get_param -n jobid_var)
19652         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19653         stack_trap "jobstats_set $old_jobenv" EXIT
19654
19655         changelog_register
19656
19657         local old_jobid_name=$($LCTL get_param jobid_name)
19658         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19659
19660         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19661                                 mdt.*.job_cleanup_interval | head -n 1)
19662         local new_interval=5
19663         do_facet $SINGLEMDS \
19664                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19665         stack_trap "do_facet $SINGLEMDS \
19666                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19667         local start=$SECONDS
19668
19669         local cmd
19670         # mkdir
19671         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19672         verify_jobstats "$cmd" "$SINGLEMDS"
19673         # rmdir
19674         cmd="rmdir $DIR/$tdir"
19675         verify_jobstats "$cmd" "$SINGLEMDS"
19676         # mkdir on secondary MDT
19677         if [ $MDSCOUNT -gt 1 ]; then
19678                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19679                 verify_jobstats "$cmd" "mds2"
19680         fi
19681         # mknod
19682         cmd="mknod $DIR/$tfile c 1 3"
19683         verify_jobstats "$cmd" "$SINGLEMDS"
19684         # unlink
19685         cmd="rm -f $DIR/$tfile"
19686         verify_jobstats "$cmd" "$SINGLEMDS"
19687         # create all files on OST0000 so verify_jobstats can find OST stats
19688         # open & close
19689         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19690         verify_jobstats "$cmd" "$SINGLEMDS"
19691         # setattr
19692         cmd="touch $DIR/$tfile"
19693         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19694         # write
19695         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19696         verify_jobstats "$cmd" "ost1"
19697         # read
19698         cancel_lru_locks osc
19699         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19700         verify_jobstats "$cmd" "ost1"
19701         # truncate
19702         cmd="$TRUNCATE $DIR/$tfile 0"
19703         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19704         # rename
19705         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19706         verify_jobstats "$cmd" "$SINGLEMDS"
19707         # jobstats expiry - sleep until old stats should be expired
19708         local left=$((new_interval + 5 - (SECONDS - start)))
19709         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19710                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19711                         "0" $left
19712         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19713         verify_jobstats "$cmd" "$SINGLEMDS"
19714         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19715             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19716
19717         # Ensure that jobid are present in changelog (if supported by MDS)
19718         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19719                 changelog_dump | tail -10
19720                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19721                 [ $jobids -eq 9 ] ||
19722                         error "Wrong changelog jobid count $jobids != 9"
19723
19724                 # LU-5862
19725                 JOBENV="disable"
19726                 jobstats_set $JOBENV
19727                 touch $DIR/$tfile
19728                 changelog_dump | grep $tfile
19729                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19730                 [ $jobids -eq 0 ] ||
19731                         error "Unexpected jobids when jobid_var=$JOBENV"
19732         fi
19733
19734         # test '%j' access to environment variable - if supported
19735         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19736                 JOBENV="JOBCOMPLEX"
19737                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19738
19739                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19740         fi
19741
19742         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19743                 JOBENV="JOBCOMPLEX"
19744                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19745
19746                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19747         fi
19748
19749         # test '%j' access to per-session jobid - if supported
19750         if lctl list_param jobid_this_session > /dev/null 2>&1
19751         then
19752                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19753                 lctl set_param jobid_this_session=$USER
19754
19755                 JOBENV="JOBCOMPLEX"
19756                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19757
19758                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19759         fi
19760 }
19761 run_test 205a "Verify job stats"
19762
19763 # LU-13117, LU-13597, LU-16599
19764 test_205b() {
19765         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19766                 skip "Need MDS version at least 2.13.54.91"
19767
19768         local job_stats="mdt.*.job_stats"
19769         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19770
19771         do_facet mds1 $LCTL set_param $job_stats=clear
19772
19773         # Setting jobid_var to USER might not be supported
19774         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19775         $LCTL set_param jobid_var=USER || true
19776         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19777         $LCTL set_param jobid_name="%j.%e.%u"
19778
19779         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19780         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19781                 { do_facet mds1 $LCTL get_param $job_stats;
19782                   error "Unexpected jobid found"; }
19783         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19784                 { do_facet mds1 $LCTL get_param $job_stats;
19785                   error "wrong job_stats format found"; }
19786
19787         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19788                 echo "MDS does not yet escape jobid" && return 0
19789
19790         mkdir_on_mdt0 $DIR/$tdir
19791         $LCTL set_param jobid_var=TEST205b
19792         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19793         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19794                       awk '/has\\x20sp/ {print $3}')
19795         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19796                   error "jobid not escaped"; }
19797
19798         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19799                 # need to run such a command on mds1:
19800                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19801                 #
19802                 # there might be multiple MDTs on single mds server, so need to
19803                 # specifiy MDT0000. Or the command will fail due to other MDTs
19804                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19805                         error "cannot clear escaped jobid in job_stats";
19806         else
19807                 echo "MDS does not support clearing escaped jobid"
19808         fi
19809 }
19810 run_test 205b "Verify job stats jobid and output format"
19811
19812 # LU-13733
19813 test_205c() {
19814         $LCTL set_param llite.*.stats=0
19815         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19816         $LCTL get_param llite.*.stats
19817         $LCTL get_param llite.*.stats | grep \
19818                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19819                         error "wrong client stats format found"
19820 }
19821 run_test 205c "Verify client stats format"
19822
19823 test_205d() {
19824         local file=$DIR/$tdir/$tfile
19825
19826         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19827                 skip "need lustre >= 2.15.53 for lljobstat"
19828         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19829                 skip "need lustre >= 2.15.53 for lljobstat"
19830         verify_yaml_available || skip_env "YAML verification not installed"
19831
19832         test_mkdir -i 0 $DIR/$tdir
19833         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19834         stack_trap "rm -rf $DIR/$tdir"
19835
19836         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19837                 error "failed to write data to $file"
19838         mv $file $file.2
19839
19840         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19841         echo -n 'verify rename_stats...'
19842         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19843                 verify_yaml || error "rename_stats is not valid YAML"
19844         echo " OK"
19845
19846         echo -n 'verify mdt job_stats...'
19847         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19848                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19849         echo " OK"
19850
19851         echo -n 'verify ost job_stats...'
19852         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19853                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19854         echo " OK"
19855 }
19856 run_test 205d "verify the format of some stats files"
19857
19858 test_205e() {
19859         local ops_comma
19860         local file=$DIR/$tdir/$tfile
19861         local -a cli_params
19862
19863         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19864                 skip "need lustre >= 2.15.53 for lljobstat"
19865         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19866                 skip "need lustre >= 2.15.53 for lljobstat"
19867         verify_yaml_available || skip_env "YAML verification not installed"
19868
19869         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19870         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19871         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19872
19873         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19874         stack_trap "rm -rf $DIR/$tdir"
19875
19876         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19877                 error "failed to create $file on ost1"
19878         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19879                 error "failed to write data to $file"
19880
19881         do_facet mds1 "$LCTL get_param *.*.job_stats"
19882         do_facet ost1 "$LCTL get_param *.*.job_stats"
19883
19884         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19885         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19886                 error "The output of lljobstat is not an valid YAML"
19887
19888         # verify that job dd.0 does exist and has some ops on ost1
19889         # typically this line is like:
19890         # - 205e.dd.0:            {ops: 20, ...}
19891         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19892                     awk '$2=="205e.dd.0:" {print $4}')
19893
19894         (( ${ops_comma%,} >= 10 )) ||
19895                 error "cannot find job 205e.dd.0 with ops >= 10"
19896 }
19897 run_test 205e "verify the output of lljobstat"
19898
19899 test_205f() {
19900         verify_yaml_available || skip_env "YAML verification not installed"
19901
19902         # check both qos_ost_weights and qos_mdt_weights
19903         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19904         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19905                 error "qos_ost_weights is not valid YAML"
19906 }
19907 run_test 205f "verify qos_ost_weights YAML format "
19908
19909 __test_205_jobstats_dump() {
19910         local -a pids
19911         local nbr_instance=$1
19912
19913         while true; do
19914                 if (( ${#pids[@]} >= nbr_instance )); then
19915                         wait ${pids[@]}
19916                         pids=()
19917                 fi
19918
19919                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19920                 pids+=( $! )
19921         done
19922 }
19923
19924 __test_205_cleanup() {
19925         kill $@
19926         # Clear all job entries
19927         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19928 }
19929
19930 test_205g() {
19931         local -a mds1_params
19932         local -a cli_params
19933         local pids
19934         local interval=5
19935
19936         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19937         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19938         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19939
19940         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19941         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19942         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19943
19944         # start jobs loop
19945         export TEST205G_ID=205g
19946         stack_trap "unset TEST205G_ID" EXIT
19947         while true; do
19948                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19949         done & pids="$! "
19950
19951         __test_205_jobstats_dump 4 & pids+="$! "
19952         stack_trap "__test_205_cleanup $pids" EXIT INT
19953
19954         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19955 }
19956 run_test 205g "stress test for job_stats procfile"
19957
19958 test_205h() {
19959         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
19960
19961         local dir=$DIR/$tdir
19962         local f=$dir/$tfile
19963         local f2=$dir/$tfile-2
19964         local f3=$dir/$tfile-3
19965         local subdir=$DIR/dir
19966         local val
19967
19968         local mdts=$(comma_list $(mdts_nodes))
19969         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
19970         local client_saved=$($LCTL get_param -n jobid_var)
19971
19972         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
19973         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
19974
19975         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
19976                 error "failed to set job_xattr parameter to user.job"
19977         $LCTL set_param jobid_var=procname.uid ||
19978                 error "failed to set jobid_var parameter"
19979
19980         test_mkdir $dir
19981
19982         touch $f
19983         val=$(getfattr -n user.job $f | grep user.job)
19984         [[ $val = user.job=\"touch.0\" ]] ||
19985                 error "expected user.job=\"touch.0\", got '$val'"
19986
19987         mkdir $subdir
19988         val=$(getfattr -n user.job $subdir | grep user.job)
19989         [[ $val = user.job=\"mkdir.0\" ]] ||
19990                 error "expected user.job=\"mkdir.0\", got '$val'"
19991
19992         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
19993                 error "failed to set job_xattr parameter to NONE"
19994
19995         touch $f2
19996         val=$(getfattr -d $f2)
19997         [[ -z $val ]] ||
19998                 error "expected no user xattr, got '$val'"
19999
20000         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20001                 error "failed to set job_xattr parameter to trusted.job"
20002
20003         touch $f3
20004         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20005         [[ $val = trusted.job=\"touch.0\" ]] ||
20006                 error "expected trusted.job=\"touch.0\", got '$val'"
20007 }
20008 run_test 205h "check jobid xattr is stored correctly"
20009
20010 test_205i() {
20011         local mdts=$(comma_list $(mdts_nodes))
20012         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20013
20014         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20015
20016         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20017                 error "failed to set mdt.*.job_xattr to user.1234567"
20018
20019         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20020                 error "failed to reject too long job_xattr name"
20021
20022         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20023                 error "failed to reject job_xattr name in bad format"
20024
20025         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20026                 error "failed to reject job_xattr name with invalid character"
20027
20028         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20029                         xargs $LCTL set_param" &&
20030                 error "failed to reject job_xattr name with non-ascii character"
20031
20032         return 0
20033 }
20034 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20035
20036 # LU-1480, LU-1773 and LU-1657
20037 test_206() {
20038         mkdir -p $DIR/$tdir
20039         $LFS setstripe -c -1 $DIR/$tdir
20040 #define OBD_FAIL_LOV_INIT 0x1403
20041         $LCTL set_param fail_loc=0xa0001403
20042         $LCTL set_param fail_val=1
20043         touch $DIR/$tdir/$tfile || true
20044 }
20045 run_test 206 "fail lov_init_raid0() doesn't lbug"
20046
20047 test_207a() {
20048         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20049         local fsz=`stat -c %s $DIR/$tfile`
20050         cancel_lru_locks mdc
20051
20052         # do not return layout in getattr intent
20053 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20054         $LCTL set_param fail_loc=0x170
20055         local sz=`stat -c %s $DIR/$tfile`
20056
20057         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20058
20059         rm -rf $DIR/$tfile
20060 }
20061 run_test 207a "can refresh layout at glimpse"
20062
20063 test_207b() {
20064         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20065         local cksum=`md5sum $DIR/$tfile`
20066         local fsz=`stat -c %s $DIR/$tfile`
20067         cancel_lru_locks mdc
20068         cancel_lru_locks osc
20069
20070         # do not return layout in getattr intent
20071 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20072         $LCTL set_param fail_loc=0x171
20073
20074         # it will refresh layout after the file is opened but before read issues
20075         echo checksum is "$cksum"
20076         echo "$cksum" |md5sum -c --quiet || error "file differs"
20077
20078         rm -rf $DIR/$tfile
20079 }
20080 run_test 207b "can refresh layout at open"
20081
20082 test_208() {
20083         # FIXME: in this test suite, only RD lease is used. This is okay
20084         # for now as only exclusive open is supported. After generic lease
20085         # is done, this test suite should be revised. - Jinshan
20086
20087         remote_mds_nodsh && skip "remote MDS with nodsh"
20088         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20089                 skip "Need MDS version at least 2.4.52"
20090
20091         echo "==== test 1: verify get lease work"
20092         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20093
20094         echo "==== test 2: verify lease can be broken by upcoming open"
20095         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20096         local PID=$!
20097         sleep 2
20098
20099         $MULTIOP $DIR/$tfile oO_RDWR:c
20100         kill -USR1 $PID && wait $PID || error "break lease error"
20101
20102         echo "==== test 3: verify lease can't be granted if an open already exists"
20103         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20104         local PID=$!
20105         sleep 2
20106
20107         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20108         kill -USR1 $PID && wait $PID || error "open file error"
20109
20110         echo "==== test 4: lease can sustain over recovery"
20111         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20112         PID=$!
20113         sleep 2
20114
20115         fail mds1
20116
20117         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20118
20119         echo "==== test 5: lease broken can't be regained by replay"
20120         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20121         PID=$!
20122         sleep 2
20123
20124         # open file to break lease and then recovery
20125         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20126         fail mds1
20127
20128         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20129
20130         rm -f $DIR/$tfile
20131 }
20132 run_test 208 "Exclusive open"
20133
20134 test_209() {
20135         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20136                 skip_env "must have disp_stripe"
20137
20138         touch $DIR/$tfile
20139         sync; sleep 5; sync;
20140
20141         echo 3 > /proc/sys/vm/drop_caches
20142         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20143                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20144         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20145
20146         # open/close 500 times
20147         for i in $(seq 500); do
20148                 cat $DIR/$tfile
20149         done
20150
20151         echo 3 > /proc/sys/vm/drop_caches
20152         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20153                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20154         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20155
20156         echo "before: $req_before, after: $req_after"
20157         [ $((req_after - req_before)) -ge 300 ] &&
20158                 error "open/close requests are not freed"
20159         return 0
20160 }
20161 run_test 209 "read-only open/close requests should be freed promptly"
20162
20163 test_210() {
20164         local pid
20165
20166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20167         pid=$!
20168         sleep 1
20169
20170         $LFS getstripe $DIR/$tfile
20171         kill -USR1 $pid
20172         wait $pid || error "multiop failed"
20173
20174         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20175         pid=$!
20176         sleep 1
20177
20178         $LFS getstripe $DIR/$tfile
20179         kill -USR1 $pid
20180         wait $pid || error "multiop failed"
20181 }
20182 run_test 210 "lfs getstripe does not break leases"
20183
20184 test_212() {
20185         size=`date +%s`
20186         size=$((size % 8192 + 1))
20187         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20188         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20189         rm -f $DIR/f212 $DIR/f212.xyz
20190 }
20191 run_test 212 "Sendfile test ============================================"
20192
20193 test_213() {
20194         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20195         cancel_lru_locks osc
20196         lctl set_param fail_loc=0x8000040f
20197         # generate a read lock
20198         cat $DIR/$tfile > /dev/null
20199         # write to the file, it will try to cancel the above read lock.
20200         cat /etc/hosts >> $DIR/$tfile
20201 }
20202 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20203
20204 test_214() { # for bug 20133
20205         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20206         for (( i=0; i < 340; i++ )) ; do
20207                 touch $DIR/$tdir/d214c/a$i
20208         done
20209
20210         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20211         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20212         ls $DIR/d214c || error "ls $DIR/d214c failed"
20213         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20214         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20215 }
20216 run_test 214 "hash-indexed directory test - bug 20133"
20217
20218 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20219 create_lnet_proc_files() {
20220         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20221 }
20222
20223 # counterpart of create_lnet_proc_files
20224 remove_lnet_proc_files() {
20225         rm -f $TMP/lnet_$1.sys
20226 }
20227
20228 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20229 # 3rd arg as regexp for body
20230 check_lnet_proc_stats() {
20231         local l=$(cat "$TMP/lnet_$1" |wc -l)
20232         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20233
20234         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20235 }
20236
20237 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20238 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20239 # optional and can be regexp for 2nd line (lnet.routes case)
20240 check_lnet_proc_entry() {
20241         local blp=2          # blp stands for 'position of 1st line of body'
20242         [ -z "$5" ] || blp=3 # lnet.routes case
20243
20244         local l=$(cat "$TMP/lnet_$1" |wc -l)
20245         # subtracting one from $blp because the body can be empty
20246         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20247
20248         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20249                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20250
20251         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20252                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20253
20254         # bail out if any unexpected line happened
20255         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20256         [ "$?" != 0 ] || error "$2 misformatted"
20257 }
20258
20259 test_215() { # for bugs 18102, 21079, 21517
20260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20261
20262         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20263         local P='[1-9][0-9]*'           # positive numeric
20264         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20265         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20266         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20267         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20268
20269         local L1 # regexp for 1st line
20270         local L2 # regexp for 2nd line (optional)
20271         local BR # regexp for the rest (body)
20272
20273         # lnet.stats should look as 11 space-separated non-negative numerics
20274         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20275         create_lnet_proc_files "stats"
20276         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20277         remove_lnet_proc_files "stats"
20278
20279         # lnet.routes should look like this:
20280         # Routing disabled/enabled
20281         # net hops priority state router
20282         # where net is a string like tcp0, hops > 0, priority >= 0,
20283         # state is up/down,
20284         # router is a string like 192.168.1.1@tcp2
20285         L1="^Routing (disabled|enabled)$"
20286         L2="^net +hops +priority +state +router$"
20287         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20288         create_lnet_proc_files "routes"
20289         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20290         remove_lnet_proc_files "routes"
20291
20292         # lnet.routers should look like this:
20293         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20294         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20295         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20296         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20297         L1="^ref +rtr_ref +alive +router$"
20298         BR="^$P +$P +(up|down) +$NID$"
20299         create_lnet_proc_files "routers"
20300         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20301         remove_lnet_proc_files "routers"
20302
20303         # lnet.peers should look like this:
20304         # nid refs state last max rtr min tx min queue
20305         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20306         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20307         # numeric (0 or >0 or <0), queue >= 0.
20308         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20309         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20310         create_lnet_proc_files "peers"
20311         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20312         remove_lnet_proc_files "peers"
20313
20314         # lnet.buffers  should look like this:
20315         # pages count credits min
20316         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20317         L1="^pages +count +credits +min$"
20318         BR="^ +$N +$N +$I +$I$"
20319         create_lnet_proc_files "buffers"
20320         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20321         remove_lnet_proc_files "buffers"
20322
20323         # lnet.nis should look like this:
20324         # nid status alive refs peer rtr max tx min
20325         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20326         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20327         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20328         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20329         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20330         create_lnet_proc_files "nis"
20331         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20332         remove_lnet_proc_files "nis"
20333
20334         # can we successfully write to lnet.stats?
20335         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20336 }
20337 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20338
20339 test_216() { # bug 20317
20340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20341         remote_ost_nodsh && skip "remote OST with nodsh"
20342
20343         local node
20344         local facets=$(get_facets OST)
20345         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20346
20347         save_lustre_params client "osc.*.contention_seconds" > $p
20348         save_lustre_params $facets \
20349                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20350         save_lustre_params $facets \
20351                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20352         save_lustre_params $facets \
20353                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20354         clear_stats osc.*.osc_stats
20355
20356         # agressive lockless i/o settings
20357         do_nodes $(comma_list $(osts_nodes)) \
20358                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20359                         ldlm.namespaces.filter-*.contended_locks=0 \
20360                         ldlm.namespaces.filter-*.contention_seconds=60"
20361         lctl set_param -n osc.*.contention_seconds=60
20362
20363         $DIRECTIO write $DIR/$tfile 0 10 4096
20364         $CHECKSTAT -s 40960 $DIR/$tfile
20365
20366         # disable lockless i/o
20367         do_nodes $(comma_list $(osts_nodes)) \
20368                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20369                         ldlm.namespaces.filter-*.contended_locks=32 \
20370                         ldlm.namespaces.filter-*.contention_seconds=0"
20371         lctl set_param -n osc.*.contention_seconds=0
20372         clear_stats osc.*.osc_stats
20373
20374         dd if=/dev/zero of=$DIR/$tfile count=0
20375         $CHECKSTAT -s 0 $DIR/$tfile
20376
20377         restore_lustre_params <$p
20378         rm -f $p
20379         rm $DIR/$tfile
20380 }
20381 run_test 216 "check lockless direct write updates file size and kms correctly"
20382
20383 test_217() { # bug 22430
20384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20385
20386         local node
20387
20388         for node in $(nodes_list); do
20389                 local nid=$(host_nids_address $node $NETTYPE)
20390                 local node_ip=$(do_node $node getent ahostsv4 $node |
20391                                 awk '{ print $1; exit; }')
20392
20393                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20394                 # if hostname matches any NID, use hostname for better testing
20395                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20396                         echo "lctl ping node $node@$NETTYPE"
20397                         lctl ping $node@$NETTYPE
20398                 else # otherwise, at least test 'lctl ping' is working
20399                         echo "lctl ping nid $(h2nettype $nid)"
20400                         lctl ping $(h2nettype $nid)
20401                         echo "skipping $node (no hyphen detected)"
20402                 fi
20403         done
20404 }
20405 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20406
20407 test_218() {
20408         # do directio so as not to populate the page cache
20409         log "creating a 10 Mb file"
20410         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20411                 error "multiop failed while creating a file"
20412         log "starting reads"
20413         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20414         log "truncating the file"
20415         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20416                 error "multiop failed while truncating the file"
20417         log "killing dd"
20418         kill %+ || true # reads might have finished
20419         echo "wait until dd is finished"
20420         wait
20421         log "removing the temporary file"
20422         rm -rf $DIR/$tfile || error "tmp file removal failed"
20423 }
20424 run_test 218 "parallel read and truncate should not deadlock"
20425
20426 test_219() {
20427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20428
20429         # write one partial page
20430         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20431         # set no grant so vvp_io_commit_write will do sync write
20432         $LCTL set_param fail_loc=0x411
20433         # write a full page at the end of file
20434         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20435
20436         $LCTL set_param fail_loc=0
20437         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20438         $LCTL set_param fail_loc=0x411
20439         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20440
20441         # LU-4201
20442         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20443         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20444 }
20445 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20446
20447 test_220() { #LU-325
20448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20449         remote_ost_nodsh && skip "remote OST with nodsh"
20450         remote_mds_nodsh && skip "remote MDS with nodsh"
20451         remote_mgs_nodsh && skip "remote MGS with nodsh"
20452
20453         local OSTIDX=0
20454
20455         # create on MDT0000 so the last_id and next_id are correct
20456         mkdir_on_mdt0 $DIR/$tdir
20457         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20458         OST=${OST%_UUID}
20459
20460         # on the mdt's osc
20461         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20462         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20463                         osp.$mdtosc_proc1.prealloc_last_id)
20464         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20465                         osp.$mdtosc_proc1.prealloc_next_id)
20466
20467         $LFS df -i
20468
20469         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20470         #define OBD_FAIL_OST_ENOINO              0x229
20471         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20472         create_pool $FSNAME.$TESTNAME || return 1
20473         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20474
20475         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20476
20477         MDSOBJS=$((last_id - next_id))
20478         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20479
20480         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20481         echo "OST still has $count kbytes free"
20482
20483         echo "create $MDSOBJS files @next_id..."
20484         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20485
20486         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20487                         osp.$mdtosc_proc1.prealloc_last_id)
20488         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20489                         osp.$mdtosc_proc1.prealloc_next_id)
20490
20491         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20492         $LFS df -i
20493
20494         echo "cleanup..."
20495
20496         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20497         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20498
20499         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20500                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20501         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20502                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20503         echo "unlink $MDSOBJS files @$next_id..."
20504         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20505 }
20506 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20507
20508 test_221() {
20509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20510
20511         dd if=`which date` of=$MOUNT/date oflag=sync
20512         chmod +x $MOUNT/date
20513
20514         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20515         $LCTL set_param fail_loc=0x80001401
20516
20517         $MOUNT/date > /dev/null
20518         rm -f $MOUNT/date
20519 }
20520 run_test 221 "make sure fault and truncate race to not cause OOM"
20521
20522 test_222a () {
20523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20524
20525         rm -rf $DIR/$tdir
20526         test_mkdir $DIR/$tdir
20527         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20528         createmany -o $DIR/$tdir/$tfile 10
20529         cancel_lru_locks mdc
20530         cancel_lru_locks osc
20531         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20532         $LCTL set_param fail_loc=0x31a
20533         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20534         $LCTL set_param fail_loc=0
20535         rm -r $DIR/$tdir
20536 }
20537 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20538
20539 test_222b () {
20540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20541
20542         rm -rf $DIR/$tdir
20543         test_mkdir $DIR/$tdir
20544         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20545         createmany -o $DIR/$tdir/$tfile 10
20546         cancel_lru_locks mdc
20547         cancel_lru_locks osc
20548         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20549         $LCTL set_param fail_loc=0x31a
20550         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20551         $LCTL set_param fail_loc=0
20552 }
20553 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20554
20555 test_223 () {
20556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20557
20558         rm -rf $DIR/$tdir
20559         test_mkdir $DIR/$tdir
20560         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20561         createmany -o $DIR/$tdir/$tfile 10
20562         cancel_lru_locks mdc
20563         cancel_lru_locks osc
20564         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20565         $LCTL set_param fail_loc=0x31b
20566         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20567         $LCTL set_param fail_loc=0
20568         rm -r $DIR/$tdir
20569 }
20570 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20571
20572 test_224a() { # LU-1039, MRP-303
20573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20574         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20575         $LCTL set_param fail_loc=0x508
20576         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20577         $LCTL set_param fail_loc=0
20578         df $DIR
20579 }
20580 run_test 224a "Don't panic on bulk IO failure"
20581
20582 test_224bd_sub() { # LU-1039, MRP-303
20583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20584         local timeout=$1
20585
20586         shift
20587         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20588
20589         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20590
20591         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20592         cancel_lru_locks osc
20593         set_checksums 0
20594         stack_trap "set_checksums $ORIG_CSUM" EXIT
20595         local at_max_saved=0
20596
20597         # adaptive timeouts may prevent seeing the issue
20598         if at_is_enabled; then
20599                 at_max_saved=$(at_max_get mds)
20600                 at_max_set 0 mds client
20601                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20602         fi
20603
20604         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20605         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20606         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20607
20608         do_facet ost1 $LCTL set_param fail_loc=0
20609         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20610         df $DIR
20611 }
20612
20613 test_224b() {
20614         test_224bd_sub 3 error "dd failed"
20615 }
20616 run_test 224b "Don't panic on bulk IO failure"
20617
20618 test_224c() { # LU-6441
20619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20620         remote_mds_nodsh && skip "remote MDS with nodsh"
20621
20622         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20623         save_writethrough $p
20624         set_cache writethrough on
20625
20626         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20627         local at_max=$($LCTL get_param -n at_max)
20628         local timeout=$($LCTL get_param -n timeout)
20629         local test_at="at_max"
20630         local param_at="$FSNAME.sys.at_max"
20631         local test_timeout="timeout"
20632         local param_timeout="$FSNAME.sys.timeout"
20633
20634         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20635
20636         set_persistent_param_and_check client "$test_at" "$param_at" 0
20637         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20638
20639         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20640         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20641         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20642         stack_trap "rm -f $DIR/$tfile"
20643         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20644         sync
20645         do_facet ost1 "$LCTL set_param fail_loc=0"
20646
20647         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20648         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20649                 $timeout
20650
20651         $LCTL set_param -n $pages_per_rpc
20652         restore_lustre_params < $p
20653         rm -f $p
20654 }
20655 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20656
20657 test_224d() { # LU-11169
20658         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20659 }
20660 run_test 224d "Don't corrupt data on bulk IO timeout"
20661
20662 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20663 test_225a () {
20664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20665         if [ -z ${MDSSURVEY} ]; then
20666                 skip_env "mds-survey not found"
20667         fi
20668         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20669                 skip "Need MDS version at least 2.2.51"
20670
20671         local mds=$(facet_host $SINGLEMDS)
20672         local target=$(do_nodes $mds 'lctl dl' |
20673                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20674
20675         local cmd1="file_count=1000 thrhi=4"
20676         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20677         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20678         local cmd="$cmd1 $cmd2 $cmd3"
20679
20680         rm -f ${TMP}/mds_survey*
20681         echo + $cmd
20682         eval $cmd || error "mds-survey with zero-stripe failed"
20683         cat ${TMP}/mds_survey*
20684         rm -f ${TMP}/mds_survey*
20685 }
20686 run_test 225a "Metadata survey sanity with zero-stripe"
20687
20688 test_225b () {
20689         if [ -z ${MDSSURVEY} ]; then
20690                 skip_env "mds-survey not found"
20691         fi
20692         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20693                 skip "Need MDS version at least 2.2.51"
20694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20695         remote_mds_nodsh && skip "remote MDS with nodsh"
20696         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20697                 skip_env "Need to mount OST to test"
20698         fi
20699
20700         local mds=$(facet_host $SINGLEMDS)
20701         local target=$(do_nodes $mds 'lctl dl' |
20702                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20703
20704         local cmd1="file_count=1000 thrhi=4"
20705         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20706         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20707         local cmd="$cmd1 $cmd2 $cmd3"
20708
20709         rm -f ${TMP}/mds_survey*
20710         echo + $cmd
20711         eval $cmd || error "mds-survey with stripe_count failed"
20712         cat ${TMP}/mds_survey*
20713         rm -f ${TMP}/mds_survey*
20714 }
20715 run_test 225b "Metadata survey sanity with stripe_count = 1"
20716
20717 mcreate_path2fid () {
20718         local mode=$1
20719         local major=$2
20720         local minor=$3
20721         local name=$4
20722         local desc=$5
20723         local path=$DIR/$tdir/$name
20724         local fid
20725         local rc
20726         local fid_path
20727
20728         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20729                 error "cannot create $desc"
20730
20731         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20732         rc=$?
20733         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20734
20735         fid_path=$($LFS fid2path $MOUNT $fid)
20736         rc=$?
20737         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20738
20739         [ "$path" == "$fid_path" ] ||
20740                 error "fid2path returned $fid_path, expected $path"
20741
20742         echo "pass with $path and $fid"
20743 }
20744
20745 test_226a () {
20746         rm -rf $DIR/$tdir
20747         mkdir -p $DIR/$tdir
20748
20749         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20750         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20751         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20752         mcreate_path2fid 0040666 0 0 dir "directory"
20753         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20754         mcreate_path2fid 0100666 0 0 file "regular file"
20755         mcreate_path2fid 0120666 0 0 link "symbolic link"
20756         mcreate_path2fid 0140666 0 0 sock "socket"
20757 }
20758 run_test 226a "call path2fid and fid2path on files of all type"
20759
20760 test_226b () {
20761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20762
20763         local MDTIDX=1
20764
20765         rm -rf $DIR/$tdir
20766         mkdir -p $DIR/$tdir
20767         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20768                 error "create remote directory failed"
20769         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20770         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20771                                 "character special file (null)"
20772         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20773                                 "character special file (no device)"
20774         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20775         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20776                                 "block special file (loop)"
20777         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20778         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20779         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20780 }
20781 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20782
20783 test_226c () {
20784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20785         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20786                 skip "Need MDS version at least 2.13.55"
20787
20788         local submnt=/mnt/submnt
20789         local srcfile=/etc/passwd
20790         local dstfile=$submnt/passwd
20791         local path
20792         local fid
20793
20794         rm -rf $DIR/$tdir
20795         rm -rf $submnt
20796         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20797                 error "create remote directory failed"
20798         mkdir -p $submnt || error "create $submnt failed"
20799         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20800                 error "mount $submnt failed"
20801         stack_trap "umount $submnt" EXIT
20802
20803         cp $srcfile $dstfile
20804         fid=$($LFS path2fid $dstfile)
20805         path=$($LFS fid2path $submnt "$fid")
20806         [ "$path" = "$dstfile" ] ||
20807                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20808 }
20809 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20810
20811 test_226e () {
20812         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
20813                 skip "Need client at least version 2.15.56"
20814
20815         # Define filename with 'newline' and a space
20816         local testfile="Test"$'\n'"file 01"
20817         # Define link name with multiple 'newline' and a space
20818         local linkfile="Link"$'\n'"file "$'\n'"01"
20819         # Remove prior hard link
20820         rm -f $DIR/"$linkfile"
20821
20822         # Create file
20823         touch $DIR/"$testfile"
20824         # Create link
20825         ln $DIR/"$testfile" $DIR/"$linkfile"
20826
20827         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
20828                 error "getstripe failed on $DIR/$testfile"
20829
20830         # Call with -0 option
20831         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
20832                 echo "FILE:" | grep -c "FILE:")
20833
20834         # With -0 option the output should be exactly 2 lines.
20835         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
20836 }
20837 run_test 226e "Verify path2fid -0 option with newline and space"
20838
20839 # LU-1299 Executing or running ldd on a truncated executable does not
20840 # cause an out-of-memory condition.
20841 test_227() {
20842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20843         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20844
20845         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20846         chmod +x $MOUNT/date
20847
20848         $MOUNT/date > /dev/null
20849         ldd $MOUNT/date > /dev/null
20850         rm -f $MOUNT/date
20851 }
20852 run_test 227 "running truncated executable does not cause OOM"
20853
20854 # LU-1512 try to reuse idle OI blocks
20855 test_228a() {
20856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20857         remote_mds_nodsh && skip "remote MDS with nodsh"
20858         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20859
20860         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20861         local myDIR=$DIR/$tdir
20862
20863         mkdir -p $myDIR
20864         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20865         $LCTL set_param fail_loc=0x80001002
20866         createmany -o $myDIR/t- 10000
20867         $LCTL set_param fail_loc=0
20868         # The guard is current the largest FID holder
20869         touch $myDIR/guard
20870         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20871                     tr -d '[')
20872         local IDX=$(($SEQ % 64))
20873
20874         do_facet $SINGLEMDS sync
20875         # Make sure journal flushed.
20876         sleep 6
20877         local blk1=$(do_facet $SINGLEMDS \
20878                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20879                      grep Blockcount | awk '{print $4}')
20880
20881         # Remove old files, some OI blocks will become idle.
20882         unlinkmany $myDIR/t- 10000
20883         # Create new files, idle OI blocks should be reused.
20884         createmany -o $myDIR/t- 2000
20885         do_facet $SINGLEMDS sync
20886         # Make sure journal flushed.
20887         sleep 6
20888         local blk2=$(do_facet $SINGLEMDS \
20889                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20890                      grep Blockcount | awk '{print $4}')
20891
20892         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20893 }
20894 run_test 228a "try to reuse idle OI blocks"
20895
20896 test_228b() {
20897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20898         remote_mds_nodsh && skip "remote MDS with nodsh"
20899         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20900
20901         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20902         local myDIR=$DIR/$tdir
20903
20904         mkdir -p $myDIR
20905         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20906         $LCTL set_param fail_loc=0x80001002
20907         createmany -o $myDIR/t- 10000
20908         $LCTL set_param fail_loc=0
20909         # The guard is current the largest FID holder
20910         touch $myDIR/guard
20911         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20912                     tr -d '[')
20913         local IDX=$(($SEQ % 64))
20914
20915         do_facet $SINGLEMDS sync
20916         # Make sure journal flushed.
20917         sleep 6
20918         local blk1=$(do_facet $SINGLEMDS \
20919                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20920                      grep Blockcount | awk '{print $4}')
20921
20922         # Remove old files, some OI blocks will become idle.
20923         unlinkmany $myDIR/t- 10000
20924
20925         # stop the MDT
20926         stop $SINGLEMDS || error "Fail to stop MDT."
20927         # remount the MDT
20928         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20929                 error "Fail to start MDT."
20930
20931         client_up || error "Fail to df."
20932         # Create new files, idle OI blocks should be reused.
20933         createmany -o $myDIR/t- 2000
20934         do_facet $SINGLEMDS sync
20935         # Make sure journal flushed.
20936         sleep 6
20937         local blk2=$(do_facet $SINGLEMDS \
20938                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20939                      grep Blockcount | awk '{print $4}')
20940
20941         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20942 }
20943 run_test 228b "idle OI blocks can be reused after MDT restart"
20944
20945 #LU-1881
20946 test_228c() {
20947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20948         remote_mds_nodsh && skip "remote MDS with nodsh"
20949         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20950
20951         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20952         local myDIR=$DIR/$tdir
20953
20954         mkdir -p $myDIR
20955         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20956         $LCTL set_param fail_loc=0x80001002
20957         # 20000 files can guarantee there are index nodes in the OI file
20958         createmany -o $myDIR/t- 20000
20959         $LCTL set_param fail_loc=0
20960         # The guard is current the largest FID holder
20961         touch $myDIR/guard
20962         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20963                     tr -d '[')
20964         local IDX=$(($SEQ % 64))
20965
20966         do_facet $SINGLEMDS sync
20967         # Make sure journal flushed.
20968         sleep 6
20969         local blk1=$(do_facet $SINGLEMDS \
20970                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20971                      grep Blockcount | awk '{print $4}')
20972
20973         # Remove old files, some OI blocks will become idle.
20974         unlinkmany $myDIR/t- 20000
20975         rm -f $myDIR/guard
20976         # The OI file should become empty now
20977
20978         # Create new files, idle OI blocks should be reused.
20979         createmany -o $myDIR/t- 2000
20980         do_facet $SINGLEMDS sync
20981         # Make sure journal flushed.
20982         sleep 6
20983         local blk2=$(do_facet $SINGLEMDS \
20984                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20985                      grep Blockcount | awk '{print $4}')
20986
20987         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20988 }
20989 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20990
20991 test_229() { # LU-2482, LU-3448
20992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20993         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20994         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20995                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20996
20997         rm -f $DIR/$tfile
20998
20999         # Create a file with a released layout and stripe count 2.
21000         $MULTIOP $DIR/$tfile H2c ||
21001                 error "failed to create file with released layout"
21002
21003         $LFS getstripe -v $DIR/$tfile
21004
21005         local pattern=$($LFS getstripe -L $DIR/$tfile)
21006         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21007
21008         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21009                 error "getstripe"
21010         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21011         stat $DIR/$tfile || error "failed to stat released file"
21012
21013         chown $RUNAS_ID $DIR/$tfile ||
21014                 error "chown $RUNAS_ID $DIR/$tfile failed"
21015
21016         chgrp $RUNAS_ID $DIR/$tfile ||
21017                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21018
21019         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21020         rm $DIR/$tfile || error "failed to remove released file"
21021 }
21022 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21023
21024 test_230a() {
21025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21027         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21028                 skip "Need MDS version at least 2.11.52"
21029
21030         local MDTIDX=1
21031
21032         test_mkdir $DIR/$tdir
21033         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21034         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21035         [ $mdt_idx -ne 0 ] &&
21036                 error "create local directory on wrong MDT $mdt_idx"
21037
21038         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21039                         error "create remote directory failed"
21040         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21041         [ $mdt_idx -ne $MDTIDX ] &&
21042                 error "create remote directory on wrong MDT $mdt_idx"
21043
21044         createmany -o $DIR/$tdir/test_230/t- 10 ||
21045                 error "create files on remote directory failed"
21046         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21047         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21048         rm -r $DIR/$tdir || error "unlink remote directory failed"
21049 }
21050 run_test 230a "Create remote directory and files under the remote directory"
21051
21052 test_230b() {
21053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21055         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21056                 skip "Need MDS version at least 2.11.52"
21057
21058         local MDTIDX=1
21059         local mdt_index
21060         local i
21061         local file
21062         local pid
21063         local stripe_count
21064         local migrate_dir=$DIR/$tdir/migrate_dir
21065         local other_dir=$DIR/$tdir/other_dir
21066
21067         test_mkdir $DIR/$tdir
21068         test_mkdir -i0 -c1 $migrate_dir
21069         test_mkdir -i0 -c1 $other_dir
21070         for ((i=0; i<10; i++)); do
21071                 mkdir -p $migrate_dir/dir_${i}
21072                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21073                         error "create files under remote dir failed $i"
21074         done
21075
21076         cp /etc/passwd $migrate_dir/$tfile
21077         cp /etc/passwd $other_dir/$tfile
21078         chattr +SAD $migrate_dir
21079         chattr +SAD $migrate_dir/$tfile
21080
21081         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21082         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21083         local old_dir_mode=$(stat -c%f $migrate_dir)
21084         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21085
21086         mkdir -p $migrate_dir/dir_default_stripe2
21087         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21088         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21089
21090         mkdir -p $other_dir
21091         ln $migrate_dir/$tfile $other_dir/luna
21092         ln $migrate_dir/$tfile $migrate_dir/sofia
21093         ln $other_dir/$tfile $migrate_dir/david
21094         ln -s $migrate_dir/$tfile $other_dir/zachary
21095         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21096         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21097
21098         local len
21099         local lnktgt
21100
21101         # inline symlink
21102         for len in 58 59 60; do
21103                 lnktgt=$(str_repeat 'l' $len)
21104                 touch $migrate_dir/$lnktgt
21105                 ln -s $lnktgt $migrate_dir/${len}char_ln
21106         done
21107
21108         # PATH_MAX
21109         for len in 4094 4095; do
21110                 lnktgt=$(str_repeat 'l' $len)
21111                 ln -s $lnktgt $migrate_dir/${len}char_ln
21112         done
21113
21114         # NAME_MAX
21115         for len in 254 255; do
21116                 touch $migrate_dir/$(str_repeat 'l' $len)
21117         done
21118
21119         $LFS migrate -m $MDTIDX $migrate_dir ||
21120                 error "fails on migrating remote dir to MDT1"
21121
21122         echo "migratate to MDT1, then checking.."
21123         for ((i = 0; i < 10; i++)); do
21124                 for file in $(find $migrate_dir/dir_${i}); do
21125                         mdt_index=$($LFS getstripe -m $file)
21126                         # broken symlink getstripe will fail
21127                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21128                                 error "$file is not on MDT${MDTIDX}"
21129                 done
21130         done
21131
21132         # the multiple link file should still in MDT0
21133         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21134         [ $mdt_index == 0 ] ||
21135                 error "$file is not on MDT${MDTIDX}"
21136
21137         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21138         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21139                 error " expect $old_dir_flag get $new_dir_flag"
21140
21141         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21142         [ "$old_file_flag" = "$new_file_flag" ] ||
21143                 error " expect $old_file_flag get $new_file_flag"
21144
21145         local new_dir_mode=$(stat -c%f $migrate_dir)
21146         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21147                 error "expect mode $old_dir_mode get $new_dir_mode"
21148
21149         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21150         [ "$old_file_mode" = "$new_file_mode" ] ||
21151                 error "expect mode $old_file_mode get $new_file_mode"
21152
21153         diff /etc/passwd $migrate_dir/$tfile ||
21154                 error "$tfile different after migration"
21155
21156         diff /etc/passwd $other_dir/luna ||
21157                 error "luna different after migration"
21158
21159         diff /etc/passwd $migrate_dir/sofia ||
21160                 error "sofia different after migration"
21161
21162         diff /etc/passwd $migrate_dir/david ||
21163                 error "david different after migration"
21164
21165         diff /etc/passwd $other_dir/zachary ||
21166                 error "zachary different after migration"
21167
21168         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21169                 error "${tfile}_ln different after migration"
21170
21171         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21172                 error "${tfile}_ln_other different after migration"
21173
21174         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21175         [ $stripe_count = 2 ] ||
21176                 error "dir strpe_count $d != 2 after migration."
21177
21178         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21179         [ $stripe_count = 2 ] ||
21180                 error "file strpe_count $d != 2 after migration."
21181
21182         #migrate back to MDT0
21183         MDTIDX=0
21184
21185         $LFS migrate -m $MDTIDX $migrate_dir ||
21186                 error "fails on migrating remote dir to MDT0"
21187
21188         echo "migrate back to MDT0, checking.."
21189         for file in $(find $migrate_dir); do
21190                 mdt_index=$($LFS getstripe -m $file)
21191                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21192                         error "$file is not on MDT${MDTIDX}"
21193         done
21194
21195         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21196         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21197                 error " expect $old_dir_flag get $new_dir_flag"
21198
21199         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21200         [ "$old_file_flag" = "$new_file_flag" ] ||
21201                 error " expect $old_file_flag get $new_file_flag"
21202
21203         local new_dir_mode=$(stat -c%f $migrate_dir)
21204         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21205                 error "expect mode $old_dir_mode get $new_dir_mode"
21206
21207         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21208         [ "$old_file_mode" = "$new_file_mode" ] ||
21209                 error "expect mode $old_file_mode get $new_file_mode"
21210
21211         diff /etc/passwd ${migrate_dir}/$tfile ||
21212                 error "$tfile different after migration"
21213
21214         diff /etc/passwd ${other_dir}/luna ||
21215                 error "luna different after migration"
21216
21217         diff /etc/passwd ${migrate_dir}/sofia ||
21218                 error "sofia different after migration"
21219
21220         diff /etc/passwd ${other_dir}/zachary ||
21221                 error "zachary different after migration"
21222
21223         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21224                 error "${tfile}_ln different after migration"
21225
21226         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21227                 error "${tfile}_ln_other different after migration"
21228
21229         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21230         [ $stripe_count = 2 ] ||
21231                 error "dir strpe_count $d != 2 after migration."
21232
21233         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21234         [ $stripe_count = 2 ] ||
21235                 error "file strpe_count $d != 2 after migration."
21236
21237         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21238 }
21239 run_test 230b "migrate directory"
21240
21241 test_230c() {
21242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21244         remote_mds_nodsh && skip "remote MDS with nodsh"
21245         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21246                 skip "Need MDS version at least 2.11.52"
21247
21248         local MDTIDX=1
21249         local total=3
21250         local mdt_index
21251         local file
21252         local migrate_dir=$DIR/$tdir/migrate_dir
21253
21254         #If migrating directory fails in the middle, all entries of
21255         #the directory is still accessiable.
21256         test_mkdir $DIR/$tdir
21257         test_mkdir -i0 -c1 $migrate_dir
21258         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21259         stat $migrate_dir
21260         createmany -o $migrate_dir/f $total ||
21261                 error "create files under ${migrate_dir} failed"
21262
21263         # fail after migrating top dir, and this will fail only once, so the
21264         # first sub file migration will fail (currently f3), others succeed.
21265         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21266         do_facet mds1 lctl set_param fail_loc=0x1801
21267         local t=$(ls $migrate_dir | wc -l)
21268         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21269                 error "migrate should fail"
21270         local u=$(ls $migrate_dir | wc -l)
21271         [ "$u" == "$t" ] || error "$u != $t during migration"
21272
21273         # add new dir/file should succeed
21274         mkdir $migrate_dir/dir ||
21275                 error "mkdir failed under migrating directory"
21276         touch $migrate_dir/file ||
21277                 error "create file failed under migrating directory"
21278
21279         # add file with existing name should fail
21280         for file in $migrate_dir/f*; do
21281                 stat $file > /dev/null || error "stat $file failed"
21282                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21283                         error "open(O_CREAT|O_EXCL) $file should fail"
21284                 $MULTIOP $file m && error "create $file should fail"
21285                 touch $DIR/$tdir/remote_dir/$tfile ||
21286                         error "touch $tfile failed"
21287                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21288                         error "link $file should fail"
21289                 mdt_index=$($LFS getstripe -m $file)
21290                 if [ $mdt_index == 0 ]; then
21291                         # file failed to migrate is not allowed to rename to
21292                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21293                                 error "rename to $file should fail"
21294                 else
21295                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21296                                 error "rename to $file failed"
21297                 fi
21298                 echo hello >> $file || error "write $file failed"
21299         done
21300
21301         # resume migration with different options should fail
21302         $LFS migrate -m 0 $migrate_dir &&
21303                 error "migrate -m 0 $migrate_dir should fail"
21304
21305         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21306                 error "migrate -c 2 $migrate_dir should fail"
21307
21308         # resume migration should succeed
21309         $LFS migrate -m $MDTIDX $migrate_dir ||
21310                 error "migrate $migrate_dir failed"
21311
21312         echo "Finish migration, then checking.."
21313         for file in $(find $migrate_dir); do
21314                 mdt_index=$($LFS getstripe -m $file)
21315                 [ $mdt_index == $MDTIDX ] ||
21316                         error "$file is not on MDT${MDTIDX}"
21317         done
21318
21319         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21320 }
21321 run_test 230c "check directory accessiblity if migration failed"
21322
21323 test_230d() {
21324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21326         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21327                 skip "Need MDS version at least 2.11.52"
21328         # LU-11235
21329         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21330
21331         local migrate_dir=$DIR/$tdir/migrate_dir
21332         local old_index
21333         local new_index
21334         local old_count
21335         local new_count
21336         local new_hash
21337         local mdt_index
21338         local i
21339         local j
21340
21341         old_index=$((RANDOM % MDSCOUNT))
21342         old_count=$((MDSCOUNT - old_index))
21343         new_index=$((RANDOM % MDSCOUNT))
21344         new_count=$((MDSCOUNT - new_index))
21345         new_hash=1 # for all_char
21346
21347         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21348         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21349
21350         test_mkdir $DIR/$tdir
21351         test_mkdir -i $old_index -c $old_count $migrate_dir
21352
21353         for ((i=0; i<100; i++)); do
21354                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21355                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21356                         error "create files under remote dir failed $i"
21357         done
21358
21359         echo -n "Migrate from MDT$old_index "
21360         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21361         echo -n "to MDT$new_index"
21362         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21363         echo
21364
21365         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21366         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21367                 error "migrate remote dir error"
21368
21369         echo "Finish migration, then checking.."
21370         for file in $(find $migrate_dir -maxdepth 1); do
21371                 mdt_index=$($LFS getstripe -m $file)
21372                 if [ $mdt_index -lt $new_index ] ||
21373                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21374                         error "$file is on MDT$mdt_index"
21375                 fi
21376         done
21377
21378         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21379 }
21380 run_test 230d "check migrate big directory"
21381
21382 test_230e() {
21383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21384         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21385         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21386                 skip "Need MDS version at least 2.11.52"
21387
21388         local i
21389         local j
21390         local a_fid
21391         local b_fid
21392
21393         mkdir_on_mdt0 $DIR/$tdir
21394         mkdir $DIR/$tdir/migrate_dir
21395         mkdir $DIR/$tdir/other_dir
21396         touch $DIR/$tdir/migrate_dir/a
21397         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21398         ls $DIR/$tdir/other_dir
21399
21400         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21401                 error "migrate dir fails"
21402
21403         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21404         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21405
21406         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21407         [ $mdt_index == 0 ] || error "a is not on MDT0"
21408
21409         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21410                 error "migrate dir fails"
21411
21412         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21413         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21414
21415         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21416         [ $mdt_index == 1 ] || error "a is not on MDT1"
21417
21418         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21419         [ $mdt_index == 1 ] || error "b is not on MDT1"
21420
21421         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21422         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21423
21424         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21425
21426         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21427 }
21428 run_test 230e "migrate mulitple local link files"
21429
21430 test_230f() {
21431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21433         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21434                 skip "Need MDS version at least 2.11.52"
21435
21436         local a_fid
21437         local ln_fid
21438
21439         mkdir -p $DIR/$tdir
21440         mkdir $DIR/$tdir/migrate_dir
21441         $LFS mkdir -i1 $DIR/$tdir/other_dir
21442         touch $DIR/$tdir/migrate_dir/a
21443         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21444         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21445         ls $DIR/$tdir/other_dir
21446
21447         # a should be migrated to MDT1, since no other links on MDT0
21448         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21449                 error "#1 migrate dir fails"
21450         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21451         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21452         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21453         [ $mdt_index == 1 ] || error "a is not on MDT1"
21454
21455         # a should stay on MDT1, because it is a mulitple link file
21456         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21457                 error "#2 migrate dir fails"
21458         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21459         [ $mdt_index == 1 ] || error "a is not on MDT1"
21460
21461         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21462                 error "#3 migrate dir fails"
21463
21464         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21465         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21466         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21467
21468         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21469         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21470
21471         # a should be migrated to MDT0, since no other links on MDT1
21472         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21473                 error "#4 migrate dir fails"
21474         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21475         [ $mdt_index == 0 ] || error "a is not on MDT0"
21476
21477         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21478 }
21479 run_test 230f "migrate mulitple remote link files"
21480
21481 test_230g() {
21482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21483         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21484         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21485                 skip "Need MDS version at least 2.11.52"
21486
21487         mkdir -p $DIR/$tdir/migrate_dir
21488
21489         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21490                 error "migrating dir to non-exist MDT succeeds"
21491         true
21492 }
21493 run_test 230g "migrate dir to non-exist MDT"
21494
21495 test_230h() {
21496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21497         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21498         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21499                 skip "Need MDS version at least 2.11.52"
21500
21501         local mdt_index
21502
21503         mkdir -p $DIR/$tdir/migrate_dir
21504
21505         $LFS migrate -m1 $DIR &&
21506                 error "migrating mountpoint1 should fail"
21507
21508         $LFS migrate -m1 $DIR/$tdir/.. &&
21509                 error "migrating mountpoint2 should fail"
21510
21511         # same as mv
21512         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21513                 error "migrating $tdir/migrate_dir/.. should fail"
21514
21515         true
21516 }
21517 run_test 230h "migrate .. and root"
21518
21519 test_230i() {
21520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21521         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21522         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21523                 skip "Need MDS version at least 2.11.52"
21524
21525         mkdir -p $DIR/$tdir/migrate_dir
21526
21527         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21528                 error "migration fails with a tailing slash"
21529
21530         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21531                 error "migration fails with two tailing slashes"
21532 }
21533 run_test 230i "lfs migrate -m tolerates trailing slashes"
21534
21535 test_230j() {
21536         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21537         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21538                 skip "Need MDS version at least 2.11.52"
21539
21540         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21541         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21542                 error "create $tfile failed"
21543         cat /etc/passwd > $DIR/$tdir/$tfile
21544
21545         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21546
21547         cmp /etc/passwd $DIR/$tdir/$tfile ||
21548                 error "DoM file mismatch after migration"
21549 }
21550 run_test 230j "DoM file data not changed after dir migration"
21551
21552 test_230k() {
21553         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21554         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21555                 skip "Need MDS version at least 2.11.56"
21556
21557         local total=20
21558         local files_on_starting_mdt=0
21559
21560         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21561         $LFS getdirstripe $DIR/$tdir
21562         for i in $(seq $total); do
21563                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21564                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21565                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21566         done
21567
21568         echo "$files_on_starting_mdt files on MDT0"
21569
21570         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21571         $LFS getdirstripe $DIR/$tdir
21572
21573         files_on_starting_mdt=0
21574         for i in $(seq $total); do
21575                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21576                         error "file $tfile.$i mismatch after migration"
21577                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21578                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21579         done
21580
21581         echo "$files_on_starting_mdt files on MDT1 after migration"
21582         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21583
21584         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21585         $LFS getdirstripe $DIR/$tdir
21586
21587         files_on_starting_mdt=0
21588         for i in $(seq $total); do
21589                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21590                         error "file $tfile.$i mismatch after 2nd migration"
21591                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21592                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21593         done
21594
21595         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21596         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21597
21598         true
21599 }
21600 run_test 230k "file data not changed after dir migration"
21601
21602 test_230l() {
21603         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21604         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21605                 skip "Need MDS version at least 2.11.56"
21606
21607         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21608         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21609                 error "create files under remote dir failed $i"
21610         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21611 }
21612 run_test 230l "readdir between MDTs won't crash"
21613
21614 test_230m() {
21615         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21616         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21617                 skip "Need MDS version at least 2.11.56"
21618
21619         local MDTIDX=1
21620         local mig_dir=$DIR/$tdir/migrate_dir
21621         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21622         local shortstr="b"
21623         local val
21624
21625         echo "Creating files and dirs with xattrs"
21626         test_mkdir $DIR/$tdir
21627         test_mkdir -i0 -c1 $mig_dir
21628         mkdir $mig_dir/dir
21629         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21630                 error "cannot set xattr attr1 on dir"
21631         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21632                 error "cannot set xattr attr2 on dir"
21633         touch $mig_dir/dir/f0
21634         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21635                 error "cannot set xattr attr1 on file"
21636         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21637                 error "cannot set xattr attr2 on file"
21638         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21639         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21640         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21641         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21642         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21643         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21644         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21645         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21646         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21647
21648         echo "Migrating to MDT1"
21649         $LFS migrate -m $MDTIDX $mig_dir ||
21650                 error "fails on migrating dir to MDT1"
21651
21652         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21653         echo "Checking xattrs"
21654         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21655         [ "$val" = $longstr ] ||
21656                 error "expecting xattr1 $longstr on dir, found $val"
21657         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21658         [ "$val" = $shortstr ] ||
21659                 error "expecting xattr2 $shortstr on dir, found $val"
21660         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21661         [ "$val" = $longstr ] ||
21662                 error "expecting xattr1 $longstr on file, found $val"
21663         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21664         [ "$val" = $shortstr ] ||
21665                 error "expecting xattr2 $shortstr on file, found $val"
21666 }
21667 run_test 230m "xattrs not changed after dir migration"
21668
21669 test_230n() {
21670         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21671         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21672                 skip "Need MDS version at least 2.13.53"
21673
21674         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21675         cat /etc/hosts > $DIR/$tdir/$tfile
21676         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21677         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21678
21679         cmp /etc/hosts $DIR/$tdir/$tfile ||
21680                 error "File data mismatch after migration"
21681 }
21682 run_test 230n "Dir migration with mirrored file"
21683
21684 test_230o() {
21685         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21686         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21687                 skip "Need MDS version at least 2.13.52"
21688
21689         local mdts=$(comma_list $(mdts_nodes))
21690         local timeout=100
21691         local restripe_status
21692         local delta
21693         local i
21694
21695         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21696
21697         # in case "crush" hash type is not set
21698         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21699
21700         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21701                            mdt.*MDT0000.enable_dir_restripe)
21702         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21703         stack_trap "do_nodes $mdts $LCTL set_param \
21704                     mdt.*.enable_dir_restripe=$restripe_status"
21705
21706         mkdir $DIR/$tdir
21707         createmany -m $DIR/$tdir/f 100 ||
21708                 error "create files under remote dir failed $i"
21709         createmany -d $DIR/$tdir/d 100 ||
21710                 error "create dirs under remote dir failed $i"
21711
21712         for i in $(seq 2 $MDSCOUNT); do
21713                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21714                 $LFS setdirstripe -c $i $DIR/$tdir ||
21715                         error "split -c $i $tdir failed"
21716                 wait_update $HOSTNAME \
21717                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21718                         error "dir split not finished"
21719                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21720                         awk '/migrate/ {sum += $2} END { print sum }')
21721                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21722                 # delta is around total_files/stripe_count
21723                 (( $delta < 200 / (i - 1) + 4 )) ||
21724                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21725         done
21726 }
21727 run_test 230o "dir split"
21728
21729 test_230p() {
21730         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21731         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21732                 skip "Need MDS version at least 2.13.52"
21733
21734         local mdts=$(comma_list $(mdts_nodes))
21735         local timeout=100
21736         local restripe_status
21737         local delta
21738         local c
21739
21740         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21741
21742         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21743
21744         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21745                            mdt.*MDT0000.enable_dir_restripe)
21746         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21747         stack_trap "do_nodes $mdts $LCTL set_param \
21748                     mdt.*.enable_dir_restripe=$restripe_status"
21749
21750         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21751         createmany -m $DIR/$tdir/f 100 ||
21752                 error "create files under remote dir failed"
21753         createmany -d $DIR/$tdir/d 100 ||
21754                 error "create dirs under remote dir failed"
21755
21756         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21757                 local mdt_hash="crush"
21758
21759                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21760                 $LFS setdirstripe -c $c $DIR/$tdir ||
21761                         error "split -c $c $tdir failed"
21762                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21763                         mdt_hash="$mdt_hash,fixed"
21764                 elif [ $c -eq 1 ]; then
21765                         mdt_hash="none"
21766                 fi
21767                 wait_update $HOSTNAME \
21768                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21769                         error "dir merge not finished"
21770                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21771                         awk '/migrate/ {sum += $2} END { print sum }')
21772                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21773                 # delta is around total_files/stripe_count
21774                 (( delta < 200 / c + 4 )) ||
21775                         error "$delta files migrated >= $((200 / c + 4))"
21776         done
21777 }
21778 run_test 230p "dir merge"
21779
21780 test_230q() {
21781         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21782         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21783                 skip "Need MDS version at least 2.13.52"
21784
21785         local mdts=$(comma_list $(mdts_nodes))
21786         local saved_threshold=$(do_facet mds1 \
21787                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21788         local saved_delta=$(do_facet mds1 \
21789                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21790         local threshold=100
21791         local delta=2
21792         local total=0
21793         local stripe_count=0
21794         local stripe_index
21795         local nr_files
21796         local create
21797
21798         # test with fewer files on ZFS
21799         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21800
21801         stack_trap "do_nodes $mdts $LCTL set_param \
21802                     mdt.*.dir_split_count=$saved_threshold"
21803         stack_trap "do_nodes $mdts $LCTL set_param \
21804                     mdt.*.dir_split_delta=$saved_delta"
21805         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21806         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21807         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21808         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21809         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21810         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21811
21812         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21813         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21814
21815         create=$((threshold * 3 / 2))
21816         while [ $stripe_count -lt $MDSCOUNT ]; do
21817                 createmany -m $DIR/$tdir/f $total $create ||
21818                         error "create sub files failed"
21819                 stat $DIR/$tdir > /dev/null
21820                 total=$((total + create))
21821                 stripe_count=$((stripe_count + delta))
21822                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21823
21824                 wait_update $HOSTNAME \
21825                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21826                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21827
21828                 wait_update $HOSTNAME \
21829                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21830                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21831
21832                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21833                 echo "$nr_files/$total files on MDT$stripe_index after split"
21834                 # allow 10% margin of imbalance with crush hash
21835                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21836                         error "$nr_files files on MDT$stripe_index after split"
21837
21838                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21839                 [ $nr_files -eq $total ] ||
21840                         error "total sub files $nr_files != $total"
21841         done
21842
21843         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21844
21845         echo "fixed layout directory won't auto split"
21846         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21847         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21848                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21849         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21850                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21851 }
21852 run_test 230q "dir auto split"
21853
21854 test_230r() {
21855         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21856         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21857         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21858                 skip "Need MDS version at least 2.13.54"
21859
21860         # maximum amount of local locks:
21861         # parent striped dir - 2 locks
21862         # new stripe in parent to migrate to - 1 lock
21863         # source and target - 2 locks
21864         # Total 5 locks for regular file
21865         mkdir -p $DIR/$tdir
21866         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21867         touch $DIR/$tdir/dir1/eee
21868
21869         # create 4 hardlink for 4 more locks
21870         # Total: 9 locks > RS_MAX_LOCKS (8)
21871         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21872         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21873         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21874         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21875         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21876         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21877         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21878         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21879
21880         cancel_lru_locks mdc
21881
21882         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21883                 error "migrate dir fails"
21884
21885         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21886 }
21887 run_test 230r "migrate with too many local locks"
21888
21889 test_230s() {
21890         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21891                 skip "Need MDS version at least 2.14.52"
21892
21893         local mdts=$(comma_list $(mdts_nodes))
21894         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21895                                 mdt.*MDT0000.enable_dir_restripe)
21896
21897         stack_trap "do_nodes $mdts $LCTL set_param \
21898                     mdt.*.enable_dir_restripe=$restripe_status"
21899
21900         local st
21901         for st in 0 1; do
21902                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21903                 test_mkdir $DIR/$tdir
21904                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21905                         error "$LFS mkdir should return EEXIST if target exists"
21906                 rmdir $DIR/$tdir
21907         done
21908 }
21909 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21910
21911 test_230t()
21912 {
21913         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21914         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21915                 skip "Need MDS version at least 2.14.50"
21916
21917         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21918         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21919         $LFS project -p 1 -s $DIR/$tdir ||
21920                 error "set $tdir project id failed"
21921         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21922                 error "set subdir project id failed"
21923         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21924 }
21925 run_test 230t "migrate directory with project ID set"
21926
21927 test_230u()
21928 {
21929         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21930         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21931                 skip "Need MDS version at least 2.14.53"
21932
21933         local count
21934
21935         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21936         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21937         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21938         for i in $(seq 0 $((MDSCOUNT - 1))); do
21939                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21940                 echo "$count dirs migrated to MDT$i"
21941         done
21942         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21943         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21944 }
21945 run_test 230u "migrate directory by QOS"
21946
21947 test_230v()
21948 {
21949         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21950         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21951                 skip "Need MDS version at least 2.14.53"
21952
21953         local count
21954
21955         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21956         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21957         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21958         for i in $(seq 0 $((MDSCOUNT - 1))); do
21959                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21960                 echo "$count subdirs migrated to MDT$i"
21961                 (( i == 3 )) && (( count > 0 )) &&
21962                         error "subdir shouldn't be migrated to MDT3"
21963         done
21964         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21965         (( count == 3 )) || error "dirs migrated to $count MDTs"
21966 }
21967 run_test 230v "subdir migrated to the MDT where its parent is located"
21968
21969 test_230w() {
21970         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21971         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21972                 skip "Need MDS version at least 2.15.0"
21973
21974         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21975         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21976         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21977
21978         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21979                 error "migrate failed"
21980
21981         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21982                 error "$tdir stripe count mismatch"
21983
21984         for i in $(seq 0 9); do
21985                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21986                         error "d$i is striped"
21987         done
21988 }
21989 run_test 230w "non-recursive mode dir migration"
21990
21991 test_230x() {
21992         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21993         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21994                 skip "Need MDS version at least 2.15.0"
21995
21996         mkdir -p $DIR/$tdir || error "mkdir failed"
21997         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21998
21999         local mdt_name=$(mdtname_from_index 0)
22000         local low=$(do_facet mds2 $LCTL get_param -n \
22001                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22002         local high=$(do_facet mds2 $LCTL get_param -n \
22003                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22004         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22005         local maxage=$(do_facet mds2 $LCTL get_param -n \
22006                 osp.*$mdt_name-osp-MDT0001.maxage)
22007
22008         stack_trap "do_facet mds2 $LCTL set_param -n \
22009                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22010                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22011         stack_trap "do_facet mds2 $LCTL set_param -n \
22012                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22013
22014         do_facet mds2 $LCTL set_param -n \
22015                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22016         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22017         sleep 4
22018         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22019                 error "migrate $tdir should fail"
22020
22021         do_facet mds2 $LCTL set_param -n \
22022                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22023         do_facet mds2 $LCTL set_param -n \
22024                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22025         sleep 4
22026         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22027                 error "migrate failed"
22028         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22029                 error "$tdir stripe count mismatch"
22030 }
22031 run_test 230x "dir migration check space"
22032
22033 test_230y() {
22034         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22035         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22036                 skip "Need MDS version at least 2.15.55.45"
22037
22038         local pid
22039
22040         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22041         $LFS getdirstripe $DIR/$tdir
22042         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22043         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22044         pid=$!
22045         sleep 1
22046
22047         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22048         do_facet mds2 lctl set_param fail_loc=0x1802
22049
22050         wait $pid
22051         do_facet mds2 lctl set_param fail_loc=0
22052         $LFS getdirstripe $DIR/$tdir
22053         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22054         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22055 }
22056 run_test 230y "unlink dir with bad hash type"
22057
22058 test_230z() {
22059         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22060         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22061                 skip "Need MDS version at least 2.15.55.45"
22062
22063         local pid
22064
22065         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22066         $LFS getdirstripe $DIR/$tdir
22067         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22068         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22069         pid=$!
22070         sleep 1
22071
22072         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22073         do_facet mds2 lctl set_param fail_loc=0x1802
22074
22075         wait $pid
22076         do_facet mds2 lctl set_param fail_loc=0
22077         $LFS getdirstripe $DIR/$tdir
22078
22079         # resume migration
22080         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22081                 error "resume migration failed"
22082         $LFS getdirstripe $DIR/$tdir
22083         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22084                 error "migration is not finished"
22085 }
22086 run_test 230z "resume dir migration with bad hash type"
22087
22088 test_231a()
22089 {
22090         # For simplicity this test assumes that max_pages_per_rpc
22091         # is the same across all OSCs
22092         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22093         local bulk_size=$((max_pages * PAGE_SIZE))
22094         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22095                                        head -n 1)
22096
22097         mkdir -p $DIR/$tdir
22098         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22099                 error "failed to set stripe with -S ${brw_size}M option"
22100         stack_trap "rm -rf $DIR/$tdir"
22101
22102         # clear the OSC stats
22103         $LCTL set_param osc.*.stats=0 &>/dev/null
22104         stop_writeback
22105
22106         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22107         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22108                 oflag=direct &>/dev/null || error "dd failed"
22109
22110         sync; sleep 1; sync # just to be safe
22111         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22112         if [ x$nrpcs != "x1" ]; then
22113                 $LCTL get_param osc.*.stats
22114                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22115         fi
22116
22117         start_writeback
22118         # Drop the OSC cache, otherwise we will read from it
22119         cancel_lru_locks osc
22120
22121         # clear the OSC stats
22122         $LCTL set_param osc.*.stats=0 &>/dev/null
22123
22124         # Client reads $bulk_size.
22125         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22126                 iflag=direct &>/dev/null || error "dd failed"
22127
22128         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22129         if [ x$nrpcs != "x1" ]; then
22130                 $LCTL get_param osc.*.stats
22131                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22132         fi
22133 }
22134 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22135
22136 test_231b() {
22137         mkdir -p $DIR/$tdir
22138         stack_trap "rm -rf $DIR/$tdir"
22139         local i
22140         for i in {0..1023}; do
22141                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22142                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22143                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22144         done
22145         sync
22146 }
22147 run_test 231b "must not assert on fully utilized OST request buffer"
22148
22149 test_232a() {
22150         mkdir -p $DIR/$tdir
22151         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22152
22153         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22154         do_facet ost1 $LCTL set_param fail_loc=0x31c
22155
22156         # ignore dd failure
22157         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22158         stack_trap "rm -f $DIR/$tdir/$tfile"
22159
22160         do_facet ost1 $LCTL set_param fail_loc=0
22161         umount_client $MOUNT || error "umount failed"
22162         mount_client $MOUNT || error "mount failed"
22163         stop ost1 || error "cannot stop ost1"
22164         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22165 }
22166 run_test 232a "failed lock should not block umount"
22167
22168 test_232b() {
22169         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22170                 skip "Need MDS version at least 2.10.58"
22171
22172         mkdir -p $DIR/$tdir
22173         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22174         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22175         stack_trap "rm -f $DIR/$tdir/$tfile"
22176         sync
22177         cancel_lru_locks osc
22178
22179         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22180         do_facet ost1 $LCTL set_param fail_loc=0x31c
22181
22182         # ignore failure
22183         $LFS data_version $DIR/$tdir/$tfile || true
22184
22185         do_facet ost1 $LCTL set_param fail_loc=0
22186         umount_client $MOUNT || error "umount failed"
22187         mount_client $MOUNT || error "mount failed"
22188         stop ost1 || error "cannot stop ost1"
22189         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22190 }
22191 run_test 232b "failed data version lock should not block umount"
22192
22193 test_233a() {
22194         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22195                 skip "Need MDS version at least 2.3.64"
22196         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22197
22198         local fid=$($LFS path2fid $MOUNT)
22199
22200         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22201                 error "cannot access $MOUNT using its FID '$fid'"
22202 }
22203 run_test 233a "checking that OBF of the FS root succeeds"
22204
22205 test_233b() {
22206         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22207                 skip "Need MDS version at least 2.5.90"
22208         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22209
22210         local fid=$($LFS path2fid $MOUNT/.lustre)
22211
22212         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22213                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22214
22215         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22216         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22217                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22218 }
22219 run_test 233b "checking that OBF of the FS .lustre succeeds"
22220
22221 test_234() {
22222         local p="$TMP/sanityN-$TESTNAME.parameters"
22223         save_lustre_params client "llite.*.xattr_cache" > $p
22224         lctl set_param llite.*.xattr_cache 1 ||
22225                 skip_env "xattr cache is not supported"
22226
22227         mkdir -p $DIR/$tdir || error "mkdir failed"
22228         touch $DIR/$tdir/$tfile || error "touch failed"
22229         # OBD_FAIL_LLITE_XATTR_ENOMEM
22230         $LCTL set_param fail_loc=0x1405
22231         getfattr -n user.attr $DIR/$tdir/$tfile &&
22232                 error "getfattr should have failed with ENOMEM"
22233         $LCTL set_param fail_loc=0x0
22234         rm -rf $DIR/$tdir
22235
22236         restore_lustre_params < $p
22237         rm -f $p
22238 }
22239 run_test 234 "xattr cache should not crash on ENOMEM"
22240
22241 test_235() {
22242         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22243                 skip "Need MDS version at least 2.4.52"
22244
22245         flock_deadlock $DIR/$tfile
22246         local RC=$?
22247         case $RC in
22248                 0)
22249                 ;;
22250                 124) error "process hangs on a deadlock"
22251                 ;;
22252                 *) error "error executing flock_deadlock $DIR/$tfile"
22253                 ;;
22254         esac
22255 }
22256 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22257
22258 #LU-2935
22259 test_236() {
22260         check_swap_layouts_support
22261
22262         local ref1=/etc/passwd
22263         local ref2=/etc/group
22264         local file1=$DIR/$tdir/f1
22265         local file2=$DIR/$tdir/f2
22266
22267         test_mkdir -c1 $DIR/$tdir
22268         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22269         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22270         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22271         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22272         local fd=$(free_fd)
22273         local cmd="exec $fd<>$file2"
22274         eval $cmd
22275         rm $file2
22276         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22277                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22278         cmd="exec $fd>&-"
22279         eval $cmd
22280         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22281
22282         #cleanup
22283         rm -rf $DIR/$tdir
22284 }
22285 run_test 236 "Layout swap on open unlinked file"
22286
22287 # LU-4659 linkea consistency
22288 test_238() {
22289         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22290                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22291                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22292                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22293
22294         touch $DIR/$tfile
22295         ln $DIR/$tfile $DIR/$tfile.lnk
22296         touch $DIR/$tfile.new
22297         mv $DIR/$tfile.new $DIR/$tfile
22298         local fid1=$($LFS path2fid $DIR/$tfile)
22299         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22300         local path1=$($LFS fid2path $FSNAME "$fid1")
22301         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22302         local path2=$($LFS fid2path $FSNAME "$fid2")
22303         [ $tfile.lnk == $path2 ] ||
22304                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22305         rm -f $DIR/$tfile*
22306 }
22307 run_test 238 "Verify linkea consistency"
22308
22309 test_239A() { # was test_239
22310         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22311                 skip "Need MDS version at least 2.5.60"
22312
22313         local list=$(comma_list $(mdts_nodes))
22314
22315         mkdir -p $DIR/$tdir
22316         createmany -o $DIR/$tdir/f- 5000
22317         unlinkmany $DIR/$tdir/f- 5000
22318         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22319                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22320         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22321                         osp.*MDT*.sync_in_flight" | calc_sum)
22322         [ "$changes" -eq 0 ] || error "$changes not synced"
22323 }
22324 run_test 239A "osp_sync test"
22325
22326 test_239a() { #LU-5297
22327         remote_mds_nodsh && skip "remote MDS with nodsh"
22328
22329         touch $DIR/$tfile
22330         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22331         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22332         chgrp $RUNAS_GID $DIR/$tfile
22333         wait_delete_completed
22334 }
22335 run_test 239a "process invalid osp sync record correctly"
22336
22337 test_239b() { #LU-5297
22338         remote_mds_nodsh && skip "remote MDS with nodsh"
22339
22340         touch $DIR/$tfile1
22341         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22342         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22343         chgrp $RUNAS_GID $DIR/$tfile1
22344         wait_delete_completed
22345         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22346         touch $DIR/$tfile2
22347         chgrp $RUNAS_GID $DIR/$tfile2
22348         wait_delete_completed
22349 }
22350 run_test 239b "process osp sync record with ENOMEM error correctly"
22351
22352 test_240() {
22353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22354         remote_mds_nodsh && skip "remote MDS with nodsh"
22355
22356         mkdir -p $DIR/$tdir
22357
22358         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22359                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22360         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22361                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22362
22363         umount_client $MOUNT || error "umount failed"
22364         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22365         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22366         mount_client $MOUNT || error "failed to mount client"
22367
22368         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22369         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22370 }
22371 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22372
22373 test_241_bio() {
22374         local count=$1
22375         local bsize=$2
22376
22377         for LOOP in $(seq $count); do
22378                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22379                 cancel_lru_locks $OSC || true
22380         done
22381 }
22382
22383 test_241_dio() {
22384         local count=$1
22385         local bsize=$2
22386
22387         for LOOP in $(seq $1); do
22388                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22389                         2>/dev/null
22390         done
22391 }
22392
22393 test_241a() { # was test_241
22394         local bsize=$PAGE_SIZE
22395
22396         (( bsize < 40960 )) && bsize=40960
22397         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22398         ls -la $DIR/$tfile
22399         cancel_lru_locks $OSC
22400         test_241_bio 1000 $bsize &
22401         PID=$!
22402         test_241_dio 1000 $bsize
22403         wait $PID
22404 }
22405 run_test 241a "bio vs dio"
22406
22407 test_241b() {
22408         local bsize=$PAGE_SIZE
22409
22410         (( bsize < 40960 )) && bsize=40960
22411         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22412         ls -la $DIR/$tfile
22413         test_241_dio 1000 $bsize &
22414         PID=$!
22415         test_241_dio 1000 $bsize
22416         wait $PID
22417 }
22418 run_test 241b "dio vs dio"
22419
22420 test_242() {
22421         remote_mds_nodsh && skip "remote MDS with nodsh"
22422
22423         mkdir_on_mdt0 $DIR/$tdir
22424         touch $DIR/$tdir/$tfile
22425
22426         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22427         do_facet mds1 lctl set_param fail_loc=0x105
22428         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22429
22430         do_facet mds1 lctl set_param fail_loc=0
22431         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22432 }
22433 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22434
22435 test_243()
22436 {
22437         test_mkdir $DIR/$tdir
22438         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22439 }
22440 run_test 243 "various group lock tests"
22441
22442 test_244a()
22443 {
22444         test_mkdir $DIR/$tdir
22445         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22446         sendfile_grouplock $DIR/$tdir/$tfile || \
22447                 error "sendfile+grouplock failed"
22448         rm -rf $DIR/$tdir
22449 }
22450 run_test 244a "sendfile with group lock tests"
22451
22452 test_244b()
22453 {
22454         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22455
22456         local threads=50
22457         local size=$((1024*1024))
22458
22459         test_mkdir $DIR/$tdir
22460         for i in $(seq 1 $threads); do
22461                 local file=$DIR/$tdir/file_$((i / 10))
22462                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22463                 local pids[$i]=$!
22464         done
22465         for i in $(seq 1 $threads); do
22466                 wait ${pids[$i]}
22467         done
22468 }
22469 run_test 244b "multi-threaded write with group lock"
22470
22471 test_245a() {
22472         local flagname="multi_mod_rpcs"
22473         local connect_data_name="max_mod_rpcs"
22474         local out
22475
22476         # check if multiple modify RPCs flag is set
22477         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22478                 grep "connect_flags:")
22479         echo "$out"
22480
22481         echo "$out" | grep -qw $flagname
22482         if [ $? -ne 0 ]; then
22483                 echo "connect flag $flagname is not set"
22484                 return
22485         fi
22486
22487         # check if multiple modify RPCs data is set
22488         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22489         echo "$out"
22490
22491         echo "$out" | grep -qw $connect_data_name ||
22492                 error "import should have connect data $connect_data_name"
22493 }
22494 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22495
22496 test_245b() {
22497         local flagname="multi_mod_rpcs"
22498         local connect_data_name="max_mod_rpcs"
22499         local out
22500
22501         remote_mds_nodsh && skip "remote MDS with nodsh"
22502         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22503
22504         # check if multiple modify RPCs flag is set
22505         out=$(do_facet mds1 \
22506               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22507               grep "connect_flags:")
22508         echo "$out"
22509
22510         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22511
22512         # check if multiple modify RPCs data is set
22513         out=$(do_facet mds1 \
22514               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22515
22516         [[ "$out" =~ $connect_data_name ]] ||
22517                 {
22518                         echo "$out"
22519                         error "missing connect data $connect_data_name"
22520                 }
22521 }
22522 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22523
22524 cleanup_247() {
22525         local submount=$1
22526
22527         trap 0
22528         umount_client $submount
22529         rmdir $submount
22530 }
22531
22532 test_247a() {
22533         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22534                 grep -q subtree ||
22535                 skip_env "Fileset feature is not supported"
22536
22537         local submount=${MOUNT}_$tdir
22538
22539         mkdir $MOUNT/$tdir
22540         mkdir -p $submount || error "mkdir $submount failed"
22541         FILESET="$FILESET/$tdir" mount_client $submount ||
22542                 error "mount $submount failed"
22543         trap "cleanup_247 $submount" EXIT
22544         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22545         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22546                 error "read $MOUNT/$tdir/$tfile failed"
22547         cleanup_247 $submount
22548 }
22549 run_test 247a "mount subdir as fileset"
22550
22551 test_247b() {
22552         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22553                 skip_env "Fileset feature is not supported"
22554
22555         local submount=${MOUNT}_$tdir
22556
22557         rm -rf $MOUNT/$tdir
22558         mkdir -p $submount || error "mkdir $submount failed"
22559         SKIP_FILESET=1
22560         FILESET="$FILESET/$tdir" mount_client $submount &&
22561                 error "mount $submount should fail"
22562         rmdir $submount
22563 }
22564 run_test 247b "mount subdir that dose not exist"
22565
22566 test_247c() {
22567         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22568                 skip_env "Fileset feature is not supported"
22569
22570         local submount=${MOUNT}_$tdir
22571
22572         mkdir -p $MOUNT/$tdir/dir1
22573         mkdir -p $submount || error "mkdir $submount failed"
22574         trap "cleanup_247 $submount" EXIT
22575         FILESET="$FILESET/$tdir" mount_client $submount ||
22576                 error "mount $submount failed"
22577         local fid=$($LFS path2fid $MOUNT/)
22578         $LFS fid2path $submount $fid && error "fid2path should fail"
22579         cleanup_247 $submount
22580 }
22581 run_test 247c "running fid2path outside subdirectory root"
22582
22583 test_247d() {
22584         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22585                 skip "Fileset feature is not supported"
22586
22587         local submount=${MOUNT}_$tdir
22588
22589         mkdir -p $MOUNT/$tdir/dir1
22590         mkdir -p $submount || error "mkdir $submount failed"
22591         FILESET="$FILESET/$tdir" mount_client $submount ||
22592                 error "mount $submount failed"
22593         trap "cleanup_247 $submount" EXIT
22594
22595         local td=$submount/dir1
22596         local fid=$($LFS path2fid $td)
22597         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22598
22599         # check that we get the same pathname back
22600         local rootpath
22601         local found
22602         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22603                 echo "$rootpath $fid"
22604                 found=$($LFS fid2path $rootpath "$fid")
22605                 [ -n "$found" ] || error "fid2path should succeed"
22606                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22607         done
22608         # check wrong root path format
22609         rootpath=$submount"_wrong"
22610         found=$($LFS fid2path $rootpath "$fid")
22611         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22612
22613         cleanup_247 $submount
22614 }
22615 run_test 247d "running fid2path inside subdirectory root"
22616
22617 # LU-8037
22618 test_247e() {
22619         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22620                 grep -q subtree ||
22621                 skip "Fileset feature is not supported"
22622
22623         local submount=${MOUNT}_$tdir
22624
22625         mkdir $MOUNT/$tdir
22626         mkdir -p $submount || error "mkdir $submount failed"
22627         FILESET="$FILESET/.." mount_client $submount &&
22628                 error "mount $submount should fail"
22629         rmdir $submount
22630 }
22631 run_test 247e "mount .. as fileset"
22632
22633 test_247f() {
22634         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22635         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22636                 skip "Need at least version 2.14.50.162"
22637         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22638                 skip "Fileset feature is not supported"
22639
22640         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22641         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22642                 error "mkdir remote failed"
22643         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22644                 error "mkdir remote/subdir failed"
22645         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22646                 error "mkdir striped failed"
22647         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22648
22649         local submount=${MOUNT}_$tdir
22650
22651         mkdir -p $submount || error "mkdir $submount failed"
22652         stack_trap "rmdir $submount"
22653
22654         local dir
22655         local fileset=$FILESET
22656         local mdts=$(comma_list $(mdts_nodes))
22657
22658         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22659         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22660                 $tdir/striped/subdir $tdir/striped/.; do
22661                 FILESET="$fileset/$dir" mount_client $submount ||
22662                         error "mount $dir failed"
22663                 umount_client $submount
22664         done
22665 }
22666 run_test 247f "mount striped or remote directory as fileset"
22667
22668 test_subdir_mount_lock()
22669 {
22670         local testdir=$1
22671         local submount=${MOUNT}_$(basename $testdir)
22672
22673         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22674
22675         mkdir -p $submount || error "mkdir $submount failed"
22676         stack_trap "rmdir $submount"
22677
22678         FILESET="$fileset/$testdir" mount_client $submount ||
22679                 error "mount $FILESET failed"
22680         stack_trap "umount $submount"
22681
22682         local mdts=$(comma_list $(mdts_nodes))
22683
22684         local nrpcs
22685
22686         stat $submount > /dev/null || error "stat $submount failed"
22687         cancel_lru_locks $MDC
22688         stat $submount > /dev/null || error "stat $submount failed"
22689         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22690         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22691         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22692         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22693                 awk '/getattr/ {sum += $2} END {print sum}')
22694
22695         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22696 }
22697
22698 test_247g() {
22699         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22700
22701         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22702                 error "mkdir $tdir failed"
22703         test_subdir_mount_lock $tdir
22704 }
22705 run_test 247g "striped directory submount revalidate ROOT from cache"
22706
22707 test_247h() {
22708         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22709         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22710                 skip "Need MDS version at least 2.15.51"
22711
22712         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22713         test_subdir_mount_lock $tdir
22714         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22715         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22716                 error "mkdir $tdir.1 failed"
22717         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22718 }
22719 run_test 247h "remote directory submount revalidate ROOT from cache"
22720
22721 test_248a() {
22722         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22723         [ -z "$fast_read_sav" ] && skip "no fast read support"
22724
22725         # create a large file for fast read verification
22726         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22727
22728         # make sure the file is created correctly
22729         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22730                 { rm -f $DIR/$tfile; skip "file creation error"; }
22731
22732         echo "Test 1: verify that fast read is 4 times faster on cache read"
22733
22734         # small read with fast read enabled
22735         $LCTL set_param -n llite.*.fast_read=1
22736         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22737                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22738                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22739         # small read with fast read disabled
22740         $LCTL set_param -n llite.*.fast_read=0
22741         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22742                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22743                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22744
22745         # verify that fast read is 4 times faster for cache read
22746         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22747                 error_not_in_vm "fast read was not 4 times faster: " \
22748                            "$t_fast vs $t_slow"
22749
22750         echo "Test 2: verify the performance between big and small read"
22751         $LCTL set_param -n llite.*.fast_read=1
22752
22753         # 1k non-cache read
22754         cancel_lru_locks osc
22755         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22756                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22757                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22758
22759         # 1M non-cache read
22760         cancel_lru_locks osc
22761         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22762                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22763                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22764
22765         # verify that big IO is not 4 times faster than small IO
22766         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22767                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22768
22769         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22770         rm -f $DIR/$tfile
22771 }
22772 run_test 248a "fast read verification"
22773
22774 test_248b() {
22775         # Default short_io_bytes=16384, try both smaller and larger sizes.
22776         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22777         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22778         echo "bs=53248 count=113 normal buffered write"
22779         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22780                 error "dd of initial data file failed"
22781         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22782
22783         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22784         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22785                 error "dd with sync normal writes failed"
22786         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22787
22788         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22789         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22790                 error "dd with sync small writes failed"
22791         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22792
22793         cancel_lru_locks osc
22794
22795         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22796         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22797         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22798         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22799                 iflag=direct || error "dd with O_DIRECT small read failed"
22800         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22801         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22802                 error "compare $TMP/$tfile.1 failed"
22803
22804         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22805         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22806
22807         # just to see what the maximum tunable value is, and test parsing
22808         echo "test invalid parameter 2MB"
22809         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22810                 error "too-large short_io_bytes allowed"
22811         echo "test maximum parameter 512KB"
22812         # if we can set a larger short_io_bytes, run test regardless of version
22813         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22814                 # older clients may not allow setting it this large, that's OK
22815                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22816                         skip "Need at least client version 2.13.50"
22817                 error "medium short_io_bytes failed"
22818         fi
22819         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22820         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22821
22822         echo "test large parameter 64KB"
22823         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22824         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22825
22826         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22827         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22828                 error "dd with sync large writes failed"
22829         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22830
22831         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22832         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22833         num=$((113 * 4096 / PAGE_SIZE))
22834         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22835         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22836                 error "dd with O_DIRECT large writes failed"
22837         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22838                 error "compare $DIR/$tfile.3 failed"
22839
22840         cancel_lru_locks osc
22841
22842         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22843         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22844                 error "dd with O_DIRECT large read failed"
22845         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22846                 error "compare $TMP/$tfile.2 failed"
22847
22848         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22849         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22850                 error "dd with O_DIRECT large read failed"
22851         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22852                 error "compare $TMP/$tfile.3 failed"
22853 }
22854 run_test 248b "test short_io read and write for both small and large sizes"
22855
22856 test_249() { # LU-7890
22857         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22858                 skip "Need at least version 2.8.54"
22859
22860         rm -f $DIR/$tfile
22861         $LFS setstripe -c 1 $DIR/$tfile
22862         # Offset 2T == 4k * 512M
22863         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22864                 error "dd to 2T offset failed"
22865 }
22866 run_test 249 "Write above 2T file size"
22867
22868 test_250() {
22869         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22870          && skip "no 16TB file size limit on ZFS"
22871
22872         $LFS setstripe -c 1 $DIR/$tfile
22873         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22874         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22875         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22876         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22877                 conv=notrunc,fsync && error "append succeeded"
22878         return 0
22879 }
22880 run_test 250 "Write above 16T limit"
22881
22882 test_251() {
22883         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22884
22885         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22886         #Skip once - writing the first stripe will succeed
22887         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22888         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22889                 error "short write happened"
22890
22891         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22892         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22893                 error "short read happened"
22894
22895         rm -f $DIR/$tfile
22896 }
22897 run_test 251 "Handling short read and write correctly"
22898
22899 test_252() {
22900         remote_mds_nodsh && skip "remote MDS with nodsh"
22901         remote_ost_nodsh && skip "remote OST with nodsh"
22902         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22903                 skip_env "ldiskfs only test"
22904         fi
22905
22906         local tgt
22907         local dev
22908         local out
22909         local uuid
22910         local num
22911         local gen
22912
22913         # check lr_reader on OST0000
22914         tgt=ost1
22915         dev=$(facet_device $tgt)
22916         out=$(do_facet $tgt $LR_READER $dev)
22917         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22918         echo "$out"
22919         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22920         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22921                 error "Invalid uuid returned by $LR_READER on target $tgt"
22922         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22923
22924         # check lr_reader -c on MDT0000
22925         tgt=mds1
22926         dev=$(facet_device $tgt)
22927         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22928                 skip "$LR_READER does not support additional options"
22929         fi
22930         out=$(do_facet $tgt $LR_READER -c $dev)
22931         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22932         echo "$out"
22933         num=$(echo "$out" | grep -c "mdtlov")
22934         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22935                 error "Invalid number of mdtlov clients returned by $LR_READER"
22936         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22937
22938         # check lr_reader -cr on MDT0000
22939         out=$(do_facet $tgt $LR_READER -cr $dev)
22940         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22941         echo "$out"
22942         echo "$out" | grep -q "^reply_data:$" ||
22943                 error "$LR_READER should have returned 'reply_data' section"
22944         num=$(echo "$out" | grep -c "client_generation")
22945         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22946 }
22947 run_test 252 "check lr_reader tool"
22948
22949 test_253() {
22950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22951         remote_mds_nodsh && skip "remote MDS with nodsh"
22952         remote_mgs_nodsh && skip "remote MGS with nodsh"
22953
22954         local ostidx=0
22955         local rc=0
22956         local ost_name=$(ostname_from_index $ostidx)
22957
22958         # on the mdt's osc
22959         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22960         do_facet $SINGLEMDS $LCTL get_param -n \
22961                 osp.$mdtosc_proc1.reserved_mb_high ||
22962                 skip  "remote MDS does not support reserved_mb_high"
22963
22964         rm -rf $DIR/$tdir
22965         wait_mds_ost_sync
22966         wait_delete_completed
22967         mkdir $DIR/$tdir
22968         stack_trap "rm -rf $DIR/$tdir"
22969
22970         pool_add $TESTNAME || error "Pool creation failed"
22971         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22972
22973         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22974                 error "Setstripe failed"
22975
22976         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22977
22978         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22979                     grep "watermarks")
22980         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22981
22982         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22983                         osp.$mdtosc_proc1.prealloc_status)
22984         echo "prealloc_status $oa_status"
22985
22986         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22987                 error "File creation should fail"
22988
22989         #object allocation was stopped, but we still able to append files
22990         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22991                 oflag=append || error "Append failed"
22992
22993         rm -f $DIR/$tdir/$tfile.0
22994
22995         # For this test, we want to delete the files we created to go out of
22996         # space but leave the watermark, so we remain nearly out of space
22997         ost_watermarks_enospc_delete_files $tfile $ostidx
22998
22999         wait_delete_completed
23000
23001         sleep_maxage
23002
23003         for i in $(seq 10 12); do
23004                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23005                         2>/dev/null || error "File creation failed after rm"
23006         done
23007
23008         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23009                         osp.$mdtosc_proc1.prealloc_status)
23010         echo "prealloc_status $oa_status"
23011
23012         if (( oa_status != 0 )); then
23013                 error "Object allocation still disable after rm"
23014         fi
23015 }
23016 run_test 253 "Check object allocation limit"
23017
23018 test_254() {
23019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23020         remote_mds_nodsh && skip "remote MDS with nodsh"
23021
23022         local mdt=$(facet_svc $SINGLEMDS)
23023
23024         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23025                 skip "MDS does not support changelog_size"
23026
23027         local cl_user
23028
23029         changelog_register || error "changelog_register failed"
23030
23031         changelog_clear 0 || error "changelog_clear failed"
23032
23033         local size1=$(do_facet $SINGLEMDS \
23034                       $LCTL get_param -n mdd.$mdt.changelog_size)
23035         echo "Changelog size $size1"
23036
23037         rm -rf $DIR/$tdir
23038         $LFS mkdir -i 0 $DIR/$tdir
23039         # change something
23040         mkdir -p $DIR/$tdir/pics/2008/zachy
23041         touch $DIR/$tdir/pics/2008/zachy/timestamp
23042         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23043         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23044         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23045         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23046         rm $DIR/$tdir/pics/desktop.jpg
23047
23048         local size2=$(do_facet $SINGLEMDS \
23049                       $LCTL get_param -n mdd.$mdt.changelog_size)
23050         echo "Changelog size after work $size2"
23051
23052         (( $size2 > $size1 )) ||
23053                 error "new Changelog size=$size2 less than old size=$size1"
23054 }
23055 run_test 254 "Check changelog size"
23056
23057 ladvise_no_type()
23058 {
23059         local type=$1
23060         local file=$2
23061
23062         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23063                 awk -F: '{print $2}' | grep $type > /dev/null
23064         if [ $? -ne 0 ]; then
23065                 return 0
23066         fi
23067         return 1
23068 }
23069
23070 ladvise_no_ioctl()
23071 {
23072         local file=$1
23073
23074         lfs ladvise -a willread $file > /dev/null 2>&1
23075         if [ $? -eq 0 ]; then
23076                 return 1
23077         fi
23078
23079         lfs ladvise -a willread $file 2>&1 |
23080                 grep "Inappropriate ioctl for device" > /dev/null
23081         if [ $? -eq 0 ]; then
23082                 return 0
23083         fi
23084         return 1
23085 }
23086
23087 percent() {
23088         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23089 }
23090
23091 # run a random read IO workload
23092 # usage: random_read_iops <filename> <filesize> <iosize>
23093 random_read_iops() {
23094         local file=$1
23095         local fsize=$2
23096         local iosize=${3:-4096}
23097
23098         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23099                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23100 }
23101
23102 drop_file_oss_cache() {
23103         local file="$1"
23104         local nodes="$2"
23105
23106         $LFS ladvise -a dontneed $file 2>/dev/null ||
23107                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23108 }
23109
23110 ladvise_willread_performance()
23111 {
23112         local repeat=10
23113         local average_origin=0
23114         local average_cache=0
23115         local average_ladvise=0
23116
23117         for ((i = 1; i <= $repeat; i++)); do
23118                 echo "Iter $i/$repeat: reading without willread hint"
23119                 cancel_lru_locks osc
23120                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23121                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23122                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23123                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23124
23125                 cancel_lru_locks osc
23126                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23127                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23128                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23129
23130                 cancel_lru_locks osc
23131                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23132                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23133                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23134                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23135                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23136         done
23137         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23138         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23139         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23140
23141         speedup_cache=$(percent $average_cache $average_origin)
23142         speedup_ladvise=$(percent $average_ladvise $average_origin)
23143
23144         echo "Average uncached read: $average_origin"
23145         echo "Average speedup with OSS cached read: " \
23146                 "$average_cache = +$speedup_cache%"
23147         echo "Average speedup with ladvise willread: " \
23148                 "$average_ladvise = +$speedup_ladvise%"
23149
23150         local lowest_speedup=20
23151         if (( ${average_cache%.*} < $lowest_speedup )); then
23152                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23153                      " got $average_cache%. Skipping ladvise willread check."
23154                 return 0
23155         fi
23156
23157         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23158         # it is still good to run until then to exercise 'ladvise willread'
23159         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23160                 [ "$ost1_FSTYPE" = "zfs" ] &&
23161                 echo "osd-zfs does not support dontneed or drop_caches" &&
23162                 return 0
23163
23164         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23165         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23166                 error_not_in_vm "Speedup with willread is less than " \
23167                         "$lowest_speedup%, got $average_ladvise%"
23168 }
23169
23170 test_255a() {
23171         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23172                 skip "lustre < 2.8.54 does not support ladvise "
23173         remote_ost_nodsh && skip "remote OST with nodsh"
23174
23175         stack_trap "rm -f $DIR/$tfile"
23176         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23177
23178         ladvise_no_type willread $DIR/$tfile &&
23179                 skip "willread ladvise is not supported"
23180
23181         ladvise_no_ioctl $DIR/$tfile &&
23182                 skip "ladvise ioctl is not supported"
23183
23184         local size_mb=100
23185         local size=$((size_mb * 1048576))
23186         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23187                 error "dd to $DIR/$tfile failed"
23188
23189         lfs ladvise -a willread $DIR/$tfile ||
23190                 error "Ladvise failed with no range argument"
23191
23192         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23193                 error "Ladvise failed with no -l or -e argument"
23194
23195         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23196                 error "Ladvise failed with only -e argument"
23197
23198         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23199                 error "Ladvise failed with only -l argument"
23200
23201         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23202                 error "End offset should not be smaller than start offset"
23203
23204         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23205                 error "End offset should not be equal to start offset"
23206
23207         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23208                 error "Ladvise failed with overflowing -s argument"
23209
23210         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23211                 error "Ladvise failed with overflowing -e argument"
23212
23213         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23214                 error "Ladvise failed with overflowing -l argument"
23215
23216         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23217                 error "Ladvise succeeded with conflicting -l and -e arguments"
23218
23219         echo "Synchronous ladvise should wait"
23220         local delay=8
23221 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23222         do_nodes $(comma_list $(osts_nodes)) \
23223                 $LCTL set_param fail_val=$delay fail_loc=0x237
23224         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23225                 $LCTL set_param fail_loc=0"
23226
23227         local start_ts=$SECONDS
23228         lfs ladvise -a willread $DIR/$tfile ||
23229                 error "Ladvise failed with no range argument"
23230         local end_ts=$SECONDS
23231         local inteval_ts=$((end_ts - start_ts))
23232
23233         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23234                 error "Synchronous advice didn't wait reply"
23235         fi
23236
23237         echo "Asynchronous ladvise shouldn't wait"
23238         local start_ts=$SECONDS
23239         lfs ladvise -a willread -b $DIR/$tfile ||
23240                 error "Ladvise failed with no range argument"
23241         local end_ts=$SECONDS
23242         local inteval_ts=$((end_ts - start_ts))
23243
23244         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23245                 error "Asynchronous advice blocked"
23246         fi
23247
23248         ladvise_willread_performance
23249 }
23250 run_test 255a "check 'lfs ladvise -a willread'"
23251
23252 facet_meminfo() {
23253         local facet=$1
23254         local info=$2
23255
23256         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23257 }
23258
23259 test_255b() {
23260         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23261                 skip "lustre < 2.8.54 does not support ladvise "
23262         remote_ost_nodsh && skip "remote OST with nodsh"
23263
23264         stack_trap "rm -f $DIR/$tfile"
23265         lfs setstripe -c 1 -i 0 $DIR/$tfile
23266
23267         ladvise_no_type dontneed $DIR/$tfile &&
23268                 skip "dontneed ladvise is not supported"
23269
23270         ladvise_no_ioctl $DIR/$tfile &&
23271                 skip "ladvise ioctl is not supported"
23272
23273         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23274                 [ "$ost1_FSTYPE" = "zfs" ] &&
23275                 skip "zfs-osd does not support 'ladvise dontneed'"
23276
23277         local size_mb=100
23278         local size=$((size_mb * 1048576))
23279         # In order to prevent disturbance of other processes, only check 3/4
23280         # of the memory usage
23281         local kibibytes=$((size_mb * 1024 * 3 / 4))
23282
23283         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23284                 error "dd to $DIR/$tfile failed"
23285
23286         #force write to complete before dropping OST cache & checking memory
23287         sync
23288
23289         local total=$(facet_meminfo ost1 MemTotal)
23290         echo "Total memory: $total KiB"
23291
23292         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23293         local before_read=$(facet_meminfo ost1 Cached)
23294         echo "Cache used before read: $before_read KiB"
23295
23296         lfs ladvise -a willread $DIR/$tfile ||
23297                 error "Ladvise willread failed"
23298         local after_read=$(facet_meminfo ost1 Cached)
23299         echo "Cache used after read: $after_read KiB"
23300
23301         lfs ladvise -a dontneed $DIR/$tfile ||
23302                 error "Ladvise dontneed again failed"
23303         local no_read=$(facet_meminfo ost1 Cached)
23304         echo "Cache used after dontneed ladvise: $no_read KiB"
23305
23306         if [ $total -lt $((before_read + kibibytes)) ]; then
23307                 echo "Memory is too small, abort checking"
23308                 return 0
23309         fi
23310
23311         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23312                 error "Ladvise willread should use more memory" \
23313                         "than $kibibytes KiB"
23314         fi
23315
23316         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23317                 error "Ladvise dontneed should release more memory" \
23318                         "than $kibibytes KiB"
23319         fi
23320 }
23321 run_test 255b "check 'lfs ladvise -a dontneed'"
23322
23323 test_255c() {
23324         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23325                 skip "lustre < 2.10.50 does not support lockahead"
23326
23327         local ost1_imp=$(get_osc_import_name client ost1)
23328         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23329                          cut -d'.' -f2)
23330         local count
23331         local new_count
23332         local difference
23333         local i
23334         local rc
23335
23336         test_mkdir -p $DIR/$tdir
23337         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23338
23339         #test 10 returns only success/failure
23340         i=10
23341         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23342         rc=$?
23343         if [ $rc -eq 255 ]; then
23344                 error "Ladvise test${i} failed, ${rc}"
23345         fi
23346
23347         #test 11 counts lock enqueue requests, all others count new locks
23348         i=11
23349         count=$(do_facet ost1 \
23350                 $LCTL get_param -n ost.OSS.ost.stats)
23351         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23352
23353         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23354         rc=$?
23355         if [ $rc -eq 255 ]; then
23356                 error "Ladvise test${i} failed, ${rc}"
23357         fi
23358
23359         new_count=$(do_facet ost1 \
23360                 $LCTL get_param -n ost.OSS.ost.stats)
23361         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23362                    awk '{ print $2 }')
23363
23364         difference="$((new_count - count))"
23365         if [ $difference -ne $rc ]; then
23366                 error "Ladvise test${i}, bad enqueue count, returned " \
23367                       "${rc}, actual ${difference}"
23368         fi
23369
23370         for i in $(seq 12 21); do
23371                 # If we do not do this, we run the risk of having too many
23372                 # locks and starting lock cancellation while we are checking
23373                 # lock counts.
23374                 cancel_lru_locks osc
23375
23376                 count=$($LCTL get_param -n \
23377                        ldlm.namespaces.$imp_name.lock_unused_count)
23378
23379                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23380                 rc=$?
23381                 if [ $rc -eq 255 ]; then
23382                         error "Ladvise test ${i} failed, ${rc}"
23383                 fi
23384
23385                 new_count=$($LCTL get_param -n \
23386                        ldlm.namespaces.$imp_name.lock_unused_count)
23387                 difference="$((new_count - count))"
23388
23389                 # Test 15 output is divided by 100 to map down to valid return
23390                 if [ $i -eq 15 ]; then
23391                         rc="$((rc * 100))"
23392                 fi
23393
23394                 if [ $difference -ne $rc ]; then
23395                         error "Ladvise test ${i}, bad lock count, returned " \
23396                               "${rc}, actual ${difference}"
23397                 fi
23398         done
23399
23400         #test 22 returns only success/failure
23401         i=22
23402         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23403         rc=$?
23404         if [ $rc -eq 255 ]; then
23405                 error "Ladvise test${i} failed, ${rc}"
23406         fi
23407 }
23408 run_test 255c "suite of ladvise lockahead tests"
23409
23410 test_256() {
23411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23412         remote_mds_nodsh && skip "remote MDS with nodsh"
23413         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23414         changelog_users $SINGLEMDS | grep "^cl" &&
23415                 skip "active changelog user"
23416
23417         local cl_user
23418         local cat_sl
23419         local mdt_dev
23420
23421         mdt_dev=$(facet_device $SINGLEMDS)
23422         echo $mdt_dev
23423
23424         changelog_register || error "changelog_register failed"
23425
23426         rm -rf $DIR/$tdir
23427         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23428
23429         changelog_clear 0 || error "changelog_clear failed"
23430
23431         # change something
23432         touch $DIR/$tdir/{1..10}
23433
23434         # stop the MDT
23435         stop $SINGLEMDS || error "Fail to stop MDT"
23436
23437         # remount the MDT
23438         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23439                 error "Fail to start MDT"
23440
23441         #after mount new plainllog is used
23442         touch $DIR/$tdir/{11..19}
23443         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23444         stack_trap "rm -f $tmpfile"
23445         cat_sl=$(do_facet $SINGLEMDS "sync; \
23446                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23447                  llog_reader $tmpfile | grep -c type=1064553b")
23448         do_facet $SINGLEMDS llog_reader $tmpfile
23449
23450         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23451
23452         changelog_clear 0 || error "changelog_clear failed"
23453
23454         cat_sl=$(do_facet $SINGLEMDS "sync; \
23455                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23456                  llog_reader $tmpfile | grep -c type=1064553b")
23457
23458         if (( cat_sl == 2 )); then
23459                 error "Empty plain llog was not deleted from changelog catalog"
23460         elif (( cat_sl != 1 )); then
23461                 error "Active plain llog shouldn't be deleted from catalog"
23462         fi
23463 }
23464 run_test 256 "Check llog delete for empty and not full state"
23465
23466 test_257() {
23467         remote_mds_nodsh && skip "remote MDS with nodsh"
23468         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23469                 skip "Need MDS version at least 2.8.55"
23470
23471         test_mkdir $DIR/$tdir
23472
23473         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23474                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23475         stat $DIR/$tdir
23476
23477 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23478         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23479         local facet=mds$((mdtidx + 1))
23480         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23481         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23482
23483         stop $facet || error "stop MDS failed"
23484         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23485                 error "start MDS fail"
23486         wait_recovery_complete $facet
23487 }
23488 run_test 257 "xattr locks are not lost"
23489
23490 # Verify we take the i_mutex when security requires it
23491 test_258a() {
23492 #define OBD_FAIL_IMUTEX_SEC 0x141c
23493         $LCTL set_param fail_loc=0x141c
23494         touch $DIR/$tfile
23495         chmod u+s $DIR/$tfile
23496         chmod a+rwx $DIR/$tfile
23497         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23498         RC=$?
23499         if [ $RC -ne 0 ]; then
23500                 error "error, failed to take i_mutex, rc=$?"
23501         fi
23502         rm -f $DIR/$tfile
23503 }
23504 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23505
23506 # Verify we do NOT take the i_mutex in the normal case
23507 test_258b() {
23508 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23509         $LCTL set_param fail_loc=0x141d
23510         touch $DIR/$tfile
23511         chmod a+rwx $DIR
23512         chmod a+rw $DIR/$tfile
23513         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23514         RC=$?
23515         if [ $RC -ne 0 ]; then
23516                 error "error, took i_mutex unnecessarily, rc=$?"
23517         fi
23518         rm -f $DIR/$tfile
23519
23520 }
23521 run_test 258b "verify i_mutex security behavior"
23522
23523 test_259() {
23524         local file=$DIR/$tfile
23525         local before
23526         local after
23527
23528         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23529
23530         stack_trap "rm -f $file" EXIT
23531
23532         wait_delete_completed
23533         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23534         echo "before: $before"
23535
23536         $LFS setstripe -i 0 -c 1 $file
23537         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23538         sync_all_data
23539         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23540         echo "after write: $after"
23541
23542 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23543         do_facet ost1 $LCTL set_param fail_loc=0x2301
23544         $TRUNCATE $file 0
23545         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23546         echo "after truncate: $after"
23547
23548         stop ost1
23549         do_facet ost1 $LCTL set_param fail_loc=0
23550         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23551         sleep 2
23552         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23553         echo "after restart: $after"
23554         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23555                 error "missing truncate?"
23556
23557         return 0
23558 }
23559 run_test 259 "crash at delayed truncate"
23560
23561 test_260() {
23562 #define OBD_FAIL_MDC_CLOSE               0x806
23563         $LCTL set_param fail_loc=0x80000806
23564         touch $DIR/$tfile
23565
23566 }
23567 run_test 260 "Check mdc_close fail"
23568
23569 ### Data-on-MDT sanity tests ###
23570 test_270a() {
23571         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23572                 skip "Need MDS version at least 2.10.55 for DoM"
23573
23574         # create DoM file
23575         local dom=$DIR/$tdir/dom_file
23576         local tmp=$DIR/$tdir/tmp_file
23577
23578         mkdir_on_mdt0 $DIR/$tdir
23579
23580         # basic checks for DoM component creation
23581         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23582                 error "Can set MDT layout to non-first entry"
23583
23584         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23585                 error "Can define multiple entries as MDT layout"
23586
23587         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23588
23589         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23590         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23591         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23592
23593         local mdtidx=$($LFS getstripe -m $dom)
23594         local mdtname=MDT$(printf %04x $mdtidx)
23595         local facet=mds$((mdtidx + 1))
23596         local space_check=1
23597
23598         # Skip free space checks with ZFS
23599         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23600
23601         # write
23602         sync
23603         local size_tmp=$((65536 * 3))
23604         local mdtfree1=$(do_facet $facet \
23605                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23606
23607         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23608         # check also direct IO along write
23609         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23610         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23611         sync
23612         cmp $tmp $dom || error "file data is different"
23613         [ $(stat -c%s $dom) == $size_tmp ] ||
23614                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23615         if [ $space_check == 1 ]; then
23616                 local mdtfree2=$(do_facet $facet \
23617                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23618
23619                 # increase in usage from by $size_tmp
23620                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23621                         error "MDT free space wrong after write: " \
23622                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23623         fi
23624
23625         # truncate
23626         local size_dom=10000
23627
23628         $TRUNCATE $dom $size_dom
23629         [ $(stat -c%s $dom) == $size_dom ] ||
23630                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23631         if [ $space_check == 1 ]; then
23632                 mdtfree1=$(do_facet $facet \
23633                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23634                 # decrease in usage from $size_tmp to new $size_dom
23635                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23636                   $(((size_tmp - size_dom) / 1024)) ] ||
23637                         error "MDT free space is wrong after truncate: " \
23638                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23639         fi
23640
23641         # append
23642         cat $tmp >> $dom
23643         sync
23644         size_dom=$((size_dom + size_tmp))
23645         [ $(stat -c%s $dom) == $size_dom ] ||
23646                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23647         if [ $space_check == 1 ]; then
23648                 mdtfree2=$(do_facet $facet \
23649                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23650                 # increase in usage by $size_tmp from previous
23651                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23652                         error "MDT free space is wrong after append: " \
23653                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23654         fi
23655
23656         # delete
23657         rm $dom
23658         if [ $space_check == 1 ]; then
23659                 mdtfree1=$(do_facet $facet \
23660                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23661                 # decrease in usage by $size_dom from previous
23662                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23663                         error "MDT free space is wrong after removal: " \
23664                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23665         fi
23666
23667         # combined striping
23668         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23669                 error "Can't create DoM + OST striping"
23670
23671         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23672         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23673         # check also direct IO along write
23674         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23675         sync
23676         cmp $tmp $dom || error "file data is different"
23677         [ $(stat -c%s $dom) == $size_tmp ] ||
23678                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23679         rm $dom $tmp
23680
23681         return 0
23682 }
23683 run_test 270a "DoM: basic functionality tests"
23684
23685 test_270b() {
23686         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23687                 skip "Need MDS version at least 2.10.55"
23688
23689         local dom=$DIR/$tdir/dom_file
23690         local max_size=1048576
23691
23692         mkdir -p $DIR/$tdir
23693         $LFS setstripe -E $max_size -L mdt $dom
23694
23695         # truncate over the limit
23696         $TRUNCATE $dom $(($max_size + 1)) &&
23697                 error "successful truncate over the maximum size"
23698         # write over the limit
23699         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23700                 error "successful write over the maximum size"
23701         # append over the limit
23702         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23703         echo "12345" >> $dom && error "successful append over the maximum size"
23704         rm $dom
23705
23706         return 0
23707 }
23708 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23709
23710 test_270c() {
23711         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23712                 skip "Need MDS version at least 2.10.55"
23713
23714         mkdir -p $DIR/$tdir
23715         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23716
23717         # check files inherit DoM EA
23718         touch $DIR/$tdir/first
23719         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23720                 error "bad pattern"
23721         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23722                 error "bad stripe count"
23723         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23724                 error "bad stripe size"
23725
23726         # check directory inherits DoM EA and uses it as default
23727         mkdir $DIR/$tdir/subdir
23728         touch $DIR/$tdir/subdir/second
23729         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23730                 error "bad pattern in sub-directory"
23731         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23732                 error "bad stripe count in sub-directory"
23733         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23734                 error "bad stripe size in sub-directory"
23735         return 0
23736 }
23737 run_test 270c "DoM: DoM EA inheritance tests"
23738
23739 test_270d() {
23740         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23741                 skip "Need MDS version at least 2.10.55"
23742
23743         mkdir -p $DIR/$tdir
23744         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23745
23746         # inherit default DoM striping
23747         mkdir $DIR/$tdir/subdir
23748         touch $DIR/$tdir/subdir/f1
23749
23750         # change default directory striping
23751         $LFS setstripe -c 1 $DIR/$tdir/subdir
23752         touch $DIR/$tdir/subdir/f2
23753         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23754                 error "wrong default striping in file 2"
23755         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23756                 error "bad pattern in file 2"
23757         return 0
23758 }
23759 run_test 270d "DoM: change striping from DoM to RAID0"
23760
23761 test_270e() {
23762         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23763                 skip "Need MDS version at least 2.10.55"
23764
23765         mkdir -p $DIR/$tdir/dom
23766         mkdir -p $DIR/$tdir/norm
23767         DOMFILES=20
23768         NORMFILES=10
23769         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23770         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23771
23772         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23773         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23774
23775         # find DoM files by layout
23776         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23777         [ $NUM -eq  $DOMFILES ] ||
23778                 error "lfs find -L: found $NUM, expected $DOMFILES"
23779         echo "Test 1: lfs find 20 DOM files by layout: OK"
23780
23781         # there should be 1 dir with default DOM striping
23782         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23783         [ $NUM -eq  1 ] ||
23784                 error "lfs find -L: found $NUM, expected 1 dir"
23785         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23786
23787         # find DoM files by stripe size
23788         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23789         [ $NUM -eq  $DOMFILES ] ||
23790                 error "lfs find -S: found $NUM, expected $DOMFILES"
23791         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23792
23793         # find files by stripe offset except DoM files
23794         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23795         [ $NUM -eq  $NORMFILES ] ||
23796                 error "lfs find -i: found $NUM, expected $NORMFILES"
23797         echo "Test 5: lfs find no DOM files by stripe index: OK"
23798         return 0
23799 }
23800 run_test 270e "DoM: lfs find with DoM files test"
23801
23802 test_270f() {
23803         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23804                 skip "Need MDS version at least 2.10.55"
23805
23806         local mdtname=${FSNAME}-MDT0000-mdtlov
23807         local dom=$DIR/$tdir/dom_file
23808         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23809                                                 lod.$mdtname.dom_stripesize)
23810         local dom_limit=131072
23811
23812         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23813         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23814                                                 lod.$mdtname.dom_stripesize)
23815         [ ${dom_limit} -eq ${dom_current} ] ||
23816                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23817
23818         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23819         $LFS setstripe -d $DIR/$tdir
23820         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23821                 error "Can't set directory default striping"
23822
23823         # exceed maximum stripe size
23824         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23825                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23826         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23827                 error "Able to create DoM component size more than LOD limit"
23828
23829         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23830         dom_current=$(do_facet mds1 $LCTL get_param -n \
23831                                                 lod.$mdtname.dom_stripesize)
23832         [ 0 -eq ${dom_current} ] ||
23833                 error "Can't set zero DoM stripe limit"
23834         rm $dom
23835
23836         # attempt to create DoM file on server with disabled DoM should
23837         # remove DoM entry from layout and be succeed
23838         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23839                 error "Can't create DoM file (DoM is disabled)"
23840         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23841                 error "File has DoM component while DoM is disabled"
23842         rm $dom
23843
23844         # attempt to create DoM file with only DoM stripe should return error
23845         $LFS setstripe -E $dom_limit -L mdt $dom &&
23846                 error "Able to create DoM-only file while DoM is disabled"
23847
23848         # too low values to be aligned with smallest stripe size 64K
23849         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23850         dom_current=$(do_facet mds1 $LCTL get_param -n \
23851                                                 lod.$mdtname.dom_stripesize)
23852         [ 30000 -eq ${dom_current} ] &&
23853                 error "Can set too small DoM stripe limit"
23854
23855         # 64K is a minimal stripe size in Lustre, expect limit of that size
23856         [ 65536 -eq ${dom_current} ] ||
23857                 error "Limit is not set to 64K but ${dom_current}"
23858
23859         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23860         dom_current=$(do_facet mds1 $LCTL get_param -n \
23861                                                 lod.$mdtname.dom_stripesize)
23862         echo $dom_current
23863         [ 2147483648 -eq ${dom_current} ] &&
23864                 error "Can set too large DoM stripe limit"
23865
23866         do_facet mds1 $LCTL set_param -n \
23867                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23868         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23869                 error "Can't create DoM component size after limit change"
23870         do_facet mds1 $LCTL set_param -n \
23871                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23872         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23873                 error "Can't create DoM file after limit decrease"
23874         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23875                 error "Can create big DoM component after limit decrease"
23876         touch ${dom}_def ||
23877                 error "Can't create file with old default layout"
23878
23879         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23880         return 0
23881 }
23882 run_test 270f "DoM: maximum DoM stripe size checks"
23883
23884 test_270g() {
23885         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23886                 skip "Need MDS version at least 2.13.52"
23887         local dom=$DIR/$tdir/$tfile
23888
23889         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23890         local lodname=${FSNAME}-MDT0000-mdtlov
23891
23892         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23893         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23894         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23895         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23896
23897         local dom_limit=1024
23898         local dom_threshold="50%"
23899
23900         $LFS setstripe -d $DIR/$tdir
23901         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23902                 error "Can't set directory default striping"
23903
23904         do_facet mds1 $LCTL set_param -n \
23905                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23906         # set 0 threshold and create DOM file to change tunable stripesize
23907         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23908         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23909                 error "Failed to create $dom file"
23910         # now tunable dom_cur_stripesize should reach maximum
23911         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23912                                         lod.${lodname}.dom_stripesize_cur_kb)
23913         [[ $dom_current == $dom_limit ]] ||
23914                 error "Current DOM stripesize is not maximum"
23915         rm $dom
23916
23917         # set threshold for further tests
23918         do_facet mds1 $LCTL set_param -n \
23919                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23920         echo "DOM threshold is $dom_threshold free space"
23921         local dom_def
23922         local dom_set
23923         # Spoof bfree to exceed threshold
23924         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23925         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23926         for spfree in 40 20 0 15 30 55; do
23927                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23928                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23929                         error "Failed to create $dom file"
23930                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23931                                         lod.${lodname}.dom_stripesize_cur_kb)
23932                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23933                 [[ $dom_def != $dom_current ]] ||
23934                         error "Default stripe size was not changed"
23935                 if (( spfree > 0 )) ; then
23936                         dom_set=$($LFS getstripe -S $dom)
23937                         (( dom_set == dom_def * 1024 )) ||
23938                                 error "DOM component size is still old"
23939                 else
23940                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23941                                 error "DoM component is set with no free space"
23942                 fi
23943                 rm $dom
23944                 dom_current=$dom_def
23945         done
23946 }
23947 run_test 270g "DoM: default DoM stripe size depends on free space"
23948
23949 test_270h() {
23950         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23951                 skip "Need MDS version at least 2.13.53"
23952
23953         local mdtname=${FSNAME}-MDT0000-mdtlov
23954         local dom=$DIR/$tdir/$tfile
23955         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23956
23957         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23958         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23959
23960         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23961         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23962                 error "can't create OST file"
23963         # mirrored file with DOM entry in the second mirror
23964         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23965                 error "can't create mirror with DoM component"
23966
23967         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23968
23969         # DOM component in the middle and has other enries in the same mirror,
23970         # should succeed but lost DoM component
23971         $LFS setstripe --copy=${dom}_1 $dom ||
23972                 error "Can't create file from OST|DOM mirror layout"
23973         # check new file has no DoM layout after all
23974         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23975                 error "File has DoM component while DoM is disabled"
23976 }
23977 run_test 270h "DoM: DoM stripe removal when disabled on server"
23978
23979 test_270i() {
23980         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23981                 skip "Need MDS version at least 2.14.54"
23982
23983         mkdir $DIR/$tdir
23984         # DoM with plain layout
23985         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23986                 error "default plain layout with DoM must fail"
23987         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23988                 error "setstripe plain file layout with DoM must fail"
23989         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23990                 error "default DoM layout with bad striping must fail"
23991         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23992                 error "setstripe to DoM layout with bad striping must fail"
23993         return 0
23994 }
23995 run_test 270i "DoM: setting invalid DoM striping should fail"
23996
23997 test_270j() {
23998         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
23999                 skip "Need MDS version at least 2.15.55.203"
24000
24001         local dom=$DIR/$tdir/$tfile
24002         local odv
24003         local ndv
24004
24005         mkdir -p $DIR/$tdir
24006
24007         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24008
24009         odv=$($LFS data_version $dom)
24010         chmod 666 $dom
24011         mv $dom ${dom}_moved
24012         link ${dom}_moved $dom
24013         setfattr -n user.attrx -v "some_attr" $dom
24014         ndv=$($LFS data_version $dom)
24015         (( $ndv == $odv )) ||
24016                 error "data version was changed by metadata operations"
24017
24018         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24019                 error "failed to write data into $dom"
24020         cancel_lru_locks mdc
24021         ndv=$($LFS data_version $dom)
24022         (( $ndv != $odv )) ||
24023                 error "data version wasn't changed on write"
24024
24025         odv=$ndv
24026         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24027         ndv=$($LFS data_version $dom)
24028         (( $ndv != $odv )) ||
24029                 error "data version wasn't changed on truncate down"
24030
24031         odv=$ndv
24032         $TRUNCATE $dom 25000
24033         ndv=$($LFS data_version $dom)
24034         (( $ndv != $odv )) ||
24035                 error "data version wasn't changed on truncate up"
24036
24037         # check also fallocate for ldiskfs
24038         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24039                 odv=$ndv
24040                 fallocate -l 1048576 $dom
24041                 ndv=$($LFS data_version $dom)
24042                 (( $ndv != $odv )) ||
24043                         error "data version wasn't changed on fallocate"
24044
24045                 odv=$ndv
24046                 fallocate -p --offset 4096 -l 4096 $dom
24047                 ndv=$($LFS data_version $dom)
24048                 (( $ndv != $odv )) ||
24049                         error "data version wasn't changed on fallocate punch"
24050         fi
24051 }
24052 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24053
24054 test_271a() {
24055         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24056                 skip "Need MDS version at least 2.10.55"
24057
24058         local dom=$DIR/$tdir/dom
24059
24060         mkdir -p $DIR/$tdir
24061
24062         $LFS setstripe -E 1024K -L mdt $dom
24063
24064         lctl set_param -n mdc.*.stats=clear
24065         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24066         cat $dom > /dev/null
24067         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24068         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24069         ls $dom
24070         rm -f $dom
24071 }
24072 run_test 271a "DoM: data is cached for read after write"
24073
24074 test_271b() {
24075         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24076                 skip "Need MDS version at least 2.10.55"
24077
24078         local dom=$DIR/$tdir/dom
24079
24080         mkdir -p $DIR/$tdir
24081
24082         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24083
24084         lctl set_param -n mdc.*.stats=clear
24085         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24086         cancel_lru_locks mdc
24087         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24088         # second stat to check size is cached on client
24089         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24090         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24091         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24092         rm -f $dom
24093 }
24094 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24095
24096 test_271ba() {
24097         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24098                 skip "Need MDS version at least 2.10.55"
24099
24100         local dom=$DIR/$tdir/dom
24101
24102         mkdir -p $DIR/$tdir
24103
24104         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24105
24106         lctl set_param -n mdc.*.stats=clear
24107         lctl set_param -n osc.*.stats=clear
24108         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24109         cancel_lru_locks mdc
24110         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24111         # second stat to check size is cached on client
24112         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24113         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24114         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24115         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24116         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24117         rm -f $dom
24118 }
24119 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24120
24121
24122 get_mdc_stats() {
24123         local mdtidx=$1
24124         local param=$2
24125         local mdt=MDT$(printf %04x $mdtidx)
24126
24127         if [ -z $param ]; then
24128                 lctl get_param -n mdc.*$mdt*.stats
24129         else
24130                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24131         fi
24132 }
24133
24134 test_271c() {
24135         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24136                 skip "Need MDS version at least 2.10.55"
24137
24138         local dom=$DIR/$tdir/dom
24139
24140         mkdir -p $DIR/$tdir
24141
24142         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24143
24144         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24145         local facet=mds$((mdtidx + 1))
24146
24147         cancel_lru_locks mdc
24148         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24149         createmany -o $dom 1000
24150         lctl set_param -n mdc.*.stats=clear
24151         smalliomany -w $dom 1000 200
24152         get_mdc_stats $mdtidx
24153         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24154         # Each file has 1 open, 1 IO enqueues, total 2000
24155         # but now we have also +1 getxattr for security.capability, total 3000
24156         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24157         unlinkmany $dom 1000
24158
24159         cancel_lru_locks mdc
24160         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24161         createmany -o $dom 1000
24162         lctl set_param -n mdc.*.stats=clear
24163         smalliomany -w $dom 1000 200
24164         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24165         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24166         # for OPEN and IO lock.
24167         [ $((enq - enq_2)) -ge 1000 ] ||
24168                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24169         unlinkmany $dom 1000
24170         return 0
24171 }
24172 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24173
24174 cleanup_271def_tests() {
24175         trap 0
24176         rm -f $1
24177 }
24178
24179 test_271d() {
24180         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24181                 skip "Need MDS version at least 2.10.57"
24182
24183         local dom=$DIR/$tdir/dom
24184         local tmp=$TMP/$tfile
24185         trap "cleanup_271def_tests $tmp" EXIT
24186
24187         mkdir -p $DIR/$tdir
24188
24189         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24190
24191         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24192
24193         cancel_lru_locks mdc
24194         dd if=/dev/urandom of=$tmp bs=1000 count=1
24195         dd if=$tmp of=$dom bs=1000 count=1
24196         cancel_lru_locks mdc
24197
24198         cat /etc/hosts >> $tmp
24199         lctl set_param -n mdc.*.stats=clear
24200
24201         # append data to the same file it should update local page
24202         echo "Append to the same page"
24203         cat /etc/hosts >> $dom
24204         local num=$(get_mdc_stats $mdtidx ost_read)
24205         local ra=$(get_mdc_stats $mdtidx req_active)
24206         local rw=$(get_mdc_stats $mdtidx req_waittime)
24207
24208         [ -z $num ] || error "$num READ RPC occured"
24209         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24210         echo "... DONE"
24211
24212         # compare content
24213         cmp $tmp $dom || error "file miscompare"
24214
24215         cancel_lru_locks mdc
24216         lctl set_param -n mdc.*.stats=clear
24217
24218         echo "Open and read file"
24219         cat $dom > /dev/null
24220         local num=$(get_mdc_stats $mdtidx ost_read)
24221         local ra=$(get_mdc_stats $mdtidx req_active)
24222         local rw=$(get_mdc_stats $mdtidx req_waittime)
24223
24224         [ -z $num ] || error "$num READ RPC occured"
24225         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24226         echo "... DONE"
24227
24228         # compare content
24229         cmp $tmp $dom || error "file miscompare"
24230
24231         return 0
24232 }
24233 run_test 271d "DoM: read on open (1K file in reply buffer)"
24234
24235 test_271f() {
24236         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24237                 skip "Need MDS version at least 2.10.57"
24238
24239         local dom=$DIR/$tdir/dom
24240         local tmp=$TMP/$tfile
24241         trap "cleanup_271def_tests $tmp" EXIT
24242
24243         mkdir -p $DIR/$tdir
24244
24245         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24246
24247         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24248
24249         cancel_lru_locks mdc
24250         dd if=/dev/urandom of=$tmp bs=265000 count=1
24251         dd if=$tmp of=$dom bs=265000 count=1
24252         cancel_lru_locks mdc
24253         cat /etc/hosts >> $tmp
24254         lctl set_param -n mdc.*.stats=clear
24255
24256         echo "Append to the same page"
24257         cat /etc/hosts >> $dom
24258         local num=$(get_mdc_stats $mdtidx ost_read)
24259         local ra=$(get_mdc_stats $mdtidx req_active)
24260         local rw=$(get_mdc_stats $mdtidx req_waittime)
24261
24262         [ -z $num ] || error "$num READ RPC occured"
24263         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24264         echo "... DONE"
24265
24266         # compare content
24267         cmp $tmp $dom || error "file miscompare"
24268
24269         cancel_lru_locks mdc
24270         lctl set_param -n mdc.*.stats=clear
24271
24272         echo "Open and read file"
24273         cat $dom > /dev/null
24274         local num=$(get_mdc_stats $mdtidx ost_read)
24275         local ra=$(get_mdc_stats $mdtidx req_active)
24276         local rw=$(get_mdc_stats $mdtidx req_waittime)
24277
24278         [ -z $num ] && num=0
24279         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24280         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24281         echo "... DONE"
24282
24283         # compare content
24284         cmp $tmp $dom || error "file miscompare"
24285
24286         return 0
24287 }
24288 run_test 271f "DoM: read on open (200K file and read tail)"
24289
24290 test_271g() {
24291         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24292                 skip "Skipping due to old client or server version"
24293
24294         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24295         # to get layout
24296         $CHECKSTAT -t file $DIR1/$tfile
24297
24298         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24299         MULTIOP_PID=$!
24300         sleep 1
24301         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24302         $LCTL set_param fail_loc=0x80000314
24303         rm $DIR1/$tfile || error "Unlink fails"
24304         RC=$?
24305         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24306         [ $RC -eq 0 ] || error "Failed write to stale object"
24307 }
24308 run_test 271g "Discard DoM data vs client flush race"
24309
24310 test_272a() {
24311         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24312                 skip "Need MDS version at least 2.11.50"
24313
24314         local dom=$DIR/$tdir/dom
24315         mkdir -p $DIR/$tdir
24316
24317         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24318         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24319                 error "failed to write data into $dom"
24320         local old_md5=$(md5sum $dom)
24321
24322         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24323                 error "failed to migrate to the same DoM component"
24324
24325         local new_md5=$(md5sum $dom)
24326
24327         [ "$old_md5" == "$new_md5" ] ||
24328                 error "md5sum differ: $old_md5, $new_md5"
24329
24330         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24331                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24332 }
24333 run_test 272a "DoM migration: new layout with the same DOM component"
24334
24335 test_272b() {
24336         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24337                 skip "Need MDS version at least 2.11.50"
24338
24339         local dom=$DIR/$tdir/dom
24340         mkdir -p $DIR/$tdir
24341         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24342         stack_trap "rm -rf $DIR/$tdir"
24343
24344         local mdtidx=$($LFS getstripe -m $dom)
24345         local mdtname=MDT$(printf %04x $mdtidx)
24346         local facet=mds$((mdtidx + 1))
24347
24348         local mdtfree1=$(do_facet $facet \
24349                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24350         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24351                 error "failed to write data into $dom"
24352         local old_md5=$(md5sum $dom)
24353         cancel_lru_locks mdc
24354         local mdtfree1=$(do_facet $facet \
24355                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24356
24357         $LFS migrate -c2 $dom ||
24358                 error "failed to migrate to the new composite layout"
24359         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24360                 error "MDT stripe was not removed"
24361         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24362                 error "$dir1 shouldn't have DATAVER EA"
24363
24364         cancel_lru_locks mdc
24365         local new_md5=$(md5sum $dom)
24366         [ "$old_md5" == "$new_md5" ] ||
24367                 error "$old_md5 != $new_md5"
24368
24369         # Skip free space checks with ZFS
24370         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24371                 local mdtfree2=$(do_facet $facet \
24372                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24373                 [ $mdtfree2 -gt $mdtfree1 ] ||
24374                         error "MDT space is not freed after migration"
24375         fi
24376         return 0
24377 }
24378 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24379
24380 test_272c() {
24381         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24382                 skip "Need MDS version at least 2.11.50"
24383
24384         local dom=$DIR/$tdir/$tfile
24385         mkdir -p $DIR/$tdir
24386         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24387         stack_trap "rm -rf $DIR/$tdir"
24388
24389         local mdtidx=$($LFS getstripe -m $dom)
24390         local mdtname=MDT$(printf %04x $mdtidx)
24391         local facet=mds$((mdtidx + 1))
24392
24393         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24394                 error "failed to write data into $dom"
24395         local old_md5=$(md5sum $dom)
24396         cancel_lru_locks mdc
24397         local mdtfree1=$(do_facet $facet \
24398                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24399
24400         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24401                 error "failed to migrate to the new composite layout"
24402         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24403                 error "MDT stripe was not removed"
24404
24405         cancel_lru_locks mdc
24406         local new_md5=$(md5sum $dom)
24407         [ "$old_md5" == "$new_md5" ] ||
24408                 error "$old_md5 != $new_md5"
24409
24410         # Skip free space checks with ZFS
24411         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24412                 local mdtfree2=$(do_facet $facet \
24413                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24414                 [ $mdtfree2 -gt $mdtfree1 ] ||
24415                         error "MDS space is not freed after migration"
24416         fi
24417         return 0
24418 }
24419 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24420
24421 test_272d() {
24422         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24423                 skip "Need MDS version at least 2.12.55"
24424
24425         local dom=$DIR/$tdir/$tfile
24426         mkdir -p $DIR/$tdir
24427         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24428
24429         local mdtidx=$($LFS getstripe -m $dom)
24430         local mdtname=MDT$(printf %04x $mdtidx)
24431         local facet=mds$((mdtidx + 1))
24432
24433         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24434                 error "failed to write data into $dom"
24435         local old_md5=$(md5sum $dom)
24436         cancel_lru_locks mdc
24437         local mdtfree1=$(do_facet $facet \
24438                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24439
24440         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24441                 error "failed mirroring to the new composite layout"
24442         $LFS mirror resync $dom ||
24443                 error "failed mirror resync"
24444         $LFS mirror split --mirror-id 1 -d $dom ||
24445                 error "failed mirror split"
24446
24447         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24448                 error "MDT stripe was not removed"
24449
24450         cancel_lru_locks mdc
24451         local new_md5=$(md5sum $dom)
24452         [ "$old_md5" == "$new_md5" ] ||
24453                 error "$old_md5 != $new_md5"
24454
24455         # Skip free space checks with ZFS
24456         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24457                 local mdtfree2=$(do_facet $facet \
24458                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24459                 [ $mdtfree2 -gt $mdtfree1 ] ||
24460                         error "MDS space is not freed after DOM mirror deletion"
24461         fi
24462         return 0
24463 }
24464 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24465
24466 test_272e() {
24467         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24468                 skip "Need MDS version at least 2.12.55"
24469
24470         local dom=$DIR/$tdir/$tfile
24471         mkdir -p $DIR/$tdir
24472         $LFS setstripe -c 2 $dom
24473
24474         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24475                 error "failed to write data into $dom"
24476         local old_md5=$(md5sum $dom)
24477         cancel_lru_locks
24478
24479         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24480                 error "failed mirroring to the DOM layout"
24481         $LFS mirror resync $dom ||
24482                 error "failed mirror resync"
24483         $LFS mirror split --mirror-id 1 -d $dom ||
24484                 error "failed mirror split"
24485
24486         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24487                 error "MDT stripe wasn't set"
24488
24489         cancel_lru_locks
24490         local new_md5=$(md5sum $dom)
24491         [ "$old_md5" == "$new_md5" ] ||
24492                 error "$old_md5 != $new_md5"
24493
24494         return 0
24495 }
24496 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24497
24498 test_272f() {
24499         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24500                 skip "Need MDS version at least 2.12.55"
24501
24502         local dom=$DIR/$tdir/$tfile
24503         mkdir -p $DIR/$tdir
24504         $LFS setstripe -c 2 $dom
24505
24506         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24507                 error "failed to write data into $dom"
24508         local old_md5=$(md5sum $dom)
24509         cancel_lru_locks
24510
24511         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24512                 error "failed migrating to the DOM file"
24513
24514         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24515                 error "MDT stripe wasn't set"
24516
24517         cancel_lru_locks
24518         local new_md5=$(md5sum $dom)
24519         [ "$old_md5" != "$new_md5" ] &&
24520                 error "$old_md5 != $new_md5"
24521
24522         return 0
24523 }
24524 run_test 272f "DoM migration: OST-striped file to DOM file"
24525
24526 test_273a() {
24527         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24528                 skip "Need MDS version at least 2.11.50"
24529
24530         # Layout swap cannot be done if either file has DOM component,
24531         # this will never be supported, migration should be used instead
24532
24533         local dom=$DIR/$tdir/$tfile
24534         mkdir -p $DIR/$tdir
24535
24536         $LFS setstripe -c2 ${dom}_plain
24537         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24538         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24539                 error "can swap layout with DoM component"
24540         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24541                 error "can swap layout with DoM component"
24542
24543         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24544         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24545                 error "can swap layout with DoM component"
24546         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24547                 error "can swap layout with DoM component"
24548         return 0
24549 }
24550 run_test 273a "DoM: layout swapping should fail with DOM"
24551
24552 test_273b() {
24553         mkdir -p $DIR/$tdir
24554         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24555
24556 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24557         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24558
24559         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24560 }
24561 run_test 273b "DoM: race writeback and object destroy"
24562
24563 test_273c() {
24564         mkdir -p $DIR/$tdir
24565         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24566
24567         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24568         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24569
24570         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24571 }
24572 run_test 273c "race writeback and object destroy"
24573
24574 test_275() {
24575         remote_ost_nodsh && skip "remote OST with nodsh"
24576         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24577                 skip "Need OST version >= 2.10.57"
24578
24579         local file=$DIR/$tfile
24580         local oss
24581
24582         oss=$(comma_list $(osts_nodes))
24583
24584         dd if=/dev/urandom of=$file bs=1M count=2 ||
24585                 error "failed to create a file"
24586         stack_trap "rm -f $file"
24587         cancel_lru_locks osc
24588
24589         #lock 1
24590         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24591                 error "failed to read a file"
24592
24593 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24594         $LCTL set_param fail_loc=0x8000031f
24595
24596         cancel_lru_locks osc &
24597         sleep 1
24598
24599 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24600         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24601         #IO takes another lock, but matches the PENDING one
24602         #and places it to the IO RPC
24603         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24604                 error "failed to read a file with PENDING lock"
24605 }
24606 run_test 275 "Read on a canceled duplicate lock"
24607
24608 test_276() {
24609         remote_ost_nodsh && skip "remote OST with nodsh"
24610         local pid
24611
24612         do_facet ost1 "(while true; do \
24613                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24614                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24615         pid=$!
24616
24617         for LOOP in $(seq 20); do
24618                 stop ost1
24619                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24620         done
24621         kill -9 $pid
24622         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24623                 rm $TMP/sanity_276_pid"
24624 }
24625 run_test 276 "Race between mount and obd_statfs"
24626
24627 test_277() {
24628         $LCTL set_param ldlm.namespaces.*.lru_size=0
24629         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24630         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24631                         grep ^used_mb | awk '{print $2}')
24632         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24633         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24634                 oflag=direct conv=notrunc
24635         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24636                         grep ^used_mb | awk '{print $2}')
24637         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24638 }
24639 run_test 277 "Direct IO shall drop page cache"
24640
24641 test_278() {
24642         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24643         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24644         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24645                 skip "needs the same host for mdt1 mdt2" && return
24646
24647         local pid1
24648         local pid2
24649
24650 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24651         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24652         stop mds2 &
24653         pid2=$!
24654
24655         stop mds1
24656
24657         echo "Starting MDTs"
24658         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24659         wait $pid2
24660 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24661 #will return NULL
24662         do_facet mds2 $LCTL set_param fail_loc=0
24663
24664         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24665         wait_recovery_complete mds2
24666 }
24667 run_test 278 "Race starting MDS between MDTs stop/start"
24668
24669 test_280() {
24670         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24671                 skip "Need MGS version at least 2.13.52"
24672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24673         combined_mgs_mds || skip "needs combined MGS/MDT"
24674
24675         umount_client $MOUNT
24676 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24677         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24678
24679         mount_client $MOUNT &
24680         sleep 1
24681         stop mgs || error "stop mgs failed"
24682         #for a race mgs would crash
24683         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24684         # make sure we unmount client before remounting
24685         wait
24686         umount_client $MOUNT
24687         mount_client $MOUNT || error "mount client failed"
24688 }
24689 run_test 280 "Race between MGS umount and client llog processing"
24690
24691 cleanup_test_300() {
24692         trap 0
24693         umask $SAVE_UMASK
24694 }
24695 test_striped_dir() {
24696         local mdt_index=$1
24697         local stripe_count
24698         local stripe_index
24699
24700         mkdir -p $DIR/$tdir
24701
24702         SAVE_UMASK=$(umask)
24703         trap cleanup_test_300 RETURN EXIT
24704
24705         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24706                                                 $DIR/$tdir/striped_dir ||
24707                 error "set striped dir error"
24708
24709         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24710         [ "$mode" = "755" ] || error "expect 755 got $mode"
24711
24712         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24713                 error "getdirstripe failed"
24714         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24715         if [ "$stripe_count" != "2" ]; then
24716                 error "1:stripe_count is $stripe_count, expect 2"
24717         fi
24718         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24719         if [ "$stripe_count" != "2" ]; then
24720                 error "2:stripe_count is $stripe_count, expect 2"
24721         fi
24722
24723         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24724         if [ "$stripe_index" != "$mdt_index" ]; then
24725                 error "stripe_index is $stripe_index, expect $mdt_index"
24726         fi
24727
24728         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24729                 error "nlink error after create striped dir"
24730
24731         mkdir $DIR/$tdir/striped_dir/a
24732         mkdir $DIR/$tdir/striped_dir/b
24733
24734         stat $DIR/$tdir/striped_dir/a ||
24735                 error "create dir under striped dir failed"
24736         stat $DIR/$tdir/striped_dir/b ||
24737                 error "create dir under striped dir failed"
24738
24739         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24740                 error "nlink error after mkdir"
24741
24742         rmdir $DIR/$tdir/striped_dir/a
24743         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24744                 error "nlink error after rmdir"
24745
24746         rmdir $DIR/$tdir/striped_dir/b
24747         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24748                 error "nlink error after rmdir"
24749
24750         chattr +i $DIR/$tdir/striped_dir
24751         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24752                 error "immutable flags not working under striped dir!"
24753         chattr -i $DIR/$tdir/striped_dir
24754
24755         rmdir $DIR/$tdir/striped_dir ||
24756                 error "rmdir striped dir error"
24757
24758         cleanup_test_300
24759
24760         true
24761 }
24762
24763 test_300a() {
24764         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24765                 skip "skipped for lustre < 2.7.0"
24766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24768
24769         test_striped_dir 0 || error "failed on striped dir on MDT0"
24770         test_striped_dir 1 || error "failed on striped dir on MDT0"
24771 }
24772 run_test 300a "basic striped dir sanity test"
24773
24774 test_300b() {
24775         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24776                 skip "skipped for lustre < 2.7.0"
24777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24779
24780         local i
24781         local mtime1
24782         local mtime2
24783         local mtime3
24784
24785         test_mkdir $DIR/$tdir || error "mkdir fail"
24786         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24787                 error "set striped dir error"
24788         for i in {0..9}; do
24789                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24790                 sleep 1
24791                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24792                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24793                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24794                 sleep 1
24795                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24796                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24797                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24798         done
24799         true
24800 }
24801 run_test 300b "check ctime/mtime for striped dir"
24802
24803 test_300c() {
24804         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24805                 skip "skipped for lustre < 2.7.0"
24806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24807         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24808
24809         local file_count
24810
24811         mkdir_on_mdt0 $DIR/$tdir
24812         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24813                 error "set striped dir error"
24814
24815         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24816                 error "chown striped dir failed"
24817
24818         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24819                 error "create 5k files failed"
24820
24821         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24822
24823         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24824
24825         rm -rf $DIR/$tdir
24826 }
24827 run_test 300c "chown && check ls under striped directory"
24828
24829 test_300d() {
24830         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24831                 skip "skipped for lustre < 2.7.0"
24832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24834
24835         local stripe_count
24836         local file
24837
24838         mkdir -p $DIR/$tdir
24839         $LFS setstripe -c 2 $DIR/$tdir
24840
24841         #local striped directory
24842         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24843                 error "set striped dir error"
24844         #look at the directories for debug purposes
24845         ls -l $DIR/$tdir
24846         $LFS getdirstripe $DIR/$tdir
24847         ls -l $DIR/$tdir/striped_dir
24848         $LFS getdirstripe $DIR/$tdir/striped_dir
24849         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24850                 error "create 10 files failed"
24851
24852         #remote striped directory
24853         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24854                 error "set striped dir error"
24855         #look at the directories for debug purposes
24856         ls -l $DIR/$tdir
24857         $LFS getdirstripe $DIR/$tdir
24858         ls -l $DIR/$tdir/remote_striped_dir
24859         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24860         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24861                 error "create 10 files failed"
24862
24863         for file in $(find $DIR/$tdir); do
24864                 stripe_count=$($LFS getstripe -c $file)
24865                 [ $stripe_count -eq 2 ] ||
24866                         error "wrong stripe $stripe_count for $file"
24867         done
24868
24869         rm -rf $DIR/$tdir
24870 }
24871 run_test 300d "check default stripe under striped directory"
24872
24873 test_300e() {
24874         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24875                 skip "Need MDS version at least 2.7.55"
24876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24878
24879         local stripe_count
24880         local file
24881
24882         mkdir -p $DIR/$tdir
24883
24884         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24885                 error "set striped dir error"
24886
24887         touch $DIR/$tdir/striped_dir/a
24888         touch $DIR/$tdir/striped_dir/b
24889         touch $DIR/$tdir/striped_dir/c
24890
24891         mkdir $DIR/$tdir/striped_dir/dir_a
24892         mkdir $DIR/$tdir/striped_dir/dir_b
24893         mkdir $DIR/$tdir/striped_dir/dir_c
24894
24895         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24896                 error "set striped adir under striped dir error"
24897
24898         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24899                 error "set striped bdir under striped dir error"
24900
24901         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24902                 error "set striped cdir under striped dir error"
24903
24904         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24905                 error "rename dir under striped dir fails"
24906
24907         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24908                 error "rename dir under different stripes fails"
24909
24910         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24911                 error "rename file under striped dir should succeed"
24912
24913         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24914                 error "rename dir under striped dir should succeed"
24915
24916         rm -rf $DIR/$tdir
24917 }
24918 run_test 300e "check rename under striped directory"
24919
24920 test_300f() {
24921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24922         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24923         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24924                 skip "Need MDS version at least 2.7.55"
24925
24926         local stripe_count
24927         local file
24928
24929         rm -rf $DIR/$tdir
24930         mkdir -p $DIR/$tdir
24931
24932         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24933                 error "set striped dir error"
24934
24935         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24936                 error "set striped dir error"
24937
24938         touch $DIR/$tdir/striped_dir/a
24939         mkdir $DIR/$tdir/striped_dir/dir_a
24940         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24941                 error "create striped dir under striped dir fails"
24942
24943         touch $DIR/$tdir/striped_dir1/b
24944         mkdir $DIR/$tdir/striped_dir1/dir_b
24945         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24946                 error "create striped dir under striped dir fails"
24947
24948         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24949                 error "rename dir under different striped dir should fail"
24950
24951         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24952                 error "rename striped dir under diff striped dir should fail"
24953
24954         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24955                 error "rename file under diff striped dirs fails"
24956
24957         rm -rf $DIR/$tdir
24958 }
24959 run_test 300f "check rename cross striped directory"
24960
24961 test_300_check_default_striped_dir()
24962 {
24963         local dirname=$1
24964         local default_count=$2
24965         local default_index=$3
24966         local stripe_count
24967         local stripe_index
24968         local dir_stripe_index
24969         local dir
24970
24971         echo "checking $dirname $default_count $default_index"
24972         $LFS setdirstripe -D -c $default_count -i $default_index \
24973                                 -H all_char $DIR/$tdir/$dirname ||
24974                 error "set default stripe on striped dir error"
24975         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24976         [ $stripe_count -eq $default_count ] ||
24977                 error "expect $default_count get $stripe_count for $dirname"
24978
24979         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24980         [ $stripe_index -eq $default_index ] ||
24981                 error "expect $default_index get $stripe_index for $dirname"
24982
24983         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24984                                                 error "create dirs failed"
24985
24986         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24987         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24988         for dir in $(find $DIR/$tdir/$dirname/*); do
24989                 stripe_count=$($LFS getdirstripe -c $dir)
24990                 (( $stripe_count == $default_count )) ||
24991                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24992                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24993                 error "stripe count $default_count != $stripe_count for $dir"
24994
24995                 stripe_index=$($LFS getdirstripe -i $dir)
24996                 [ $default_index -eq -1 ] ||
24997                         [ $stripe_index -eq $default_index ] ||
24998                         error "$stripe_index != $default_index for $dir"
24999
25000                 #check default stripe
25001                 stripe_count=$($LFS getdirstripe -D -c $dir)
25002                 [ $stripe_count -eq $default_count ] ||
25003                 error "default count $default_count != $stripe_count for $dir"
25004
25005                 stripe_index=$($LFS getdirstripe -D -i $dir)
25006                 [ $stripe_index -eq $default_index ] ||
25007                 error "default index $default_index != $stripe_index for $dir"
25008         done
25009         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25010 }
25011
25012 test_300g() {
25013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25014         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25015                 skip "Need MDS version at least 2.7.55"
25016
25017         local dir
25018         local stripe_count
25019         local stripe_index
25020
25021         mkdir_on_mdt0 $DIR/$tdir
25022         mkdir $DIR/$tdir/normal_dir
25023
25024         #Checking when client cache stripe index
25025         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25026         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25027                 error "create striped_dir failed"
25028
25029         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25030                 error "create dir0 fails"
25031         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25032         [ $stripe_index -eq 0 ] ||
25033                 error "dir0 expect index 0 got $stripe_index"
25034
25035         mkdir $DIR/$tdir/striped_dir/dir1 ||
25036                 error "create dir1 fails"
25037         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25038         [ $stripe_index -eq 1 ] ||
25039                 error "dir1 expect index 1 got $stripe_index"
25040
25041         #check default stripe count/stripe index
25042         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25043         test_300_check_default_striped_dir normal_dir 1 0
25044         test_300_check_default_striped_dir normal_dir -1 1
25045         test_300_check_default_striped_dir normal_dir 2 -1
25046
25047         #delete default stripe information
25048         echo "delete default stripeEA"
25049         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25050                 error "set default stripe on striped dir error"
25051
25052         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25053         for dir in $(find $DIR/$tdir/normal_dir/*); do
25054                 stripe_count=$($LFS getdirstripe -c $dir)
25055                 [ $stripe_count -eq 0 ] ||
25056                         error "expect 1 get $stripe_count for $dir"
25057         done
25058 }
25059 run_test 300g "check default striped directory for normal directory"
25060
25061 test_300h() {
25062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25063         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25064                 skip "Need MDS version at least 2.7.55"
25065
25066         local dir
25067         local stripe_count
25068
25069         mkdir $DIR/$tdir
25070         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25071                 error "set striped dir error"
25072
25073         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25074         test_300_check_default_striped_dir striped_dir 1 0
25075         test_300_check_default_striped_dir striped_dir -1 1
25076         test_300_check_default_striped_dir striped_dir 2 -1
25077
25078         #delete default stripe information
25079         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25080                 error "set default stripe on striped dir error"
25081
25082         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25083         for dir in $(find $DIR/$tdir/striped_dir/*); do
25084                 stripe_count=$($LFS getdirstripe -c $dir)
25085                 [ $stripe_count -eq 0 ] ||
25086                         error "expect 1 get $stripe_count for $dir"
25087         done
25088 }
25089 run_test 300h "check default striped directory for striped directory"
25090
25091 test_300i() {
25092         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25093         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25094         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25095                 skip "Need MDS version at least 2.7.55"
25096
25097         local stripe_count
25098         local file
25099
25100         mkdir $DIR/$tdir
25101
25102         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25103                 error "set striped dir error"
25104
25105         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25106                 error "create files under striped dir failed"
25107
25108         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25109                 error "set striped hashdir error"
25110
25111         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25112                 error "create dir0 under hash dir failed"
25113         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25114                 error "create dir1 under hash dir failed"
25115         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25116                 error "create dir2 under hash dir failed"
25117
25118         # unfortunately, we need to umount to clear dir layout cache for now
25119         # once we fully implement dir layout, we can drop this
25120         umount_client $MOUNT || error "umount failed"
25121         mount_client $MOUNT || error "mount failed"
25122
25123         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25124         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25125         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25126
25127         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25128                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25129                         error "create crush2 dir $tdir/hashdir/d3 failed"
25130                 $LFS find -H crush2 $DIR/$tdir/hashdir
25131                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25132                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25133
25134                 # mkdir with an invalid hash type (hash=fail_val) from client
25135                 # should be replaced on MDS with a valid (default) hash type
25136                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25137                 $LCTL set_param fail_loc=0x1901 fail_val=99
25138                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25139
25140                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25141                 local expect=$(do_facet mds1 \
25142                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25143                 [[ $hash == $expect ]] ||
25144                         error "d99 hash '$hash' != expected hash '$expect'"
25145         fi
25146
25147         #set the stripe to be unknown hash type on read
25148         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25149         $LCTL set_param fail_loc=0x1901 fail_val=99
25150         for ((i = 0; i < 10; i++)); do
25151                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25152                         error "stat f-$i failed"
25153                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25154         done
25155
25156         touch $DIR/$tdir/striped_dir/f0 &&
25157                 error "create under striped dir with unknown hash should fail"
25158
25159         $LCTL set_param fail_loc=0
25160
25161         umount_client $MOUNT || error "umount failed"
25162         mount_client $MOUNT || error "mount failed"
25163
25164         return 0
25165 }
25166 run_test 300i "client handle unknown hash type striped directory"
25167
25168 test_300j() {
25169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25171         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25172                 skip "Need MDS version at least 2.7.55"
25173
25174         local stripe_count
25175         local file
25176
25177         mkdir $DIR/$tdir
25178
25179         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25180         $LCTL set_param fail_loc=0x1702
25181         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25182                 error "set striped dir error"
25183
25184         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25185                 error "create files under striped dir failed"
25186
25187         $LCTL set_param fail_loc=0
25188
25189         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25190
25191         return 0
25192 }
25193 run_test 300j "test large update record"
25194
25195 test_300k() {
25196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25197         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25198         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25199                 skip "Need MDS version at least 2.7.55"
25200
25201         # this test needs a huge transaction
25202         local kb
25203         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25204              osd*.$FSNAME-MDT0000.kbytestotal")
25205         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25206
25207         local stripe_count
25208         local file
25209
25210         mkdir $DIR/$tdir
25211
25212         #define OBD_FAIL_LARGE_STRIPE   0x1703
25213         $LCTL set_param fail_loc=0x1703
25214         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25215                 error "set striped dir error"
25216         $LCTL set_param fail_loc=0
25217
25218         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25219                 error "getstripeddir fails"
25220         rm -rf $DIR/$tdir/striped_dir ||
25221                 error "unlink striped dir fails"
25222
25223         return 0
25224 }
25225 run_test 300k "test large striped directory"
25226
25227 test_300l() {
25228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25229         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25230         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25231                 skip "Need MDS version at least 2.7.55"
25232
25233         local stripe_index
25234
25235         test_mkdir -p $DIR/$tdir/striped_dir
25236         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25237                         error "chown $RUNAS_ID failed"
25238         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25239                 error "set default striped dir failed"
25240
25241         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25242         $LCTL set_param fail_loc=0x80000158
25243         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25244
25245         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25246         [ $stripe_index -eq 1 ] ||
25247                 error "expect 1 get $stripe_index for $dir"
25248 }
25249 run_test 300l "non-root user to create dir under striped dir with stale layout"
25250
25251 test_300m() {
25252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25253         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25254         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25255                 skip "Need MDS version at least 2.7.55"
25256
25257         mkdir -p $DIR/$tdir/striped_dir
25258         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25259                 error "set default stripes dir error"
25260
25261         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25262
25263         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25264         [ $stripe_count -eq 0 ] ||
25265                         error "expect 0 get $stripe_count for a"
25266
25267         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25268                 error "set default stripes dir error"
25269
25270         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25271
25272         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25273         [ $stripe_count -eq 0 ] ||
25274                         error "expect 0 get $stripe_count for b"
25275
25276         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25277                 error "set default stripes dir error"
25278
25279         mkdir $DIR/$tdir/striped_dir/c &&
25280                 error "default stripe_index is invalid, mkdir c should fails"
25281
25282         rm -rf $DIR/$tdir || error "rmdir fails"
25283 }
25284 run_test 300m "setstriped directory on single MDT FS"
25285
25286 cleanup_300n() {
25287         local list=$(comma_list $(mdts_nodes))
25288
25289         trap 0
25290         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25291 }
25292
25293 test_300n() {
25294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25296         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25297                 skip "Need MDS version at least 2.7.55"
25298         remote_mds_nodsh && skip "remote MDS with nodsh"
25299
25300         local stripe_index
25301         local list=$(comma_list $(mdts_nodes))
25302
25303         trap cleanup_300n RETURN EXIT
25304         mkdir -p $DIR/$tdir
25305         chmod 777 $DIR/$tdir
25306         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25307                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25308                 error "create striped dir succeeds with gid=0"
25309
25310         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25311         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25312                 error "create striped dir fails with gid=-1"
25313
25314         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25315         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25316                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25317                 error "set default striped dir succeeds with gid=0"
25318
25319
25320         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25321         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25322                 error "set default striped dir fails with gid=-1"
25323
25324
25325         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25326         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25327                                         error "create test_dir fails"
25328         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25329                                         error "create test_dir1 fails"
25330         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25331                                         error "create test_dir2 fails"
25332         cleanup_300n
25333 }
25334 run_test 300n "non-root user to create dir under striped dir with default EA"
25335
25336 test_300o() {
25337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25339         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25340                 skip "Need MDS version at least 2.7.55"
25341
25342         local numfree1
25343         local numfree2
25344
25345         mkdir -p $DIR/$tdir
25346
25347         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25348         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25349         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25350                 skip "not enough free inodes $numfree1 $numfree2"
25351         fi
25352
25353         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25354         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25355         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25356                 skip "not enough free space $numfree1 $numfree2"
25357         fi
25358
25359         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25360                 error "setdirstripe fails"
25361
25362         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25363                 error "create dirs fails"
25364
25365         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25366         ls $DIR/$tdir/striped_dir > /dev/null ||
25367                 error "ls striped dir fails"
25368         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25369                 error "unlink big striped dir fails"
25370 }
25371 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25372
25373 test_300p() {
25374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25376         remote_mds_nodsh && skip "remote MDS with nodsh"
25377
25378         mkdir_on_mdt0 $DIR/$tdir
25379
25380         #define OBD_FAIL_OUT_ENOSPC     0x1704
25381         do_facet mds2 lctl set_param fail_loc=0x80001704
25382         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25383                  && error "create striped directory should fail"
25384
25385         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25386
25387         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25388         true
25389 }
25390 run_test 300p "create striped directory without space"
25391
25392 test_300q() {
25393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25395
25396         local fd=$(free_fd)
25397         local cmd="exec $fd<$tdir"
25398         cd $DIR
25399         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25400         eval $cmd
25401         cmd="exec $fd<&-"
25402         trap "eval $cmd" EXIT
25403         cd $tdir || error "cd $tdir fails"
25404         rmdir  ../$tdir || error "rmdir $tdir fails"
25405         mkdir local_dir && error "create dir succeeds"
25406         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25407         eval $cmd
25408         return 0
25409 }
25410 run_test 300q "create remote directory under orphan directory"
25411
25412 test_300r() {
25413         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25414                 skip "Need MDS version at least 2.7.55" && return
25415         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25416
25417         mkdir $DIR/$tdir
25418
25419         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25420                 error "set striped dir error"
25421
25422         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25423                 error "getstripeddir fails"
25424
25425         local stripe_count
25426         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25427                       awk '/lmv_stripe_count:/ { print $2 }')
25428
25429         [ $MDSCOUNT -ne $stripe_count ] &&
25430                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25431
25432         rm -rf $DIR/$tdir/striped_dir ||
25433                 error "unlink striped dir fails"
25434 }
25435 run_test 300r "test -1 striped directory"
25436
25437 test_300s_helper() {
25438         local count=$1
25439
25440         local stripe_dir=$DIR/$tdir/striped_dir.$count
25441
25442         $LFS mkdir -c $count $stripe_dir ||
25443                 error "lfs mkdir -c error"
25444
25445         $LFS getdirstripe $stripe_dir ||
25446                 error "lfs getdirstripe fails"
25447
25448         local stripe_count
25449         stripe_count=$($LFS getdirstripe $stripe_dir |
25450                       awk '/lmv_stripe_count:/ { print $2 }')
25451
25452         [ $count -ne $stripe_count ] &&
25453                 error_noexit "bad stripe count $stripe_count expected $count"
25454
25455         local dupe_stripes
25456         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25457                 awk '/0x/ {count[$1] += 1}; END {
25458                         for (idx in count) {
25459                                 if (count[idx]>1) {
25460                                         print "index " idx " count " count[idx]
25461                                 }
25462                         }
25463                 }')
25464
25465         if [[ -n "$dupe_stripes" ]] ; then
25466                 lfs getdirstripe $stripe_dir
25467                 error_noexit "Dupe MDT above: $dupe_stripes "
25468         fi
25469
25470         rm -rf $stripe_dir ||
25471                 error_noexit "unlink $stripe_dir fails"
25472 }
25473
25474 test_300s() {
25475         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25476                 skip "Need MDS version at least 2.7.55" && return
25477         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25478
25479         mkdir $DIR/$tdir
25480         for count in $(seq 2 $MDSCOUNT); do
25481                 test_300s_helper $count
25482         done
25483 }
25484 run_test 300s "test lfs mkdir -c without -i"
25485
25486 test_300t() {
25487         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25488                 skip "need MDS 2.14.55 or later"
25489         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25490
25491         local testdir="$DIR/$tdir/striped_dir"
25492         local dir1=$testdir/dir1
25493         local dir2=$testdir/dir2
25494
25495         mkdir -p $testdir
25496
25497         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25498                 error "failed to set default stripe count for $testdir"
25499
25500         mkdir $dir1
25501         local stripe_count=$($LFS getdirstripe -c $dir1)
25502
25503         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25504
25505         local max_count=$((MDSCOUNT - 1))
25506         local mdts=$(comma_list $(mdts_nodes))
25507
25508         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25509         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25510
25511         mkdir $dir2
25512         stripe_count=$($LFS getdirstripe -c $dir2)
25513
25514         (( $stripe_count == $max_count )) || error "wrong stripe count"
25515 }
25516 run_test 300t "test max_mdt_stripecount"
25517
25518 prepare_remote_file() {
25519         mkdir $DIR/$tdir/src_dir ||
25520                 error "create remote source failed"
25521
25522         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25523                  error "cp to remote source failed"
25524         touch $DIR/$tdir/src_dir/a
25525
25526         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25527                 error "create remote target dir failed"
25528
25529         touch $DIR/$tdir/tgt_dir/b
25530
25531         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25532                 error "rename dir cross MDT failed!"
25533
25534         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25535                 error "src_child still exists after rename"
25536
25537         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25538                 error "missing file(a) after rename"
25539
25540         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25541                 error "diff after rename"
25542 }
25543
25544 test_310a() {
25545         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25547
25548         local remote_file=$DIR/$tdir/tgt_dir/b
25549
25550         mkdir -p $DIR/$tdir
25551
25552         prepare_remote_file || error "prepare remote file failed"
25553
25554         #open-unlink file
25555         $OPENUNLINK $remote_file $remote_file ||
25556                 error "openunlink $remote_file failed"
25557         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25558 }
25559 run_test 310a "open unlink remote file"
25560
25561 test_310b() {
25562         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25564
25565         local remote_file=$DIR/$tdir/tgt_dir/b
25566
25567         mkdir -p $DIR/$tdir
25568
25569         prepare_remote_file || error "prepare remote file failed"
25570
25571         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25572         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25573         $CHECKSTAT -t file $remote_file || error "check file failed"
25574 }
25575 run_test 310b "unlink remote file with multiple links while open"
25576
25577 test_310c() {
25578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25579         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25580
25581         local remote_file=$DIR/$tdir/tgt_dir/b
25582
25583         mkdir -p $DIR/$tdir
25584
25585         prepare_remote_file || error "prepare remote file failed"
25586
25587         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25588         multiop_bg_pause $remote_file O_uc ||
25589                         error "mulitop failed for remote file"
25590         MULTIPID=$!
25591         $MULTIOP $DIR/$tfile Ouc
25592         kill -USR1 $MULTIPID
25593         wait $MULTIPID
25594 }
25595 run_test 310c "open-unlink remote file with multiple links"
25596
25597 #LU-4825
25598 test_311() {
25599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25600         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25601         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25602                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25603         remote_mds_nodsh && skip "remote MDS with nodsh"
25604
25605         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25606         local mdts=$(comma_list $(mdts_nodes))
25607
25608         mkdir -p $DIR/$tdir
25609         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25610         createmany -o $DIR/$tdir/$tfile. 1000
25611
25612         # statfs data is not real time, let's just calculate it
25613         old_iused=$((old_iused + 1000))
25614
25615         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25616                         osp.*OST0000*MDT0000.create_count")
25617         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25618                                 osp.*OST0000*MDT0000.max_create_count")
25619         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25620
25621         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25622         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25623         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25624
25625         unlinkmany $DIR/$tdir/$tfile. 1000
25626
25627         do_nodes $mdts "$LCTL set_param -n \
25628                         osp.*OST0000*.max_create_count=$max_count"
25629         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25630                 do_nodes $mdts "$LCTL set_param -n \
25631                                 osp.*OST0000*.create_count=$count"
25632         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25633                         grep "=0" && error "create_count is zero"
25634
25635         local new_iused
25636         for i in $(seq 120); do
25637                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25638                 # system may be too busy to destroy all objs in time, use
25639                 # a somewhat small value to not fail autotest
25640                 [ $((old_iused - new_iused)) -gt 400 ] && break
25641                 sleep 1
25642         done
25643
25644         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25645         [ $((old_iused - new_iused)) -gt 400 ] ||
25646                 error "objs not destroyed after unlink"
25647 }
25648 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25649
25650 zfs_get_objid()
25651 {
25652         local ost=$1
25653         local tf=$2
25654         local fid=($($LFS getstripe $tf | grep 0x))
25655         local seq=${fid[3]#0x}
25656         local objid=${fid[1]}
25657
25658         local vdevdir=$(dirname $(facet_vdevice $ost))
25659         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25660         local zfs_zapid=$(do_facet $ost $cmd |
25661                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25662                           awk '/Object/{getline; print $1}')
25663         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25664                           awk "/$objid = /"'{printf $3}')
25665
25666         echo $zfs_objid
25667 }
25668
25669 zfs_object_blksz() {
25670         local ost=$1
25671         local objid=$2
25672
25673         local vdevdir=$(dirname $(facet_vdevice $ost))
25674         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25675         local blksz=$(do_facet $ost $cmd $objid |
25676                       awk '/dblk/{getline; printf $4}')
25677
25678         case "${blksz: -1}" in
25679                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25680                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25681                 *) ;;
25682         esac
25683
25684         echo $blksz
25685 }
25686
25687 test_312() { # LU-4856
25688         remote_ost_nodsh && skip "remote OST with nodsh"
25689         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25690
25691         local max_blksz=$(do_facet ost1 \
25692                           $ZFS get -p recordsize $(facet_device ost1) |
25693                           awk '!/VALUE/{print $3}')
25694         local tf=$DIR/$tfile
25695
25696         $LFS setstripe -c1 $tf
25697         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25698
25699         # Get ZFS object id
25700         local zfs_objid=$(zfs_get_objid $facet $tf)
25701         # block size change by sequential overwrite
25702         local bs
25703
25704         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25705                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25706
25707                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25708                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25709         done
25710         rm -f $tf
25711
25712         $LFS setstripe -c1 $tf
25713         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25714
25715         # block size change by sequential append write
25716         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25717         zfs_objid=$(zfs_get_objid $facet $tf)
25718         local count
25719
25720         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25721                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25722                         oflag=sync conv=notrunc
25723
25724                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25725                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25726                         error "blksz error, actual $blksz, " \
25727                                 "expected: 2 * $count * $PAGE_SIZE"
25728         done
25729         rm -f $tf
25730
25731         # random write
25732         $LFS setstripe -c1 $tf
25733         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25734         zfs_objid=$(zfs_get_objid $facet $tf)
25735
25736         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25737         blksz=$(zfs_object_blksz $facet $zfs_objid)
25738         (( blksz == PAGE_SIZE )) ||
25739                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25740
25741         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25742         blksz=$(zfs_object_blksz $facet $zfs_objid)
25743         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25744
25745         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25746         blksz=$(zfs_object_blksz $facet $zfs_objid)
25747         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25748 }
25749 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25750
25751 test_313() {
25752         remote_ost_nodsh && skip "remote OST with nodsh"
25753
25754         local file=$DIR/$tfile
25755
25756         rm -f $file
25757         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25758
25759         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25760         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25761         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25762                 error "write should failed"
25763         do_facet ost1 "$LCTL set_param fail_loc=0"
25764         rm -f $file
25765 }
25766 run_test 313 "io should fail after last_rcvd update fail"
25767
25768 test_314() {
25769         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25770
25771         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25772         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25773         rm -f $DIR/$tfile
25774         wait_delete_completed
25775         do_facet ost1 "$LCTL set_param fail_loc=0"
25776 }
25777 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25778
25779 test_315() { # LU-618
25780         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25781
25782         local file=$DIR/$tfile
25783         rm -f $file
25784
25785         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25786                 error "multiop file write failed"
25787         $MULTIOP $file oO_RDONLY:r4063232_c &
25788         PID=$!
25789
25790         sleep 2
25791
25792         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25793         kill -USR1 $PID
25794
25795         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25796         rm -f $file
25797 }
25798 run_test 315 "read should be accounted"
25799
25800 test_316() {
25801         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25802         large_xattr_enabled || skip "ea_inode feature disabled"
25803
25804         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25805         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25806         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25807         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25808
25809         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25810 }
25811 run_test 316 "lfs migrate of file with large_xattr enabled"
25812
25813 test_317() {
25814         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25815                 skip "Need MDS version at least 2.11.53"
25816         if [ "$ost1_FSTYPE" == "zfs" ]; then
25817                 skip "LU-10370: no implementation for ZFS"
25818         fi
25819
25820         local trunc_sz
25821         local grant_blk_size
25822
25823         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25824                         awk '/grant_block_size:/ { print $2; exit; }')
25825         #
25826         # Create File of size 5M. Truncate it to below size's and verify
25827         # blocks count.
25828         #
25829         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25830                 error "Create file $DIR/$tfile failed"
25831         stack_trap "rm -f $DIR/$tfile" EXIT
25832
25833         for trunc_sz in 2097152 4097 4000 509 0; do
25834                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25835                         error "truncate $tfile to $trunc_sz failed"
25836                 local sz=$(stat --format=%s $DIR/$tfile)
25837                 local blk=$(stat --format=%b $DIR/$tfile)
25838                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25839                                      grant_blk_size) * 8))
25840
25841                 if [[ $blk -ne $trunc_blk ]]; then
25842                         $(which stat) $DIR/$tfile
25843                         error "Expected Block $trunc_blk got $blk for $tfile"
25844                 fi
25845
25846                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25847                         error "Expected Size $trunc_sz got $sz for $tfile"
25848         done
25849
25850         #
25851         # sparse file test
25852         # Create file with a hole and write actual 65536 bytes which aligned
25853         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25854         #
25855         local bs=65536
25856         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25857                 error "Create file : $DIR/$tfile"
25858
25859         #
25860         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25861         # blocks. The block count must drop to 8.
25862         #
25863         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25864                 ((bs - grant_blk_size) + 1)))
25865         $TRUNCATE $DIR/$tfile $trunc_sz ||
25866                 error "truncate $tfile to $trunc_sz failed"
25867
25868         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25869         sz=$(stat --format=%s $DIR/$tfile)
25870         blk=$(stat --format=%b $DIR/$tfile)
25871
25872         if [[ $blk -ne $trunc_bsz ]]; then
25873                 $(which stat) $DIR/$tfile
25874                 error "Expected Block $trunc_bsz got $blk for $tfile"
25875         fi
25876
25877         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25878                 error "Expected Size $trunc_sz got $sz for $tfile"
25879 }
25880 run_test 317 "Verify blocks get correctly update after truncate"
25881
25882 test_318() {
25883         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25884         local old_max_active=$($LCTL get_param -n \
25885                             ${llite_name}.max_read_ahead_async_active \
25886                             2>/dev/null)
25887
25888         $LCTL set_param llite.*.max_read_ahead_async_active=256
25889         local max_active=$($LCTL get_param -n \
25890                            ${llite_name}.max_read_ahead_async_active \
25891                            2>/dev/null)
25892         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25893
25894         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25895                 error "set max_read_ahead_async_active should succeed"
25896
25897         $LCTL set_param llite.*.max_read_ahead_async_active=512
25898         max_active=$($LCTL get_param -n \
25899                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25900         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25901
25902         # restore @max_active
25903         [ $old_max_active -ne 0 ] && $LCTL set_param \
25904                 llite.*.max_read_ahead_async_active=$old_max_active
25905
25906         local old_threshold=$($LCTL get_param -n \
25907                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25908         local max_per_file_mb=$($LCTL get_param -n \
25909                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25910
25911         local invalid=$(($max_per_file_mb + 1))
25912         $LCTL set_param \
25913                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25914                         && error "set $invalid should fail"
25915
25916         local valid=$(($invalid - 1))
25917         $LCTL set_param \
25918                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25919                         error "set $valid should succeed"
25920         local threshold=$($LCTL get_param -n \
25921                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25922         [ $threshold -eq $valid ] || error \
25923                 "expect threshold $valid got $threshold"
25924         $LCTL set_param \
25925                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25926 }
25927 run_test 318 "Verify async readahead tunables"
25928
25929 test_319() {
25930         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25931
25932         local before=$(date +%s)
25933         local evict
25934         local mdir=$DIR/$tdir
25935         local file=$mdir/xxx
25936
25937         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25938         touch $file
25939
25940 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25941         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25942         $LFS migrate -m1 $mdir &
25943
25944         sleep 1
25945         dd if=$file of=/dev/null
25946         wait
25947         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25948           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25949
25950         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25951 }
25952 run_test 319 "lost lease lock on migrate error"
25953
25954 test_398a() { # LU-4198
25955         local ost1_imp=$(get_osc_import_name client ost1)
25956         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25957                          cut -d'.' -f2)
25958
25959         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25960         stack_trap "rm -f $DIR/$tfile"
25961         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25962
25963         # request a new lock on client
25964         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25965
25966         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25967         local lock_count=$($LCTL get_param -n \
25968                            ldlm.namespaces.$imp_name.lru_size)
25969         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25970
25971         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25972
25973         # no lock cached, should use lockless DIO and not enqueue new lock
25974         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25975         lock_count=$($LCTL get_param -n \
25976                      ldlm.namespaces.$imp_name.lru_size)
25977         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25978
25979         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25980
25981         # no lock cached, should use locked DIO append
25982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25983                 conv=notrunc || error "DIO append failed"
25984         lock_count=$($LCTL get_param -n \
25985                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25986         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25987 }
25988 run_test 398a "direct IO should cancel lock otherwise lockless"
25989
25990 test_398b() { # LU-4198
25991         local before=$(date +%s)
25992         local njobs=4
25993         local size=48
25994
25995         which fio || skip_env "no fio installed"
25996         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25998
25999         # Single page, multiple pages, stripe size, 4*stripe size
26000         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26001                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26002                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26003                         --numjobs=$njobs --fallocate=none \
26004                         --iodepth=16 --allow_file_create=0 \
26005                         --size=$((size/njobs))M \
26006                         --filename=$DIR/$tfile &
26007                 bg_pid=$!
26008
26009                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26010                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26011                         --numjobs=$njobs --fallocate=none \
26012                         --iodepth=16 --allow_file_create=0 \
26013                         --size=$((size/njobs))M \
26014                         --filename=$DIR/$tfile || true
26015                 wait $bg_pid
26016         done
26017
26018         evict=$(do_facet client $LCTL get_param \
26019                 osc.$FSNAME-OST*-osc-*/state |
26020             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26021
26022         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26023                 (do_facet client $LCTL get_param \
26024                         osc.$FSNAME-OST*-osc-*/state;
26025                     error "eviction happened: $evict before:$before")
26026
26027         rm -f $DIR/$tfile
26028 }
26029 run_test 398b "DIO and buffer IO race"
26030
26031 test_398c() { # LU-4198
26032         local ost1_imp=$(get_osc_import_name client ost1)
26033         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26034                          cut -d'.' -f2)
26035
26036         which fio || skip_env "no fio installed"
26037
26038         saved_debug=$($LCTL get_param -n debug)
26039         $LCTL set_param debug=0
26040
26041         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26042         ((size /= 1024)) # by megabytes
26043         ((size /= 2)) # write half of the OST at most
26044         [ $size -gt 40 ] && size=40 #reduce test time anyway
26045
26046         $LFS setstripe -c 1 $DIR/$tfile
26047
26048         # it seems like ldiskfs reserves more space than necessary if the
26049         # writing blocks are not mapped, so it extends the file firstly
26050         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26051         cancel_lru_locks osc
26052
26053         # clear and verify rpc_stats later
26054         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26055
26056         local njobs=4
26057         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26058         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26059                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26060                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26061                 --filename=$DIR/$tfile
26062         [ $? -eq 0 ] || error "fio write error"
26063
26064         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26065                 error "Locks were requested while doing AIO"
26066
26067         # get the percentage of 1-page I/O
26068         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26069                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26070                 awk '{print $7}')
26071         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26072
26073         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26074         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26075                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26076                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26077                 --filename=$DIR/$tfile
26078         [ $? -eq 0 ] || error "fio mixed read write error"
26079
26080         echo "AIO with large block size ${size}M"
26081         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26082                 --numjobs=1 --fallocate=none --ioengine=libaio \
26083                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26084                 --filename=$DIR/$tfile
26085         [ $? -eq 0 ] || error "fio large block size failed"
26086
26087         rm -f $DIR/$tfile
26088         $LCTL set_param debug="$saved_debug"
26089 }
26090 run_test 398c "run fio to test AIO"
26091
26092 test_398d() { #  LU-13846
26093         which aiocp || skip_env "no aiocp installed"
26094         local aio_file=$DIR/$tfile.aio
26095
26096         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26097
26098         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26099         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26100         stack_trap "rm -f $DIR/$tfile $aio_file"
26101
26102         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26103
26104         # make sure we don't crash and fail properly
26105         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26106                 error "aio not aligned with PAGE SIZE should fail"
26107
26108         rm -f $DIR/$tfile $aio_file
26109 }
26110 run_test 398d "run aiocp to verify block size > stripe size"
26111
26112 test_398e() {
26113         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26114         touch $DIR/$tfile.new
26115         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26116 }
26117 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26118
26119 test_398f() { #  LU-14687
26120         which aiocp || skip_env "no aiocp installed"
26121         local aio_file=$DIR/$tfile.aio
26122
26123         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26124
26125         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26126         stack_trap "rm -f $DIR/$tfile $aio_file"
26127
26128         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26129         $LCTL set_param fail_loc=0x1418
26130         # make sure we don't crash and fail properly
26131         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26132                 error "aio with page allocation failure succeeded"
26133         $LCTL set_param fail_loc=0
26134         diff $DIR/$tfile $aio_file
26135         [[ $? != 0 ]] || error "no diff after failed aiocp"
26136 }
26137 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26138
26139 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26140 # stripe and i/o size must be > stripe size
26141 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26142 # single RPC in flight.  This test shows async DIO submission is working by
26143 # showing multiple RPCs in flight.
26144 test_398g() { #  LU-13798
26145         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26146
26147         # We need to do some i/o first to acquire enough grant to put our RPCs
26148         # in flight; otherwise a new connection may not have enough grant
26149         # available
26150         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26151                 error "parallel dio failed"
26152         stack_trap "rm -f $DIR/$tfile"
26153
26154         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26155         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26156         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26157         stack_trap "$LCTL set_param -n $pages_per_rpc"
26158
26159         # Recreate file so it's empty
26160         rm -f $DIR/$tfile
26161         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26162         #Pause rpc completion to guarantee we see multiple rpcs in flight
26163         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26164         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26165         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26166
26167         # Clear rpc stats
26168         $LCTL set_param osc.*.rpc_stats=c
26169
26170         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26171                 error "parallel dio failed"
26172         stack_trap "rm -f $DIR/$tfile"
26173
26174         $LCTL get_param osc.*-OST0000-*.rpc_stats
26175         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26176                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26177                 grep "8:" | awk '{print $8}')
26178         # We look at the "8 rpcs in flight" field, and verify A) it is present
26179         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26180         # as expected for an 8M DIO to a file with 1M stripes.
26181         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26182
26183         # Verify turning off parallel dio works as expected
26184         # Clear rpc stats
26185         $LCTL set_param osc.*.rpc_stats=c
26186         $LCTL set_param llite.*.parallel_dio=0
26187         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26188
26189         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26190                 error "dio with parallel dio disabled failed"
26191
26192         # Ideally, we would see only one RPC in flight here, but there is an
26193         # unavoidable race between i/o completion and RPC in flight counting,
26194         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26195         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26196         # So instead we just verify it's always < 8.
26197         $LCTL get_param osc.*-OST0000-*.rpc_stats
26198         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26199                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26200                 grep '^$' -B1 | grep . | awk '{print $1}')
26201         [ $ret != "8:" ] ||
26202                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26203 }
26204 run_test 398g "verify parallel dio async RPC submission"
26205
26206 test_398h() { #  LU-13798
26207         local dio_file=$DIR/$tfile.dio
26208
26209         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26210
26211         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26212         stack_trap "rm -f $DIR/$tfile $dio_file"
26213
26214         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26215                 error "parallel dio failed"
26216         diff $DIR/$tfile $dio_file
26217         [[ $? == 0 ]] || error "file diff after aiocp"
26218 }
26219 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26220
26221 test_398i() { #  LU-13798
26222         local dio_file=$DIR/$tfile.dio
26223
26224         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26225
26226         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26227         stack_trap "rm -f $DIR/$tfile $dio_file"
26228
26229         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26230         $LCTL set_param fail_loc=0x1418
26231         # make sure we don't crash and fail properly
26232         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26233                 error "parallel dio page allocation failure succeeded"
26234         diff $DIR/$tfile $dio_file
26235         [[ $? != 0 ]] || error "no diff after failed aiocp"
26236 }
26237 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26238
26239 test_398j() { #  LU-13798
26240         # Stripe size > RPC size but less than i/o size tests split across
26241         # stripes and RPCs for individual i/o op
26242         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26243
26244         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26245         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26246         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26247         stack_trap "$LCTL set_param -n $pages_per_rpc"
26248
26249         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26250                 error "parallel dio write failed"
26251         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26252
26253         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26254                 error "parallel dio read failed"
26255         diff $DIR/$tfile $DIR/$tfile.2
26256         [[ $? == 0 ]] || error "file diff after parallel dio read"
26257 }
26258 run_test 398j "test parallel dio where stripe size > rpc_size"
26259
26260 test_398k() { #  LU-13798
26261         wait_delete_completed
26262         wait_mds_ost_sync
26263
26264         # 4 stripe file; we will cause out of space on OST0
26265         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26266
26267         # Fill OST0 (if it's not too large)
26268         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26269                    head -n1)
26270         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26271                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26272         fi
26273         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26274         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26275                 error "dd should fill OST0"
26276         stack_trap "rm -f $DIR/$tfile.1"
26277
26278         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26279         err=$?
26280
26281         ls -la $DIR/$tfile
26282         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26283                 error "file is not 0 bytes in size"
26284
26285         # dd above should not succeed, but don't error until here so we can
26286         # get debug info above
26287         [[ $err != 0 ]] ||
26288                 error "parallel dio write with enospc succeeded"
26289         stack_trap "rm -f $DIR/$tfile"
26290 }
26291 run_test 398k "test enospc on first stripe"
26292
26293 test_398l() { #  LU-13798
26294         wait_delete_completed
26295         wait_mds_ost_sync
26296
26297         # 4 stripe file; we will cause out of space on OST0
26298         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26299         # happens on the second i/o chunk we issue
26300         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26301
26302         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26303         stack_trap "rm -f $DIR/$tfile"
26304
26305         # Fill OST0 (if it's not too large)
26306         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26307                    head -n1)
26308         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26309                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26310         fi
26311         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26312         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26313                 error "dd should fill OST0"
26314         stack_trap "rm -f $DIR/$tfile.1"
26315
26316         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26317         err=$?
26318         stack_trap "rm -f $DIR/$tfile.2"
26319
26320         # Check that short write completed as expected
26321         ls -la $DIR/$tfile.2
26322         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26323                 error "file is not 1M in size"
26324
26325         # dd above should not succeed, but don't error until here so we can
26326         # get debug info above
26327         [[ $err != 0 ]] ||
26328                 error "parallel dio write with enospc succeeded"
26329
26330         # Truncate source file to same length as output file and diff them
26331         $TRUNCATE $DIR/$tfile 1048576
26332         diff $DIR/$tfile $DIR/$tfile.2
26333         [[ $? == 0 ]] || error "data incorrect after short write"
26334 }
26335 run_test 398l "test enospc on intermediate stripe/RPC"
26336
26337 test_398m() { #  LU-13798
26338         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26339
26340         # Set up failure on OST0, the first stripe:
26341         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26342         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26343         # OST0 is on ost1, OST1 is on ost2.
26344         # So this fail_val specifies OST0
26345         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26346         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26347
26348         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26349                 error "parallel dio write with failure on first stripe succeeded"
26350         stack_trap "rm -f $DIR/$tfile"
26351         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26352
26353         # Place data in file for read
26354         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26355                 error "parallel dio write failed"
26356
26357         # Fail read on OST0, first stripe
26358         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26359         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26360         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26361                 error "parallel dio read with error on first stripe succeeded"
26362         rm -f $DIR/$tfile.2
26363         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26364
26365         # Switch to testing on OST1, second stripe
26366         # Clear file contents, maintain striping
26367         echo > $DIR/$tfile
26368         # Set up failure on OST1, second stripe:
26369         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26370         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26371
26372         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26373                 error "parallel dio write with failure on second stripe succeeded"
26374         stack_trap "rm -f $DIR/$tfile"
26375         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26376
26377         # Place data in file for read
26378         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26379                 error "parallel dio write failed"
26380
26381         # Fail read on OST1, second stripe
26382         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26383         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26384         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26385                 error "parallel dio read with error on second stripe succeeded"
26386         rm -f $DIR/$tfile.2
26387         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26388 }
26389 run_test 398m "test RPC failures with parallel dio"
26390
26391 # Parallel submission of DIO should not cause problems for append, but it's
26392 # important to verify.
26393 test_398n() { #  LU-13798
26394         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26395
26396         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26397                 error "dd to create source file failed"
26398         stack_trap "rm -f $DIR/$tfile"
26399
26400         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26401                 error "parallel dio write with failure on second stripe succeeded"
26402         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26403         diff $DIR/$tfile $DIR/$tfile.1
26404         [[ $? == 0 ]] || error "data incorrect after append"
26405
26406 }
26407 run_test 398n "test append with parallel DIO"
26408
26409 test_398o() {
26410         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26411 }
26412 run_test 398o "right kms with DIO"
26413
26414 test_398p()
26415 {
26416         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26417         which aiocp || skip_env "no aiocp installed"
26418
26419         local stripe_size=$((1024 * 1024)) #1 MiB
26420         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26421         local file_size=$((25 * stripe_size))
26422
26423         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26424         stack_trap "rm -f $DIR/$tfile*"
26425         # Just a bit bigger than the largest size in the test set below
26426         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26427                 error "buffered i/o to create file failed"
26428
26429         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26430                 $((stripe_size * 4)); do
26431
26432                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26433
26434                 echo "bs: $bs, file_size $file_size"
26435                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26436                         $DIR/$tfile.1 $DIR/$tfile.2 &
26437                 pid_dio1=$!
26438                 # Buffered I/O with similar but not the same block size
26439                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26440                         conv=notrunc &
26441                 pid_bio2=$!
26442                 wait $pid_dio1
26443                 rc1=$?
26444                 wait $pid_bio2
26445                 rc2=$?
26446                 if (( rc1 != 0 )); then
26447                         error "aio copy 1 w/bsize $bs failed: $rc1"
26448                 fi
26449                 if (( rc2 != 0 )); then
26450                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26451                 fi
26452
26453                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26454                         error "size incorrect"
26455                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26456                         error "files differ, bsize $bs"
26457                 rm -f $DIR/$tfile.2
26458         done
26459 }
26460 run_test 398p "race aio with buffered i/o"
26461
26462 test_fake_rw() {
26463         local read_write=$1
26464         if [ "$read_write" = "write" ]; then
26465                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26466         elif [ "$read_write" = "read" ]; then
26467                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26468         else
26469                 error "argument error"
26470         fi
26471
26472         # turn off debug for performance testing
26473         local saved_debug=$($LCTL get_param -n debug)
26474         $LCTL set_param debug=0
26475
26476         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26477
26478         # get ost1 size - $FSNAME-OST0000
26479         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26480         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26481         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26482
26483         if [ "$read_write" = "read" ]; then
26484                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26485         fi
26486
26487         local start_time=$(date +%s.%N)
26488         $dd_cmd bs=1M count=$blocks oflag=sync ||
26489                 error "real dd $read_write error"
26490         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26491
26492         if [ "$read_write" = "write" ]; then
26493                 rm -f $DIR/$tfile
26494         fi
26495
26496         # define OBD_FAIL_OST_FAKE_RW           0x238
26497         do_facet ost1 $LCTL set_param fail_loc=0x238
26498
26499         local start_time=$(date +%s.%N)
26500         $dd_cmd bs=1M count=$blocks oflag=sync ||
26501                 error "fake dd $read_write error"
26502         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26503
26504         if [ "$read_write" = "write" ]; then
26505                 # verify file size
26506                 cancel_lru_locks osc
26507                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26508                         error "$tfile size not $blocks MB"
26509         fi
26510         do_facet ost1 $LCTL set_param fail_loc=0
26511
26512         echo "fake $read_write $duration_fake vs. normal $read_write" \
26513                 "$duration in seconds"
26514         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26515                 error_not_in_vm "fake write is slower"
26516
26517         $LCTL set_param -n debug="$saved_debug"
26518         rm -f $DIR/$tfile
26519 }
26520 test_399a() { # LU-7655 for OST fake write
26521         remote_ost_nodsh && skip "remote OST with nodsh"
26522
26523         test_fake_rw write
26524 }
26525 run_test 399a "fake write should not be slower than normal write"
26526
26527 test_399b() { # LU-8726 for OST fake read
26528         remote_ost_nodsh && skip "remote OST with nodsh"
26529         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26530                 skip_env "ldiskfs only test"
26531         fi
26532
26533         test_fake_rw read
26534 }
26535 run_test 399b "fake read should not be slower than normal read"
26536
26537 test_400a() { # LU-1606, was conf-sanity test_74
26538         if ! which $CC > /dev/null 2>&1; then
26539                 skip_env "$CC is not installed"
26540         fi
26541
26542         local extra_flags=''
26543         local out=$TMP/$tfile
26544         local prefix=/usr/include/lustre
26545         local prog
26546
26547         # Oleg removes .c files in his test rig so test if any c files exist
26548         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26549                 skip_env "Needed .c test files are missing"
26550
26551         if ! [[ -d $prefix ]]; then
26552                 # Assume we're running in tree and fixup the include path.
26553                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26554                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26555                 extra_flags+=" -L$LUSTRE/utils/.libs"
26556         fi
26557
26558         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26559                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26560                         error "client api broken"
26561         done
26562         rm -f $out
26563 }
26564 run_test 400a "Lustre client api program can compile and link"
26565
26566 test_400b() { # LU-1606, LU-5011
26567         local header
26568         local out=$TMP/$tfile
26569         local prefix=/usr/include/linux/lustre
26570
26571         # We use a hard coded prefix so that this test will not fail
26572         # when run in tree. There are headers in lustre/include/lustre/
26573         # that are not packaged (like lustre_idl.h) and have more
26574         # complicated include dependencies (like config.h and lnet/types.h).
26575         # Since this test about correct packaging we just skip them when
26576         # they don't exist (see below) rather than try to fixup cppflags.
26577
26578         if ! which $CC > /dev/null 2>&1; then
26579                 skip_env "$CC is not installed"
26580         fi
26581
26582         for header in $prefix/*.h; do
26583                 if ! [[ -f "$header" ]]; then
26584                         continue
26585                 fi
26586
26587                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26588                         continue # lustre_ioctl.h is internal header
26589                 fi
26590
26591                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26592                         error "cannot compile '$header'"
26593         done
26594         rm -f $out
26595 }
26596 run_test 400b "packaged headers can be compiled"
26597
26598 test_401a() { #LU-7437
26599         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26600         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26601
26602         #count the number of parameters by "list_param -R"
26603         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26604         #count the number of parameters by listing proc files
26605         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26606         echo "proc_dirs='$proc_dirs'"
26607         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26608         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26609                       sort -u | wc -l)
26610
26611         [ $params -eq $procs ] ||
26612                 error "found $params parameters vs. $procs proc files"
26613
26614         # test the list_param -D option only returns directories
26615         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26616         #count the number of parameters by listing proc directories
26617         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26618                 sort -u | wc -l)
26619
26620         [ $params -eq $procs ] ||
26621                 error "found $params parameters vs. $procs proc files"
26622 }
26623 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26624
26625 test_401b() {
26626         # jobid_var may not allow arbitrary values, so use jobid_name
26627         # if available
26628         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26629                 local testname=jobid_name tmp='testing%p'
26630         else
26631                 local testname=jobid_var tmp=testing
26632         fi
26633
26634         local save=$($LCTL get_param -n $testname)
26635
26636         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26637                 error "no error returned when setting bad parameters"
26638
26639         local jobid_new=$($LCTL get_param -n foe $testname baz)
26640         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26641
26642         $LCTL set_param -n fog=bam $testname=$save bat=fog
26643         local jobid_old=$($LCTL get_param -n foe $testname bag)
26644         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26645 }
26646 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26647
26648 test_401c() {
26649         # jobid_var may not allow arbitrary values, so use jobid_name
26650         # if available
26651         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26652                 local testname=jobid_name
26653         else
26654                 local testname=jobid_var
26655         fi
26656
26657         local jobid_var_old=$($LCTL get_param -n $testname)
26658         local jobid_var_new
26659
26660         $LCTL set_param $testname= &&
26661                 error "no error returned for 'set_param a='"
26662
26663         jobid_var_new=$($LCTL get_param -n $testname)
26664         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26665                 error "$testname was changed by setting without value"
26666
26667         $LCTL set_param $testname &&
26668                 error "no error returned for 'set_param a'"
26669
26670         jobid_var_new=$($LCTL get_param -n $testname)
26671         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26672                 error "$testname was changed by setting without value"
26673 }
26674 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26675
26676 test_401d() {
26677         # jobid_var may not allow arbitrary values, so use jobid_name
26678         # if available
26679         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26680                 local testname=jobid_name new_value='foo=bar%p'
26681         else
26682                 local testname=jobid_var new_valuie=foo=bar
26683         fi
26684
26685         local jobid_var_old=$($LCTL get_param -n $testname)
26686         local jobid_var_new
26687
26688         $LCTL set_param $testname=$new_value ||
26689                 error "'set_param a=b' did not accept a value containing '='"
26690
26691         jobid_var_new=$($LCTL get_param -n $testname)
26692         [[ "$jobid_var_new" == "$new_value" ]] ||
26693                 error "'set_param a=b' failed on a value containing '='"
26694
26695         # Reset the $testname to test the other format
26696         $LCTL set_param $testname=$jobid_var_old
26697         jobid_var_new=$($LCTL get_param -n $testname)
26698         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26699                 error "failed to reset $testname"
26700
26701         $LCTL set_param $testname $new_value ||
26702                 error "'set_param a b' did not accept a value containing '='"
26703
26704         jobid_var_new=$($LCTL get_param -n $testname)
26705         [[ "$jobid_var_new" == "$new_value" ]] ||
26706                 error "'set_param a b' failed on a value containing '='"
26707
26708         $LCTL set_param $testname $jobid_var_old
26709         jobid_var_new=$($LCTL get_param -n $testname)
26710         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26711                 error "failed to reset $testname"
26712 }
26713 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26714
26715 test_401e() { # LU-14779
26716         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26717                 error "lctl list_param MGC* failed"
26718         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26719         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26720                 error "lctl get_param lru_size failed"
26721 }
26722 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26723
26724 test_402() {
26725         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26726         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26727                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26728         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26729                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26730                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26731         remote_mds_nodsh && skip "remote MDS with nodsh"
26732
26733         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26734 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26735         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26736         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26737                 echo "Touch failed - OK"
26738 }
26739 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26740
26741 test_403() {
26742         local file1=$DIR/$tfile.1
26743         local file2=$DIR/$tfile.2
26744         local tfile=$TMP/$tfile
26745
26746         rm -f $file1 $file2 $tfile
26747
26748         touch $file1
26749         ln $file1 $file2
26750
26751         # 30 sec OBD_TIMEOUT in ll_getattr()
26752         # right before populating st_nlink
26753         $LCTL set_param fail_loc=0x80001409
26754         stat -c %h $file1 > $tfile &
26755
26756         # create an alias, drop all locks and reclaim the dentry
26757         < $file2
26758         cancel_lru_locks mdc
26759         cancel_lru_locks osc
26760         sysctl -w vm.drop_caches=2
26761
26762         wait
26763
26764         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26765
26766         rm -f $tfile $file1 $file2
26767 }
26768 run_test 403 "i_nlink should not drop to zero due to aliasing"
26769
26770 test_404() { # LU-6601
26771         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26772                 skip "Need server version newer than 2.8.52"
26773         remote_mds_nodsh && skip "remote MDS with nodsh"
26774
26775         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26776                 awk '/osp .*-osc-MDT/ { print $4}')
26777
26778         local osp
26779         for osp in $mosps; do
26780                 echo "Deactivate: " $osp
26781                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26782                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26783                         awk -vp=$osp '$4 == p { print $2 }')
26784                 [ $stat = IN ] || {
26785                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26786                         error "deactivate error"
26787                 }
26788                 echo "Activate: " $osp
26789                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26790                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26791                         awk -vp=$osp '$4 == p { print $2 }')
26792                 [ $stat = UP ] || {
26793                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26794                         error "activate error"
26795                 }
26796         done
26797 }
26798 run_test 404 "validate manual {de}activated works properly for OSPs"
26799
26800 test_405() {
26801         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26802         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26803                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26804                         skip "Layout swap lock is not supported"
26805
26806         check_swap_layouts_support
26807         check_swap_layout_no_dom $DIR
26808
26809         test_mkdir $DIR/$tdir
26810         swap_lock_test -d $DIR/$tdir ||
26811                 error "One layout swap locked test failed"
26812 }
26813 run_test 405 "Various layout swap lock tests"
26814
26815 test_406() {
26816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26817         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26818         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26820         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26821                 skip "Need MDS version at least 2.8.50"
26822
26823         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26824         local test_pool=$TESTNAME
26825
26826         pool_add $test_pool || error "pool_add failed"
26827         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26828                 error "pool_add_targets failed"
26829
26830         save_layout_restore_at_exit $MOUNT
26831
26832         # parent set default stripe count only, child will stripe from both
26833         # parent and fs default
26834         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26835                 error "setstripe $MOUNT failed"
26836         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26837         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26838         for i in $(seq 10); do
26839                 local f=$DIR/$tdir/$tfile.$i
26840                 touch $f || error "touch failed"
26841                 local count=$($LFS getstripe -c $f)
26842                 [ $count -eq $OSTCOUNT ] ||
26843                         error "$f stripe count $count != $OSTCOUNT"
26844                 local offset=$($LFS getstripe -i $f)
26845                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26846                 local size=$($LFS getstripe -S $f)
26847                 [ $size -eq $((def_stripe_size * 2)) ] ||
26848                         error "$f stripe size $size != $((def_stripe_size * 2))"
26849                 local pool=$($LFS getstripe -p $f)
26850                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26851         done
26852
26853         # change fs default striping, delete parent default striping, now child
26854         # will stripe from new fs default striping only
26855         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26856                 error "change $MOUNT default stripe failed"
26857         $LFS setstripe -c 0 $DIR/$tdir ||
26858                 error "delete $tdir default stripe failed"
26859         for i in $(seq 11 20); do
26860                 local f=$DIR/$tdir/$tfile.$i
26861                 touch $f || error "touch $f failed"
26862                 local count=$($LFS getstripe -c $f)
26863                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26864                 local offset=$($LFS getstripe -i $f)
26865                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26866                 local size=$($LFS getstripe -S $f)
26867                 [ $size -eq $def_stripe_size ] ||
26868                         error "$f stripe size $size != $def_stripe_size"
26869                 local pool=$($LFS getstripe -p $f)
26870                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26871         done
26872
26873         unlinkmany $DIR/$tdir/$tfile. 1 20
26874
26875         local f=$DIR/$tdir/$tfile
26876         pool_remove_all_targets $test_pool $f
26877         pool_remove $test_pool $f
26878 }
26879 run_test 406 "DNE support fs default striping"
26880
26881 test_407() {
26882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26883         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26884                 skip "Need MDS version at least 2.8.55"
26885         remote_mds_nodsh && skip "remote MDS with nodsh"
26886
26887         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26888                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26889         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26890                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26891         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26892
26893         #define OBD_FAIL_DT_TXN_STOP    0x2019
26894         for idx in $(seq $MDSCOUNT); do
26895                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26896         done
26897         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26898         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26899                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26900         true
26901 }
26902 run_test 407 "transaction fail should cause operation fail"
26903
26904 test_408() {
26905         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26906
26907         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26908         lctl set_param fail_loc=0x8000040a
26909         # let ll_prepare_partial_page() fail
26910         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26911
26912         rm -f $DIR/$tfile
26913
26914         # create at least 100 unused inodes so that
26915         # shrink_icache_memory(0) should not return 0
26916         touch $DIR/$tfile-{0..100}
26917         rm -f $DIR/$tfile-{0..100}
26918         sync
26919
26920         echo 2 > /proc/sys/vm/drop_caches
26921 }
26922 run_test 408 "drop_caches should not hang due to page leaks"
26923
26924 test_409()
26925 {
26926         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26927
26928         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26929         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26930         touch $DIR/$tdir/guard || error "(2) Fail to create"
26931
26932         local PREFIX=$(str_repeat 'A' 128)
26933         echo "Create 1K hard links start at $(date)"
26934         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26935                 error "(3) Fail to hard link"
26936
26937         echo "Links count should be right although linkEA overflow"
26938         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26939         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26940         [ $linkcount -eq 1001 ] ||
26941                 error "(5) Unexpected hard links count: $linkcount"
26942
26943         echo "List all links start at $(date)"
26944         ls -l $DIR/$tdir/foo > /dev/null ||
26945                 error "(6) Fail to list $DIR/$tdir/foo"
26946
26947         echo "Unlink hard links start at $(date)"
26948         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26949                 error "(7) Fail to unlink"
26950         echo "Unlink hard links finished at $(date)"
26951 }
26952 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26953
26954 test_410()
26955 {
26956         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26957                 skip "Need client version at least 2.9.59"
26958         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26959                 skip "Need MODULES build"
26960
26961         # Create a file, and stat it from the kernel
26962         local testfile=$DIR/$tfile
26963         touch $testfile
26964
26965         local run_id=$RANDOM
26966         local my_ino=$(stat --format "%i" $testfile)
26967
26968         # Try to insert the module. This will always fail as the
26969         # module is designed to not be inserted.
26970         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26971             &> /dev/null
26972
26973         # Anything but success is a test failure
26974         dmesg | grep -q \
26975             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26976             error "no inode match"
26977 }
26978 run_test 410 "Test inode number returned from kernel thread"
26979
26980 cleanup_test411_cgroup() {
26981         trap 0
26982         rmdir "$1"
26983 }
26984
26985 test_411() {
26986         local cg_basedir=/sys/fs/cgroup/memory
26987         # LU-9966
26988         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26989                 skip "no setup for cgroup"
26990
26991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26992                 error "test file creation failed"
26993         cancel_lru_locks osc
26994
26995         # Create a very small memory cgroup to force a slab allocation error
26996         local cgdir=$cg_basedir/osc_slab_alloc
26997         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26998         trap "cleanup_test411_cgroup $cgdir" EXIT
26999         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27000         echo 1M > $cgdir/memory.limit_in_bytes
27001
27002         # Should not LBUG, just be killed by oom-killer
27003         # dd will return 0 even allocation failure in some environment.
27004         # So don't check return value
27005         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27006         cleanup_test411_cgroup $cgdir
27007
27008         return 0
27009 }
27010 run_test 411 "Slab allocation error with cgroup does not LBUG"
27011
27012 test_412() {
27013         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27014         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27015                 skip "Need server version at least 2.10.55"
27016
27017         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27018                 error "mkdir failed"
27019         $LFS getdirstripe $DIR/$tdir
27020         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27021         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27022                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27023         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27024         [ $stripe_count -eq 2 ] ||
27025                 error "expect 2 get $stripe_count"
27026
27027         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27028
27029         local index
27030         local index2
27031
27032         # subdirs should be on the same MDT as parent
27033         for i in $(seq 0 $((MDSCOUNT - 1))); do
27034                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27035                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27036                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27037                 (( index == i )) || error "mdt$i/sub on MDT$index"
27038         done
27039
27040         # stripe offset -1, ditto
27041         for i in {1..10}; do
27042                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27043                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27044                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27045                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27046                 (( index == index2 )) ||
27047                         error "qos$i on MDT$index, sub on MDT$index2"
27048         done
27049
27050         local testdir=$DIR/$tdir/inherit
27051
27052         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27053         # inherit 2 levels
27054         for i in 1 2; do
27055                 testdir=$testdir/s$i
27056                 mkdir $testdir || error "mkdir $testdir failed"
27057                 index=$($LFS getstripe -m $testdir)
27058                 (( index == 1 )) ||
27059                         error "$testdir on MDT$index"
27060         done
27061
27062         # not inherit any more
27063         testdir=$testdir/s3
27064         mkdir $testdir || error "mkdir $testdir failed"
27065         getfattr -d -m dmv $testdir | grep dmv &&
27066                 error "default LMV set on $testdir" || true
27067 }
27068 run_test 412 "mkdir on specific MDTs"
27069
27070 TEST413_COUNT=${TEST413_COUNT:-200}
27071
27072 #
27073 # set_maxage() is used by test_413 only.
27074 # This is a helper function to set maxage. Does not return any value.
27075 # Input: maxage to set
27076 #
27077 set_maxage() {
27078         local lmv_qos_maxage
27079         local lod_qos_maxage
27080         local new_maxage=$1
27081
27082         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27083         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27084         stack_trap "$LCTL set_param \
27085                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27086         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27087                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27088         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27089                 lod.*.mdt_qos_maxage=$new_maxage
27090         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27091                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27092 }
27093
27094 generate_uneven_mdts() {
27095         local threshold=$1
27096         local ffree
27097         local bavail
27098         local max
27099         local min
27100         local max_index
27101         local min_index
27102         local tmp
27103         local i
27104
27105         echo
27106         echo "Check for uneven MDTs: "
27107
27108         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27109         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27110         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27111
27112         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27113         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27114         max_index=0
27115         min_index=0
27116         for ((i = 1; i < ${#ffree[@]}; i++)); do
27117                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27118                 if [ $tmp -gt $max ]; then
27119                         max=$tmp
27120                         max_index=$i
27121                 fi
27122                 if [ $tmp -lt $min ]; then
27123                         min=$tmp
27124                         min_index=$i
27125                 fi
27126         done
27127
27128         (( min > 0 )) || skip "low space on MDT$min_index"
27129         (( ${ffree[min_index]} > 0 )) ||
27130                 skip "no free files on MDT$min_index"
27131         (( ${ffree[min_index]} < 10000000 )) ||
27132                 skip "too many free files on MDT$min_index"
27133
27134         # Check if we need to generate uneven MDTs
27135         local diff=$(((max - min) * 100 / min))
27136         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27137         local testdir # individual folder within $testdirp
27138         local start
27139         local cmd
27140
27141         # fallocate is faster to consume space on MDT, if available
27142         if check_fallocate_supported mds$((min_index + 1)); then
27143                 cmd="fallocate -l 128K "
27144         else
27145                 cmd="dd if=/dev/zero bs=128K count=1 of="
27146         fi
27147
27148         echo "using cmd $cmd"
27149         for (( i = 0; diff < threshold; i++ )); do
27150                 testdir=${testdirp}/$i
27151                 [ -d $testdir ] && continue
27152
27153                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27154
27155                 mkdir -p $testdirp
27156                 # generate uneven MDTs, create till $threshold% diff
27157                 echo -n "weight diff=$diff% must be > $threshold% ..."
27158                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27159                 $LFS mkdir -i $min_index $testdir ||
27160                         error "mkdir $testdir failed"
27161                 $LFS setstripe -E 1M -L mdt $testdir ||
27162                         error "setstripe $testdir failed"
27163                 start=$SECONDS
27164                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27165                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27166                 done
27167                 sync; sleep 1; sync
27168
27169                 # wait for QOS to update
27170                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27171
27172                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27173                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27174                 max=$(((${ffree[max_index]} >> 8) *
27175                         (${bavail[max_index]} * bsize >> 16)))
27176                 min=$(((${ffree[min_index]} >> 8) *
27177                         (${bavail[min_index]} * bsize >> 16)))
27178                 (( min > 0 )) || skip "low space on MDT$min_index"
27179                 diff=$(((max - min) * 100 / min))
27180         done
27181
27182         echo "MDT filesfree available: ${ffree[*]}"
27183         echo "MDT blocks available: ${bavail[*]}"
27184         echo "weight diff=$diff%"
27185 }
27186
27187 test_qos_mkdir() {
27188         local mkdir_cmd=$1
27189         local stripe_count=$2
27190         local mdts=$(comma_list $(mdts_nodes))
27191
27192         local testdir
27193         local lmv_qos_prio_free
27194         local lmv_qos_threshold_rr
27195         local lod_qos_prio_free
27196         local lod_qos_threshold_rr
27197         local total
27198         local count
27199         local i
27200
27201         # @total is total directories created if it's testing plain
27202         # directories, otherwise it's total stripe object count for
27203         # striped directories test.
27204         # remote/striped directory unlinking is slow on zfs and may
27205         # timeout, test with fewer directories
27206         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27207
27208         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27209         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27210         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27211                 head -n1)
27212         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27213         stack_trap "$LCTL set_param \
27214                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27215         stack_trap "$LCTL set_param \
27216                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27217
27218         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27219                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27220         lod_qos_prio_free=${lod_qos_prio_free%%%}
27221         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27222                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27223         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27224         stack_trap "do_nodes $mdts $LCTL set_param \
27225                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27226         stack_trap "do_nodes $mdts $LCTL set_param \
27227                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27228
27229         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27230         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27231
27232         testdir=$DIR/$tdir-s$stripe_count/rr
27233
27234         local stripe_index=$($LFS getstripe -m $testdir)
27235         local test_mkdir_rr=true
27236
27237         getfattr -d -m dmv -e hex $testdir | grep dmv
27238         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27239                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27240                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27241                         test_mkdir_rr=false
27242         fi
27243
27244         echo
27245         $test_mkdir_rr &&
27246                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27247                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27248
27249         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27250         for (( i = 0; i < total / stripe_count; i++ )); do
27251                 eval $mkdir_cmd $testdir/subdir$i ||
27252                         error "$mkdir_cmd subdir$i failed"
27253         done
27254
27255         for (( i = 0; i < $MDSCOUNT; i++ )); do
27256                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27257                 echo "$count directories created on MDT$i"
27258                 if $test_mkdir_rr; then
27259                         (( count == total / stripe_count / MDSCOUNT )) ||
27260                                 error "subdirs are not evenly distributed"
27261                 elif (( i == stripe_index )); then
27262                         (( count == total / stripe_count )) ||
27263                                 error "$count subdirs created on MDT$i"
27264                 else
27265                         (( count == 0 )) ||
27266                                 error "$count subdirs created on MDT$i"
27267                 fi
27268
27269                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27270                         count=$($LFS getdirstripe $testdir/* |
27271                                 grep -c -P "^\s+$i\t")
27272                         echo "$count stripes created on MDT$i"
27273                         # deviation should < 5% of average
27274                         delta=$((count - total / MDSCOUNT))
27275                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27276                                 error "stripes are not evenly distributed"
27277                 fi
27278         done
27279
27280         echo
27281         echo "Check for uneven MDTs: "
27282
27283         local ffree
27284         local bavail
27285         local max
27286         local min
27287         local max_index
27288         local min_index
27289         local tmp
27290
27291         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27292         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27293         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27294
27295         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27296         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27297         max_index=0
27298         min_index=0
27299         for ((i = 1; i < ${#ffree[@]}; i++)); do
27300                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27301                 if [ $tmp -gt $max ]; then
27302                         max=$tmp
27303                         max_index=$i
27304                 fi
27305                 if [ $tmp -lt $min ]; then
27306                         min=$tmp
27307                         min_index=$i
27308                 fi
27309         done
27310         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27311
27312         (( min > 0 )) || skip "low space on MDT$min_index"
27313         (( ${ffree[min_index]} < 10000000 )) ||
27314                 skip "too many free files on MDT$min_index"
27315
27316         generate_uneven_mdts 120
27317
27318         echo "MDT filesfree available: ${ffree[*]}"
27319         echo "MDT blocks available: ${bavail[*]}"
27320         echo "weight diff=$(((max - min) * 100 / min))%"
27321         echo
27322         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27323
27324         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27325         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27326         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27327         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27328         # decrease statfs age, so that it can be updated in time
27329         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27330         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27331
27332         sleep 1
27333
27334         testdir=$DIR/$tdir-s$stripe_count/qos
27335
27336         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27337         for (( i = 0; i < total / stripe_count; i++ )); do
27338                 eval $mkdir_cmd $testdir/subdir$i ||
27339                         error "$mkdir_cmd subdir$i failed"
27340         done
27341
27342         max=0
27343         for (( i = 0; i < $MDSCOUNT; i++ )); do
27344                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27345                 (( count > max )) && max=$count
27346                 echo "$count directories created on MDT$i : curmax=$max"
27347         done
27348
27349         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27350
27351         # D-value should > 10% of average
27352         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27353                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27354
27355         # ditto for stripes
27356         if (( stripe_count > 1 )); then
27357                 max=0
27358                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27359                         count=$($LFS getdirstripe $testdir/* |
27360                                 grep -c -P "^\s+$i\t")
27361                         (( count > max )) && max=$count
27362                         echo "$count stripes created on MDT$i"
27363                 done
27364
27365                 min=$($LFS getdirstripe $testdir/* |
27366                         grep -c -P "^\s+$min_index\t")
27367                 (( max - min > total / MDSCOUNT / 10 )) ||
27368                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27369         fi
27370 }
27371
27372 most_full_mdt() {
27373         local ffree
27374         local bavail
27375         local bsize
27376         local min
27377         local min_index
27378         local tmp
27379
27380         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27381         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27382         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27383
27384         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27385         min_index=0
27386         for ((i = 1; i < ${#ffree[@]}; i++)); do
27387                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27388                 (( tmp < min )) && min=$tmp && min_index=$i
27389         done
27390
27391         echo -n $min_index
27392 }
27393
27394 test_413a() {
27395         [ $MDSCOUNT -lt 2 ] &&
27396                 skip "We need at least 2 MDTs for this test"
27397
27398         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27399                 skip "Need server version at least 2.12.52"
27400
27401         local stripe_max=$((MDSCOUNT - 1))
27402         local stripe_count
27403
27404         # let caller set maxage for latest result
27405         set_maxage 1
27406
27407         # fill MDT unevenly
27408         generate_uneven_mdts 120
27409
27410         # test 4-stripe directory at most, otherwise it's too slow
27411         # We are being very defensive. Although Autotest uses 4 MDTs.
27412         # We make sure stripe_max does not go over 4.
27413         (( stripe_max > 4 )) && stripe_max=4
27414         # unlinking striped directory is slow on zfs, and may timeout, only test
27415         # plain directory
27416         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27417         for stripe_count in $(seq 1 $stripe_max); do
27418                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27419                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27420                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27421                         error "mkdir failed"
27422                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27423         done
27424 }
27425 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27426
27427 test_413b() {
27428         [ $MDSCOUNT -lt 2 ] &&
27429                 skip "We need at least 2 MDTs for this test"
27430
27431         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27432                 skip "Need server version at least 2.12.52"
27433
27434         local stripe_max=$((MDSCOUNT - 1))
27435         local testdir
27436         local stripe_count
27437
27438         # let caller set maxage for latest result
27439         set_maxage 1
27440
27441         # fill MDT unevenly
27442         generate_uneven_mdts 120
27443
27444         # test 4-stripe directory at most, otherwise it's too slow
27445         # We are being very defensive. Although Autotest uses 4 MDTs.
27446         # We make sure stripe_max does not go over 4.
27447         (( stripe_max > 4 )) && stripe_max=4
27448         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27449         for stripe_count in $(seq 1 $stripe_max); do
27450                 testdir=$DIR/$tdir-s$stripe_count
27451                 mkdir $testdir || error "mkdir $testdir failed"
27452                 mkdir $testdir/rr || error "mkdir rr failed"
27453                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27454                         error "mkdir qos failed"
27455                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27456                         $testdir/rr || error "setdirstripe rr failed"
27457                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27458                         error "setdirstripe failed"
27459                 test_qos_mkdir "mkdir" $stripe_count
27460         done
27461 }
27462 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27463
27464 test_413c() {
27465         (( $MDSCOUNT >= 2 )) ||
27466                 skip "We need at least 2 MDTs for this test"
27467
27468         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27469                 skip "Need server version at least 2.14.51"
27470
27471         local testdir
27472         local inherit
27473         local inherit_rr
27474         local lmv_qos_maxage
27475         local lod_qos_maxage
27476
27477         # let caller set maxage for latest result
27478         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27479         $LCTL set_param lmv.*.qos_maxage=1
27480         stack_trap "$LCTL set_param \
27481                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27482         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27483                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27484         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27485                 lod.*.mdt_qos_maxage=1
27486         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27487                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27488
27489         # fill MDT unevenly
27490         generate_uneven_mdts 120
27491
27492         testdir=$DIR/${tdir}-s1
27493         mkdir $testdir || error "mkdir $testdir failed"
27494         mkdir $testdir/rr || error "mkdir rr failed"
27495         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27496         # default max_inherit is -1, default max_inherit_rr is 0
27497         $LFS setdirstripe -D -c 1 $testdir/rr ||
27498                 error "setdirstripe rr failed"
27499         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27500                 error "setdirstripe qos failed"
27501         test_qos_mkdir "mkdir" 1
27502
27503         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27504         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27505         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27506         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27507         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27508
27509         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27510         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27511         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27512         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27513         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27514         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27515         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27516                 error "level2 shouldn't have default LMV" || true
27517 }
27518 run_test 413c "mkdir with default LMV max inherit rr"
27519
27520 test_413d() {
27521         (( MDSCOUNT >= 2 )) ||
27522                 skip "We need at least 2 MDTs for this test"
27523
27524         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27525                 skip "Need server version at least 2.14.51"
27526
27527         local lmv_qos_threshold_rr
27528
27529         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27530                 head -n1)
27531         stack_trap "$LCTL set_param \
27532                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27533
27534         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27535         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27536         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27537                 error "$tdir shouldn't have default LMV"
27538         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27539                 error "mkdir sub failed"
27540
27541         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27542
27543         (( count == 100 )) || error "$count subdirs on MDT0"
27544 }
27545 run_test 413d "inherit ROOT default LMV"
27546
27547 test_413e() {
27548         (( MDSCOUNT >= 2 )) ||
27549                 skip "We need at least 2 MDTs for this test"
27550         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27551                 skip "Need server version at least 2.14.55"
27552
27553         local testdir=$DIR/$tdir
27554         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27555         local max_inherit
27556         local sub_max_inherit
27557
27558         mkdir -p $testdir || error "failed to create $testdir"
27559
27560         # set default max-inherit to -1 if stripe count is 0 or 1
27561         $LFS setdirstripe -D -c 1 $testdir ||
27562                 error "failed to set default LMV"
27563         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27564         (( max_inherit == -1 )) ||
27565                 error "wrong max_inherit value $max_inherit"
27566
27567         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27568         $LFS setdirstripe -D -c -1 $testdir ||
27569                 error "failed to set default LMV"
27570         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27571         (( max_inherit > 0 )) ||
27572                 error "wrong max_inherit value $max_inherit"
27573
27574         # and the subdir will decrease the max_inherit by 1
27575         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27576         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27577         (( sub_max_inherit == max_inherit - 1)) ||
27578                 error "wrong max-inherit of subdir $sub_max_inherit"
27579
27580         # check specified --max-inherit and warning message
27581         stack_trap "rm -f $tmpfile"
27582         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27583                 error "failed to set default LMV"
27584         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27585         (( max_inherit == -1 )) ||
27586                 error "wrong max_inherit value $max_inherit"
27587
27588         # check the warning messages
27589         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27590                 error "failed to detect warning string"
27591         fi
27592 }
27593 run_test 413e "check default max-inherit value"
27594
27595 test_fs_dmv_inherit()
27596 {
27597         local testdir=$DIR/$tdir
27598
27599         local count
27600         local inherit
27601         local inherit_rr
27602
27603         for i in 1 2; do
27604                 mkdir $testdir || error "mkdir $testdir failed"
27605                 count=$($LFS getdirstripe -D -c $testdir)
27606                 (( count == 1 )) ||
27607                         error "$testdir default LMV count mismatch $count != 1"
27608                 inherit=$($LFS getdirstripe -D -X $testdir)
27609                 (( inherit == 3 - i )) ||
27610                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27611                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27612                 (( inherit_rr == 3 - i )) ||
27613                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27614                 testdir=$testdir/sub
27615         done
27616
27617         mkdir $testdir || error "mkdir $testdir failed"
27618         count=$($LFS getdirstripe -D -c $testdir)
27619         (( count == 0 )) ||
27620                 error "$testdir default LMV count not zero: $count"
27621 }
27622
27623 test_413f() {
27624         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27625
27626         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27627                 skip "Need server version at least 2.14.55"
27628
27629         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27630                 error "dump $DIR default LMV failed"
27631         stack_trap "setfattr --restore=$TMP/dmv.ea"
27632
27633         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27634                 error "set $DIR default LMV failed"
27635
27636         test_fs_dmv_inherit
27637 }
27638 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27639
27640 test_413g() {
27641         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27642
27643         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27644         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27645                 error "dump $DIR default LMV failed"
27646         stack_trap "setfattr --restore=$TMP/dmv.ea"
27647
27648         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27649                 error "set $DIR default LMV failed"
27650
27651         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27652                 error "mount $MOUNT2 failed"
27653         stack_trap "umount_client $MOUNT2"
27654
27655         local saved_DIR=$DIR
27656
27657         export DIR=$MOUNT2
27658
27659         stack_trap "export DIR=$saved_DIR"
27660
27661         # first check filesystem-wide default LMV inheritance
27662         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27663
27664         # then check subdirs are spread to all MDTs
27665         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27666
27667         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27668
27669         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27670 }
27671 run_test 413g "enforce ROOT default LMV on subdir mount"
27672
27673 test_413h() {
27674         (( MDSCOUNT >= 2 )) ||
27675                 skip "We need at least 2 MDTs for this test"
27676
27677         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27678                 skip "Need server version at least 2.15.50.6"
27679
27680         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27681
27682         stack_trap "$LCTL set_param \
27683                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27684         $LCTL set_param lmv.*.qos_maxage=1
27685
27686         local depth=5
27687         local rr_depth=4
27688         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27689         local count=$((MDSCOUNT * 20))
27690
27691         generate_uneven_mdts 50
27692
27693         mkdir -p $dir || error "mkdir $dir failed"
27694         stack_trap "rm -rf $dir"
27695         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27696                 --max-inherit-rr=$rr_depth $dir
27697
27698         for ((d=0; d < depth + 2; d++)); do
27699                 log "dir=$dir:"
27700                 for ((sub=0; sub < count; sub++)); do
27701                         mkdir $dir/d$sub
27702                 done
27703                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27704                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27705                 # subdirs within $rr_depth should be created round-robin
27706                 if (( d < rr_depth )); then
27707                         (( ${num[0]} != count )) ||
27708                                 error "all objects created on MDT ${num[1]}"
27709                 fi
27710
27711                 dir=$dir/d0
27712         done
27713 }
27714 run_test 413h "don't stick to parent for round-robin dirs"
27715
27716 test_413i() {
27717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27718
27719         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27720                 skip "Need server version at least 2.14.55"
27721
27722         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27723                 error "dump $DIR default LMV failed"
27724         stack_trap "setfattr --restore=$TMP/dmv.ea"
27725
27726         local testdir=$DIR/$tdir
27727         local def_max_rr=1
27728         local def_max=3
27729         local count
27730
27731         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27732                 --max-inherit-rr=$def_max_rr $DIR ||
27733                 error "set $DIR default LMV failed"
27734
27735         for i in $(seq 2 3); do
27736                 def_max=$((def_max - 1))
27737                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27738
27739                 mkdir $testdir
27740                 # RR is decremented and keeps zeroed once exhausted
27741                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27742                 (( count == def_max_rr )) ||
27743                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27744
27745                 # max-inherit is decremented
27746                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27747                 (( count == def_max )) ||
27748                         error_noexit "$testdir: max-inherit $count != $def_max"
27749
27750                 testdir=$testdir/d$i
27751         done
27752
27753         # d3 is the last inherited from ROOT, no inheritance anymore
27754         # i.e. no the default layout anymore
27755         mkdir -p $testdir/d4/d5
27756         count=$($LFS getdirstripe -D --max-inherit $testdir)
27757         (( count == -1 )) ||
27758                 error_noexit "$testdir: max-inherit $count != -1"
27759
27760         local p_count=$($LFS getdirstripe -i $testdir)
27761
27762         for i in $(seq 4 5); do
27763                 testdir=$testdir/d$i
27764
27765                 # the root default layout is not applied once exhausted
27766                 count=$($LFS getdirstripe -i $testdir)
27767                 (( count == p_count )) ||
27768                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27769         done
27770
27771         $LFS setdirstripe -i 0 $DIR/d2
27772         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27773         (( count == -1 )) ||
27774                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27775 }
27776 run_test 413i "check default layout inheritance"
27777
27778 test_413z() {
27779         local pids=""
27780         local subdir
27781         local pid
27782
27783         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27784                 unlinkmany $subdir/f. $TEST413_COUNT &
27785                 pids="$pids $!"
27786         done
27787
27788         for pid in $pids; do
27789                 wait $pid
27790         done
27791
27792         true
27793 }
27794 run_test 413z "413 test cleanup"
27795
27796 test_414() {
27797 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27798         $LCTL set_param fail_loc=0x80000521
27799         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27800         rm -f $DIR/$tfile
27801 }
27802 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27803
27804 test_415() {
27805         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27806         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27807                 skip "Need server version at least 2.11.52"
27808
27809         # LU-11102
27810         local total=500
27811         local max=120
27812
27813         # this test may be slow on ZFS
27814         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27815
27816         # though this test is designed for striped directory, let's test normal
27817         # directory too since lock is always saved as CoS lock.
27818         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27819         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27820         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27821         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27822         wait_delete_completed_mds
27823
27824         # run a loop without concurrent touch to measure rename duration.
27825         # only for test debug/robustness, NOT part of COS functional test.
27826         local start_time=$SECONDS
27827         for ((i = 0; i < total; i++)); do
27828                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27829                         > /dev/null
27830         done
27831         local baseline=$((SECONDS - start_time))
27832         echo "rename $total files without 'touch' took $baseline sec"
27833
27834         (
27835                 while true; do
27836                         touch $DIR/$tdir
27837                 done
27838         ) &
27839         local setattr_pid=$!
27840
27841         # rename files back to original name so unlinkmany works
27842         start_time=$SECONDS
27843         for ((i = 0; i < total; i++)); do
27844                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27845                         > /dev/null
27846         done
27847         local duration=$((SECONDS - start_time))
27848
27849         kill -9 $setattr_pid
27850
27851         echo "rename $total files with 'touch' took $duration sec"
27852         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27853         (( duration <= max )) ||
27854                 error_not_in_vm "rename took $duration > $max sec"
27855 }
27856 run_test 415 "lock revoke is not missing"
27857
27858 test_416() {
27859         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27860                 skip "Need server version at least 2.11.55"
27861
27862         # define OBD_FAIL_OSD_TXN_START    0x19a
27863         do_facet mds1 lctl set_param fail_loc=0x19a
27864
27865         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27866
27867         true
27868 }
27869 run_test 416 "transaction start failure won't cause system hung"
27870
27871 cleanup_417() {
27872         trap 0
27873         do_nodes $(comma_list $(mdts_nodes)) \
27874                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27875         do_nodes $(comma_list $(mdts_nodes)) \
27876                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27877         do_nodes $(comma_list $(mdts_nodes)) \
27878                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27879 }
27880
27881 test_417() {
27882         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27883         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27884                 skip "Need MDS version at least 2.11.56"
27885
27886         trap cleanup_417 RETURN EXIT
27887
27888         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27889         do_nodes $(comma_list $(mdts_nodes)) \
27890                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27891         $LFS migrate -m 0 $DIR/$tdir.1 &&
27892                 error "migrate dir $tdir.1 should fail"
27893
27894         do_nodes $(comma_list $(mdts_nodes)) \
27895                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27896         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27897                 error "create remote dir $tdir.2 should fail"
27898
27899         do_nodes $(comma_list $(mdts_nodes)) \
27900                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27901         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27902                 error "create striped dir $tdir.3 should fail"
27903         true
27904 }
27905 run_test 417 "disable remote dir, striped dir and dir migration"
27906
27907 # Checks that the outputs of df [-i] and lfs df [-i] match
27908 #
27909 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27910 check_lfs_df() {
27911         local dir=$2
27912         local inodes
27913         local df_out
27914         local lfs_df_out
27915         local count
27916         local passed=false
27917
27918         # blocks or inodes
27919         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27920
27921         for count in {1..100}; do
27922                 do_nodes "$CLIENTS" \
27923                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27924                 sync; sleep 0.2
27925
27926                 # read the lines of interest
27927                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27928                         error "df $inodes $dir | tail -n +2 failed"
27929                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27930                         error "lfs df $inodes $dir | grep summary: failed"
27931
27932                 # skip first substrings of each output as they are different
27933                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27934                 # compare the two outputs
27935                 passed=true
27936                 #  skip "available" on MDT until LU-13997 is fixed.
27937                 #for i in {1..5}; do
27938                 for i in 1 2 4 5; do
27939                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27940                 done
27941                 $passed && break
27942         done
27943
27944         if ! $passed; then
27945                 df -P $inodes $dir
27946                 echo
27947                 lfs df $inodes $dir
27948                 error "df and lfs df $1 output mismatch: "      \
27949                       "df ${inodes}: ${df_out[*]}, "            \
27950                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27951         fi
27952 }
27953
27954 test_418() {
27955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27956
27957         local dir=$DIR/$tdir
27958         local numfiles=$((RANDOM % 4096 + 2))
27959         local numblocks=$((RANDOM % 256 + 1))
27960
27961         wait_delete_completed
27962         test_mkdir $dir
27963
27964         # check block output
27965         check_lfs_df blocks $dir
27966         # check inode output
27967         check_lfs_df inodes $dir
27968
27969         # create a single file and retest
27970         echo "Creating a single file and testing"
27971         createmany -o $dir/$tfile- 1 &>/dev/null ||
27972                 error "creating 1 file in $dir failed"
27973         check_lfs_df blocks $dir
27974         check_lfs_df inodes $dir
27975
27976         # create a random number of files
27977         echo "Creating $((numfiles - 1)) files and testing"
27978         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27979                 error "creating $((numfiles - 1)) files in $dir failed"
27980
27981         # write a random number of blocks to the first test file
27982         echo "Writing $numblocks 4K blocks and testing"
27983         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27984                 count=$numblocks &>/dev/null ||
27985                 error "dd to $dir/${tfile}-0 failed"
27986
27987         # retest
27988         check_lfs_df blocks $dir
27989         check_lfs_df inodes $dir
27990
27991         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27992                 error "unlinking $numfiles files in $dir failed"
27993 }
27994 run_test 418 "df and lfs df outputs match"
27995
27996 test_419()
27997 {
27998         local dir=$DIR/$tdir
27999
28000         mkdir -p $dir
28001         touch $dir/file
28002
28003         cancel_lru_locks mdc
28004
28005         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28006         $LCTL set_param fail_loc=0x1410
28007         cat $dir/file
28008         $LCTL set_param fail_loc=0
28009         rm -rf $dir
28010 }
28011 run_test 419 "Verify open file by name doesn't crash kernel"
28012
28013 test_420()
28014 {
28015         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28016                 skip "Need MDS version at least 2.12.53"
28017
28018         local SAVE_UMASK=$(umask)
28019         local dir=$DIR/$tdir
28020         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28021
28022         mkdir -p $dir
28023         umask 0000
28024         mkdir -m03777 $dir/testdir
28025         ls -dn $dir/testdir
28026         # Need to remove trailing '.' when SELinux is enabled
28027         local dirperms=$(ls -dn $dir/testdir |
28028                          awk '{ sub(/\.$/, "", $1); print $1}')
28029         [ $dirperms == "drwxrwsrwt" ] ||
28030                 error "incorrect perms on $dir/testdir"
28031
28032         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28033                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28034         ls -n $dir/testdir/testfile
28035         local fileperms=$(ls -n $dir/testdir/testfile |
28036                           awk '{ sub(/\.$/, "", $1); print $1}')
28037         [ $fileperms == "-rwxr-xr-x" ] ||
28038                 error "incorrect perms on $dir/testdir/testfile"
28039
28040         umask $SAVE_UMASK
28041 }
28042 run_test 420 "clear SGID bit on non-directories for non-members"
28043
28044 test_421a() {
28045         local cnt
28046         local fid1
28047         local fid2
28048
28049         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28050                 skip "Need MDS version at least 2.12.54"
28051
28052         test_mkdir $DIR/$tdir
28053         createmany -o $DIR/$tdir/f 3
28054         cnt=$(ls -1 $DIR/$tdir | wc -l)
28055         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28056
28057         fid1=$(lfs path2fid $DIR/$tdir/f1)
28058         fid2=$(lfs path2fid $DIR/$tdir/f2)
28059         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28060
28061         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28062         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28063
28064         cnt=$(ls -1 $DIR/$tdir | wc -l)
28065         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28066
28067         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28068         createmany -o $DIR/$tdir/f 3
28069         cnt=$(ls -1 $DIR/$tdir | wc -l)
28070         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28071
28072         fid1=$(lfs path2fid $DIR/$tdir/f1)
28073         fid2=$(lfs path2fid $DIR/$tdir/f2)
28074         echo "remove using fsname $FSNAME"
28075         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28076
28077         cnt=$(ls -1 $DIR/$tdir | wc -l)
28078         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28079 }
28080 run_test 421a "simple rm by fid"
28081
28082 test_421b() {
28083         local cnt
28084         local FID1
28085         local FID2
28086
28087         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28088                 skip "Need MDS version at least 2.12.54"
28089
28090         test_mkdir $DIR/$tdir
28091         createmany -o $DIR/$tdir/f 3
28092         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28093         MULTIPID=$!
28094
28095         FID1=$(lfs path2fid $DIR/$tdir/f1)
28096         FID2=$(lfs path2fid $DIR/$tdir/f2)
28097         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28098
28099         kill -USR1 $MULTIPID
28100         wait
28101
28102         cnt=$(ls $DIR/$tdir | wc -l)
28103         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28104 }
28105 run_test 421b "rm by fid on open file"
28106
28107 test_421c() {
28108         local cnt
28109         local FIDS
28110
28111         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28112                 skip "Need MDS version at least 2.12.54"
28113
28114         test_mkdir $DIR/$tdir
28115         createmany -o $DIR/$tdir/f 3
28116         touch $DIR/$tdir/$tfile
28117         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28118         cnt=$(ls -1 $DIR/$tdir | wc -l)
28119         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28120
28121         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28122         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28123
28124         cnt=$(ls $DIR/$tdir | wc -l)
28125         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28126 }
28127 run_test 421c "rm by fid against hardlinked files"
28128
28129 test_421d() {
28130         local cnt
28131         local FIDS
28132
28133         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28134                 skip "Need MDS version at least 2.12.54"
28135
28136         test_mkdir $DIR/$tdir
28137         createmany -o $DIR/$tdir/f 4097
28138         cnt=$(ls -1 $DIR/$tdir | wc -l)
28139         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28140
28141         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28142         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28143
28144         cnt=$(ls $DIR/$tdir | wc -l)
28145         rm -rf $DIR/$tdir
28146         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28147 }
28148 run_test 421d "rmfid en masse"
28149
28150 test_421e() {
28151         local cnt
28152         local FID
28153
28154         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28155         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28156                 skip "Need MDS version at least 2.12.54"
28157
28158         mkdir -p $DIR/$tdir
28159         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28160         createmany -o $DIR/$tdir/striped_dir/f 512
28161         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28162         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28163
28164         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28165                 sed "s/[/][^:]*://g")
28166         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28167
28168         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28169         rm -rf $DIR/$tdir
28170         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28171 }
28172 run_test 421e "rmfid in DNE"
28173
28174 test_421f() {
28175         local cnt
28176         local FID
28177
28178         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28179                 skip "Need MDS version at least 2.12.54"
28180
28181         test_mkdir $DIR/$tdir
28182         touch $DIR/$tdir/f
28183         cnt=$(ls -1 $DIR/$tdir | wc -l)
28184         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28185
28186         FID=$(lfs path2fid $DIR/$tdir/f)
28187         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28188         # rmfid should fail
28189         cnt=$(ls -1 $DIR/$tdir | wc -l)
28190         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28191
28192         chmod a+rw $DIR/$tdir
28193         ls -la $DIR/$tdir
28194         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28195         # rmfid should fail
28196         cnt=$(ls -1 $DIR/$tdir | wc -l)
28197         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28198
28199         rm -f $DIR/$tdir/f
28200         $RUNAS touch $DIR/$tdir/f
28201         FID=$(lfs path2fid $DIR/$tdir/f)
28202         echo "rmfid as root"
28203         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28204         cnt=$(ls -1 $DIR/$tdir | wc -l)
28205         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28206
28207         rm -f $DIR/$tdir/f
28208         $RUNAS touch $DIR/$tdir/f
28209         cnt=$(ls -1 $DIR/$tdir | wc -l)
28210         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28211         FID=$(lfs path2fid $DIR/$tdir/f)
28212         # rmfid w/o user_fid2path mount option should fail
28213         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28214         cnt=$(ls -1 $DIR/$tdir | wc -l)
28215         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28216
28217         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28218         stack_trap "rmdir $tmpdir"
28219         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28220                 error "failed to mount client'"
28221         stack_trap "umount_client $tmpdir"
28222
28223         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28224         # rmfid should succeed
28225         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28226         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28227
28228         # rmfid shouldn't allow to remove files due to dir's permission
28229         chmod a+rwx $tmpdir/$tdir
28230         touch $tmpdir/$tdir/f
28231         ls -la $tmpdir/$tdir
28232         FID=$(lfs path2fid $tmpdir/$tdir/f)
28233         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28234         return 0
28235 }
28236 run_test 421f "rmfid checks permissions"
28237
28238 test_421g() {
28239         local cnt
28240         local FIDS
28241
28242         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28243         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28244                 skip "Need MDS version at least 2.12.54"
28245
28246         mkdir -p $DIR/$tdir
28247         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28248         createmany -o $DIR/$tdir/striped_dir/f 512
28249         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28250         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28251
28252         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28253                 sed "s/[/][^:]*://g")
28254
28255         rm -f $DIR/$tdir/striped_dir/f1*
28256         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28257         removed=$((512 - cnt))
28258
28259         # few files have been just removed, so we expect
28260         # rmfid to fail on their fids
28261         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28262         [ $removed != $errors ] && error "$errors != $removed"
28263
28264         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28265         rm -rf $DIR/$tdir
28266         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28267 }
28268 run_test 421g "rmfid to return errors properly"
28269
28270 test_421h() {
28271         local mount_other
28272         local mount_ret
28273         local rmfid_ret
28274         local old_fid
28275         local fidA
28276         local fidB
28277         local fidC
28278         local fidD
28279
28280         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28281                 skip "Need MDS version at least 2.15.53"
28282
28283         test_mkdir $DIR/$tdir
28284         test_mkdir $DIR/$tdir/subdir
28285         touch $DIR/$tdir/subdir/file0
28286         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28287         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28288         rm -f $DIR/$tdir/subdir/file0
28289         touch $DIR/$tdir/subdir/fileA
28290         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28291         echo File $DIR/$tdir/subdir/fileA FID $fidA
28292         touch $DIR/$tdir/subdir/fileB
28293         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28294         echo File $DIR/$tdir/subdir/fileB FID $fidB
28295         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28296         touch $DIR/$tdir/subdir/fileC
28297         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28298         echo File $DIR/$tdir/subdir/fileC FID $fidC
28299         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28300         touch $DIR/$tdir/fileD
28301         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28302         echo File $DIR/$tdir/fileD FID $fidD
28303
28304         # mount another client mount point with subdirectory mount
28305         export FILESET=/$tdir/subdir
28306         mount_other=${MOUNT}_other
28307         mount_client $mount_other ${MOUNT_OPTS}
28308         mount_ret=$?
28309         export FILESET=""
28310         (( mount_ret == 0 )) || error "mount $mount_other failed"
28311
28312         echo Removing FIDs:
28313         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28314         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28315         rmfid_ret=$?
28316
28317         umount_client $mount_other || error "umount $mount_other failed"
28318
28319         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28320
28321         # fileA should have been deleted
28322         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28323
28324         # fileB should have been deleted
28325         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28326
28327         # fileC should not have been deleted, fid also exists outside of fileset
28328         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28329
28330         # fileD should not have been deleted, it exists outside of fileset
28331         stat $DIR/$tdir/fileD || error "fileD deleted"
28332 }
28333 run_test 421h "rmfid with fileset mount"
28334
28335 test_422() {
28336         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28337         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28338         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28339         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28340         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28341
28342         local amc=$(at_max_get client)
28343         local amo=$(at_max_get mds1)
28344         local timeout=`lctl get_param -n timeout`
28345
28346         at_max_set 0 client
28347         at_max_set 0 mds1
28348
28349 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28350         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28351                         fail_val=$(((2*timeout + 10)*1000))
28352         touch $DIR/$tdir/d3/file &
28353         sleep 2
28354 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28355         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28356                         fail_val=$((2*timeout + 5))
28357         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28358         local pid=$!
28359         sleep 1
28360         kill -9 $pid
28361         sleep $((2 * timeout))
28362         echo kill $pid
28363         kill -9 $pid
28364         lctl mark touch
28365         touch $DIR/$tdir/d2/file3
28366         touch $DIR/$tdir/d2/file4
28367         touch $DIR/$tdir/d2/file5
28368
28369         wait
28370         at_max_set $amc client
28371         at_max_set $amo mds1
28372
28373         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28374         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28375                 error "Watchdog is always throttled"
28376 }
28377 run_test 422 "kill a process with RPC in progress"
28378
28379 stat_test() {
28380     df -h $MOUNT &
28381     df -h $MOUNT &
28382     df -h $MOUNT &
28383     df -h $MOUNT &
28384     df -h $MOUNT &
28385     df -h $MOUNT &
28386 }
28387
28388 test_423() {
28389     local _stats
28390     # ensure statfs cache is expired
28391     sleep 2;
28392
28393     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28394     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28395
28396     return 0
28397 }
28398 run_test 423 "statfs should return a right data"
28399
28400 test_424() {
28401 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28402         $LCTL set_param fail_loc=0x80000522
28403         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28404         rm -f $DIR/$tfile
28405 }
28406 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28407
28408 test_425() {
28409         test_mkdir -c -1 $DIR/$tdir
28410         $LFS setstripe -c -1 $DIR/$tdir
28411
28412         lru_resize_disable "" 100
28413         stack_trap "lru_resize_enable" EXIT
28414
28415         sleep 5
28416
28417         for i in $(seq $((MDSCOUNT * 125))); do
28418                 local t=$DIR/$tdir/$tfile_$i
28419
28420                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28421                         error_noexit "Create file $t"
28422         done
28423         stack_trap "rm -rf $DIR/$tdir" EXIT
28424
28425         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28426                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28427                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28428
28429                 [ $lock_count -le $lru_size ] ||
28430                         error "osc lock count $lock_count > lru size $lru_size"
28431         done
28432
28433         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28434                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28435                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28436
28437                 [ $lock_count -le $lru_size ] ||
28438                         error "mdc lock count $lock_count > lru size $lru_size"
28439         done
28440 }
28441 run_test 425 "lock count should not exceed lru size"
28442
28443 test_426() {
28444         splice-test -r $DIR/$tfile
28445         splice-test -rd $DIR/$tfile
28446         splice-test $DIR/$tfile
28447         splice-test -d $DIR/$tfile
28448 }
28449 run_test 426 "splice test on Lustre"
28450
28451 test_427() {
28452         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28453         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28454                 skip "Need MDS version at least 2.12.4"
28455         local log
28456
28457         mkdir $DIR/$tdir
28458         mkdir $DIR/$tdir/1
28459         mkdir $DIR/$tdir/2
28460         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28461         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28462
28463         $LFS getdirstripe $DIR/$tdir/1/dir
28464
28465         #first setfattr for creating updatelog
28466         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28467
28468 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28469         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28470         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28471         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28472
28473         sleep 2
28474         fail mds2
28475         wait_recovery_complete mds2 $((2*TIMEOUT))
28476
28477         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28478         echo $log | grep "get update log failed" &&
28479                 error "update log corruption is detected" || true
28480 }
28481 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28482
28483 test_428() {
28484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28485         local cache_limit=$CACHE_MAX
28486
28487         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28488         $LCTL set_param -n llite.*.max_cached_mb=64
28489
28490         mkdir $DIR/$tdir
28491         $LFS setstripe -c 1 $DIR/$tdir
28492         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28493         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28494         #test write
28495         for f in $(seq 4); do
28496                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28497         done
28498         wait
28499
28500         cancel_lru_locks osc
28501         # Test read
28502         for f in $(seq 4); do
28503                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28504         done
28505         wait
28506 }
28507 run_test 428 "large block size IO should not hang"
28508
28509 test_429() { # LU-7915 / LU-10948
28510         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28511         local testfile=$DIR/$tfile
28512         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28513         local new_flag=1
28514         local first_rpc
28515         local second_rpc
28516         local third_rpc
28517
28518         $LCTL get_param $ll_opencache_threshold_count ||
28519                 skip "client does not have opencache parameter"
28520
28521         set_opencache $new_flag
28522         stack_trap "restore_opencache"
28523         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28524                 error "enable opencache failed"
28525         touch $testfile
28526         # drop MDC DLM locks
28527         cancel_lru_locks mdc
28528         # clear MDC RPC stats counters
28529         $LCTL set_param $mdc_rpcstats=clear
28530
28531         # According to the current implementation, we need to run 3 times
28532         # open & close file to verify if opencache is enabled correctly.
28533         # 1st, RPCs are sent for lookup/open and open handle is released on
28534         #      close finally.
28535         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28536         #      so open handle won't be released thereafter.
28537         # 3rd, No RPC is sent out.
28538         $MULTIOP $testfile oc || error "multiop failed"
28539         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28540         echo "1st: $first_rpc RPCs in flight"
28541
28542         $MULTIOP $testfile oc || error "multiop failed"
28543         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28544         echo "2nd: $second_rpc RPCs in flight"
28545
28546         $MULTIOP $testfile oc || error "multiop failed"
28547         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28548         echo "3rd: $third_rpc RPCs in flight"
28549
28550         #verify no MDC RPC is sent
28551         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28552 }
28553 run_test 429 "verify if opencache flag on client side does work"
28554
28555 lseek_test_430() {
28556         local offset
28557         local file=$1
28558
28559         # data at [200K, 400K)
28560         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28561                 error "256K->512K dd fails"
28562         # data at [2M, 3M)
28563         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28564                 error "2M->3M dd fails"
28565         # data at [4M, 5M)
28566         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28567                 error "4M->5M dd fails"
28568         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28569         # start at first component hole #1
28570         printf "Seeking hole from 1000 ... "
28571         offset=$(lseek_test -l 1000 $file)
28572         echo $offset
28573         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28574         printf "Seeking data from 1000 ... "
28575         offset=$(lseek_test -d 1000 $file)
28576         echo $offset
28577         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28578
28579         # start at first component data block
28580         printf "Seeking hole from 300000 ... "
28581         offset=$(lseek_test -l 300000 $file)
28582         echo $offset
28583         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28584         printf "Seeking data from 300000 ... "
28585         offset=$(lseek_test -d 300000 $file)
28586         echo $offset
28587         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28588
28589         # start at the first component but beyond end of object size
28590         printf "Seeking hole from 1000000 ... "
28591         offset=$(lseek_test -l 1000000 $file)
28592         echo $offset
28593         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28594         printf "Seeking data from 1000000 ... "
28595         offset=$(lseek_test -d 1000000 $file)
28596         echo $offset
28597         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28598
28599         # start at second component stripe 2 (empty file)
28600         printf "Seeking hole from 1500000 ... "
28601         offset=$(lseek_test -l 1500000 $file)
28602         echo $offset
28603         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28604         printf "Seeking data from 1500000 ... "
28605         offset=$(lseek_test -d 1500000 $file)
28606         echo $offset
28607         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28608
28609         # start at second component stripe 1 (all data)
28610         printf "Seeking hole from 3000000 ... "
28611         offset=$(lseek_test -l 3000000 $file)
28612         echo $offset
28613         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28614         printf "Seeking data from 3000000 ... "
28615         offset=$(lseek_test -d 3000000 $file)
28616         echo $offset
28617         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28618
28619         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28620                 error "2nd dd fails"
28621         echo "Add data block at 640K...1280K"
28622
28623         # start at before new data block, in hole
28624         printf "Seeking hole from 600000 ... "
28625         offset=$(lseek_test -l 600000 $file)
28626         echo $offset
28627         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28628         printf "Seeking data from 600000 ... "
28629         offset=$(lseek_test -d 600000 $file)
28630         echo $offset
28631         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28632
28633         # start at the first component new data block
28634         printf "Seeking hole from 1000000 ... "
28635         offset=$(lseek_test -l 1000000 $file)
28636         echo $offset
28637         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28638         printf "Seeking data from 1000000 ... "
28639         offset=$(lseek_test -d 1000000 $file)
28640         echo $offset
28641         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28642
28643         # start at second component stripe 2, new data
28644         printf "Seeking hole from 1200000 ... "
28645         offset=$(lseek_test -l 1200000 $file)
28646         echo $offset
28647         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28648         printf "Seeking data from 1200000 ... "
28649         offset=$(lseek_test -d 1200000 $file)
28650         echo $offset
28651         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28652
28653         # start beyond file end
28654         printf "Using offset > filesize ... "
28655         lseek_test -l 4000000 $file && error "lseek should fail"
28656         printf "Using offset > filesize ... "
28657         lseek_test -d 4000000 $file && error "lseek should fail"
28658
28659         printf "Done\n\n"
28660 }
28661
28662 test_430a() {
28663         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28664                 skip "MDT does not support SEEK_HOLE"
28665
28666         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28667                 skip "OST does not support SEEK_HOLE"
28668
28669         local file=$DIR/$tdir/$tfile
28670
28671         mkdir -p $DIR/$tdir
28672
28673         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28674         # OST stripe #1 will have continuous data at [1M, 3M)
28675         # OST stripe #2 is empty
28676         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28677         lseek_test_430 $file
28678         rm $file
28679         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28680         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28681         lseek_test_430 $file
28682         rm $file
28683         $LFS setstripe -c2 -S 512K $file
28684         echo "Two stripes, stripe size 512K"
28685         lseek_test_430 $file
28686         rm $file
28687         # FLR with stale mirror
28688         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28689                        -N -c2 -S 1M $file
28690         echo "Mirrored file:"
28691         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28692         echo "Plain 2 stripes 1M"
28693         lseek_test_430 $file
28694         rm $file
28695 }
28696 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28697
28698 test_430b() {
28699         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28700                 skip "OST does not support SEEK_HOLE"
28701
28702         local offset
28703         local file=$DIR/$tdir/$tfile
28704
28705         mkdir -p $DIR/$tdir
28706         # Empty layout lseek should fail
28707         $MCREATE $file
28708         # seek from 0
28709         printf "Seeking hole from 0 ... "
28710         lseek_test -l 0 $file && error "lseek should fail"
28711         printf "Seeking data from 0 ... "
28712         lseek_test -d 0 $file && error "lseek should fail"
28713         rm $file
28714
28715         # 1M-hole file
28716         $LFS setstripe -E 1M -c2 -E eof $file
28717         $TRUNCATE $file 1048576
28718         printf "Seeking hole from 1000000 ... "
28719         offset=$(lseek_test -l 1000000 $file)
28720         echo $offset
28721         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28722         printf "Seeking data from 1000000 ... "
28723         lseek_test -d 1000000 $file && error "lseek should fail"
28724         rm $file
28725
28726         # full component followed by non-inited one
28727         $LFS setstripe -E 1M -c2 -E eof $file
28728         dd if=/dev/urandom of=$file bs=1M count=1
28729         printf "Seeking hole from 1000000 ... "
28730         offset=$(lseek_test -l 1000000 $file)
28731         echo $offset
28732         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28733         printf "Seeking hole from 1048576 ... "
28734         lseek_test -l 1048576 $file && error "lseek should fail"
28735         # init second component and truncate back
28736         echo "123" >> $file
28737         $TRUNCATE $file 1048576
28738         printf "Seeking hole from 1000000 ... "
28739         offset=$(lseek_test -l 1000000 $file)
28740         echo $offset
28741         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28742         printf "Seeking hole from 1048576 ... "
28743         lseek_test -l 1048576 $file && error "lseek should fail"
28744         # boundary checks for big values
28745         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28746         offset=$(lseek_test -d 0 $file.10g)
28747         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28748         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28749         offset=$(lseek_test -d 0 $file.100g)
28750         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28751         return 0
28752 }
28753 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28754
28755 test_430c() {
28756         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28757                 skip "OST does not support SEEK_HOLE"
28758
28759         local file=$DIR/$tdir/$tfile
28760         local start
28761
28762         mkdir -p $DIR/$tdir
28763         stack_trap "rm -f $file $file.tmp"
28764         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28765
28766         # cp version 8.33+ prefers lseek over fiemap
28767         local ver=$(cp --version | awk '{ print $4; exit; }')
28768
28769         echo "cp $ver installed"
28770         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28771                 start=$SECONDS
28772                 time cp -v $file $file.tmp || error "cp $file failed"
28773                 (( SECONDS - start < 5 )) || {
28774                         strace cp $file $file.tmp |&
28775                                 grep -E "open|read|seek|FIEMAP" |
28776                                 grep -A 100 $file
28777                         error "cp: too long runtime $((SECONDS - start))"
28778                 }
28779         else
28780                 echo "cp test skipped due to $ver < 8.33"
28781         fi
28782
28783         # tar version 1.29+ supports SEEK_HOLE/DATA
28784         ver=$(tar --version | awk '{ print $4; exit; }')
28785         echo "tar $ver installed"
28786         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28787                 start=$SECONDS
28788                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28789                 (( SECONDS - start < 5 )) || {
28790                         strace tar cf $file.tmp --sparse $file |&
28791                                 grep -E "open|read|seek|FIEMAP" |
28792                                 grep -A 100 $file
28793                         error "tar: too long runtime $((SECONDS - start))"
28794                 }
28795         else
28796                 echo "tar test skipped due to $ver < 1.29"
28797         fi
28798 }
28799 run_test 430c "lseek: external tools check"
28800
28801 test_431() { # LU-14187
28802         local file=$DIR/$tdir/$tfile
28803
28804         mkdir -p $DIR/$tdir
28805         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28806         dd if=/dev/urandom of=$file bs=4k count=1
28807         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28808         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28809         #define OBD_FAIL_OST_RESTART_IO 0x251
28810         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28811         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28812         cp $file $file.0
28813         cancel_lru_locks
28814         sync_all_data
28815         echo 3 > /proc/sys/vm/drop_caches
28816         diff  $file $file.0 || error "data diff"
28817 }
28818 run_test 431 "Restart transaction for IO"
28819
28820 cleanup_test_432() {
28821         do_facet mgs $LCTL nodemap_activate 0
28822         wait_nm_sync active
28823 }
28824
28825 test_432() {
28826         local tmpdir=$TMP/dir432
28827
28828         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28829                 skip "Need MDS version at least 2.14.52"
28830
28831         stack_trap cleanup_test_432 EXIT
28832         mkdir $DIR/$tdir
28833         mkdir $tmpdir
28834
28835         do_facet mgs $LCTL nodemap_activate 1
28836         wait_nm_sync active
28837         do_facet mgs $LCTL nodemap_modify --name default \
28838                 --property admin --value 1
28839         do_facet mgs $LCTL nodemap_modify --name default \
28840                 --property trusted --value 1
28841         cancel_lru_locks mdc
28842         wait_nm_sync default admin_nodemap
28843         wait_nm_sync default trusted_nodemap
28844
28845         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28846                grep -ci "Operation not permitted") -ne 0 ]; then
28847                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28848         fi
28849 }
28850 run_test 432 "mv dir from outside Lustre"
28851
28852 test_433() {
28853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28854
28855         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28856                 skip "inode cache not supported"
28857
28858         $LCTL set_param llite.*.inode_cache=0
28859         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28860
28861         local count=256
28862         local before
28863         local after
28864
28865         cancel_lru_locks mdc
28866         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28867         createmany -m $DIR/$tdir/f $count
28868         createmany -d $DIR/$tdir/d $count
28869         ls -l $DIR/$tdir > /dev/null
28870         stack_trap "rm -rf $DIR/$tdir"
28871
28872         before=$(num_objects)
28873         cancel_lru_locks mdc
28874         after=$(num_objects)
28875
28876         # sometimes even @before is less than 2 * count
28877         while (( before - after < count )); do
28878                 sleep 1
28879                 after=$(num_objects)
28880                 wait=$((wait + 1))
28881                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28882                 if (( wait > 60 )); then
28883                         error "inode slab grew from $before to $after"
28884                 fi
28885         done
28886
28887         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28888 }
28889 run_test 433 "ldlm lock cancel releases dentries and inodes"
28890
28891 test_434() {
28892         local file
28893         local getxattr_count
28894         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28895         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28896
28897         [[ $(getenforce) == "Disabled" ]] ||
28898                 skip "lsm selinux module have to be disabled for this test"
28899
28900         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28901                 error "fail to create $DIR/$tdir/ on MDT0000"
28902
28903         touch $DIR/$tdir/$tfile-{001..100}
28904
28905         # disable the xattr cache
28906         save_lustre_params client "llite.*.xattr_cache" > $p
28907         lctl set_param llite.*.xattr_cache=0
28908         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28909
28910         # clear clients mdc stats
28911         clear_stats $mdc_stat_param ||
28912                 error "fail to clear stats on mdc MDT0000"
28913
28914         for file in $DIR/$tdir/$tfile-{001..100}; do
28915                 getfattr -n security.selinux $file |&
28916                         grep -q "Operation not supported" ||
28917                         error "getxattr on security.selinux should return EOPNOTSUPP"
28918         done
28919
28920         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28921         (( getxattr_count < 100 )) ||
28922                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28923 }
28924 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28925
28926 test_440() {
28927         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28928                 source $LUSTRE/scripts/bash-completion/lustre
28929         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28930                 source /usr/share/bash-completion/completions/lustre
28931         else
28932                 skip "bash completion scripts not found"
28933         fi
28934
28935         local lctl_completions
28936         local lfs_completions
28937
28938         lctl_completions=$(_lustre_cmds lctl)
28939         if [[ ! $lctl_completions =~ "get_param" ]]; then
28940                 error "lctl bash completion failed"
28941         fi
28942
28943         lfs_completions=$(_lustre_cmds lfs)
28944         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28945                 error "lfs bash completion failed"
28946         fi
28947 }
28948 run_test 440 "bash completion for lfs, lctl"
28949
28950 prep_801() {
28951         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28952         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28953                 skip "Need server version at least 2.9.55"
28954
28955         start_full_debug_logging
28956 }
28957
28958 post_801() {
28959         stop_full_debug_logging
28960 }
28961
28962 barrier_stat() {
28963         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28964                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28965                            awk '/The barrier for/ { print $7 }')
28966                 echo $st
28967         else
28968                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28969                 echo \'$st\'
28970         fi
28971 }
28972
28973 barrier_expired() {
28974         local expired
28975
28976         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28977                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28978                           awk '/will be expired/ { print $7 }')
28979         else
28980                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28981         fi
28982
28983         echo $expired
28984 }
28985
28986 test_801a() {
28987         prep_801
28988
28989         echo "Start barrier_freeze at: $(date)"
28990         #define OBD_FAIL_BARRIER_DELAY          0x2202
28991         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28992         # Do not reduce barrier time - See LU-11873
28993         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28994
28995         sleep 2
28996         local b_status=$(barrier_stat)
28997         echo "Got barrier status at: $(date)"
28998         [ "$b_status" = "'freezing_p1'" ] ||
28999                 error "(1) unexpected barrier status $b_status"
29000
29001         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29002         wait
29003         b_status=$(barrier_stat)
29004         [ "$b_status" = "'frozen'" ] ||
29005                 error "(2) unexpected barrier status $b_status"
29006
29007         local expired=$(barrier_expired)
29008         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29009         sleep $((expired + 3))
29010
29011         b_status=$(barrier_stat)
29012         [ "$b_status" = "'expired'" ] ||
29013                 error "(3) unexpected barrier status $b_status"
29014
29015         # Do not reduce barrier time - See LU-11873
29016         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29017                 error "(4) fail to freeze barrier"
29018
29019         b_status=$(barrier_stat)
29020         [ "$b_status" = "'frozen'" ] ||
29021                 error "(5) unexpected barrier status $b_status"
29022
29023         echo "Start barrier_thaw at: $(date)"
29024         #define OBD_FAIL_BARRIER_DELAY          0x2202
29025         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29026         do_facet mgs $LCTL barrier_thaw $FSNAME &
29027
29028         sleep 2
29029         b_status=$(barrier_stat)
29030         echo "Got barrier status at: $(date)"
29031         [ "$b_status" = "'thawing'" ] ||
29032                 error "(6) unexpected barrier status $b_status"
29033
29034         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29035         wait
29036         b_status=$(barrier_stat)
29037         [ "$b_status" = "'thawed'" ] ||
29038                 error "(7) unexpected barrier status $b_status"
29039
29040         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29041         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29042         do_facet mgs $LCTL barrier_freeze $FSNAME
29043
29044         b_status=$(barrier_stat)
29045         [ "$b_status" = "'failed'" ] ||
29046                 error "(8) unexpected barrier status $b_status"
29047
29048         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29049         do_facet mgs $LCTL barrier_thaw $FSNAME
29050
29051         post_801
29052 }
29053 run_test 801a "write barrier user interfaces and stat machine"
29054
29055 test_801b() {
29056         prep_801
29057
29058         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29059         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29060         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29061         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29062         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29063
29064         cancel_lru_locks mdc
29065
29066         # 180 seconds should be long enough
29067         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29068
29069         local b_status=$(barrier_stat)
29070         [ "$b_status" = "'frozen'" ] ||
29071                 error "(6) unexpected barrier status $b_status"
29072
29073         mkdir $DIR/$tdir/d0/d10 &
29074         mkdir_pid=$!
29075
29076         touch $DIR/$tdir/d1/f13 &
29077         touch_pid=$!
29078
29079         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29080         ln_pid=$!
29081
29082         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29083         mv_pid=$!
29084
29085         rm -f $DIR/$tdir/d4/f12 &
29086         rm_pid=$!
29087
29088         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29089
29090         # To guarantee taht the 'stat' is not blocked
29091         b_status=$(barrier_stat)
29092         [ "$b_status" = "'frozen'" ] ||
29093                 error "(8) unexpected barrier status $b_status"
29094
29095         # let above commands to run at background
29096         sleep 5
29097
29098         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29099         ps -p $touch_pid || error "(10) touch should be blocked"
29100         ps -p $ln_pid || error "(11) link should be blocked"
29101         ps -p $mv_pid || error "(12) rename should be blocked"
29102         ps -p $rm_pid || error "(13) unlink should be blocked"
29103
29104         b_status=$(barrier_stat)
29105         [ "$b_status" = "'frozen'" ] ||
29106                 error "(14) unexpected barrier status $b_status"
29107
29108         do_facet mgs $LCTL barrier_thaw $FSNAME
29109         b_status=$(barrier_stat)
29110         [ "$b_status" = "'thawed'" ] ||
29111                 error "(15) unexpected barrier status $b_status"
29112
29113         wait $mkdir_pid || error "(16) mkdir should succeed"
29114         wait $touch_pid || error "(17) touch should succeed"
29115         wait $ln_pid || error "(18) link should succeed"
29116         wait $mv_pid || error "(19) rename should succeed"
29117         wait $rm_pid || error "(20) unlink should succeed"
29118
29119         post_801
29120 }
29121 run_test 801b "modification will be blocked by write barrier"
29122
29123 test_801c() {
29124         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29125
29126         prep_801
29127
29128         stop mds2 || error "(1) Fail to stop mds2"
29129
29130         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29131
29132         local b_status=$(barrier_stat)
29133         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29134                 do_facet mgs $LCTL barrier_thaw $FSNAME
29135                 error "(2) unexpected barrier status $b_status"
29136         }
29137
29138         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29139                 error "(3) Fail to rescan barrier bitmap"
29140
29141         # Do not reduce barrier time - See LU-11873
29142         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29143
29144         b_status=$(barrier_stat)
29145         [ "$b_status" = "'frozen'" ] ||
29146                 error "(4) unexpected barrier status $b_status"
29147
29148         do_facet mgs $LCTL barrier_thaw $FSNAME
29149         b_status=$(barrier_stat)
29150         [ "$b_status" = "'thawed'" ] ||
29151                 error "(5) unexpected barrier status $b_status"
29152
29153         local devname=$(mdsdevname 2)
29154
29155         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29156
29157         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29158                 error "(7) Fail to rescan barrier bitmap"
29159
29160         post_801
29161 }
29162 run_test 801c "rescan barrier bitmap"
29163
29164 test_802b() {
29165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29166         remote_mds_nodsh && skip "remote MDS with nodsh"
29167
29168         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29169                 skip "readonly option not available"
29170
29171         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29172
29173         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29174                 error "(2) Fail to copy"
29175
29176         # write back all cached data before setting MDT to readonly
29177         cancel_lru_locks
29178         sync_all_data
29179
29180         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29181         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29182
29183         echo "Modify should be refused"
29184         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29185
29186         echo "Read should be allowed"
29187         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29188                 error "(7) Read should succeed under ro mode"
29189
29190         # disable readonly
29191         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29192 }
29193 run_test 802b "be able to set MDTs to readonly"
29194
29195 test_803a() {
29196         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29197         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29198                 skip "MDS needs to be newer than 2.10.54"
29199
29200         mkdir_on_mdt0 $DIR/$tdir
29201         # Create some objects on all MDTs to trigger related logs objects
29202         for idx in $(seq $MDSCOUNT); do
29203                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29204                         $DIR/$tdir/dir${idx} ||
29205                         error "Fail to create $DIR/$tdir/dir${idx}"
29206         done
29207
29208         wait_delete_completed # ensure old test cleanups are finished
29209         sleep 3
29210         echo "before create:"
29211         $LFS df -i $MOUNT
29212         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29213
29214         for i in {1..10}; do
29215                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29216                         error "Fail to create $DIR/$tdir/foo$i"
29217         done
29218
29219         # sync ZFS-on-MDS to refresh statfs data
29220         wait_zfs_commit mds1
29221         sleep 3
29222         echo "after create:"
29223         $LFS df -i $MOUNT
29224         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29225
29226         # allow for an llog to be cleaned up during the test
29227         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29228                 error "before ($before_used) + 10 > after ($after_used)"
29229
29230         for i in {1..10}; do
29231                 rm -rf $DIR/$tdir/foo$i ||
29232                         error "Fail to remove $DIR/$tdir/foo$i"
29233         done
29234
29235         # sync ZFS-on-MDS to refresh statfs data
29236         wait_zfs_commit mds1
29237         wait_delete_completed
29238         sleep 3 # avoid MDT return cached statfs
29239         echo "after unlink:"
29240         $LFS df -i $MOUNT
29241         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29242
29243         # allow for an llog to be created during the test
29244         [ $after_used -le $((before_used + 1)) ] ||
29245                 error "after ($after_used) > before ($before_used) + 1"
29246 }
29247 run_test 803a "verify agent object for remote object"
29248
29249 test_803b() {
29250         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29251         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29252                 skip "MDS needs to be newer than 2.13.56"
29253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29254
29255         for i in $(seq 0 $((MDSCOUNT - 1))); do
29256                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29257         done
29258
29259         local before=0
29260         local after=0
29261
29262         local tmp
29263
29264         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29265         for i in $(seq 0 $((MDSCOUNT - 1))); do
29266                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29267                         awk '/getattr/ { print $2 }')
29268                 before=$((before + tmp))
29269         done
29270         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29271         for i in $(seq 0 $((MDSCOUNT - 1))); do
29272                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29273                         awk '/getattr/ { print $2 }')
29274                 after=$((after + tmp))
29275         done
29276
29277         [ $before -eq $after ] || error "getattr count $before != $after"
29278 }
29279 run_test 803b "remote object can getattr from cache"
29280
29281 test_804() {
29282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29283         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29284                 skip "MDS needs to be newer than 2.10.54"
29285         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29286
29287         mkdir -p $DIR/$tdir
29288         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29289                 error "Fail to create $DIR/$tdir/dir0"
29290
29291         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29292         local dev=$(mdsdevname 2)
29293
29294         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29295                 grep ${fid} || error "NOT found agent entry for dir0"
29296
29297         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29298                 error "Fail to create $DIR/$tdir/dir1"
29299
29300         touch $DIR/$tdir/dir1/foo0 ||
29301                 error "Fail to create $DIR/$tdir/dir1/foo0"
29302         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29303         local rc=0
29304
29305         for idx in $(seq $MDSCOUNT); do
29306                 dev=$(mdsdevname $idx)
29307                 do_facet mds${idx} \
29308                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29309                         grep ${fid} && rc=$idx
29310         done
29311
29312         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29313                 error "Fail to rename foo0 to foo1"
29314         if [ $rc -eq 0 ]; then
29315                 for idx in $(seq $MDSCOUNT); do
29316                         dev=$(mdsdevname $idx)
29317                         do_facet mds${idx} \
29318                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29319                         grep ${fid} && rc=$idx
29320                 done
29321         fi
29322
29323         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29324                 error "Fail to rename foo1 to foo2"
29325         if [ $rc -eq 0 ]; then
29326                 for idx in $(seq $MDSCOUNT); do
29327                         dev=$(mdsdevname $idx)
29328                         do_facet mds${idx} \
29329                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29330                         grep ${fid} && rc=$idx
29331                 done
29332         fi
29333
29334         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29335
29336         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29337                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29338         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29339                 error "Fail to rename foo2 to foo0"
29340         unlink $DIR/$tdir/dir1/foo0 ||
29341                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29342         rm -rf $DIR/$tdir/dir0 ||
29343                 error "Fail to rm $DIR/$tdir/dir0"
29344
29345         for idx in $(seq $MDSCOUNT); do
29346                 rc=0
29347
29348                 stop mds${idx}
29349                 dev=$(mdsdevname $idx)
29350                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29351                         rc=$?
29352                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29353                         error "mount mds$idx failed"
29354                 df $MOUNT > /dev/null 2>&1
29355
29356                 # e2fsck should not return error
29357                 [ $rc -eq 0 ] ||
29358                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29359         done
29360 }
29361 run_test 804 "verify agent entry for remote entry"
29362
29363 cleanup_805() {
29364         do_facet $SINGLEMDS zfs set quota=$old $fsset
29365         unlinkmany $DIR/$tdir/f- 1000000
29366         trap 0
29367 }
29368
29369 test_805() {
29370         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29371         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29372         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29373                 skip "netfree not implemented before 0.7"
29374         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29375                 skip "Need MDS version at least 2.10.57"
29376
29377         local fsset
29378         local freekb
29379         local usedkb
29380         local old
29381         local quota
29382         local pref="osd-zfs.$FSNAME-MDT0000."
29383
29384         # limit available space on MDS dataset to meet nospace issue
29385         # quickly. then ZFS 0.7.2 can use reserved space if asked
29386         # properly (using netfree flag in osd_declare_destroy()
29387         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29388         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29389                 gawk '{print $3}')
29390         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29391         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29392         let "usedkb=usedkb-freekb"
29393         let "freekb=freekb/2"
29394         if let "freekb > 5000"; then
29395                 let "freekb=5000"
29396         fi
29397         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29398         trap cleanup_805 EXIT
29399         mkdir_on_mdt0 $DIR/$tdir
29400         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29401                 error "Can't set PFL layout"
29402         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29403         rm -rf $DIR/$tdir || error "not able to remove"
29404         do_facet $SINGLEMDS zfs set quota=$old $fsset
29405         trap 0
29406 }
29407 run_test 805 "ZFS can remove from full fs"
29408
29409 # Size-on-MDS test
29410 check_lsom_data()
29411 {
29412         local file=$1
29413         local expect=$(stat -c %s $file)
29414
29415         check_lsom_size $1 $expect
29416
29417         local blocks=$($LFS getsom -b $file)
29418         expect=$(stat -c %b $file)
29419         [[ $blocks == $expect ]] ||
29420                 error "$file expected blocks: $expect, got: $blocks"
29421 }
29422
29423 check_lsom_size()
29424 {
29425         local size
29426         local expect=$2
29427
29428         cancel_lru_locks mdc
29429
29430         size=$($LFS getsom -s $1)
29431         [[ $size == $expect ]] ||
29432                 error "$file expected size: $expect, got: $size"
29433 }
29434
29435 test_806() {
29436         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29437                 skip "Need MDS version at least 2.11.52"
29438
29439         local bs=1048576
29440
29441         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29442
29443         disable_opencache
29444         stack_trap "restore_opencache"
29445
29446         # single-threaded write
29447         echo "Test SOM for single-threaded write"
29448         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29449                 error "write $tfile failed"
29450         check_lsom_size $DIR/$tfile $bs
29451
29452         local num=32
29453         local size=$(($num * $bs))
29454         local offset=0
29455         local i
29456
29457         echo "Test SOM for single client multi-threaded($num) write"
29458         $TRUNCATE $DIR/$tfile 0
29459         for ((i = 0; i < $num; i++)); do
29460                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29461                 local pids[$i]=$!
29462                 offset=$((offset + $bs))
29463         done
29464         for (( i=0; i < $num; i++ )); do
29465                 wait ${pids[$i]}
29466         done
29467         check_lsom_size $DIR/$tfile $size
29468
29469         $TRUNCATE $DIR/$tfile 0
29470         for ((i = 0; i < $num; i++)); do
29471                 offset=$((offset - $bs))
29472                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29473                 local pids[$i]=$!
29474         done
29475         for (( i=0; i < $num; i++ )); do
29476                 wait ${pids[$i]}
29477         done
29478         check_lsom_size $DIR/$tfile $size
29479
29480         # multi-client writes
29481         num=$(get_node_count ${CLIENTS//,/ })
29482         size=$(($num * $bs))
29483         offset=0
29484         i=0
29485
29486         echo "Test SOM for multi-client ($num) writes"
29487         $TRUNCATE $DIR/$tfile 0
29488         for client in ${CLIENTS//,/ }; do
29489                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29490                 local pids[$i]=$!
29491                 i=$((i + 1))
29492                 offset=$((offset + $bs))
29493         done
29494         for (( i=0; i < $num; i++ )); do
29495                 wait ${pids[$i]}
29496         done
29497         check_lsom_size $DIR/$tfile $offset
29498
29499         i=0
29500         $TRUNCATE $DIR/$tfile 0
29501         for client in ${CLIENTS//,/ }; do
29502                 offset=$((offset - $bs))
29503                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29504                 local pids[$i]=$!
29505                 i=$((i + 1))
29506         done
29507         for (( i=0; i < $num; i++ )); do
29508                 wait ${pids[$i]}
29509         done
29510         check_lsom_size $DIR/$tfile $size
29511
29512         # verify SOM blocks count
29513         echo "Verify SOM block count"
29514         $TRUNCATE $DIR/$tfile 0
29515         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29516                 error "failed to write file $tfile with fdatasync and fstat"
29517         check_lsom_data $DIR/$tfile
29518
29519         $TRUNCATE $DIR/$tfile 0
29520         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29521                 error "failed to write file $tfile with fdatasync"
29522         check_lsom_data $DIR/$tfile
29523
29524         $TRUNCATE $DIR/$tfile 0
29525         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29526                 error "failed to write file $tfile with sync IO"
29527         check_lsom_data $DIR/$tfile
29528
29529         # verify truncate
29530         echo "Test SOM for truncate"
29531         # use ftruncate to sync blocks on close request
29532         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29533         check_lsom_size $DIR/$tfile 16384
29534         check_lsom_data $DIR/$tfile
29535
29536         $TRUNCATE $DIR/$tfile 1234
29537         check_lsom_size $DIR/$tfile 1234
29538         # sync blocks on the MDT
29539         $MULTIOP $DIR/$tfile oc
29540         check_lsom_data $DIR/$tfile
29541 }
29542 run_test 806 "Verify Lazy Size on MDS"
29543
29544 test_807() {
29545         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29546         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29547                 skip "Need MDS version at least 2.11.52"
29548
29549         # Registration step
29550         changelog_register || error "changelog_register failed"
29551         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29552         changelog_users $SINGLEMDS | grep -q $cl_user ||
29553                 error "User $cl_user not found in changelog_users"
29554
29555         rm -rf $DIR/$tdir || error "rm $tdir failed"
29556         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29557         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29558         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29559         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29560                 error "truncate $tdir/trunc failed"
29561
29562         local bs=1048576
29563         echo "Test SOM for single-threaded write with fsync"
29564         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29565                 error "write $tfile failed"
29566         sync;sync;sync
29567
29568         # multi-client wirtes
29569         local num=$(get_node_count ${CLIENTS//,/ })
29570         local offset=0
29571         local i=0
29572
29573         echo "Test SOM for multi-client ($num) writes"
29574         touch $DIR/$tfile || error "touch $tfile failed"
29575         $TRUNCATE $DIR/$tfile 0
29576         for client in ${CLIENTS//,/ }; do
29577                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29578                 local pids[$i]=$!
29579                 i=$((i + 1))
29580                 offset=$((offset + $bs))
29581         done
29582         for (( i=0; i < $num; i++ )); do
29583                 wait ${pids[$i]}
29584         done
29585
29586         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29587         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29588         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29589         check_lsom_data $DIR/$tdir/trunc
29590         check_lsom_data $DIR/$tdir/single_dd
29591         check_lsom_data $DIR/$tfile
29592
29593         rm -rf $DIR/$tdir
29594         # Deregistration step
29595         changelog_deregister || error "changelog_deregister failed"
29596 }
29597 run_test 807 "verify LSOM syncing tool"
29598
29599 check_som_nologged()
29600 {
29601         local lines=$($LFS changelog $FSNAME-MDT0000 |
29602                 grep 'x=trusted.som' | wc -l)
29603         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29604 }
29605
29606 test_808() {
29607         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29608                 skip "Need MDS version at least 2.11.55"
29609
29610         # Registration step
29611         changelog_register || error "changelog_register failed"
29612
29613         touch $DIR/$tfile || error "touch $tfile failed"
29614         check_som_nologged
29615
29616         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29617                 error "write $tfile failed"
29618         check_som_nologged
29619
29620         $TRUNCATE $DIR/$tfile 1234
29621         check_som_nologged
29622
29623         $TRUNCATE $DIR/$tfile 1048576
29624         check_som_nologged
29625
29626         # Deregistration step
29627         changelog_deregister || error "changelog_deregister failed"
29628 }
29629 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29630
29631 check_som_nodata()
29632 {
29633         $LFS getsom $1
29634         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29635 }
29636
29637 test_809() {
29638         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29639                 skip "Need MDS version at least 2.11.56"
29640
29641         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29642                 error "failed to create DoM-only file $DIR/$tfile"
29643         touch $DIR/$tfile || error "touch $tfile failed"
29644         check_som_nodata $DIR/$tfile
29645
29646         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29647                 error "write $tfile failed"
29648         check_som_nodata $DIR/$tfile
29649
29650         $TRUNCATE $DIR/$tfile 1234
29651         check_som_nodata $DIR/$tfile
29652
29653         $TRUNCATE $DIR/$tfile 4097
29654         check_som_nodata $DIR/$file
29655 }
29656 run_test 809 "Verify no SOM xattr store for DoM-only files"
29657
29658 test_810() {
29659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29660         $GSS && skip_env "could not run with gss"
29661         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29662                 skip "OST < 2.12.58 doesn't align checksum"
29663
29664         set_checksums 1
29665         stack_trap "set_checksums $ORIG_CSUM" EXIT
29666         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29667
29668         local csum
29669         local before
29670         local after
29671         for csum in $CKSUM_TYPES; do
29672                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29673                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29674                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29675                         eval set -- $i
29676                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29677                         before=$(md5sum $DIR/$tfile)
29678                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29679                         after=$(md5sum $DIR/$tfile)
29680                         [ "$before" == "$after" ] ||
29681                                 error "$csum: $before != $after bs=$1 seek=$2"
29682                 done
29683         done
29684 }
29685 run_test 810 "partial page writes on ZFS (LU-11663)"
29686
29687 test_812a() {
29688         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29689                 skip "OST < 2.12.51 doesn't support this fail_loc"
29690
29691         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29692         # ensure ost1 is connected
29693         stat $DIR/$tfile >/dev/null || error "can't stat"
29694         wait_osc_import_state client ost1 FULL
29695         # no locks, no reqs to let the connection idle
29696         cancel_lru_locks osc
29697
29698         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29699 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29700         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29701         wait_osc_import_state client ost1 CONNECTING
29702         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29703
29704         stat $DIR/$tfile >/dev/null || error "can't stat file"
29705 }
29706 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29707
29708 test_812b() { # LU-12378
29709         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29710                 skip "OST < 2.12.51 doesn't support this fail_loc"
29711
29712         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29713         # ensure ost1 is connected
29714         stat $DIR/$tfile >/dev/null || error "can't stat"
29715         wait_osc_import_state client ost1 FULL
29716         # no locks, no reqs to let the connection idle
29717         cancel_lru_locks osc
29718
29719         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29720 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29721         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29722         wait_osc_import_state client ost1 CONNECTING
29723         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29724
29725         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29726         wait_osc_import_state client ost1 IDLE
29727 }
29728 run_test 812b "do not drop no resend request for idle connect"
29729
29730 test_812c() {
29731         local old
29732
29733         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29734
29735         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29736         $LFS getstripe $DIR/$tfile
29737         $LCTL set_param osc.*.idle_timeout=10
29738         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29739         # ensure ost1 is connected
29740         stat $DIR/$tfile >/dev/null || error "can't stat"
29741         wait_osc_import_state client ost1 FULL
29742         # no locks, no reqs to let the connection idle
29743         cancel_lru_locks osc
29744
29745 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29746         $LCTL set_param fail_loc=0x80000533
29747         sleep 15
29748         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29749 }
29750 run_test 812c "idle import vs lock enqueue race"
29751
29752 test_813() {
29753         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29754         [ -z "$file_heat_sav" ] && skip "no file heat support"
29755
29756         local readsample
29757         local writesample
29758         local readbyte
29759         local writebyte
29760         local readsample1
29761         local writesample1
29762         local readbyte1
29763         local writebyte1
29764
29765         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29766         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29767
29768         $LCTL set_param -n llite.*.file_heat=1
29769         echo "Turn on file heat"
29770         echo "Period second: $period_second, Decay percentage: $decay_pct"
29771
29772         echo "QQQQ" > $DIR/$tfile
29773         echo "QQQQ" > $DIR/$tfile
29774         echo "QQQQ" > $DIR/$tfile
29775         cat $DIR/$tfile > /dev/null
29776         cat $DIR/$tfile > /dev/null
29777         cat $DIR/$tfile > /dev/null
29778         cat $DIR/$tfile > /dev/null
29779
29780         local out=$($LFS heat_get $DIR/$tfile)
29781
29782         $LFS heat_get $DIR/$tfile
29783         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29784         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29785         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29786         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29787
29788         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29789         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29790         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29791         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29792
29793         sleep $((period_second + 3))
29794         echo "Sleep $((period_second + 3)) seconds..."
29795         # The recursion formula to calculate the heat of the file f is as
29796         # follow:
29797         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29798         # Where Hi is the heat value in the period between time points i*I and
29799         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29800         # to the weight of Ci.
29801         out=$($LFS heat_get $DIR/$tfile)
29802         $LFS heat_get $DIR/$tfile
29803         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29804         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29805         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29806         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29807
29808         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29809                 error "read sample ($readsample) is wrong"
29810         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29811                 error "write sample ($writesample) is wrong"
29812         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29813                 error "read bytes ($readbyte) is wrong"
29814         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29815                 error "write bytes ($writebyte) is wrong"
29816
29817         echo "QQQQ" > $DIR/$tfile
29818         echo "QQQQ" > $DIR/$tfile
29819         echo "QQQQ" > $DIR/$tfile
29820         cat $DIR/$tfile > /dev/null
29821         cat $DIR/$tfile > /dev/null
29822         cat $DIR/$tfile > /dev/null
29823         cat $DIR/$tfile > /dev/null
29824
29825         sleep $((period_second + 3))
29826         echo "Sleep $((period_second + 3)) seconds..."
29827
29828         out=$($LFS heat_get $DIR/$tfile)
29829         $LFS heat_get $DIR/$tfile
29830         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29831         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29832         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29833         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29834
29835         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29836                 4 * $decay_pct) / 100") -eq 1 ] ||
29837                 error "read sample ($readsample1) is wrong"
29838         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29839                 3 * $decay_pct) / 100") -eq 1 ] ||
29840                 error "write sample ($writesample1) is wrong"
29841         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29842                 20 * $decay_pct) / 100") -eq 1 ] ||
29843                 error "read bytes ($readbyte1) is wrong"
29844         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29845                 15 * $decay_pct) / 100") -eq 1 ] ||
29846                 error "write bytes ($writebyte1) is wrong"
29847
29848         echo "Turn off file heat for the file $DIR/$tfile"
29849         $LFS heat_set -o $DIR/$tfile
29850
29851         echo "QQQQ" > $DIR/$tfile
29852         echo "QQQQ" > $DIR/$tfile
29853         echo "QQQQ" > $DIR/$tfile
29854         cat $DIR/$tfile > /dev/null
29855         cat $DIR/$tfile > /dev/null
29856         cat $DIR/$tfile > /dev/null
29857         cat $DIR/$tfile > /dev/null
29858
29859         out=$($LFS heat_get $DIR/$tfile)
29860         $LFS heat_get $DIR/$tfile
29861         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29862         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29863         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29864         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29865
29866         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29867         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29868         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29869         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29870
29871         echo "Trun on file heat for the file $DIR/$tfile"
29872         $LFS heat_set -O $DIR/$tfile
29873
29874         echo "QQQQ" > $DIR/$tfile
29875         echo "QQQQ" > $DIR/$tfile
29876         echo "QQQQ" > $DIR/$tfile
29877         cat $DIR/$tfile > /dev/null
29878         cat $DIR/$tfile > /dev/null
29879         cat $DIR/$tfile > /dev/null
29880         cat $DIR/$tfile > /dev/null
29881
29882         out=$($LFS heat_get $DIR/$tfile)
29883         $LFS heat_get $DIR/$tfile
29884         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29885         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29886         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29887         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29888
29889         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29890         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29891         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29892         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29893
29894         $LFS heat_set -c $DIR/$tfile
29895         $LCTL set_param -n llite.*.file_heat=0
29896         echo "Turn off file heat support for the Lustre filesystem"
29897
29898         echo "QQQQ" > $DIR/$tfile
29899         echo "QQQQ" > $DIR/$tfile
29900         echo "QQQQ" > $DIR/$tfile
29901         cat $DIR/$tfile > /dev/null
29902         cat $DIR/$tfile > /dev/null
29903         cat $DIR/$tfile > /dev/null
29904         cat $DIR/$tfile > /dev/null
29905
29906         out=$($LFS heat_get $DIR/$tfile)
29907         $LFS heat_get $DIR/$tfile
29908         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29909         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29910         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29911         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29912
29913         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29914         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29915         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29916         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29917
29918         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29919         rm -f $DIR/$tfile
29920 }
29921 run_test 813 "File heat verfication"
29922
29923 test_814()
29924 {
29925         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29926         echo -n y >> $DIR/$tfile
29927         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29928         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29929 }
29930 run_test 814 "sparse cp works as expected (LU-12361)"
29931
29932 test_815()
29933 {
29934         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29935         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29936 }
29937 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29938
29939 test_816() {
29940         local ost1_imp=$(get_osc_import_name client ost1)
29941         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29942                          cut -d'.' -f2)
29943
29944         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29945         # ensure ost1 is connected
29946
29947         stat $DIR/$tfile >/dev/null || error "can't stat"
29948         wait_osc_import_state client ost1 FULL
29949         # no locks, no reqs to let the connection idle
29950         cancel_lru_locks osc
29951         lru_resize_disable osc
29952         local before
29953         local now
29954         before=$($LCTL get_param -n \
29955                  ldlm.namespaces.$imp_name.lru_size)
29956
29957         wait_osc_import_state client ost1 IDLE
29958         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29959         now=$($LCTL get_param -n \
29960               ldlm.namespaces.$imp_name.lru_size)
29961         [ $before == $now ] || error "lru_size changed $before != $now"
29962 }
29963 run_test 816 "do not reset lru_resize on idle reconnect"
29964
29965 cleanup_817() {
29966         umount $tmpdir
29967         exportfs -u localhost:$DIR/nfsexp
29968         rm -rf $DIR/nfsexp
29969 }
29970
29971 test_817() {
29972         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29973
29974         mkdir -p $DIR/nfsexp
29975         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29976                 error "failed to export nfs"
29977
29978         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29979         stack_trap cleanup_817 EXIT
29980
29981         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29982                 error "failed to mount nfs to $tmpdir"
29983
29984         cp /bin/true $tmpdir
29985         $DIR/nfsexp/true || error "failed to execute 'true' command"
29986 }
29987 run_test 817 "nfsd won't cache write lock for exec file"
29988
29989 test_818() {
29990         test_mkdir -i0 -c1 $DIR/$tdir
29991         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29992         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29993         stop $SINGLEMDS
29994
29995         # restore osp-syn threads
29996         stack_trap "fail $SINGLEMDS"
29997
29998         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29999         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30000         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30001                 error "start $SINGLEMDS failed"
30002         rm -rf $DIR/$tdir
30003
30004         local testid=$(echo $TESTNAME | tr '_' ' ')
30005
30006         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30007                 grep "run LFSCK" || error "run LFSCK is not suggested"
30008 }
30009 run_test 818 "unlink with failed llog"
30010
30011 test_819a() {
30012         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30013         cancel_lru_locks osc
30014         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30015         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30016         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30017         rm -f $TDIR/$tfile
30018 }
30019 run_test 819a "too big niobuf in read"
30020
30021 test_819b() {
30022         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30023         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30024         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30025         cancel_lru_locks osc
30026         sleep 1
30027         rm -f $TDIR/$tfile
30028 }
30029 run_test 819b "too big niobuf in write"
30030
30031
30032 function test_820_start_ost() {
30033         sleep 5
30034
30035         for num in $(seq $OSTCOUNT); do
30036                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30037         done
30038 }
30039
30040 test_820() {
30041         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30042
30043         mkdir $DIR/$tdir
30044         umount_client $MOUNT || error "umount failed"
30045         for num in $(seq $OSTCOUNT); do
30046                 stop ost$num
30047         done
30048
30049         # mount client with no active OSTs
30050         # so that the client can't initialize max LOV EA size
30051         # from OSC notifications
30052         mount_client $MOUNT || error "mount failed"
30053         # delay OST starting to keep this 0 max EA size for a while
30054         test_820_start_ost &
30055
30056         # create a directory on MDS2
30057         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30058                 error "Failed to create directory"
30059         # open intent should update default EA size
30060         # see mdc_update_max_ea_from_body()
30061         # notice this is the very first RPC to MDS2
30062         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30063         ret=$?
30064         echo $out
30065         # With SSK, this situation can lead to -EPERM being returned.
30066         # In that case, simply retry.
30067         if [ $ret -ne 0 ] && $SHARED_KEY; then
30068                 if echo "$out" | grep -q "not permitted"; then
30069                         cp /etc/services $DIR/$tdir/mds2
30070                         ret=$?
30071                 fi
30072         fi
30073         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30074 }
30075 run_test 820 "update max EA from open intent"
30076
30077 test_823() {
30078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30079         local OST_MAX_PRECREATE=20000
30080
30081         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30082                 skip "Need MDS version at least 2.14.56"
30083
30084         save_lustre_params mds1 \
30085                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30086         do_facet $SINGLEMDS "$LCTL set_param -n \
30087                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30088         do_facet $SINGLEMDS "$LCTL set_param -n \
30089                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30090
30091         stack_trap "restore_lustre_params < $p; rm $p"
30092
30093         do_facet $SINGLEMDS "$LCTL set_param -n \
30094                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30095
30096         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30097                       osp.$FSNAME-OST0000*MDT0000.create_count")
30098         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30099                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30100         local expect_count=$(((($max/2)/256) * 256))
30101
30102         log "setting create_count to 100200:"
30103         log " -result- count: $count with max: $max, expecting: $expect_count"
30104
30105         [[ $count -eq expect_count ]] ||
30106                 error "Create count not set to max precreate."
30107 }
30108 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30109
30110 test_831() {
30111         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30112                 skip "Need MDS version 2.14.56"
30113
30114         local sync_changes=$(do_facet $SINGLEMDS \
30115                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30116
30117         [ "$sync_changes" -gt 100 ] &&
30118                 skip "Sync changes $sync_changes > 100 already"
30119
30120         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30121
30122         $LFS mkdir -i 0 $DIR/$tdir
30123         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30124
30125         save_lustre_params mds1 \
30126                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30127         save_lustre_params mds1 \
30128                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30129
30130         do_facet mds1 "$LCTL set_param -n \
30131                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30132                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30133         stack_trap "restore_lustre_params < $p" EXIT
30134
30135         createmany -o $DIR/$tdir/f- 1000
30136         unlinkmany $DIR/$tdir/f- 1000 &
30137         local UNLINK_PID=$!
30138
30139         while sleep 1; do
30140                 sync_changes=$(do_facet mds1 \
30141                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30142                 # the check in the code is racy, fail the test
30143                 # if the value above the limit by 10.
30144                 [ $sync_changes -gt 110 ] && {
30145                         kill -2 $UNLINK_PID
30146                         wait
30147                         error "osp changes throttling failed, $sync_changes>110"
30148                 }
30149                 kill -0 $UNLINK_PID 2> /dev/null || break
30150         done
30151         wait
30152 }
30153 run_test 831 "throttling unlink/setattr queuing on OSP"
30154
30155 test_832() {
30156         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30157         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30158                 skip "Need MDS version 2.15.52+"
30159         is_rmentry_supported || skip "rm_entry not supported"
30160
30161         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30162         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30163         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30164                 error "mkdir remote_dir failed"
30165         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30166                 error "mkdir striped_dir failed"
30167         touch $DIR/$tdir/file || error "touch file failed"
30168         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30169         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30170 }
30171 run_test 832 "lfs rm_entry"
30172
30173 test_833() {
30174         local file=$DIR/$tfile
30175
30176         stack_trap "rm -f $file" EXIT
30177         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30178
30179         local wpid
30180         local rpid
30181         local rpid2
30182
30183         # Buffered I/O write
30184         (
30185                 while [ ! -e $DIR/sanity.833.lck ]; do
30186                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30187                                 error "failed to write $file"
30188                         sleep 0.$((RANDOM % 4 + 1))
30189                 done
30190         )&
30191         wpid=$!
30192
30193         # Buffered I/O read
30194         (
30195                 while [ ! -e $DIR/sanity.833.lck ]; do
30196                         dd if=$file of=/dev/null bs=1M count=50 ||
30197                                 error "failed to read $file"
30198                         sleep 0.$((RANDOM % 4 + 1))
30199                 done
30200         )&
30201         rpid=$!
30202
30203         # Direct I/O read
30204         (
30205                 while [ ! -e $DIR/sanity.833.lck ]; do
30206                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30207                                 error "failed to read $file in direct I/O mode"
30208                         sleep 0.$((RANDOM % 4 + 1))
30209                 done
30210         )&
30211         rpid2=$!
30212
30213         sleep 30
30214         touch $DIR/sanity.833.lck
30215         wait $wpid || error "$?: buffered write failed"
30216         wait $rpid || error "$?: buffered read failed"
30217         wait $rpid2 || error "$?: direct read failed"
30218 }
30219 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30220
30221 #
30222 # tests that do cleanup/setup should be run at the end
30223 #
30224
30225 test_900() {
30226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30227         local ls
30228
30229         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30230         $LCTL set_param fail_loc=0x903
30231
30232         cancel_lru_locks MGC
30233
30234         FAIL_ON_ERROR=true cleanup
30235         FAIL_ON_ERROR=true setup
30236 }
30237 run_test 900 "umount should not race with any mgc requeue thread"
30238
30239 # LUS-6253/LU-11185
30240 test_901() {
30241         local old
30242         local count
30243         local oldc
30244         local newc
30245         local olds
30246         local news
30247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30248
30249         # some get_param have a bug to handle dot in param name
30250         cancel_lru_locks MGC
30251         old=$(mount -t lustre | wc -l)
30252         # 1 config+sptlrpc
30253         # 2 params
30254         # 3 nodemap
30255         # 4 IR
30256         old=$((old * 4))
30257         oldc=0
30258         count=0
30259         while [ $old -ne $oldc ]; do
30260                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30261                 sleep 1
30262                 ((count++))
30263                 if [ $count -ge $TIMEOUT ]; then
30264                         error "too large timeout"
30265                 fi
30266         done
30267         umount_client $MOUNT || error "umount failed"
30268         mount_client $MOUNT || error "mount failed"
30269         cancel_lru_locks MGC
30270         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30271
30272         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30273
30274         return 0
30275 }
30276 run_test 901 "don't leak a mgc lock on client umount"
30277
30278 # LU-13377
30279 test_902() {
30280         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30281                 skip "client does not have LU-13377 fix"
30282         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30283         $LCTL set_param fail_loc=0x1415
30284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30285         cancel_lru_locks osc
30286         rm -f $DIR/$tfile
30287 }
30288 run_test 902 "test short write doesn't hang lustre"
30289
30290 # LU-14711
30291 test_903() {
30292         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30293         echo "blah" > $DIR/${tfile}-2
30294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30295         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30296         $LCTL set_param fail_loc=0x417 fail_val=20
30297
30298         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30299         sleep 1 # To start the destroy
30300         wait_destroy_complete 150 || error "Destroy taking too long"
30301         cat $DIR/$tfile > /dev/null || error "Evicted"
30302 }
30303 run_test 903 "Test long page discard does not cause evictions"
30304
30305 test_904() {
30306         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30307         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30308                 grep -q project || skip "skip project quota not supported"
30309
30310         local testfile="$DIR/$tdir/$tfile"
30311         local xattr="trusted.projid"
30312         local projid
30313         local mdts=$(comma_list $(mdts_nodes))
30314         local saved=$(do_facet mds1 $LCTL get_param -n \
30315                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30316
30317         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30318         stack_trap "do_nodes $mdts $LCTL set_param \
30319                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30320
30321         mkdir -p $DIR/$tdir
30322         touch $testfile
30323         #hide projid xattr on server
30324         $LFS project -p 1 $testfile ||
30325                 error "set $testfile project id failed"
30326         getfattr -m - $testfile | grep $xattr &&
30327                 error "do not show trusted.projid when disabled on server"
30328         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30329         #should be hidden when projid is 0
30330         $LFS project -p 0 $testfile ||
30331                 error "set $testfile project id failed"
30332         getfattr -m - $testfile | grep $xattr &&
30333                 error "do not show trusted.projid with project ID 0"
30334
30335         #still can getxattr explicitly
30336         projid=$(getfattr -n $xattr $testfile |
30337                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30338         [ $projid == "0" ] ||
30339                 error "projid expected 0 not $projid"
30340
30341         #set the projid via setxattr
30342         setfattr -n $xattr -v "1000" $testfile ||
30343                 error "setattr failed with $?"
30344         projid=($($LFS project $testfile))
30345         [ ${projid[0]} == "1000" ] ||
30346                 error "projid expected 1000 not $projid"
30347
30348         #check the new projid via getxattr
30349         $LFS project -p 1001 $testfile ||
30350                 error "set $testfile project id failed"
30351         getfattr -m - $testfile | grep $xattr ||
30352                 error "should show trusted.projid when project ID != 0"
30353         projid=$(getfattr -n $xattr $testfile |
30354                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30355         [ $projid == "1001" ] ||
30356                 error "projid expected 1001 not $projid"
30357
30358         #try to set invalid projid
30359         setfattr -n $xattr -v "4294967295" $testfile &&
30360                 error "set invalid projid should fail"
30361
30362         #remove the xattr means setting projid to 0
30363         setfattr -x $xattr $testfile ||
30364                 error "setfattr failed with $?"
30365         projid=($($LFS project $testfile))
30366         [ ${projid[0]} == "0" ] ||
30367                 error "projid expected 0 not $projid"
30368
30369         #should be hidden when parent has inherit flag and same projid
30370         $LFS project -srp 1002 $DIR/$tdir ||
30371                 error "set $tdir project id failed"
30372         getfattr -m - $testfile | grep $xattr &&
30373                 error "do not show trusted.projid with inherit flag"
30374
30375         #still can getxattr explicitly
30376         projid=$(getfattr -n $xattr $testfile |
30377                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30378         [ $projid == "1002" ] ||
30379                 error "projid expected 1002 not $projid"
30380 }
30381 run_test 904 "virtual project ID xattr"
30382
30383 # LU-8582
30384 test_905() {
30385         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30386                 skip "need OST version >= 2.15.50.220 for fail_loc"
30387
30388         remote_ost_nodsh && skip "remote OST with nodsh"
30389         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30390
30391         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30392
30393         #define OBD_FAIL_OST_OPCODE 0x253
30394         # OST_LADVISE = 21
30395         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30396         $LFS ladvise -a willread $DIR/$tfile &&
30397                 error "unexpected success of ladvise with fault injection"
30398         $LFS ladvise -a willread $DIR/$tfile |&
30399                 grep -q "Operation not supported"
30400         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30401 }
30402 run_test 905 "bad or new opcode should not stuck client"
30403
30404 test_906() {
30405         grep -q io_uring_setup /proc/kallsyms ||
30406                 skip "Client OS does not support io_uring I/O engine"
30407         io_uring_probe || skip "kernel does not support io_uring fully"
30408         which fio || skip_env "no fio installed"
30409         fio --enghelp | grep -q io_uring ||
30410                 skip_env "fio does not support io_uring I/O engine"
30411
30412         local file=$DIR/$tfile
30413         local ioengine="io_uring"
30414         local numjobs=2
30415         local size=50M
30416
30417         fio --name=seqwrite --ioengine=$ioengine        \
30418                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30419                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30420                 error "fio seqwrite $file failed"
30421
30422         fio --name=seqread --ioengine=$ioengine \
30423                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30424                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30425                 error "fio seqread $file failed"
30426
30427         rm -f $file || error "rm -f $file failed"
30428 }
30429 run_test 906 "Simple test for io_uring I/O engine via fio"
30430
30431 complete_test $SECONDS
30432 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30433 check_and_cleanup_lustre
30434 if [ "$I_MOUNTED" != "yes" ]; then
30435         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30436 fi
30437 exit_status