Whamcloud - gitweb
LU-16673 tests: add checking for user USER0
[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         (( $MDS1_VERSION >= $(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 > 1 )) || skip "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 == $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 == $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 == $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 == $appendcount )) ||
3068                 error "(4) stripe count $count, should be $appendcount for append"
3069
3070         # Test append stripe count of -1
3071         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3072         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3073                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3074                 touch $DIR/$tdir/$tfile.specific.{1..128}
3075         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3076
3077         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3078         appendcount=$OSTCOUNT
3079         echo 1 >> $DIR/$tdir/${tfile}.5
3080         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3081         (( $count == $appendcount )) ||
3082                 error "(5) stripe count $count, should be $appendcount for append"
3083
3084         # Set append striping back to default of 1
3085         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3086
3087         # Try a new default striping, PFL + DOM
3088         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3089
3090         # Create normal DOM file, DOM returns stripe count == 0
3091         setcount=0
3092         touch $DIR/$tdir/${tfile}.6
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3094         (( $count == $setcount )) ||
3095                 error "(6) stripe count $count, should be $setcount"
3096
3097         # Show
3098         appendcount=1
3099         echo 1 >> $DIR/$tdir/${tfile}.7_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3101         (( $count == $appendcount )) ||
3102                 error "(7) stripe count $count, should be $appendcount for append"
3103
3104         # Clean up DOM layout
3105         $LFS setstripe -d $DIR/$tdir
3106
3107         save_layout_restore_at_exit $MOUNT
3108         # Now test that append striping works when layout is from root
3109         $LFS setstripe -c 2 $MOUNT
3110         # Make a special directory for this
3111         mkdir $DIR/${tdir}/${tdir}.2
3112
3113         # Verify for normal file
3114         setcount=2
3115         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3116         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3117         (( $count == $setcount )) ||
3118                 error "(8) stripe count $count, should be $setcount"
3119
3120         appendcount=1
3121         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3122         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3123         (( $count == $appendcount )) ||
3124                 error "(9) stripe count $count, should be $appendcount for append"
3125
3126         # Now test O_APPEND striping with pools
3127         pool_add $TESTNAME || error "pool creation failed"
3128         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3129         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3130
3131         echo 1 >> $DIR/$tdir/${tfile}.10_append
3132
3133         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3134         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3135
3136         # Check that count is still correct
3137         appendcount=1
3138         echo 1 >> $DIR/$tdir/${tfile}.11_append
3139         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3140         (( $count == $appendcount )) ||
3141                 error "(11) stripe count $count, should be $appendcount for append"
3142
3143         # Disable O_APPEND stripe count, verify pool works separately
3144         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3145
3146         echo 1 >> $DIR/$tdir/${tfile}.12_append
3147
3148         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3149         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3150
3151         # Remove pool setting, verify it's not applied
3152         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3153
3154         echo 1 >> $DIR/$tdir/${tfile}.13_append
3155
3156         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3157         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3158 }
3159 run_test 27M "test O_APPEND striping"
3160
3161 test_27N() {
3162         combined_mgs_mds && skip "needs separate MGS/MDT"
3163
3164         pool_add $TESTNAME || error "pool_add failed"
3165         do_facet mgs "$LCTL pool_list $FSNAME" |
3166                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3167                 error "lctl pool_list on MGS failed"
3168 }
3169 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3170
3171 clean_foreign_symlink() {
3172         trap 0
3173         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3174         for i in $DIR/$tdir/* ; do
3175                 $LFS unlink_foreign $i || true
3176         done
3177 }
3178
3179 test_27O() {
3180         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3181                 skip "Need MDS version newer than 2.12.51"
3182
3183         test_mkdir $DIR/$tdir
3184         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3185         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3186
3187         trap clean_foreign_symlink EXIT
3188
3189         # enable foreign_symlink behaviour
3190         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3191
3192         # foreign symlink LOV format is a partial path by default
3193
3194         # create foreign file (lfs + API)
3195         $LFS setstripe --foreign=symlink --flags 0xda05 \
3196                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3197                 error "$DIR/$tdir/${tfile}: create failed"
3198
3199         $LFS getstripe -v $DIR/$tdir/${tfile} |
3200                 grep "lfm_magic:.*0x0BD70BD0" ||
3201                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3202         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3204         $LFS getstripe -v $DIR/$tdir/${tfile} |
3205                 grep "lfm_flags:.*0x0000DA05" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3207         $LFS getstripe $DIR/$tdir/${tfile} |
3208                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3209                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3210
3211         # modify striping should fail
3212         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3213                 error "$DIR/$tdir/$tfile: setstripe should fail"
3214
3215         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3216         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3217         cat /etc/passwd > $DIR/$tdir/$tfile &&
3218                 error "$DIR/$tdir/$tfile: write should fail"
3219
3220         # rename should succeed
3221         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3222                 error "$DIR/$tdir/$tfile: rename has failed"
3223
3224         #remove foreign_symlink file should fail
3225         rm $DIR/$tdir/${tfile}.new &&
3226                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3227
3228         #test fake symlink
3229         mkdir /tmp/${uuid1} ||
3230                 error "/tmp/${uuid1}: mkdir has failed"
3231         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3232                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3233         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3234         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3235                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3236         #read should succeed now
3237         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3238                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3239         #write should succeed now
3240         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3241                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3242         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3244         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3245                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3246
3247         #check that getstripe still works
3248         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3249                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3250
3251         # chmod should still succeed
3252         chmod 644 $DIR/$tdir/${tfile}.new ||
3253                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3254
3255         # chown should still succeed
3256         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3257                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3258
3259         # rename should still succeed
3260         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3261                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3262
3263         #remove foreign_symlink file should still fail
3264         rm $DIR/$tdir/${tfile} &&
3265                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3266
3267         #use special ioctl() to unlink foreign_symlink file
3268         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3269                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3270
3271 }
3272 run_test 27O "basic ops on foreign file of symlink type"
3273
3274 test_27P() {
3275         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3276                 skip "Need MDS version newer than 2.12.49"
3277
3278         test_mkdir $DIR/$tdir
3279         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3280         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3281
3282         trap clean_foreign_symlink EXIT
3283
3284         # enable foreign_symlink behaviour
3285         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3286
3287         # foreign symlink LMV format is a partial path by default
3288
3289         # create foreign dir (lfs + API)
3290         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3291                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3292                 error "$DIR/$tdir/${tdir}: create failed"
3293
3294         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3295
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3297                 grep "lfm_magic:.*0x0CD50CD0" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3299         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3300                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3301         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3302                 grep "lfm_flags:.*0x0000DA05" ||
3303                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3304         $LFS getdirstripe $DIR/$tdir/${tdir} |
3305                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3306                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3307
3308         # file create in dir should fail
3309         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3310         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3311
3312         # rename should succeed
3313         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3314                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3315
3316         #remove foreign_symlink dir should fail
3317         rmdir $DIR/$tdir/${tdir}.new &&
3318                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3319
3320         #test fake symlink
3321         mkdir -p /tmp/${uuid1}/${uuid2} ||
3322                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3323         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3324                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3325         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3326         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3327                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3328         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3329                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3330
3331         #check that getstripe fails now that foreign_symlink enabled
3332         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3333                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3334
3335         # file create in dir should work now
3336         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3337                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3338         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3339                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3340         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3341                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3342
3343         # chmod should still succeed
3344         chmod 755 $DIR/$tdir/${tdir}.new ||
3345                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3346
3347         # chown should still succeed
3348         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3349                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3350
3351         # rename should still succeed
3352         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3353                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3354
3355         #remove foreign_symlink dir should still fail
3356         rmdir $DIR/$tdir/${tdir} &&
3357                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3358
3359         #use special ioctl() to unlink foreign_symlink file
3360         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3361                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3362
3363         #created file should still exist
3364         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3365                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3366         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3367                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3368 }
3369 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3370
3371 test_27Q() {
3372         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3373         stack_trap "rm -f $TMP/$tfile*"
3374
3375         test_mkdir $DIR/$tdir-1
3376         test_mkdir $DIR/$tdir-2
3377
3378         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3379         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3380
3381         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3382         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3383
3384         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3385         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3386
3387         # Create some bad symlinks and ensure that we don't loop
3388         # forever or something. These should return ELOOP (40) and
3389         # ENOENT (2) but I don't want to test for that because there's
3390         # always some weirdo architecture that needs to ruin
3391         # everything by defining these error numbers differently.
3392
3393         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3394         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3395
3396         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3397         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3398
3399         return 0
3400 }
3401 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3402
3403 test_27R() {
3404         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3405                 skip "need MDS 2.14.55 or later"
3406         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3407
3408         local testdir="$DIR/$tdir"
3409         test_mkdir -p $testdir
3410         stack_trap "rm -rf $testdir"
3411         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3412
3413         local f1="$testdir/f1"
3414         touch $f1 || error "failed to touch $f1"
3415         local count=$($LFS getstripe -c $f1)
3416         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3417
3418         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3419         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3420
3421         local maxcount=$(($OSTCOUNT - 1))
3422         local mdts=$(comma_list $(mdts_nodes))
3423         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3424         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3425
3426         local f2="$testdir/f2"
3427         touch $f2 || error "failed to touch $f2"
3428         local count=$($LFS getstripe -c $f2)
3429         (( $count == $maxcount )) || error "wrong stripe count"
3430 }
3431 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3432
3433 test_27T() {
3434         [ $(facet_host client) == $(facet_host ost1) ] &&
3435                 skip "need ost1 and client on different nodes"
3436
3437 #define OBD_FAIL_OSC_NO_GRANT            0x411
3438         $LCTL set_param fail_loc=0x20000411 fail_val=1
3439 #define OBD_FAIL_OST_ENOSPC              0x215
3440         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3441         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3442         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3443                 error "multiop failed"
3444 }
3445 run_test 27T "no eio on close on partial write due to enosp"
3446
3447 test_27U() {
3448         local dir=$DIR/$tdir
3449         local file=$dir/$tfile
3450         local append_pool=${TESTNAME}-append
3451         local normal_pool=${TESTNAME}-normal
3452         local pool
3453         local stripe_count
3454         local stripe_count2
3455         local mdts=$(comma_list $(mdts_nodes))
3456
3457         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3458                 skip "Need MDS version at least 2.15.51 for append pool feature"
3459
3460         # Validate existing append_* params and ensure restore
3461         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3462         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3463         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3464
3465         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3466         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3467         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3468
3469         pool_add $append_pool || error "pool creation failed"
3470         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3471
3472         pool_add $normal_pool || error "pool creation failed"
3473         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3474
3475         test_mkdir $dir
3476         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3477
3478         echo XXX >> $file.1
3479         $LFS getstripe $file.1
3480
3481         pool=$($LFS getstripe -p $file.1)
3482         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3483
3484         stripe_count2=$($LFS getstripe -c $file.1)
3485         ((stripe_count2 == stripe_count)) ||
3486                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3487
3488         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3489
3490         echo XXX >> $file.2
3491         $LFS getstripe $file.2
3492
3493         pool=$($LFS getstripe -p $file.2)
3494         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3495
3496         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3497
3498         echo XXX >> $file.3
3499         $LFS getstripe $file.3
3500
3501         stripe_count2=$($LFS getstripe -c $file.3)
3502         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3503 }
3504 run_test 27U "append pool and stripe count work with composite default layout"
3505
3506 # createtest also checks that device nodes are created and
3507 # then visible correctly (#2091)
3508 test_28() { # bug 2091
3509         test_mkdir $DIR/d28
3510         $CREATETEST $DIR/d28/ct || error "createtest failed"
3511 }
3512 run_test 28 "create/mknod/mkdir with bad file types ============"
3513
3514 test_29() {
3515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3516
3517         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3518                 disable_opencache
3519                 stack_trap "restore_opencache"
3520         }
3521
3522         sync; sleep 1; sync # flush out any dirty pages from previous tests
3523         cancel_lru_locks
3524         test_mkdir $DIR/d29
3525         touch $DIR/d29/foo
3526         log 'first d29'
3527         ls -l $DIR/d29
3528
3529         declare -i LOCKCOUNTORIG=0
3530         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3531                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3532         done
3533         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3534
3535         declare -i LOCKUNUSEDCOUNTORIG=0
3536         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3537                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3538         done
3539
3540         log 'second d29'
3541         ls -l $DIR/d29
3542         log 'done'
3543
3544         declare -i LOCKCOUNTCURRENT=0
3545         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3546                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3547         done
3548
3549         declare -i LOCKUNUSEDCOUNTCURRENT=0
3550         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3551                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3552         done
3553
3554         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3555                 $LCTL set_param -n ldlm.dump_namespaces ""
3556                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3557                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3558                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3559                 return 2
3560         fi
3561         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3562                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3563                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3564                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3565                 return 3
3566         fi
3567 }
3568 run_test 29 "IT_GETATTR regression  ============================"
3569
3570 test_30a() { # was test_30
3571         cp $(which ls) $DIR || cp /bin/ls $DIR
3572         $DIR/ls / || error "Can't execute binary from lustre"
3573         rm $DIR/ls
3574 }
3575 run_test 30a "execute binary from Lustre (execve) =============="
3576
3577 test_30b() {
3578         cp `which ls` $DIR || cp /bin/ls $DIR
3579         chmod go+rx $DIR/ls
3580         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3581         rm $DIR/ls
3582 }
3583 run_test 30b "execute binary from Lustre as non-root ==========="
3584
3585 test_30c() { # b=22376
3586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3587
3588         cp $(which ls) $DIR || cp /bin/ls $DIR
3589         chmod a-rw $DIR/ls
3590         cancel_lru_locks mdc
3591         cancel_lru_locks osc
3592         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3593         rm -f $DIR/ls
3594 }
3595 run_test 30c "execute binary from Lustre without read perms ===="
3596
3597 test_30d() {
3598         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3599
3600         for i in {1..10}; do
3601                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3602                 local PID=$!
3603                 sleep 1
3604                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3605                 wait $PID || error "executing dd from Lustre failed"
3606                 rm -f $DIR/$tfile
3607         done
3608
3609         rm -f $DIR/dd
3610 }
3611 run_test 30d "execute binary from Lustre while clear locks"
3612
3613 test_31a() {
3614         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3615         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3616 }
3617 run_test 31a "open-unlink file =================================="
3618
3619 test_31b() {
3620         touch $DIR/f31 || error "touch $DIR/f31 failed"
3621         ln $DIR/f31 $DIR/f31b || error "ln failed"
3622         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3623         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3624 }
3625 run_test 31b "unlink file with multiple links while open ======="
3626
3627 test_31c() {
3628         touch $DIR/f31 || error "touch $DIR/f31 failed"
3629         ln $DIR/f31 $DIR/f31c || error "ln failed"
3630         multiop_bg_pause $DIR/f31 O_uc ||
3631                 error "multiop_bg_pause for $DIR/f31 failed"
3632         MULTIPID=$!
3633         $MULTIOP $DIR/f31c Ouc
3634         kill -USR1 $MULTIPID
3635         wait $MULTIPID
3636 }
3637 run_test 31c "open-unlink file with multiple links ============="
3638
3639 test_31d() {
3640         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3641         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3642 }
3643 run_test 31d "remove of open directory ========================="
3644
3645 test_31e() { # bug 2904
3646         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3647 }
3648 run_test 31e "remove of open non-empty directory ==============="
3649
3650 test_31f() { # bug 4554
3651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3652
3653         set -vx
3654         test_mkdir $DIR/d31f
3655         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3656         cp /etc/hosts $DIR/d31f
3657         ls -l $DIR/d31f
3658         $LFS getstripe $DIR/d31f/hosts
3659         multiop_bg_pause $DIR/d31f D_c || return 1
3660         MULTIPID=$!
3661
3662         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3663         test_mkdir $DIR/d31f
3664         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3665         cp /etc/hosts $DIR/d31f
3666         ls -l $DIR/d31f
3667         $LFS getstripe $DIR/d31f/hosts
3668         multiop_bg_pause $DIR/d31f D_c || return 1
3669         MULTIPID2=$!
3670
3671         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3672         wait $MULTIPID || error "first opendir $MULTIPID failed"
3673
3674         sleep 6
3675
3676         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3677         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3678         set +vx
3679 }
3680 run_test 31f "remove of open directory with open-unlink file ==="
3681
3682 test_31g() {
3683         echo "-- cross directory link --"
3684         test_mkdir -c1 $DIR/${tdir}ga
3685         test_mkdir -c1 $DIR/${tdir}gb
3686         touch $DIR/${tdir}ga/f
3687         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3688         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3689         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3690         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3691         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3692 }
3693 run_test 31g "cross directory link==============="
3694
3695 test_31h() {
3696         echo "-- cross directory link --"
3697         test_mkdir -c1 $DIR/${tdir}
3698         test_mkdir -c1 $DIR/${tdir}/dir
3699         touch $DIR/${tdir}/f
3700         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3701         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3702         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3703         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3704         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3705 }
3706 run_test 31h "cross directory link under child==============="
3707
3708 test_31i() {
3709         echo "-- cross directory link --"
3710         test_mkdir -c1 $DIR/$tdir
3711         test_mkdir -c1 $DIR/$tdir/dir
3712         touch $DIR/$tdir/dir/f
3713         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3714         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3715         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3716         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3717         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3718 }
3719 run_test 31i "cross directory link under parent==============="
3720
3721 test_31j() {
3722         test_mkdir -c1 -p $DIR/$tdir
3723         test_mkdir -c1 -p $DIR/$tdir/dir1
3724         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3725         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3726         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3727         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3728         return 0
3729 }
3730 run_test 31j "link for directory==============="
3731
3732 test_31k() {
3733         test_mkdir -c1 -p $DIR/$tdir
3734         touch $DIR/$tdir/s
3735         touch $DIR/$tdir/exist
3736         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3737         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3738         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3739         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3740         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3741         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3742         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3743         return 0
3744 }
3745 run_test 31k "link to file: the same, non-existing, dir==============="
3746
3747 test_31l() {
3748         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3749
3750         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3751         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3752                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3753
3754         touch $DIR/$tfile || error "create failed"
3755         mkdir $DIR/$tdir || error "mkdir failed"
3756         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3757 }
3758 run_test 31l "link to file: target dir has trailing slash"
3759
3760 test_31m() {
3761         mkdir $DIR/d31m
3762         touch $DIR/d31m/s
3763         mkdir $DIR/d31m2
3764         touch $DIR/d31m2/exist
3765         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3766         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3767         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3768         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3769         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3770         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3771         return 0
3772 }
3773 run_test 31m "link to file: the same, non-existing, dir==============="
3774
3775 test_31n() {
3776         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3777         nlink=$(stat --format=%h $DIR/$tfile)
3778         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3779         local fd=$(free_fd)
3780         local cmd="exec $fd<$DIR/$tfile"
3781         eval $cmd
3782         cmd="exec $fd<&-"
3783         trap "eval $cmd" EXIT
3784         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3785         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3786         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3787         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3788         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3789         eval $cmd
3790 }
3791 run_test 31n "check link count of unlinked file"
3792
3793 link_one() {
3794         local tempfile=$(mktemp $1_XXXXXX)
3795         mlink $tempfile $1 2> /dev/null &&
3796                 echo "$BASHPID: link $tempfile to $1 succeeded"
3797         munlink $tempfile
3798 }
3799
3800 test_31o() { # LU-2901
3801         test_mkdir $DIR/$tdir
3802         for LOOP in $(seq 100); do
3803                 rm -f $DIR/$tdir/$tfile*
3804                 for THREAD in $(seq 8); do
3805                         link_one $DIR/$tdir/$tfile.$LOOP &
3806                 done
3807                 wait
3808                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3809                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3810                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3811                         break || true
3812         done
3813 }
3814 run_test 31o "duplicate hard links with same filename"
3815
3816 test_31p() {
3817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3818
3819         test_mkdir $DIR/$tdir
3820         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3821         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3822
3823         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3824                 error "open unlink test1 failed"
3825         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3826                 error "open unlink test2 failed"
3827
3828         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3829                 error "test1 still exists"
3830         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3831                 error "test2 still exists"
3832 }
3833 run_test 31p "remove of open striped directory"
3834
3835 test_31q() {
3836         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3837
3838         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3839         index=$($LFS getdirstripe -i $DIR/$tdir)
3840         [ $index -eq 3 ] || error "first stripe index $index != 3"
3841         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3842         [ $index -eq 1 ] || error "second stripe index $index != 1"
3843
3844         # when "-c <stripe_count>" is set, the number of MDTs specified after
3845         # "-i" should equal to the stripe count
3846         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3847 }
3848 run_test 31q "create striped directory on specific MDTs"
3849
3850 #LU-14949
3851 test_31r() {
3852         touch $DIR/$tfile.target
3853         touch $DIR/$tfile.source
3854
3855         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3856         $LCTL set_param fail_loc=0x1419 fail_val=3
3857         cat $DIR/$tfile.target &
3858         CATPID=$!
3859
3860         # Guarantee open is waiting before we get here
3861         sleep 1
3862         mv $DIR/$tfile.source $DIR/$tfile.target
3863
3864         wait $CATPID
3865         RC=$?
3866         if [[ $RC -ne 0 ]]; then
3867                 error "open with cat failed, rc=$RC"
3868         fi
3869 }
3870 run_test 31r "open-rename(replace) race"
3871
3872 cleanup_test32_mount() {
3873         local rc=0
3874         trap 0
3875         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3876         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3877         losetup -d $loopdev || true
3878         rm -rf $DIR/$tdir
3879         return $rc
3880 }
3881
3882 test_32a() {
3883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3884
3885         echo "== more mountpoints and symlinks ================="
3886         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3887         trap cleanup_test32_mount EXIT
3888         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3889         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3890                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3891         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3892                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3893         cleanup_test32_mount
3894 }
3895 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3896
3897 test_32b() {
3898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3899
3900         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3901         trap cleanup_test32_mount EXIT
3902         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3903         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3904                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3905         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3906                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3907         cleanup_test32_mount
3908 }
3909 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3910
3911 test_32c() {
3912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3913
3914         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3915         trap cleanup_test32_mount EXIT
3916         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3917         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3918                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3919         test_mkdir -p $DIR/$tdir/d2/test_dir
3920         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3921                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3922         cleanup_test32_mount
3923 }
3924 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3925
3926 test_32d() {
3927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3928
3929         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3930         trap cleanup_test32_mount EXIT
3931         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3932         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3933                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3934         test_mkdir -p $DIR/$tdir/d2/test_dir
3935         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3936                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3937         cleanup_test32_mount
3938 }
3939 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3940
3941 test_32e() {
3942         rm -fr $DIR/$tdir
3943         test_mkdir -p $DIR/$tdir/tmp
3944         local tmp_dir=$DIR/$tdir/tmp
3945         ln -s $DIR/$tdir $tmp_dir/symlink11
3946         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3947         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3948         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3949 }
3950 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3951
3952 test_32f() {
3953         rm -fr $DIR/$tdir
3954         test_mkdir -p $DIR/$tdir/tmp
3955         local tmp_dir=$DIR/$tdir/tmp
3956         ln -s $DIR/$tdir $tmp_dir/symlink11
3957         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3958         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3959         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3960 }
3961 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3962
3963 test_32g() {
3964         local tmp_dir=$DIR/$tdir/tmp
3965         test_mkdir -p $tmp_dir
3966         test_mkdir $DIR/${tdir}2
3967         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3968         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3969         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3970         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3971         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3972         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3973 }
3974 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3975
3976 test_32h() {
3977         rm -fr $DIR/$tdir $DIR/${tdir}2
3978         tmp_dir=$DIR/$tdir/tmp
3979         test_mkdir -p $tmp_dir
3980         test_mkdir $DIR/${tdir}2
3981         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3982         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3983         ls $tmp_dir/symlink12 || error "listing symlink12"
3984         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3985 }
3986 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3987
3988 test_32i() {
3989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3990
3991         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3992         trap cleanup_test32_mount EXIT
3993         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3994         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3995                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3996         touch $DIR/$tdir/test_file
3997         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3998                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3999         cleanup_test32_mount
4000 }
4001 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4002
4003 test_32j() {
4004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4005
4006         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4007         trap cleanup_test32_mount EXIT
4008         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4009         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4010                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4011         touch $DIR/$tdir/test_file
4012         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4013                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4014         cleanup_test32_mount
4015 }
4016 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4017
4018 test_32k() {
4019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4020
4021         rm -fr $DIR/$tdir
4022         trap cleanup_test32_mount EXIT
4023         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4024         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4025                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4026         test_mkdir -p $DIR/$tdir/d2
4027         touch $DIR/$tdir/d2/test_file || error "touch failed"
4028         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4029                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4030         cleanup_test32_mount
4031 }
4032 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4033
4034 test_32l() {
4035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4036
4037         rm -fr $DIR/$tdir
4038         trap cleanup_test32_mount EXIT
4039         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4040         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4041                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4042         test_mkdir -p $DIR/$tdir/d2
4043         touch $DIR/$tdir/d2/test_file || error "touch failed"
4044         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4045                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4046         cleanup_test32_mount
4047 }
4048 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4049
4050 test_32m() {
4051         rm -fr $DIR/d32m
4052         test_mkdir -p $DIR/d32m/tmp
4053         TMP_DIR=$DIR/d32m/tmp
4054         ln -s $DIR $TMP_DIR/symlink11
4055         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4056         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4057                 error "symlink11 not a link"
4058         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4059                 error "symlink01 not a link"
4060 }
4061 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4062
4063 test_32n() {
4064         rm -fr $DIR/d32n
4065         test_mkdir -p $DIR/d32n/tmp
4066         TMP_DIR=$DIR/d32n/tmp
4067         ln -s $DIR $TMP_DIR/symlink11
4068         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4069         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4070         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4071 }
4072 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4073
4074 test_32o() {
4075         touch $DIR/$tfile
4076         test_mkdir -p $DIR/d32o/tmp
4077         TMP_DIR=$DIR/d32o/tmp
4078         ln -s $DIR/$tfile $TMP_DIR/symlink12
4079         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4080         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4081                 error "symlink12 not a link"
4082         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4083         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4084                 error "$DIR/d32o/tmp/symlink12 not file type"
4085         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4086                 error "$DIR/d32o/symlink02 not file type"
4087 }
4088 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4089
4090 test_32p() {
4091         log 32p_1
4092         rm -fr $DIR/d32p
4093         log 32p_2
4094         rm -f $DIR/$tfile
4095         log 32p_3
4096         touch $DIR/$tfile
4097         log 32p_4
4098         test_mkdir -p $DIR/d32p/tmp
4099         log 32p_5
4100         TMP_DIR=$DIR/d32p/tmp
4101         log 32p_6
4102         ln -s $DIR/$tfile $TMP_DIR/symlink12
4103         log 32p_7
4104         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4105         log 32p_8
4106         cat $DIR/d32p/tmp/symlink12 ||
4107                 error "Can't open $DIR/d32p/tmp/symlink12"
4108         log 32p_9
4109         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4110         log 32p_10
4111 }
4112 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4113
4114 test_32q() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4118         trap cleanup_test32_mount EXIT
4119         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4120         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4121         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4122                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4123         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4124         cleanup_test32_mount
4125 }
4126 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4127
4128 test_32r() {
4129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4130
4131         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4132         trap cleanup_test32_mount EXIT
4133         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4134         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4135         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4136                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4137         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4138         cleanup_test32_mount
4139 }
4140 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4141
4142 test_33aa() {
4143         rm -f $DIR/$tfile
4144         touch $DIR/$tfile
4145         chmod 444 $DIR/$tfile
4146         chown $RUNAS_ID $DIR/$tfile
4147         log 33_1
4148         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4149         log 33_2
4150 }
4151 run_test 33aa "write file with mode 444 (should return error)"
4152
4153 test_33a() {
4154         rm -fr $DIR/$tdir
4155         test_mkdir $DIR/$tdir
4156         chown $RUNAS_ID $DIR/$tdir
4157         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4158                 error "$RUNAS create $tdir/$tfile failed"
4159         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4160                 error "open RDWR" || true
4161 }
4162 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4163
4164 test_33b() {
4165         rm -fr $DIR/$tdir
4166         test_mkdir $DIR/$tdir
4167         chown $RUNAS_ID $DIR/$tdir
4168         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4169 }
4170 run_test 33b "test open file with malformed flags (No panic)"
4171
4172 test_33c() {
4173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4174         remote_ost_nodsh && skip "remote OST with nodsh"
4175
4176         local ostnum
4177         local ostname
4178         local write_bytes
4179         local all_zeros
4180
4181         all_zeros=true
4182         test_mkdir $DIR/$tdir
4183         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4184
4185         sync
4186         for ostnum in $(seq $OSTCOUNT); do
4187                 # test-framework's OST numbering is one-based, while Lustre's
4188                 # is zero-based
4189                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4190                 # check if at least some write_bytes stats are counted
4191                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4192                               obdfilter.$ostname.stats |
4193                               awk '/^write_bytes/ {print $7}' )
4194                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4195                 if (( ${write_bytes:-0} > 0 )); then
4196                         all_zeros=false
4197                         break
4198                 fi
4199         done
4200
4201         $all_zeros || return 0
4202
4203         # Write four bytes
4204         echo foo > $DIR/$tdir/bar
4205         # Really write them
4206         sync
4207
4208         # Total up write_bytes after writing.  We'd better find non-zeros.
4209         for ostnum in $(seq $OSTCOUNT); do
4210                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4211                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4212                               obdfilter/$ostname/stats |
4213                               awk '/^write_bytes/ {print $7}' )
4214                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4215                 if (( ${write_bytes:-0} > 0 )); then
4216                         all_zeros=false
4217                         break
4218                 fi
4219         done
4220
4221         if $all_zeros; then
4222                 for ostnum in $(seq $OSTCOUNT); do
4223                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4224                         echo "Check write_bytes is in obdfilter.*.stats:"
4225                         do_facet ost$ostnum lctl get_param -n \
4226                                 obdfilter.$ostname.stats
4227                 done
4228                 error "OST not keeping write_bytes stats (b=22312)"
4229         fi
4230 }
4231 run_test 33c "test write_bytes stats"
4232
4233 test_33d() {
4234         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4236
4237         local MDTIDX=1
4238         local remote_dir=$DIR/$tdir/remote_dir
4239
4240         test_mkdir $DIR/$tdir
4241         $LFS mkdir -i $MDTIDX $remote_dir ||
4242                 error "create remote directory failed"
4243
4244         touch $remote_dir/$tfile
4245         chmod 444 $remote_dir/$tfile
4246         chown $RUNAS_ID $remote_dir/$tfile
4247
4248         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4249
4250         chown $RUNAS_ID $remote_dir
4251         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4252                                         error "create" || true
4253         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4254                                     error "open RDWR" || true
4255         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4256 }
4257 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4258
4259 test_33e() {
4260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4261
4262         mkdir $DIR/$tdir
4263
4264         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4265         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4266         mkdir $DIR/$tdir/local_dir
4267
4268         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4269         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4270         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4271
4272         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4273                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4274
4275         rmdir $DIR/$tdir/* || error "rmdir failed"
4276
4277         umask 777
4278         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4279         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4280         mkdir $DIR/$tdir/local_dir
4281
4282         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4283         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4284         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4285
4286         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4287                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4288
4289         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4290
4291         umask 000
4292         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4293         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4294         mkdir $DIR/$tdir/local_dir
4295
4296         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4297         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4298         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4299
4300         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4301                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4302 }
4303 run_test 33e "mkdir and striped directory should have same mode"
4304
4305 cleanup_33f() {
4306         trap 0
4307         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4308 }
4309
4310 test_33f() {
4311         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4312         remote_mds_nodsh && skip "remote MDS with nodsh"
4313
4314         mkdir $DIR/$tdir
4315         chmod go+rwx $DIR/$tdir
4316         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4317         trap cleanup_33f EXIT
4318
4319         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4320                 error "cannot create striped directory"
4321
4322         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4323                 error "cannot create files in striped directory"
4324
4325         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4326                 error "cannot remove files in striped directory"
4327
4328         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4329                 error "cannot remove striped directory"
4330
4331         cleanup_33f
4332 }
4333 run_test 33f "nonroot user can create, access, and remove a striped directory"
4334
4335 test_33g() {
4336         mkdir -p $DIR/$tdir/dir2
4337
4338         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4339         echo $err
4340         [[ $err =~ "exists" ]] || error "Not exists error"
4341 }
4342 run_test 33g "nonroot user create already existing root created file"
4343
4344 sub_33h() {
4345         local hash_type=$1
4346         local count=250
4347
4348         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4349                 error "lfs mkdir -H $hash_type $tdir failed"
4350         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4351
4352         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4353         local index2
4354         local fname
4355
4356         for fname in $DIR/$tdir/$tfile.bak \
4357                      $DIR/$tdir/$tfile.SAV \
4358                      $DIR/$tdir/$tfile.orig \
4359                      $DIR/$tdir/$tfile~; do
4360                 touch $fname || error "touch $fname failed"
4361                 index2=$($LFS getstripe -m $fname)
4362                 (( $index == $index2 )) ||
4363                         error "$fname MDT index mismatch $index != $index2"
4364         done
4365
4366         local failed=0
4367         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4368         local pattern
4369
4370         for pattern in ${patterns[*]}; do
4371                 echo "pattern $pattern"
4372                 fname=$DIR/$tdir/$pattern
4373                 for (( i = 0; i < $count; i++ )); do
4374                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4375                                 error "mktemp $DIR/$tdir/$pattern failed"
4376                         index2=$($LFS getstripe -m $fname)
4377                         (( $index == $index2 )) && continue
4378
4379                         failed=$((failed + 1))
4380                         echo "$fname MDT index mismatch $index != $index2"
4381                 done
4382         done
4383
4384         echo "$failed/$count MDT index mismatches, expect ~2-4"
4385         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4386
4387         local same=0
4388         local expect
4389
4390         # verify that "crush" is still broken with all files on same MDT,
4391         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4392         [[ "$hash_type" == "crush" ]] && expect=$count ||
4393                 expect=$((count / MDSCOUNT))
4394
4395         # crush2 doesn't put all-numeric suffixes on the same MDT,
4396         # filename like $tfile.12345678 should *not* be considered temp
4397         for pattern in ${patterns[*]}; do
4398                 local base=${pattern%%X*}
4399                 local suff=${pattern#$base}
4400
4401                 echo "pattern $pattern"
4402                 for (( i = 0; i < $count; i++ )); do
4403                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4404                         touch $fname || error "touch $fname failed"
4405                         index2=$($LFS getstripe -m $fname)
4406                         (( $index != $index2 )) && continue
4407
4408                         same=$((same + 1))
4409                 done
4410         done
4411
4412         # the number of "bad" hashes is random, as it depends on the random
4413         # filenames generated by "mktemp".  Allow some margin in the results.
4414         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4415         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4416            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4417                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4418         same=0
4419
4420         # crush2 doesn't put suffixes with special characters on the same MDT
4421         # filename like $tfile.txt.1234 should *not* be considered temp
4422         for pattern in ${patterns[*]}; do
4423                 local base=${pattern%%X*}
4424                 local suff=${pattern#$base}
4425
4426                 pattern=$base...${suff/XXX}
4427                 echo "pattern=$pattern"
4428                 for (( i = 0; i < $count; i++ )); do
4429                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4430                                 error "touch $fname failed"
4431                         index2=$($LFS getstripe -m $fname)
4432                         (( $index != $index2 )) && continue
4433
4434                         same=$((same + 1))
4435                 done
4436         done
4437
4438         # the number of "bad" hashes is random, as it depends on the random
4439         # filenames generated by "mktemp".  Allow some margin in the results.
4440         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4441         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4442            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4443                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4444 }
4445
4446 test_33h() {
4447         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4448         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4449                 skip "Need MDS version at least 2.13.50"
4450
4451         sub_33h crush
4452 }
4453 run_test 33h "temp file is located on the same MDT as target (crush)"
4454
4455 test_33hh() {
4456         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4457         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4458         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4459                 skip "Need MDS version at least 2.15.0 for crush2"
4460
4461         sub_33h crush2
4462 }
4463 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4464
4465 test_33i()
4466 {
4467         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4468
4469         local FNAME=$(str_repeat 'f' 250)
4470
4471         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4472         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4473
4474         local count
4475         local total
4476
4477         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4478
4479         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4480
4481         lctl --device %$MDC deactivate
4482         stack_trap "lctl --device %$MDC activate"
4483         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4484         total=$(\ls -l $DIR/$tdir | wc -l)
4485         # "ls -l" will list total in the first line
4486         total=$((total - 1))
4487         (( total + count == 1000 )) ||
4488                 error "ls list $total files, $count files on MDT1"
4489 }
4490 run_test 33i "striped directory can be accessed when one MDT is down"
4491
4492 test_33j() {
4493         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4494
4495         mkdir -p $DIR/$tdir/
4496
4497         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4498                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4499
4500         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4501                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4502
4503         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4504                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4505
4506         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4507                 error "-D was not specified, but still failed"
4508 }
4509 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4510
4511 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4512 test_34a() {
4513         rm -f $DIR/f34
4514         $MCREATE $DIR/f34 || error "mcreate failed"
4515         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4516                 error "getstripe failed"
4517         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4518         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4519                 error "getstripe failed"
4520         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4521                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4522 }
4523 run_test 34a "truncate file that has not been opened ==========="
4524
4525 test_34b() {
4526         [ ! -f $DIR/f34 ] && test_34a
4527         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4528                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4529         $OPENFILE -f O_RDONLY $DIR/f34
4530         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4531                 error "getstripe failed"
4532         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4533                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4534 }
4535 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4536
4537 test_34c() {
4538         [ ! -f $DIR/f34 ] && test_34a
4539         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4540                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4541         $OPENFILE -f O_RDWR $DIR/f34
4542         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4543                 error "$LFS getstripe failed"
4544         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4545                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4546 }
4547 run_test 34c "O_RDWR opening file-with-size works =============="
4548
4549 test_34d() {
4550         [ ! -f $DIR/f34 ] && test_34a
4551         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4552                 error "dd failed"
4553         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4554                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4555         rm $DIR/f34
4556 }
4557 run_test 34d "write to sparse file ============================="
4558
4559 test_34e() {
4560         rm -f $DIR/f34e
4561         $MCREATE $DIR/f34e || error "mcreate failed"
4562         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4563         $CHECKSTAT -s 1000 $DIR/f34e ||
4564                 error "Size of $DIR/f34e not equal to 1000 bytes"
4565         $OPENFILE -f O_RDWR $DIR/f34e
4566         $CHECKSTAT -s 1000 $DIR/f34e ||
4567                 error "Size of $DIR/f34e not equal to 1000 bytes"
4568 }
4569 run_test 34e "create objects, some with size and some without =="
4570
4571 test_34f() { # bug 6242, 6243
4572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4573
4574         SIZE34F=48000
4575         rm -f $DIR/f34f
4576         $MCREATE $DIR/f34f || error "mcreate failed"
4577         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4578         dd if=$DIR/f34f of=$TMP/f34f
4579         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4580         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4581         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4582         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4583         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4584 }
4585 run_test 34f "read from a file with no objects until EOF ======="
4586
4587 test_34g() {
4588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4589
4590         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4591                 error "dd failed"
4592         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4593         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4594                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4595         cancel_lru_locks osc
4596         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4597                 error "wrong size after lock cancel"
4598
4599         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4600         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4601                 error "expanding truncate failed"
4602         cancel_lru_locks osc
4603         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4604                 error "wrong expanded size after lock cancel"
4605 }
4606 run_test 34g "truncate long file ==============================="
4607
4608 test_34h() {
4609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4610
4611         local gid=10
4612         local sz=1000
4613
4614         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4615         sync # Flush the cache so that multiop below does not block on cache
4616              # flush when getting the group lock
4617         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4618         MULTIPID=$!
4619
4620         # Since just timed wait is not good enough, let's do a sync write
4621         # that way we are sure enough time for a roundtrip + processing
4622         # passed + 2 seconds of extra margin.
4623         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4624         rm $DIR/${tfile}-1
4625         sleep 2
4626
4627         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4628                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4629                 kill -9 $MULTIPID
4630         fi
4631         wait $MULTIPID
4632         local nsz=`stat -c %s $DIR/$tfile`
4633         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4634 }
4635 run_test 34h "ftruncate file under grouplock should not block"
4636
4637 test_35a() {
4638         cp /bin/sh $DIR/f35a
4639         chmod 444 $DIR/f35a
4640         chown $RUNAS_ID $DIR/f35a
4641         $RUNAS $DIR/f35a && error || true
4642         rm $DIR/f35a
4643 }
4644 run_test 35a "exec file with mode 444 (should return and not leak)"
4645
4646 test_36a() {
4647         rm -f $DIR/f36
4648         utime $DIR/f36 || error "utime failed for MDS"
4649 }
4650 run_test 36a "MDS utime check (mknod, utime)"
4651
4652 test_36b() {
4653         echo "" > $DIR/f36
4654         utime $DIR/f36 || error "utime failed for OST"
4655 }
4656 run_test 36b "OST utime check (open, utime)"
4657
4658 test_36c() {
4659         rm -f $DIR/d36/f36
4660         test_mkdir $DIR/d36
4661         chown $RUNAS_ID $DIR/d36
4662         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4663 }
4664 run_test 36c "non-root MDS utime check (mknod, utime)"
4665
4666 test_36d() {
4667         [ ! -d $DIR/d36 ] && test_36c
4668         echo "" > $DIR/d36/f36
4669         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4670 }
4671 run_test 36d "non-root OST utime check (open, utime)"
4672
4673 test_36e() {
4674         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4675
4676         test_mkdir $DIR/$tdir
4677         touch $DIR/$tdir/$tfile
4678         $RUNAS utime $DIR/$tdir/$tfile &&
4679                 error "utime worked, expected failure" || true
4680 }
4681 run_test 36e "utime on non-owned file (should return error)"
4682
4683 subr_36fh() {
4684         local fl="$1"
4685         local LANG_SAVE=$LANG
4686         local LC_LANG_SAVE=$LC_LANG
4687         export LANG=C LC_LANG=C # for date language
4688
4689         DATESTR="Dec 20  2000"
4690         test_mkdir $DIR/$tdir
4691         lctl set_param fail_loc=$fl
4692         date; date +%s
4693         cp /etc/hosts $DIR/$tdir/$tfile
4694         sync & # write RPC generated with "current" inode timestamp, but delayed
4695         sleep 1
4696         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4697         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4698         cancel_lru_locks $OSC
4699         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4700         date; date +%s
4701         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4702                 echo "BEFORE: $LS_BEFORE" && \
4703                 echo "AFTER : $LS_AFTER" && \
4704                 echo "WANT  : $DATESTR" && \
4705                 error "$DIR/$tdir/$tfile timestamps changed" || true
4706
4707         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4708 }
4709
4710 test_36f() {
4711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4712
4713         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4714         subr_36fh "0x80000214"
4715 }
4716 run_test 36f "utime on file racing with OST BRW write =========="
4717
4718 test_36g() {
4719         remote_ost_nodsh && skip "remote OST with nodsh"
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4722                 skip "Need MDS version at least 2.12.51"
4723
4724         local fmd_max_age
4725         local fmd
4726         local facet="ost1"
4727         local tgt="obdfilter"
4728
4729         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4730
4731         test_mkdir $DIR/$tdir
4732         fmd_max_age=$(do_facet $facet \
4733                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4734                 head -n 1")
4735
4736         echo "FMD max age: ${fmd_max_age}s"
4737         touch $DIR/$tdir/$tfile
4738         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4739                 gawk '{cnt=cnt+$1}  END{print cnt}')
4740         echo "FMD before: $fmd"
4741         [[ $fmd == 0 ]] &&
4742                 error "FMD wasn't create by touch"
4743         sleep $((fmd_max_age + 12))
4744         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4745                 gawk '{cnt=cnt+$1}  END{print cnt}')
4746         echo "FMD after: $fmd"
4747         [[ $fmd == 0 ]] ||
4748                 error "FMD wasn't expired by ping"
4749 }
4750 run_test 36g "FMD cache expiry ====================="
4751
4752 test_36h() {
4753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4754
4755         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4756         subr_36fh "0x80000227"
4757 }
4758 run_test 36h "utime on file racing with OST BRW write =========="
4759
4760 test_36i() {
4761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4762
4763         test_mkdir $DIR/$tdir
4764         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4765
4766         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4767         local new_mtime=$((mtime + 200))
4768
4769         #change Modify time of striped dir
4770         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4771                         error "change mtime failed"
4772
4773         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4774
4775         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4776 }
4777 run_test 36i "change mtime on striped directory"
4778
4779 # test_37 - duplicate with tests 32q 32r
4780
4781 test_38() {
4782         local file=$DIR/$tfile
4783         touch $file
4784         openfile -f O_DIRECTORY $file
4785         local RC=$?
4786         local ENOTDIR=20
4787         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4788         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4789 }
4790 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4791
4792 test_39a() { # was test_39
4793         touch $DIR/$tfile
4794         touch $DIR/${tfile}2
4795 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4796 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4797 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4798         sleep 2
4799         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4800         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4801                 echo "mtime"
4802                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4803                 echo "atime"
4804                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4805                 echo "ctime"
4806                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4807                 error "O_TRUNC didn't change timestamps"
4808         fi
4809 }
4810 run_test 39a "mtime changed on create"
4811
4812 test_39b() {
4813         test_mkdir -c1 $DIR/$tdir
4814         cp -p /etc/passwd $DIR/$tdir/fopen
4815         cp -p /etc/passwd $DIR/$tdir/flink
4816         cp -p /etc/passwd $DIR/$tdir/funlink
4817         cp -p /etc/passwd $DIR/$tdir/frename
4818         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4819
4820         sleep 1
4821         echo "aaaaaa" >> $DIR/$tdir/fopen
4822         echo "aaaaaa" >> $DIR/$tdir/flink
4823         echo "aaaaaa" >> $DIR/$tdir/funlink
4824         echo "aaaaaa" >> $DIR/$tdir/frename
4825
4826         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4827         local link_new=`stat -c %Y $DIR/$tdir/flink`
4828         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4829         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4830
4831         cat $DIR/$tdir/fopen > /dev/null
4832         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4833         rm -f $DIR/$tdir/funlink2
4834         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4835
4836         for (( i=0; i < 2; i++ )) ; do
4837                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4838                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4839                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4840                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4841
4842                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4843                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4844                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4845                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4846
4847                 cancel_lru_locks $OSC
4848                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4849         done
4850 }
4851 run_test 39b "mtime change on open, link, unlink, rename  ======"
4852
4853 # this should be set to past
4854 TEST_39_MTIME=`date -d "1 year ago" +%s`
4855
4856 # bug 11063
4857 test_39c() {
4858         touch $DIR1/$tfile
4859         sleep 2
4860         local mtime0=`stat -c %Y $DIR1/$tfile`
4861
4862         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4863         local mtime1=`stat -c %Y $DIR1/$tfile`
4864         [ "$mtime1" = $TEST_39_MTIME ] || \
4865                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4866
4867         local d1=`date +%s`
4868         echo hello >> $DIR1/$tfile
4869         local d2=`date +%s`
4870         local mtime2=`stat -c %Y $DIR1/$tfile`
4871         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4872                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4873
4874         mv $DIR1/$tfile $DIR1/$tfile-1
4875
4876         for (( i=0; i < 2; i++ )) ; do
4877                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4878                 [ "$mtime2" = "$mtime3" ] || \
4879                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4880
4881                 cancel_lru_locks $OSC
4882                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4883         done
4884 }
4885 run_test 39c "mtime change on rename ==========================="
4886
4887 # bug 21114
4888 test_39d() {
4889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4890
4891         touch $DIR1/$tfile
4892         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4893
4894         for (( i=0; i < 2; i++ )) ; do
4895                 local mtime=`stat -c %Y $DIR1/$tfile`
4896                 [ $mtime = $TEST_39_MTIME ] || \
4897                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4898
4899                 cancel_lru_locks $OSC
4900                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4901         done
4902 }
4903 run_test 39d "create, utime, stat =============================="
4904
4905 # bug 21114
4906 test_39e() {
4907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4908
4909         touch $DIR1/$tfile
4910         local mtime1=`stat -c %Y $DIR1/$tfile`
4911
4912         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4913
4914         for (( i=0; i < 2; i++ )) ; do
4915                 local mtime2=`stat -c %Y $DIR1/$tfile`
4916                 [ $mtime2 = $TEST_39_MTIME ] || \
4917                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4918
4919                 cancel_lru_locks $OSC
4920                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4921         done
4922 }
4923 run_test 39e "create, stat, utime, stat ========================"
4924
4925 # bug 21114
4926 test_39f() {
4927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4928
4929         touch $DIR1/$tfile
4930         mtime1=`stat -c %Y $DIR1/$tfile`
4931
4932         sleep 2
4933         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4934
4935         for (( i=0; i < 2; i++ )) ; do
4936                 local mtime2=`stat -c %Y $DIR1/$tfile`
4937                 [ $mtime2 = $TEST_39_MTIME ] || \
4938                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4939
4940                 cancel_lru_locks $OSC
4941                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4942         done
4943 }
4944 run_test 39f "create, stat, sleep, utime, stat ================="
4945
4946 # bug 11063
4947 test_39g() {
4948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4949
4950         echo hello >> $DIR1/$tfile
4951         local mtime1=`stat -c %Y $DIR1/$tfile`
4952
4953         sleep 2
4954         chmod o+r $DIR1/$tfile
4955
4956         for (( i=0; i < 2; i++ )) ; do
4957                 local mtime2=`stat -c %Y $DIR1/$tfile`
4958                 [ "$mtime1" = "$mtime2" ] || \
4959                         error "lost mtime: $mtime2, should be $mtime1"
4960
4961                 cancel_lru_locks $OSC
4962                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4963         done
4964 }
4965 run_test 39g "write, chmod, stat ==============================="
4966
4967 # bug 11063
4968 test_39h() {
4969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4970
4971         touch $DIR1/$tfile
4972         sleep 1
4973
4974         local d1=`date`
4975         echo hello >> $DIR1/$tfile
4976         local mtime1=`stat -c %Y $DIR1/$tfile`
4977
4978         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4979         local d2=`date`
4980         if [ "$d1" != "$d2" ]; then
4981                 echo "write and touch not within one second"
4982         else
4983                 for (( i=0; i < 2; i++ )) ; do
4984                         local mtime2=`stat -c %Y $DIR1/$tfile`
4985                         [ "$mtime2" = $TEST_39_MTIME ] || \
4986                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4987
4988                         cancel_lru_locks $OSC
4989                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4990                 done
4991         fi
4992 }
4993 run_test 39h "write, utime within one second, stat ============="
4994
4995 test_39i() {
4996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4997
4998         touch $DIR1/$tfile
4999         sleep 1
5000
5001         echo hello >> $DIR1/$tfile
5002         local mtime1=`stat -c %Y $DIR1/$tfile`
5003
5004         mv $DIR1/$tfile $DIR1/$tfile-1
5005
5006         for (( i=0; i < 2; i++ )) ; do
5007                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5008
5009                 [ "$mtime1" = "$mtime2" ] || \
5010                         error "lost mtime: $mtime2, should be $mtime1"
5011
5012                 cancel_lru_locks $OSC
5013                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5014         done
5015 }
5016 run_test 39i "write, rename, stat =============================="
5017
5018 test_39j() {
5019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5020
5021         start_full_debug_logging
5022         touch $DIR1/$tfile
5023         sleep 1
5024
5025         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5026         lctl set_param fail_loc=0x80000412
5027         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5028                 error "multiop failed"
5029         local multipid=$!
5030         local mtime1=`stat -c %Y $DIR1/$tfile`
5031
5032         mv $DIR1/$tfile $DIR1/$tfile-1
5033
5034         kill -USR1 $multipid
5035         wait $multipid || error "multiop close failed"
5036
5037         for (( i=0; i < 2; i++ )) ; do
5038                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5039                 [ "$mtime1" = "$mtime2" ] ||
5040                         error "mtime is lost on close: $mtime2, " \
5041                               "should be $mtime1"
5042
5043                 cancel_lru_locks
5044                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5045         done
5046         lctl set_param fail_loc=0
5047         stop_full_debug_logging
5048 }
5049 run_test 39j "write, rename, close, stat ======================="
5050
5051 test_39k() {
5052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5053
5054         touch $DIR1/$tfile
5055         sleep 1
5056
5057         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5058         local multipid=$!
5059         local mtime1=`stat -c %Y $DIR1/$tfile`
5060
5061         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5062
5063         kill -USR1 $multipid
5064         wait $multipid || error "multiop close failed"
5065
5066         for (( i=0; i < 2; i++ )) ; do
5067                 local mtime2=`stat -c %Y $DIR1/$tfile`
5068
5069                 [ "$mtime2" = $TEST_39_MTIME ] || \
5070                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5071
5072                 cancel_lru_locks
5073                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5074         done
5075 }
5076 run_test 39k "write, utime, close, stat ========================"
5077
5078 # this should be set to future
5079 TEST_39_ATIME=`date -d "1 year" +%s`
5080
5081 test_39l() {
5082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5083         remote_mds_nodsh && skip "remote MDS with nodsh"
5084
5085         local atime_diff=$(do_facet $SINGLEMDS \
5086                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5087         rm -rf $DIR/$tdir
5088         mkdir_on_mdt0 $DIR/$tdir
5089
5090         # test setting directory atime to future
5091         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5092         local atime=$(stat -c %X $DIR/$tdir)
5093         [ "$atime" = $TEST_39_ATIME ] ||
5094                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5095
5096         # test setting directory atime from future to now
5097         local now=$(date +%s)
5098         touch -a -d @$now $DIR/$tdir
5099
5100         atime=$(stat -c %X $DIR/$tdir)
5101         [ "$atime" -eq "$now"  ] ||
5102                 error "atime is not updated from future: $atime, $now"
5103
5104         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5105         sleep 3
5106
5107         # test setting directory atime when now > dir atime + atime_diff
5108         local d1=$(date +%s)
5109         ls $DIR/$tdir
5110         local d2=$(date +%s)
5111         cancel_lru_locks mdc
5112         atime=$(stat -c %X $DIR/$tdir)
5113         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5114                 error "atime is not updated  : $atime, should be $d2"
5115
5116         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5117         sleep 3
5118
5119         # test not setting directory atime when now < dir atime + atime_diff
5120         ls $DIR/$tdir
5121         cancel_lru_locks mdc
5122         atime=$(stat -c %X $DIR/$tdir)
5123         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5124                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5125
5126         do_facet $SINGLEMDS \
5127                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5128 }
5129 run_test 39l "directory atime update ==========================="
5130
5131 test_39m() {
5132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5133
5134         touch $DIR1/$tfile
5135         sleep 2
5136         local far_past_mtime=$(date -d "May 29 1953" +%s)
5137         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5138
5139         touch -m -d @$far_past_mtime $DIR1/$tfile
5140         touch -a -d @$far_past_atime $DIR1/$tfile
5141
5142         for (( i=0; i < 2; i++ )) ; do
5143                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5144                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5145                         error "atime or mtime set incorrectly"
5146
5147                 cancel_lru_locks $OSC
5148                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5149         done
5150 }
5151 run_test 39m "test atime and mtime before 1970"
5152
5153 test_39n() { # LU-3832
5154         remote_mds_nodsh && skip "remote MDS with nodsh"
5155
5156         local atime_diff=$(do_facet $SINGLEMDS \
5157                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5158         local atime0
5159         local atime1
5160         local atime2
5161
5162         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5163
5164         rm -rf $DIR/$tfile
5165         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5166         atime0=$(stat -c %X $DIR/$tfile)
5167
5168         sleep 5
5169         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5170         atime1=$(stat -c %X $DIR/$tfile)
5171
5172         sleep 5
5173         cancel_lru_locks mdc
5174         cancel_lru_locks osc
5175         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5176         atime2=$(stat -c %X $DIR/$tfile)
5177
5178         do_facet $SINGLEMDS \
5179                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5180
5181         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5182         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5183 }
5184 run_test 39n "check that O_NOATIME is honored"
5185
5186 test_39o() {
5187         TESTDIR=$DIR/$tdir/$tfile
5188         [ -e $TESTDIR ] && rm -rf $TESTDIR
5189         mkdir -p $TESTDIR
5190         cd $TESTDIR
5191         links1=2
5192         ls
5193         mkdir a b
5194         ls
5195         links2=$(stat -c %h .)
5196         [ $(($links1 + 2)) != $links2 ] &&
5197                 error "wrong links count $(($links1 + 2)) != $links2"
5198         rmdir b
5199         links3=$(stat -c %h .)
5200         [ $(($links1 + 1)) != $links3 ] &&
5201                 error "wrong links count $links1 != $links3"
5202         return 0
5203 }
5204 run_test 39o "directory cached attributes updated after create"
5205
5206 test_39p() {
5207         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5208
5209         local MDTIDX=1
5210         TESTDIR=$DIR/$tdir/$tdir
5211         [ -e $TESTDIR ] && rm -rf $TESTDIR
5212         test_mkdir -p $TESTDIR
5213         cd $TESTDIR
5214         links1=2
5215         ls
5216         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5217         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5218         ls
5219         links2=$(stat -c %h .)
5220         [ $(($links1 + 2)) != $links2 ] &&
5221                 error "wrong links count $(($links1 + 2)) != $links2"
5222         rmdir remote_dir2
5223         links3=$(stat -c %h .)
5224         [ $(($links1 + 1)) != $links3 ] &&
5225                 error "wrong links count $links1 != $links3"
5226         return 0
5227 }
5228 run_test 39p "remote directory cached attributes updated after create ========"
5229
5230 test_39r() {
5231         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5232                 skip "no atime update on old OST"
5233         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5234                 skip_env "ldiskfs only test"
5235         fi
5236
5237         local saved_adiff
5238         saved_adiff=$(do_facet ost1 \
5239                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5240         stack_trap "do_facet ost1 \
5241                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5242
5243         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5244
5245         $LFS setstripe -i 0 $DIR/$tfile
5246         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5247                 error "can't write initial file"
5248         cancel_lru_locks osc
5249
5250         # exceed atime_diff and access file
5251         sleep 10
5252         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5253                 error "can't udpate atime"
5254
5255         local atime_cli=$(stat -c %X $DIR/$tfile)
5256         echo "client atime: $atime_cli"
5257         # allow atime update to be written to device
5258         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5259         sleep 5
5260
5261         local ostdev=$(ostdevname 1)
5262         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5263         local seq=${fid[3]#0x}
5264         local oid=${fid[1]}
5265         local oid_hex
5266
5267         if [ $seq == 0 ]; then
5268                 oid_hex=${fid[1]}
5269         else
5270                 oid_hex=${fid[2]#0x}
5271         fi
5272         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5273         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5274
5275         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5276         local atime_ost=$(do_facet ost1 "$cmd" |&
5277                           awk -F'[: ]' '/atime:/ { print $4 }')
5278         (( atime_cli == atime_ost )) ||
5279                 error "atime on client $atime_cli != ost $atime_ost"
5280 }
5281 run_test 39r "lazy atime update on OST"
5282
5283 test_39q() { # LU-8041
5284         local testdir=$DIR/$tdir
5285         mkdir -p $testdir
5286         multiop_bg_pause $testdir D_c || error "multiop failed"
5287         local multipid=$!
5288         cancel_lru_locks mdc
5289         kill -USR1 $multipid
5290         local atime=$(stat -c %X $testdir)
5291         [ "$atime" -ne 0 ] || error "atime is zero"
5292 }
5293 run_test 39q "close won't zero out atime"
5294
5295 test_39s() {
5296         local atime0
5297         local atime1
5298         local atime2
5299         local atime3
5300         local atime4
5301
5302         umount_client $MOUNT
5303         mount_client $MOUNT relatime
5304
5305         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5306         atime0=$(stat -c %X $DIR/$tfile)
5307
5308         # First read updates atime
5309         sleep 1
5310         cat $DIR/$tfile >/dev/null
5311         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5312
5313         # Next reads do not update atime
5314         sleep 1
5315         cat $DIR/$tfile >/dev/null
5316         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5317
5318         # If mtime is greater than atime, atime is updated
5319         sleep 1
5320         touch -m $DIR/$tfile # (mtime = now)
5321         sleep 1
5322         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5323         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5324
5325         # Next reads do not update atime
5326         sleep 1
5327         cat $DIR/$tfile >/dev/null
5328         atime4=$(stat -c %X $DIR/$tfile)
5329
5330         # Remount the client to clear 'relatime' option
5331         remount_client $MOUNT
5332
5333         (( atime0 < atime1 )) ||
5334                 error "atime $atime0 should be smaller than $atime1"
5335         (( atime1 == atime2 )) ||
5336                 error "atime $atime1 was updated to $atime2"
5337         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5338         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5339 }
5340 run_test 39s "relatime is supported"
5341
5342 test_40() {
5343         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5344         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5345                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5346         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5347                 error "$tfile is not 4096 bytes in size"
5348 }
5349 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5350
5351 test_41() {
5352         # bug 1553
5353         small_write $DIR/f41 18
5354 }
5355 run_test 41 "test small file write + fstat ====================="
5356
5357 count_ost_writes() {
5358         lctl get_param -n ${OSC}.*.stats |
5359                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5360                         END { printf("%0.0f", writes) }'
5361 }
5362
5363 # decent default
5364 WRITEBACK_SAVE=500
5365 DIRTY_RATIO_SAVE=40
5366 MAX_DIRTY_RATIO=50
5367 BG_DIRTY_RATIO_SAVE=10
5368 MAX_BG_DIRTY_RATIO=25
5369
5370 start_writeback() {
5371         trap 0
5372         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5373         # dirty_ratio, dirty_background_ratio
5374         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5375                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5376                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5377                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5378         else
5379                 # if file not here, we are a 2.4 kernel
5380                 kill -CONT `pidof kupdated`
5381         fi
5382 }
5383
5384 stop_writeback() {
5385         # setup the trap first, so someone cannot exit the test at the
5386         # exact wrong time and mess up a machine
5387         trap start_writeback EXIT
5388         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5389         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5390                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5391                 sysctl -w vm.dirty_writeback_centisecs=0
5392                 sysctl -w vm.dirty_writeback_centisecs=0
5393                 # save and increase /proc/sys/vm/dirty_ratio
5394                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5395                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5396                 # save and increase /proc/sys/vm/dirty_background_ratio
5397                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5398                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5399         else
5400                 # if file not here, we are a 2.4 kernel
5401                 kill -STOP `pidof kupdated`
5402         fi
5403 }
5404
5405 # ensure that all stripes have some grant before we test client-side cache
5406 setup_test42() {
5407         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5408                 dd if=/dev/zero of=$i bs=4k count=1
5409                 rm $i
5410         done
5411 }
5412
5413 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5414 # file truncation, and file removal.
5415 test_42a() {
5416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5417
5418         setup_test42
5419         cancel_lru_locks $OSC
5420         stop_writeback
5421         sync; sleep 1; sync # just to be safe
5422         BEFOREWRITES=`count_ost_writes`
5423         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5424         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5425         AFTERWRITES=`count_ost_writes`
5426         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5427                 error "$BEFOREWRITES < $AFTERWRITES"
5428         start_writeback
5429 }
5430 run_test 42a "ensure that we don't flush on close"
5431
5432 test_42b() {
5433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5434
5435         setup_test42
5436         cancel_lru_locks $OSC
5437         stop_writeback
5438         sync
5439         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5440         BEFOREWRITES=$(count_ost_writes)
5441         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5442         AFTERWRITES=$(count_ost_writes)
5443         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5444                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5445         fi
5446         BEFOREWRITES=$(count_ost_writes)
5447         sync || error "sync: $?"
5448         AFTERWRITES=$(count_ost_writes)
5449         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5450                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5451         fi
5452         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5453         start_writeback
5454         return 0
5455 }
5456 run_test 42b "test destroy of file with cached dirty data ======"
5457
5458 # if these tests just want to test the effect of truncation,
5459 # they have to be very careful.  consider:
5460 # - the first open gets a {0,EOF}PR lock
5461 # - the first write conflicts and gets a {0, count-1}PW
5462 # - the rest of the writes are under {count,EOF}PW
5463 # - the open for truncate tries to match a {0,EOF}PR
5464 #   for the filesize and cancels the PWs.
5465 # any number of fixes (don't get {0,EOF} on open, match
5466 # composite locks, do smarter file size management) fix
5467 # this, but for now we want these tests to verify that
5468 # the cancellation with truncate intent works, so we
5469 # start the file with a full-file pw lock to match against
5470 # until the truncate.
5471 trunc_test() {
5472         test=$1
5473         file=$DIR/$test
5474         offset=$2
5475         cancel_lru_locks $OSC
5476         stop_writeback
5477         # prime the file with 0,EOF PW to match
5478         touch $file
5479         $TRUNCATE $file 0
5480         sync; sync
5481         # now the real test..
5482         dd if=/dev/zero of=$file bs=1024 count=100
5483         BEFOREWRITES=`count_ost_writes`
5484         $TRUNCATE $file $offset
5485         cancel_lru_locks $OSC
5486         AFTERWRITES=`count_ost_writes`
5487         start_writeback
5488 }
5489
5490 test_42c() {
5491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5492
5493         trunc_test 42c 1024
5494         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5495                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5496         rm $file
5497 }
5498 run_test 42c "test partial truncate of file with cached dirty data"
5499
5500 test_42d() {
5501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5502
5503         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5504         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5505         $LCTL set_param debug=+cache
5506
5507         trunc_test 42d 0
5508         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5509                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5510         rm $file
5511 }
5512 run_test 42d "test complete truncate of file with cached dirty data"
5513
5514 test_42e() { # bug22074
5515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5516
5517         local TDIR=$DIR/${tdir}e
5518         local pages=16 # hardcoded 16 pages, don't change it.
5519         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5520         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5521         local max_dirty_mb
5522         local warmup_files
5523
5524         test_mkdir $DIR/${tdir}e
5525         $LFS setstripe -c 1 $TDIR
5526         createmany -o $TDIR/f $files
5527
5528         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5529
5530         # we assume that with $OSTCOUNT files, at least one of them will
5531         # be allocated on OST0.
5532         warmup_files=$((OSTCOUNT * max_dirty_mb))
5533         createmany -o $TDIR/w $warmup_files
5534
5535         # write a large amount of data into one file and sync, to get good
5536         # avail_grant number from OST.
5537         for ((i=0; i<$warmup_files; i++)); do
5538                 idx=$($LFS getstripe -i $TDIR/w$i)
5539                 [ $idx -ne 0 ] && continue
5540                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5541                 break
5542         done
5543         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5544         sync
5545         $LCTL get_param $proc_osc0/cur_dirty_bytes
5546         $LCTL get_param $proc_osc0/cur_grant_bytes
5547
5548         # create as much dirty pages as we can while not to trigger the actual
5549         # RPCs directly. but depends on the env, VFS may trigger flush during this
5550         # period, hopefully we are good.
5551         for ((i=0; i<$warmup_files; i++)); do
5552                 idx=$($LFS getstripe -i $TDIR/w$i)
5553                 [ $idx -ne 0 ] && continue
5554                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5555         done
5556         $LCTL get_param $proc_osc0/cur_dirty_bytes
5557         $LCTL get_param $proc_osc0/cur_grant_bytes
5558
5559         # perform the real test
5560         $LCTL set_param $proc_osc0/rpc_stats 0
5561         for ((;i<$files; i++)); do
5562                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5563                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5564         done
5565         sync
5566         $LCTL get_param $proc_osc0/rpc_stats
5567
5568         local percent=0
5569         local have_ppr=false
5570         $LCTL get_param $proc_osc0/rpc_stats |
5571                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5572                         # skip lines until we are at the RPC histogram data
5573                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5574                         $have_ppr || continue
5575
5576                         # we only want the percent stat for < 16 pages
5577                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5578
5579                         percent=$((percent + WPCT))
5580                         if [[ $percent -gt 15 ]]; then
5581                                 error "less than 16-pages write RPCs" \
5582                                       "$percent% > 15%"
5583                                 break
5584                         fi
5585                 done
5586         rm -rf $TDIR
5587 }
5588 run_test 42e "verify sub-RPC writes are not done synchronously"
5589
5590 test_43A() { # was test_43
5591         test_mkdir $DIR/$tdir
5592         cp -p /bin/ls $DIR/$tdir/$tfile
5593         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5594         pid=$!
5595         # give multiop a chance to open
5596         sleep 1
5597
5598         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5599         kill -USR1 $pid
5600         # Wait for multiop to exit
5601         wait $pid
5602 }
5603 run_test 43A "execution of file opened for write should return -ETXTBSY"
5604
5605 test_43a() {
5606         test_mkdir $DIR/$tdir
5607         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5608         $DIR/$tdir/sleep 60 &
5609         SLEEP_PID=$!
5610         # Make sure exec of $tdir/sleep wins race with truncate
5611         sleep 1
5612         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5613         kill $SLEEP_PID
5614 }
5615 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5616
5617 test_43b() {
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619
5620         test_mkdir $DIR/$tdir
5621         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5622         $DIR/$tdir/sleep 60 &
5623         SLEEP_PID=$!
5624         # Make sure exec of $tdir/sleep wins race with truncate
5625         sleep 1
5626         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5627         kill $SLEEP_PID
5628 }
5629 run_test 43b "truncate of file being executed should return -ETXTBSY"
5630
5631 test_43c() {
5632         local testdir="$DIR/$tdir"
5633         test_mkdir $testdir
5634         cp $SHELL $testdir/
5635         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5636                 ( cd $testdir && md5sum -c )
5637 }
5638 run_test 43c "md5sum of copy into lustre"
5639
5640 test_44A() { # was test_44
5641         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5642
5643         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5644         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5645 }
5646 run_test 44A "zero length read from a sparse stripe"
5647
5648 test_44a() {
5649         local nstripe=$($LFS getstripe -c -d $DIR)
5650         [ -z "$nstripe" ] && skip "can't get stripe info"
5651         [[ $nstripe -gt $OSTCOUNT ]] &&
5652                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5653
5654         local stride=$($LFS getstripe -S -d $DIR)
5655         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5656                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5657         fi
5658
5659         OFFSETS="0 $((stride/2)) $((stride-1))"
5660         for offset in $OFFSETS; do
5661                 for i in $(seq 0 $((nstripe-1))); do
5662                         local GLOBALOFFSETS=""
5663                         # size in Bytes
5664                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5665                         local myfn=$DIR/d44a-$size
5666                         echo "--------writing $myfn at $size"
5667                         ll_sparseness_write $myfn $size ||
5668                                 error "ll_sparseness_write"
5669                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5670                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5671                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5672
5673                         for j in $(seq 0 $((nstripe-1))); do
5674                                 # size in Bytes
5675                                 size=$((((j + $nstripe )*$stride + $offset)))
5676                                 ll_sparseness_write $myfn $size ||
5677                                         error "ll_sparseness_write"
5678                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5679                         done
5680                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5681                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5682                         rm -f $myfn
5683                 done
5684         done
5685 }
5686 run_test 44a "test sparse pwrite ==============================="
5687
5688 dirty_osc_total() {
5689         tot=0
5690         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5691                 tot=$(($tot + $d))
5692         done
5693         echo $tot
5694 }
5695 do_dirty_record() {
5696         before=`dirty_osc_total`
5697         echo executing "\"$*\""
5698         eval $*
5699         after=`dirty_osc_total`
5700         echo before $before, after $after
5701 }
5702 test_45() {
5703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5704
5705         f="$DIR/f45"
5706         # Obtain grants from OST if it supports it
5707         echo blah > ${f}_grant
5708         stop_writeback
5709         sync
5710         do_dirty_record "echo blah > $f"
5711         [[ $before -eq $after ]] && error "write wasn't cached"
5712         do_dirty_record "> $f"
5713         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5714         do_dirty_record "echo blah > $f"
5715         [[ $before -eq $after ]] && error "write wasn't cached"
5716         do_dirty_record "sync"
5717         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5718         do_dirty_record "echo blah > $f"
5719         [[ $before -eq $after ]] && error "write wasn't cached"
5720         do_dirty_record "cancel_lru_locks osc"
5721         [[ $before -gt $after ]] ||
5722                 error "lock cancellation didn't lower dirty count"
5723         start_writeback
5724 }
5725 run_test 45 "osc io page accounting ============================"
5726
5727 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5728 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5729 # objects offset and an assert hit when an rpc was built with 1023's mapped
5730 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5731 test_46() {
5732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5733
5734         f="$DIR/f46"
5735         stop_writeback
5736         sync
5737         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5738         sync
5739         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5740         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5741         sync
5742         start_writeback
5743 }
5744 run_test 46 "dirtying a previously written page ================"
5745
5746 # test_47 is removed "Device nodes check" is moved to test_28
5747
5748 test_48a() { # bug 2399
5749         [ "$mds1_FSTYPE" = "zfs" ] &&
5750         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5751                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5752
5753         test_mkdir $DIR/$tdir
5754         cd $DIR/$tdir
5755         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5756         test_mkdir $DIR/$tdir
5757         touch foo || error "'touch foo' failed after recreating cwd"
5758         test_mkdir bar
5759         touch .foo || error "'touch .foo' failed after recreating cwd"
5760         test_mkdir .bar
5761         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5762         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5763         cd . || error "'cd .' failed after recreating cwd"
5764         mkdir . && error "'mkdir .' worked after recreating cwd"
5765         rmdir . && error "'rmdir .' worked after recreating cwd"
5766         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5767         cd .. || error "'cd ..' failed after recreating cwd"
5768 }
5769 run_test 48a "Access renamed working dir (should return errors)="
5770
5771 test_48b() { # bug 2399
5772         rm -rf $DIR/$tdir
5773         test_mkdir $DIR/$tdir
5774         cd $DIR/$tdir
5775         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5776         touch foo && error "'touch foo' worked after removing cwd"
5777         mkdir foo && error "'mkdir foo' worked after removing cwd"
5778         touch .foo && error "'touch .foo' worked after removing cwd"
5779         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5780         ls . > /dev/null && error "'ls .' worked after removing cwd"
5781         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5782         mkdir . && error "'mkdir .' worked after removing cwd"
5783         rmdir . && error "'rmdir .' worked after removing cwd"
5784         ln -s . foo && error "'ln -s .' worked after removing cwd"
5785         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5786 }
5787 run_test 48b "Access removed working dir (should return errors)="
5788
5789 test_48c() { # bug 2350
5790         #lctl set_param debug=-1
5791         #set -vx
5792         rm -rf $DIR/$tdir
5793         test_mkdir -p $DIR/$tdir/dir
5794         cd $DIR/$tdir/dir
5795         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5796         $TRACE touch foo && error "touch foo worked after removing cwd"
5797         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5798         touch .foo && error "touch .foo worked after removing cwd"
5799         mkdir .foo && error "mkdir .foo worked after removing cwd"
5800         $TRACE ls . && error "'ls .' worked after removing cwd"
5801         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5802         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5803         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5804         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5805         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5806 }
5807 run_test 48c "Access removed working subdir (should return errors)"
5808
5809 test_48d() { # bug 2350
5810         #lctl set_param debug=-1
5811         #set -vx
5812         rm -rf $DIR/$tdir
5813         test_mkdir -p $DIR/$tdir/dir
5814         cd $DIR/$tdir/dir
5815         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5816         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5817         $TRACE touch foo && error "'touch foo' worked after removing parent"
5818         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5819         touch .foo && error "'touch .foo' worked after removing parent"
5820         mkdir .foo && error "mkdir .foo worked after removing parent"
5821         $TRACE ls . && error "'ls .' worked after removing parent"
5822         $TRACE ls .. && error "'ls ..' worked after removing parent"
5823         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5824         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5825         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5826         true
5827 }
5828 run_test 48d "Access removed parent subdir (should return errors)"
5829
5830 test_48e() { # bug 4134
5831         #lctl set_param debug=-1
5832         #set -vx
5833         rm -rf $DIR/$tdir
5834         test_mkdir -p $DIR/$tdir/dir
5835         cd $DIR/$tdir/dir
5836         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5837         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5838         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5839         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5840         # On a buggy kernel addition of "touch foo" after cd .. will
5841         # produce kernel oops in lookup_hash_it
5842         touch ../foo && error "'cd ..' worked after recreate parent"
5843         cd $DIR
5844         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5845 }
5846 run_test 48e "Access to recreated parent subdir (should return errors)"
5847
5848 test_48f() {
5849         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5850                 skip "need MDS >= 2.13.55"
5851         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5852         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5853                 skip "needs different host for mdt1 mdt2"
5854         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5855
5856         $LFS mkdir -i0 $DIR/$tdir
5857         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5858
5859         for d in sub1 sub2 sub3; do
5860                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5861                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5862                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5863         done
5864
5865         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5866 }
5867 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5868
5869 test_49() { # LU-1030
5870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5871         remote_ost_nodsh && skip "remote OST with nodsh"
5872
5873         # get ost1 size - $FSNAME-OST0000
5874         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5875                 awk '{ print $4 }')
5876         # write 800M at maximum
5877         [[ $ost1_size -lt 2 ]] && ost1_size=2
5878         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5879
5880         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5881         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5882         local dd_pid=$!
5883
5884         # change max_pages_per_rpc while writing the file
5885         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5886         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5887         # loop until dd process exits
5888         while ps ax -opid | grep -wq $dd_pid; do
5889                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5890                 sleep $((RANDOM % 5 + 1))
5891         done
5892         # restore original max_pages_per_rpc
5893         $LCTL set_param $osc1_mppc=$orig_mppc
5894         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5895 }
5896 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5897
5898 test_50() {
5899         # bug 1485
5900         test_mkdir $DIR/$tdir
5901         cd $DIR/$tdir
5902         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5903 }
5904 run_test 50 "special situations: /proc symlinks  ==============="
5905
5906 test_51a() {    # was test_51
5907         # bug 1516 - create an empty entry right after ".." then split dir
5908         test_mkdir -c1 $DIR/$tdir
5909         touch $DIR/$tdir/foo
5910         $MCREATE $DIR/$tdir/bar
5911         rm $DIR/$tdir/foo
5912         createmany -m $DIR/$tdir/longfile 201
5913         FNUM=202
5914         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5915                 $MCREATE $DIR/$tdir/longfile$FNUM
5916                 FNUM=$(($FNUM + 1))
5917                 echo -n "+"
5918         done
5919         echo
5920         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5921 }
5922 run_test 51a "special situations: split htree with empty entry =="
5923
5924 cleanup_print_lfs_df () {
5925         trap 0
5926         $LFS df
5927         $LFS df -i
5928 }
5929
5930 test_51b() {
5931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5932
5933         local dir=$DIR/$tdir
5934         local nrdirs=$((65536 + 100))
5935
5936         # cleanup the directory
5937         rm -fr $dir
5938
5939         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5940
5941         $LFS df
5942         $LFS df -i
5943         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5944         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5945         [[ $numfree -lt $nrdirs ]] &&
5946                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5947
5948         # need to check free space for the directories as well
5949         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5950         numfree=$(( blkfree / $(fs_inode_ksize) ))
5951         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5952
5953         trap cleanup_print_lfs_df EXIT
5954
5955         # create files
5956         createmany -d $dir/d $nrdirs || {
5957                 unlinkmany $dir/d $nrdirs
5958                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5959         }
5960
5961         # really created :
5962         nrdirs=$(ls -U $dir | wc -l)
5963
5964         # unlink all but 100 subdirectories, then check it still works
5965         local left=100
5966         local delete=$((nrdirs - left))
5967
5968         $LFS df
5969         $LFS df -i
5970
5971         # for ldiskfs the nlink count should be 1, but this is OSD specific
5972         # and so this is listed for informational purposes only
5973         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5974         unlinkmany -d $dir/d $delete ||
5975                 error "unlink of first $delete subdirs failed"
5976
5977         echo "nlink between: $(stat -c %h $dir)"
5978         local found=$(ls -U $dir | wc -l)
5979         [ $found -ne $left ] &&
5980                 error "can't find subdirs: found only $found, expected $left"
5981
5982         unlinkmany -d $dir/d $delete $left ||
5983                 error "unlink of second $left subdirs failed"
5984         # regardless of whether the backing filesystem tracks nlink accurately
5985         # or not, the nlink count shouldn't be more than "." and ".." here
5986         local after=$(stat -c %h $dir)
5987         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5988                 echo "nlink after: $after"
5989
5990         cleanup_print_lfs_df
5991 }
5992 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5993
5994 test_51d_sub() {
5995         local stripecount=$1
5996         local nfiles=$2
5997
5998         log "create files with stripecount=$stripecount"
5999         $LFS setstripe -C $stripecount $DIR/$tdir
6000         createmany -o $DIR/$tdir/t- $nfiles
6001         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6002         for ((n = 0; n < $OSTCOUNT; n++)); do
6003                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6004                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6005                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6006                             '($1 == '$n') { objs += 1 } \
6007                             END { printf("%0.0f", objs) }')
6008                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6009         done
6010         unlinkmany $DIR/$tdir/t- $nfiles
6011         rm  -f $TMP/$tfile
6012
6013         local nlast
6014         local min=4
6015         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6016
6017         # For some combinations of stripecount and OSTCOUNT current code
6018         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6019         # than others. Rather than skipping this test entirely, check that
6020         # and keep testing to ensure imbalance does not get worse. LU-15282
6021         (( (OSTCOUNT == 6 && stripecount == 4) ||
6022            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6023            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6024         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6025                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6026                         { $LFS df && $LFS df -i &&
6027                         error "stripecount=$stripecount: " \
6028                               "OST $n has fewer objects vs. OST $nlast " \
6029                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6030                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6031                         { $LFS df && $LFS df -i &&
6032                         error "stripecount=$stripecount: " \
6033                               "OST $n has more objects vs. OST $nlast " \
6034                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6035
6036                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6037                         { $LFS df && $LFS df -i &&
6038                         error "stripecount=$stripecount: " \
6039                               "OST $n has fewer #0 objects vs. OST $nlast " \
6040                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6041                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6042                         { $LFS df && $LFS df -i &&
6043                         error "stripecount=$stripecount: " \
6044                               "OST $n has more #0 objects vs. OST $nlast " \
6045                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6046         done
6047 }
6048
6049 test_51d() {
6050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6051         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6052
6053         local stripecount
6054         local per_ost=100
6055         local nfiles=$((per_ost * OSTCOUNT))
6056         local mdts=$(comma_list $(mdts_nodes))
6057         local param="osp.*.create_count"
6058         local qos_old=$(do_facet mds1 \
6059                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6060
6061         do_nodes $mdts \
6062                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6063         stack_trap "do_nodes $mdts \
6064                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6065
6066         test_mkdir $DIR/$tdir
6067         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6068         (( dirstripes > 0 )) || dirstripes=1
6069
6070         # Ensure enough OST objects precreated for tests to pass without
6071         # running out of objects.  This is an LOV r-r OST algorithm test,
6072         # not an OST object precreation test.
6073         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6074         (( old >= nfiles )) ||
6075         {
6076                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6077
6078                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6079                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6080
6081                 # trigger precreation from all MDTs for all OSTs
6082                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6083                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6084                 done
6085         }
6086
6087         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6088                 sleep 8  # allow object precreation to catch up
6089                 test_51d_sub $stripecount $nfiles
6090         done
6091 }
6092 run_test 51d "check LOV round-robin OST object distribution"
6093
6094 test_51e() {
6095         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6096                 skip_env "ldiskfs only test"
6097         fi
6098
6099         test_mkdir -c1 $DIR/$tdir
6100         test_mkdir -c1 $DIR/$tdir/d0
6101
6102         touch $DIR/$tdir/d0/foo
6103         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6104                 error "file exceed 65000 nlink limit!"
6105         unlinkmany $DIR/$tdir/d0/f- 65001
6106         return 0
6107 }
6108 run_test 51e "check file nlink limit"
6109
6110 test_51f() {
6111         test_mkdir $DIR/$tdir
6112
6113         local max=100000
6114         local ulimit_old=$(ulimit -n)
6115         local spare=20 # number of spare fd's for scripts/libraries, etc.
6116         local mdt=$($LFS getstripe -m $DIR/$tdir)
6117         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6118
6119         echo "MDT$mdt numfree=$numfree, max=$max"
6120         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6121         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6122                 while ! ulimit -n $((numfree + spare)); do
6123                         numfree=$((numfree * 3 / 4))
6124                 done
6125                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6126         else
6127                 echo "left ulimit at $ulimit_old"
6128         fi
6129
6130         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6131                 unlinkmany $DIR/$tdir/f $numfree
6132                 error "create+open $numfree files in $DIR/$tdir failed"
6133         }
6134         ulimit -n $ulimit_old
6135
6136         # if createmany exits at 120s there will be fewer than $numfree files
6137         unlinkmany $DIR/$tdir/f $numfree || true
6138 }
6139 run_test 51f "check many open files limit"
6140
6141 test_52a() {
6142         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6143         test_mkdir $DIR/$tdir
6144         touch $DIR/$tdir/foo
6145         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6146         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6147         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6148         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6149         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6150                                         error "link worked"
6151         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6152         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6153         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6154                                                      error "lsattr"
6155         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6156         cp -r $DIR/$tdir $TMP/
6157         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6158 }
6159 run_test 52a "append-only flag test (should return errors)"
6160
6161 test_52b() {
6162         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6163         test_mkdir $DIR/$tdir
6164         touch $DIR/$tdir/foo
6165         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6166         cat test > $DIR/$tdir/foo && error "cat test worked"
6167         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6168         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6169         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6170                                         error "link worked"
6171         echo foo >> $DIR/$tdir/foo && error "echo worked"
6172         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6173         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6174         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6175         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6176                                                         error "lsattr"
6177         chattr -i $DIR/$tdir/foo || error "chattr failed"
6178
6179         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6180 }
6181 run_test 52b "immutable flag test (should return errors) ======="
6182
6183 test_53() {
6184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6185         remote_mds_nodsh && skip "remote MDS with nodsh"
6186         remote_ost_nodsh && skip "remote OST with nodsh"
6187
6188         local param
6189         local param_seq
6190         local ostname
6191         local mds_last
6192         local mds_last_seq
6193         local ost_last
6194         local ost_last_seq
6195         local ost_last_id
6196         local ostnum
6197         local node
6198         local found=false
6199         local support_last_seq=true
6200
6201         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6202                 support_last_seq=false
6203
6204         # only test MDT0000
6205         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6206         local value
6207         for value in $(do_facet $SINGLEMDS \
6208                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6209                 param=$(echo ${value[0]} | cut -d "=" -f1)
6210                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6211
6212                 if $support_last_seq; then
6213                         param_seq=$(echo $param |
6214                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6215                         mds_last_seq=$(do_facet $SINGLEMDS \
6216                                        $LCTL get_param -n $param_seq)
6217                 fi
6218                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6219
6220                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6221                 node=$(facet_active_host ost$((ostnum+1)))
6222                 param="obdfilter.$ostname.last_id"
6223                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6224                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6225                         ost_last_id=$ost_last
6226
6227                         if $support_last_seq; then
6228                                 ost_last_id=$(echo $ost_last |
6229                                               awk -F':' '{print $2}' |
6230                                               sed -e "s/^0x//g")
6231                                 ost_last_seq=$(echo $ost_last |
6232                                                awk -F':' '{print $1}')
6233                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6234                         fi
6235
6236                         if [[ $ost_last_id != $mds_last ]]; then
6237                                 error "$ost_last_id != $mds_last"
6238                         else
6239                                 found=true
6240                                 break
6241                         fi
6242                 done
6243         done
6244         $found || error "can not match last_seq/last_id for $mdtosc"
6245         return 0
6246 }
6247 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6248
6249 test_54a() {
6250         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6251
6252         LANG=C $SOCKETSERVER $DIR/socket ||
6253                 error "$SOCKETSERVER $DIR/socket failed: $?"
6254         LANG=C $SOCKETCLIENT $DIR/socket ||
6255                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6256         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6257 }
6258 run_test 54a "unix domain socket test =========================="
6259
6260 test_54b() {
6261         f="$DIR/f54b"
6262         mknod $f c 1 3
6263         chmod 0666 $f
6264         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6265 }
6266 run_test 54b "char device works in lustre ======================"
6267
6268 find_loop_dev() {
6269         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6270         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6271         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6272
6273         for i in $(seq 3 7); do
6274                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6275                 LOOPDEV=$LOOPBASE$i
6276                 LOOPNUM=$i
6277                 break
6278         done
6279 }
6280
6281 cleanup_54c() {
6282         local rc=0
6283         loopdev="$DIR/loop54c"
6284
6285         trap 0
6286         $UMOUNT $DIR/$tdir || rc=$?
6287         losetup -d $loopdev || true
6288         losetup -d $LOOPDEV || true
6289         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6290         return $rc
6291 }
6292
6293 test_54c() {
6294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6295
6296         loopdev="$DIR/loop54c"
6297
6298         find_loop_dev
6299         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6300         trap cleanup_54c EXIT
6301         mknod $loopdev b 7 $LOOPNUM
6302         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6303         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6304         losetup $loopdev $DIR/$tfile ||
6305                 error "can't set up $loopdev for $DIR/$tfile"
6306         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6307         test_mkdir $DIR/$tdir
6308         mount -t ext2 $loopdev $DIR/$tdir ||
6309                 error "error mounting $loopdev on $DIR/$tdir"
6310         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6311                 error "dd write"
6312         df $DIR/$tdir
6313         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6314                 error "dd read"
6315         cleanup_54c
6316 }
6317 run_test 54c "block device works in lustre ====================="
6318
6319 test_54d() {
6320         local pipe="$DIR/$tfile.pipe"
6321         local string="aaaaaa"
6322
6323         mknod $pipe p
6324         echo -n "$string" > $pipe &
6325         local result=$(cat $pipe)
6326         [[ "$result" == "$string" ]] || error "$result != $string"
6327 }
6328 run_test 54d "fifo device works in lustre ======================"
6329
6330 test_54e() {
6331         f="$DIR/f54e"
6332         string="aaaaaa"
6333         cp -aL /dev/console $f
6334         echo $string > $f || error "echo $string to $f failed"
6335 }
6336 run_test 54e "console/tty device works in lustre ======================"
6337
6338 test_56a() {
6339         local numfiles=3
6340         local numdirs=2
6341         local dir=$DIR/$tdir
6342
6343         rm -rf $dir
6344         test_mkdir -p $dir/dir
6345         for i in $(seq $numfiles); do
6346                 touch $dir/file$i
6347                 touch $dir/dir/file$i
6348         done
6349
6350         local numcomp=$($LFS getstripe --component-count $dir)
6351
6352         [[ $numcomp == 0 ]] && numcomp=1
6353
6354         # test lfs getstripe with --recursive
6355         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6356
6357         [[ $filenum -eq $((numfiles * 2)) ]] ||
6358                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6359         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6360         [[ $filenum -eq $numfiles ]] ||
6361                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6362         echo "$LFS getstripe showed obdidx or l_ost_idx"
6363
6364         # test lfs getstripe with file instead of dir
6365         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6366         [[ $filenum -eq 1 ]] ||
6367                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6368         echo "$LFS getstripe file1 passed"
6369
6370         #test lfs getstripe with --verbose
6371         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6372         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6373                 error "$LFS getstripe --verbose $dir: "\
6374                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6375         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6376                 error "$LFS getstripe $dir: showed lmm_magic"
6377
6378         #test lfs getstripe with -v prints lmm_fid
6379         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6380         local countfids=$((numdirs + numfiles * numcomp))
6381         [[ $filenum -eq $countfids ]] ||
6382                 error "$LFS getstripe -v $dir: "\
6383                       "got $filenum want $countfids lmm_fid"
6384         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6385                 error "$LFS getstripe $dir: showed lmm_fid by default"
6386         echo "$LFS getstripe --verbose passed"
6387
6388         #check for FID information
6389         local fid1=$($LFS getstripe --fid $dir/file1)
6390         local fid2=$($LFS getstripe --verbose $dir/file1 |
6391                      awk '/lmm_fid: / { print $2; exit; }')
6392         local fid3=$($LFS path2fid $dir/file1)
6393
6394         [ "$fid1" != "$fid2" ] &&
6395                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6396         [ "$fid1" != "$fid3" ] &&
6397                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6398         echo "$LFS getstripe --fid passed"
6399
6400         #test lfs getstripe with --obd
6401         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6402                 error "$LFS getstripe --obd wrong_uuid: should return error"
6403
6404         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6405
6406         local ostidx=1
6407         local obduuid=$(ostuuid_from_index $ostidx)
6408         local found=$($LFS getstripe -r --obd $obduuid $dir |
6409                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6410
6411         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6412         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6413                 ((filenum--))
6414         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6415                 ((filenum--))
6416
6417         [[ $found -eq $filenum ]] ||
6418                 error "$LFS getstripe --obd: found $found expect $filenum"
6419         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6420                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6421                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6422                 error "$LFS getstripe --obd: should not show file on other obd"
6423         echo "$LFS getstripe --obd passed"
6424 }
6425 run_test 56a "check $LFS getstripe"
6426
6427 test_56b() {
6428         local dir=$DIR/$tdir
6429         local numdirs=3
6430
6431         test_mkdir $dir
6432         for i in $(seq $numdirs); do
6433                 test_mkdir $dir/dir$i
6434         done
6435
6436         # test lfs getdirstripe default mode is non-recursion, which is
6437         # different from lfs getstripe
6438         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6439
6440         [[ $dircnt -eq 1 ]] ||
6441                 error "$LFS getdirstripe: found $dircnt, not 1"
6442         dircnt=$($LFS getdirstripe --recursive $dir |
6443                 grep -c lmv_stripe_count)
6444         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6445                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6446 }
6447 run_test 56b "check $LFS getdirstripe"
6448
6449 test_56bb() {
6450         verify_yaml_available || skip_env "YAML verification not installed"
6451         local output_file=$DIR/$tfile.out
6452
6453         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6454
6455         cat $output_file
6456         cat $output_file | verify_yaml || error "layout is not valid YAML"
6457 }
6458 run_test 56bb "check $LFS getdirstripe layout is YAML"
6459
6460 test_56c() {
6461         remote_ost_nodsh && skip "remote OST with nodsh"
6462
6463         local ost_idx=0
6464         local ost_name=$(ostname_from_index $ost_idx)
6465         local old_status=$(ost_dev_status $ost_idx)
6466         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6467
6468         [[ -z "$old_status" ]] ||
6469                 skip_env "OST $ost_name is in $old_status status"
6470
6471         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6472         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6473                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6474         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6475                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6476                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6477         fi
6478
6479         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6480                 error "$LFS df -v showing inactive devices"
6481         sleep_maxage
6482
6483         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6484
6485         [[ "$new_status" =~ "D" ]] ||
6486                 error "$ost_name status is '$new_status', missing 'D'"
6487         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6488                 [[ "$new_status" =~ "N" ]] ||
6489                         error "$ost_name status is '$new_status', missing 'N'"
6490         fi
6491         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6492                 [[ "$new_status" =~ "f" ]] ||
6493                         error "$ost_name status is '$new_status', missing 'f'"
6494         fi
6495
6496         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6497         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6498                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6499         [[ -z "$p" ]] && restore_lustre_params < $p || true
6500         sleep_maxage
6501
6502         new_status=$(ost_dev_status $ost_idx)
6503         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6504                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6505         # can't check 'f' as devices may actually be on flash
6506 }
6507 run_test 56c "check 'lfs df' showing device status"
6508
6509 test_56d() {
6510         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6511         local osts=$($LFS df -v $MOUNT | grep -c OST)
6512
6513         $LFS df $MOUNT
6514
6515         (( mdts == MDSCOUNT )) ||
6516                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6517         (( osts == OSTCOUNT )) ||
6518                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6519 }
6520 run_test 56d "'lfs df -v' prints only configured devices"
6521
6522 test_56e() {
6523         err_enoent=2 # No such file or directory
6524         err_eopnotsupp=95 # Operation not supported
6525
6526         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6527         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6528
6529         # Check for handling of path not exists
6530         output=$($LFS df $enoent_mnt 2>&1)
6531         ret=$?
6532
6533         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6534         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6535                 error "expect failure $err_enoent, not $ret"
6536
6537         # Check for handling of non-Lustre FS
6538         output=$($LFS df $notsup_mnt)
6539         ret=$?
6540
6541         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6542         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6543                 error "expect success $err_eopnotsupp, not $ret"
6544
6545         # Check for multiple LustreFS argument
6546         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6547         ret=$?
6548
6549         [[ $output -eq 3 && $ret -eq 0 ]] ||
6550                 error "expect success 3, not $output, rc = $ret"
6551
6552         # Check for correct non-Lustre FS handling among multiple
6553         # LustreFS argument
6554         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6555                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6556         ret=$?
6557
6558         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6559                 error "expect success 2, not $output, rc = $ret"
6560 }
6561 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6562
6563 NUMFILES=3
6564 NUMDIRS=3
6565 setup_56() {
6566         local local_tdir="$1"
6567         local local_numfiles="$2"
6568         local local_numdirs="$3"
6569         local dir_params="$4"
6570         local dir_stripe_params="$5"
6571
6572         if [ ! -d "$local_tdir" ] ; then
6573                 test_mkdir -p $dir_stripe_params $local_tdir
6574                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6575                 for i in $(seq $local_numfiles) ; do
6576                         touch $local_tdir/file$i
6577                 done
6578                 for i in $(seq $local_numdirs) ; do
6579                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6580                         for j in $(seq $local_numfiles) ; do
6581                                 touch $local_tdir/dir$i/file$j
6582                         done
6583                 done
6584         fi
6585 }
6586
6587 setup_56_special() {
6588         local local_tdir=$1
6589         local local_numfiles=$2
6590         local local_numdirs=$3
6591
6592         setup_56 $local_tdir $local_numfiles $local_numdirs
6593
6594         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6595                 for i in $(seq $local_numfiles) ; do
6596                         mknod $local_tdir/loop${i}b b 7 $i
6597                         mknod $local_tdir/null${i}c c 1 3
6598                         ln -s $local_tdir/file1 $local_tdir/link${i}
6599                 done
6600                 for i in $(seq $local_numdirs) ; do
6601                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6602                         mknod $local_tdir/dir$i/null${i}c c 1 3
6603                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6604                 done
6605         fi
6606 }
6607
6608 test_56g() {
6609         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6610         local expected=$(($NUMDIRS + 2))
6611
6612         setup_56 $dir $NUMFILES $NUMDIRS
6613
6614         # test lfs find with -name
6615         for i in $(seq $NUMFILES) ; do
6616                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6617
6618                 [ $nums -eq $expected ] ||
6619                         error "lfs find -name '*$i' $dir wrong: "\
6620                               "found $nums, expected $expected"
6621         done
6622 }
6623 run_test 56g "check lfs find -name"
6624
6625 test_56h() {
6626         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6627         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6628
6629         setup_56 $dir $NUMFILES $NUMDIRS
6630
6631         # test lfs find with ! -name
6632         for i in $(seq $NUMFILES) ; do
6633                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6634
6635                 [ $nums -eq $expected ] ||
6636                         error "lfs find ! -name '*$i' $dir wrong: "\
6637                               "found $nums, expected $expected"
6638         done
6639 }
6640 run_test 56h "check lfs find ! -name"
6641
6642 test_56i() {
6643         local dir=$DIR/$tdir
6644
6645         test_mkdir $dir
6646
6647         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6648         local out=$($cmd)
6649
6650         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6651 }
6652 run_test 56i "check 'lfs find -ost UUID' skips directories"
6653
6654 test_56j() {
6655         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6656
6657         setup_56_special $dir $NUMFILES $NUMDIRS
6658
6659         local expected=$((NUMDIRS + 1))
6660         local cmd="$LFS find -type d $dir"
6661         local nums=$($cmd | wc -l)
6662
6663         [ $nums -eq $expected ] ||
6664                 error "'$cmd' wrong: found $nums, expected $expected"
6665 }
6666 run_test 56j "check lfs find -type d"
6667
6668 test_56k() {
6669         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6670
6671         setup_56_special $dir $NUMFILES $NUMDIRS
6672
6673         local expected=$(((NUMDIRS + 1) * NUMFILES))
6674         local cmd="$LFS find -type f $dir"
6675         local nums=$($cmd | wc -l)
6676
6677         [ $nums -eq $expected ] ||
6678                 error "'$cmd' wrong: found $nums, expected $expected"
6679 }
6680 run_test 56k "check lfs find -type f"
6681
6682 test_56l() {
6683         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6684
6685         setup_56_special $dir $NUMFILES $NUMDIRS
6686
6687         local expected=$((NUMDIRS + NUMFILES))
6688         local cmd="$LFS find -type b $dir"
6689         local nums=$($cmd | wc -l)
6690
6691         [ $nums -eq $expected ] ||
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693 }
6694 run_test 56l "check lfs find -type b"
6695
6696 test_56m() {
6697         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6698
6699         setup_56_special $dir $NUMFILES $NUMDIRS
6700
6701         local expected=$((NUMDIRS + NUMFILES))
6702         local cmd="$LFS find -type c $dir"
6703         local nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706 }
6707 run_test 56m "check lfs find -type c"
6708
6709 test_56n() {
6710         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6711         setup_56_special $dir $NUMFILES $NUMDIRS
6712
6713         local expected=$((NUMDIRS + NUMFILES))
6714         local cmd="$LFS find -type l $dir"
6715         local nums=$($cmd | wc -l)
6716
6717         [ $nums -eq $expected ] ||
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719 }
6720 run_test 56n "check lfs find -type l"
6721
6722 test_56o() {
6723         local dir=$DIR/$tdir
6724
6725         setup_56 $dir $NUMFILES $NUMDIRS
6726         utime $dir/file1 > /dev/null || error "utime (1)"
6727         utime $dir/file2 > /dev/null || error "utime (2)"
6728         utime $dir/dir1 > /dev/null || error "utime (3)"
6729         utime $dir/dir2 > /dev/null || error "utime (4)"
6730         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6731         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6732
6733         local expected=4
6734         local nums=$($LFS find -mtime +0 $dir | wc -l)
6735
6736         [ $nums -eq $expected ] ||
6737                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6738
6739         expected=12
6740         cmd="$LFS find -mtime 0 $dir"
6741         nums=$($cmd | wc -l)
6742         [ $nums -eq $expected ] ||
6743                 error "'$cmd' wrong: found $nums, expected $expected"
6744 }
6745 run_test 56o "check lfs find -mtime for old files"
6746
6747 test_56ob() {
6748         local dir=$DIR/$tdir
6749         local expected=1
6750         local count=0
6751
6752         # just to make sure there is something that won't be found
6753         test_mkdir $dir
6754         touch $dir/$tfile.now
6755
6756         for age in year week day hour min; do
6757                 count=$((count + 1))
6758
6759                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6760                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6761                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6762
6763                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6764                 local nums=$($cmd | wc -l)
6765                 [ $nums -eq $expected ] ||
6766                         error "'$cmd' wrong: found $nums, expected $expected"
6767
6768                 cmd="$LFS find $dir -atime $count${age:0:1}"
6769                 nums=$($cmd | wc -l)
6770                 [ $nums -eq $expected ] ||
6771                         error "'$cmd' wrong: found $nums, expected $expected"
6772         done
6773
6774         sleep 2
6775         cmd="$LFS find $dir -ctime +1s -type f"
6776         nums=$($cmd | wc -l)
6777         (( $nums == $count * 2 + 1)) ||
6778                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6779 }
6780 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6781
6782 test_newerXY_base() {
6783         local x=$1
6784         local y=$2
6785         local dir=$DIR/$tdir
6786         local ref
6787         local negref
6788
6789         if [ $y == "t" ]; then
6790                 if [ $x == "b" ]; then
6791                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6792                 else
6793                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6794                 fi
6795         else
6796                 ref=$DIR/$tfile.newer.$x$y
6797                 touch $ref || error "touch $ref failed"
6798         fi
6799
6800         echo "before = $ref"
6801         sleep 2
6802         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6803         sleep 2
6804         if [ $y == "t" ]; then
6805                 if [ $x == "b" ]; then
6806                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6807                 else
6808                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6809                 fi
6810         else
6811                 negref=$DIR/$tfile.negnewer.$x$y
6812                 touch $negref || error "touch $negref failed"
6813         fi
6814
6815         echo "after = $negref"
6816         local cmd="$LFS find $dir -newer$x$y $ref"
6817         local nums=$(eval $cmd | wc -l)
6818         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6819
6820         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6821                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6822
6823         cmd="$LFS find $dir ! -newer$x$y $negref"
6824         nums=$(eval $cmd | wc -l)
6825         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6826                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6827
6828         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6829         nums=$(eval $cmd | wc -l)
6830         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6831                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6832
6833         rm -rf $DIR/*
6834 }
6835
6836 test_56oc() {
6837         test_newerXY_base "a" "a"
6838         test_newerXY_base "a" "m"
6839         test_newerXY_base "a" "c"
6840         test_newerXY_base "m" "a"
6841         test_newerXY_base "m" "m"
6842         test_newerXY_base "m" "c"
6843         test_newerXY_base "c" "a"
6844         test_newerXY_base "c" "m"
6845         test_newerXY_base "c" "c"
6846
6847         test_newerXY_base "a" "t"
6848         test_newerXY_base "m" "t"
6849         test_newerXY_base "c" "t"
6850
6851         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6852            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6853                 ! btime_supported && echo "btime unsupported" && return 0
6854
6855         test_newerXY_base "b" "b"
6856         test_newerXY_base "b" "t"
6857 }
6858 run_test 56oc "check lfs find -newerXY work"
6859
6860 btime_supported() {
6861         local dir=$DIR/$tdir
6862         local rc
6863
6864         mkdir -p $dir
6865         touch $dir/$tfile
6866         $LFS find $dir -btime -1d -type f
6867         rc=$?
6868         rm -rf $dir
6869         return $rc
6870 }
6871
6872 test_56od() {
6873         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6874                 ! btime_supported && skip "btime unsupported on MDS"
6875
6876         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6877                 ! btime_supported && skip "btime unsupported on clients"
6878
6879         local dir=$DIR/$tdir
6880         local ref=$DIR/$tfile.ref
6881         local negref=$DIR/$tfile.negref
6882
6883         mkdir $dir || error "mkdir $dir failed"
6884         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6885         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6886         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6887         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6888         touch $ref || error "touch $ref failed"
6889         # sleep 3 seconds at least
6890         sleep 3
6891
6892         local before=$(do_facet mds1 date +%s)
6893         local skew=$(($(date +%s) - before + 1))
6894
6895         if (( skew < 0 && skew > -5 )); then
6896                 sleep $((0 - skew + 1))
6897                 skew=0
6898         fi
6899
6900         # Set the dir stripe params to limit files all on MDT0,
6901         # otherwise we need to calc the max clock skew between
6902         # the client and MDTs.
6903         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6904         sleep 2
6905         touch $negref || error "touch $negref failed"
6906
6907         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6908         local nums=$($cmd | wc -l)
6909         local expected=$(((NUMFILES + 1) * NUMDIRS))
6910
6911         [ $nums -eq $expected ] ||
6912                 error "'$cmd' wrong: found $nums, expected $expected"
6913
6914         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6915         nums=$($cmd | wc -l)
6916         expected=$((NUMFILES + 1))
6917         [ $nums -eq $expected ] ||
6918                 error "'$cmd' wrong: found $nums, expected $expected"
6919
6920         [ $skew -lt 0 ] && return
6921
6922         local after=$(do_facet mds1 date +%s)
6923         local age=$((after - before + 1 + skew))
6924
6925         cmd="$LFS find $dir -btime -${age}s -type f"
6926         nums=$($cmd | wc -l)
6927         expected=$(((NUMFILES + 1) * NUMDIRS))
6928
6929         echo "Clock skew between client and server: $skew, age:$age"
6930         [ $nums -eq $expected ] ||
6931                 error "'$cmd' wrong: found $nums, expected $expected"
6932
6933         expected=$(($NUMDIRS + 1))
6934         cmd="$LFS find $dir -btime -${age}s -type d"
6935         nums=$($cmd | wc -l)
6936         [ $nums -eq $expected ] ||
6937                 error "'$cmd' wrong: found $nums, expected $expected"
6938         rm -f $ref $negref || error "Failed to remove $ref $negref"
6939 }
6940 run_test 56od "check lfs find -btime with units"
6941
6942 test_56p() {
6943         [ $RUNAS_ID -eq $UID ] &&
6944                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6945
6946         local dir=$DIR/$tdir
6947
6948         setup_56 $dir $NUMFILES $NUMDIRS
6949         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6950
6951         local expected=$NUMFILES
6952         local cmd="$LFS find -uid $RUNAS_ID $dir"
6953         local nums=$($cmd | wc -l)
6954
6955         [ $nums -eq $expected ] ||
6956                 error "'$cmd' wrong: found $nums, expected $expected"
6957
6958         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6959         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6960         nums=$($cmd | wc -l)
6961         [ $nums -eq $expected ] ||
6962                 error "'$cmd' wrong: found $nums, expected $expected"
6963 }
6964 run_test 56p "check lfs find -uid and ! -uid"
6965
6966 test_56q() {
6967         [ $RUNAS_ID -eq $UID ] &&
6968                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6969
6970         local dir=$DIR/$tdir
6971
6972         setup_56 $dir $NUMFILES $NUMDIRS
6973         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6974
6975         local expected=$NUMFILES
6976         local cmd="$LFS find -gid $RUNAS_GID $dir"
6977         local nums=$($cmd | wc -l)
6978
6979         [ $nums -eq $expected ] ||
6980                 error "'$cmd' wrong: found $nums, expected $expected"
6981
6982         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6983         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6984         nums=$($cmd | wc -l)
6985         [ $nums -eq $expected ] ||
6986                 error "'$cmd' wrong: found $nums, expected $expected"
6987 }
6988 run_test 56q "check lfs find -gid and ! -gid"
6989
6990 test_56r() {
6991         local dir=$DIR/$tdir
6992
6993         setup_56 $dir $NUMFILES $NUMDIRS
6994
6995         local expected=12
6996         local cmd="$LFS find -size 0 -type f -lazy $dir"
6997         local nums=$($cmd | wc -l)
6998
6999         [ $nums -eq $expected ] ||
7000                 error "'$cmd' wrong: found $nums, expected $expected"
7001         cmd="$LFS find -size 0 -type f $dir"
7002         nums=$($cmd | wc -l)
7003         [ $nums -eq $expected ] ||
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005
7006         expected=0
7007         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7008         nums=$($cmd | wc -l)
7009         [ $nums -eq $expected ] ||
7010                 error "'$cmd' wrong: found $nums, expected $expected"
7011         cmd="$LFS find ! -size 0 -type f $dir"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015
7016         echo "test" > $dir/$tfile
7017         echo "test2" > $dir/$tfile.2 && sync
7018         expected=1
7019         cmd="$LFS find -size 5 -type f -lazy $dir"
7020         nums=$($cmd | wc -l)
7021         [ $nums -eq $expected ] ||
7022                 error "'$cmd' wrong: found $nums, expected $expected"
7023         cmd="$LFS find -size 5 -type f $dir"
7024         nums=$($cmd | wc -l)
7025         [ $nums -eq $expected ] ||
7026                 error "'$cmd' wrong: found $nums, expected $expected"
7027
7028         expected=1
7029         cmd="$LFS find -size +5 -type f -lazy $dir"
7030         nums=$($cmd | wc -l)
7031         [ $nums -eq $expected ] ||
7032                 error "'$cmd' wrong: found $nums, expected $expected"
7033         cmd="$LFS find -size +5 -type f $dir"
7034         nums=$($cmd | wc -l)
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037
7038         expected=2
7039         cmd="$LFS find -size +0 -type f -lazy $dir"
7040         nums=$($cmd | wc -l)
7041         [ $nums -eq $expected ] ||
7042                 error "'$cmd' wrong: found $nums, expected $expected"
7043         cmd="$LFS find -size +0 -type f $dir"
7044         nums=$($cmd | wc -l)
7045         [ $nums -eq $expected ] ||
7046                 error "'$cmd' wrong: found $nums, expected $expected"
7047
7048         expected=2
7049         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7050         nums=$($cmd | wc -l)
7051         [ $nums -eq $expected ] ||
7052                 error "'$cmd' wrong: found $nums, expected $expected"
7053         cmd="$LFS find ! -size -5 -type f $dir"
7054         nums=$($cmd | wc -l)
7055         [ $nums -eq $expected ] ||
7056                 error "'$cmd' wrong: found $nums, expected $expected"
7057
7058         expected=12
7059         cmd="$LFS find -size -5 -type f -lazy $dir"
7060         nums=$($cmd | wc -l)
7061         [ $nums -eq $expected ] ||
7062                 error "'$cmd' wrong: found $nums, expected $expected"
7063         cmd="$LFS find -size -5 -type f $dir"
7064         nums=$($cmd | wc -l)
7065         [ $nums -eq $expected ] ||
7066                 error "'$cmd' wrong: found $nums, expected $expected"
7067 }
7068 run_test 56r "check lfs find -size works"
7069
7070 test_56ra_sub() {
7071         local expected=$1
7072         local glimpses=$2
7073         local cmd="$3"
7074
7075         cancel_lru_locks $OSC
7076
7077         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7078         local nums=$($cmd | wc -l)
7079
7080         [ $nums -eq $expected ] ||
7081                 error "'$cmd' wrong: found $nums, expected $expected"
7082
7083         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7084
7085         if (( rpcs_before + glimpses != rpcs_after )); then
7086                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7087                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7088
7089                 if [[ $glimpses == 0 ]]; then
7090                         error "'$cmd' should not send glimpse RPCs to OST"
7091                 else
7092                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7093                 fi
7094         fi
7095 }
7096
7097 test_56ra() {
7098         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7099                 skip "MDS < 2.12.58 doesn't return LSOM data"
7100         local dir=$DIR/$tdir
7101         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7102
7103         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7104
7105         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7106         $LCTL set_param -n llite.*.statahead_agl=0
7107         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7108
7109         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7110         # open and close all files to ensure LSOM is updated
7111         cancel_lru_locks $OSC
7112         find $dir -type f | xargs cat > /dev/null
7113
7114         #   expect_found  glimpse_rpcs  command_to_run
7115         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7116         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7117         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7118         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7119
7120         echo "test" > $dir/$tfile
7121         echo "test2" > $dir/$tfile.2 && sync
7122         cancel_lru_locks $OSC
7123         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7124
7125         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7126         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7127         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7128         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7129
7130         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7131         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7132         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7133         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7134         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7135         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7136 }
7137 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7138
7139 test_56rb() {
7140         local dir=$DIR/$tdir
7141         local tmp=$TMP/$tfile.log
7142         local mdt_idx;
7143
7144         test_mkdir -p $dir || error "failed to mkdir $dir"
7145         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7146                 error "failed to setstripe $dir/$tfile"
7147         mdt_idx=$($LFS getdirstripe -i $dir)
7148         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7149
7150         stack_trap "rm -f $tmp" EXIT
7151         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7152         ! grep -q obd_uuid $tmp ||
7153                 error "failed to find --size +100K --ost 0 $dir"
7154         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7155         ! grep -q obd_uuid $tmp ||
7156                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7157 }
7158 run_test 56rb "check lfs find --size --ost/--mdt works"
7159
7160 test_56rc() {
7161         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7162         local dir=$DIR/$tdir
7163         local found
7164
7165         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7166         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7167         (( $MDSCOUNT > 2 )) &&
7168                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7169         mkdir $dir/$tdir-{1..10}
7170         touch $dir/$tfile-{1..10}
7171
7172         found=$($LFS find $dir --mdt-count 2 | wc -l)
7173         expect=11
7174         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7175
7176         found=$($LFS find $dir -T +1 | wc -l)
7177         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7178         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7179
7180         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7181         expect=11
7182         (( $found == $expect )) || error "found $found all_char, expect $expect"
7183
7184         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7185         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7186         (( $found == $expect )) || error "found $found all_char, expect $expect"
7187 }
7188 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7189
7190 test_56rd() {
7191         local dir=$DIR/$tdir
7192
7193         test_mkdir $dir
7194         rm -f $dir/*
7195
7196         mkfifo $dir/fifo || error "failed to create fifo file"
7197         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7198                 error "should not fail even cannot get projid from pipe file"
7199         found=$($LFS find $dir -t p --printf "%y")
7200         [[ "p" == $found ]] || error "found $found, expect p"
7201
7202         mknod $dir/chardev c 1 5 ||
7203                 error "failed to create character device file"
7204         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7205                 error "should not fail even cannot get projid from chardev file"
7206         found=$($LFS find $dir -t c --printf "%y")
7207         [[ "c" == $found ]] || error "found $found, expect c"
7208
7209         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7210         (( found == 2 )) || error "unable to list all files"
7211 }
7212 run_test 56rd "check lfs find --printf special files"
7213
7214 test_56s() { # LU-611 #LU-9369
7215         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7216
7217         local dir=$DIR/$tdir
7218         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7219
7220         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7221         for i in $(seq $NUMDIRS); do
7222                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7223         done
7224
7225         local expected=$NUMDIRS
7226         local cmd="$LFS find -c $OSTCOUNT $dir"
7227         local nums=$($cmd | wc -l)
7228
7229         [ $nums -eq $expected ] || {
7230                 $LFS getstripe -R $dir
7231                 error "'$cmd' wrong: found $nums, expected $expected"
7232         }
7233
7234         expected=$((NUMDIRS + onestripe))
7235         cmd="$LFS find -stripe-count +0 -type f $dir"
7236         nums=$($cmd | wc -l)
7237         [ $nums -eq $expected ] || {
7238                 $LFS getstripe -R $dir
7239                 error "'$cmd' wrong: found $nums, expected $expected"
7240         }
7241
7242         expected=$onestripe
7243         cmd="$LFS find -stripe-count 1 -type f $dir"
7244         nums=$($cmd | wc -l)
7245         [ $nums -eq $expected ] || {
7246                 $LFS getstripe -R $dir
7247                 error "'$cmd' wrong: found $nums, expected $expected"
7248         }
7249
7250         cmd="$LFS find -stripe-count -2 -type f $dir"
7251         nums=$($cmd | wc -l)
7252         [ $nums -eq $expected ] || {
7253                 $LFS getstripe -R $dir
7254                 error "'$cmd' wrong: found $nums, expected $expected"
7255         }
7256
7257         expected=0
7258         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7259         nums=$($cmd | wc -l)
7260         [ $nums -eq $expected ] || {
7261                 $LFS getstripe -R $dir
7262                 error "'$cmd' wrong: found $nums, expected $expected"
7263         }
7264 }
7265 run_test 56s "check lfs find -stripe-count works"
7266
7267 test_56t() { # LU-611 #LU-9369
7268         local dir=$DIR/$tdir
7269
7270         setup_56 $dir 0 $NUMDIRS
7271         for i in $(seq $NUMDIRS); do
7272                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7273         done
7274
7275         local expected=$NUMDIRS
7276         local cmd="$LFS find -S 8M $dir"
7277         local nums=$($cmd | wc -l)
7278
7279         [ $nums -eq $expected ] || {
7280                 $LFS getstripe -R $dir
7281                 error "'$cmd' wrong: found $nums, expected $expected"
7282         }
7283         rm -rf $dir
7284
7285         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7286
7287         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7288
7289         expected=$(((NUMDIRS + 1) * NUMFILES))
7290         cmd="$LFS find -stripe-size 512k -type f $dir"
7291         nums=$($cmd | wc -l)
7292         [ $nums -eq $expected ] ||
7293                 error "'$cmd' wrong: found $nums, expected $expected"
7294
7295         cmd="$LFS find -stripe-size +320k -type f $dir"
7296         nums=$($cmd | wc -l)
7297         [ $nums -eq $expected ] ||
7298                 error "'$cmd' wrong: found $nums, expected $expected"
7299
7300         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7301         cmd="$LFS find -stripe-size +200k -type f $dir"
7302         nums=$($cmd | wc -l)
7303         [ $nums -eq $expected ] ||
7304                 error "'$cmd' wrong: found $nums, expected $expected"
7305
7306         cmd="$LFS find -stripe-size -640k -type f $dir"
7307         nums=$($cmd | wc -l)
7308         [ $nums -eq $expected ] ||
7309                 error "'$cmd' wrong: found $nums, expected $expected"
7310
7311         expected=4
7312         cmd="$LFS find -stripe-size 256k -type f $dir"
7313         nums=$($cmd | wc -l)
7314         [ $nums -eq $expected ] ||
7315                 error "'$cmd' wrong: found $nums, expected $expected"
7316
7317         cmd="$LFS find -stripe-size -320k -type f $dir"
7318         nums=$($cmd | wc -l)
7319         [ $nums -eq $expected ] ||
7320                 error "'$cmd' wrong: found $nums, expected $expected"
7321
7322         expected=0
7323         cmd="$LFS find -stripe-size 1024k -type f $dir"
7324         nums=$($cmd | wc -l)
7325         [ $nums -eq $expected ] ||
7326                 error "'$cmd' wrong: found $nums, expected $expected"
7327 }
7328 run_test 56t "check lfs find -stripe-size works"
7329
7330 test_56u() { # LU-611
7331         local dir=$DIR/$tdir
7332
7333         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7334
7335         if [[ $OSTCOUNT -gt 1 ]]; then
7336                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7337                 onestripe=4
7338         else
7339                 onestripe=0
7340         fi
7341
7342         local expected=$(((NUMDIRS + 1) * NUMFILES))
7343         local cmd="$LFS find -stripe-index 0 -type f $dir"
7344         local nums=$($cmd | wc -l)
7345
7346         [ $nums -eq $expected ] ||
7347                 error "'$cmd' wrong: found $nums, expected $expected"
7348
7349         expected=$onestripe
7350         cmd="$LFS find -stripe-index 1 -type f $dir"
7351         nums=$($cmd | wc -l)
7352         [ $nums -eq $expected ] ||
7353                 error "'$cmd' wrong: found $nums, expected $expected"
7354
7355         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7356         nums=$($cmd | wc -l)
7357         [ $nums -eq $expected ] ||
7358                 error "'$cmd' wrong: found $nums, expected $expected"
7359
7360         expected=0
7361         # This should produce an error and not return any files
7362         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7363         nums=$($cmd 2>/dev/null | wc -l)
7364         [ $nums -eq $expected ] ||
7365                 error "'$cmd' wrong: found $nums, expected $expected"
7366
7367         if [[ $OSTCOUNT -gt 1 ]]; then
7368                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7369                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7370                 nums=$($cmd | wc -l)
7371                 [ $nums -eq $expected ] ||
7372                         error "'$cmd' wrong: found $nums, expected $expected"
7373         fi
7374 }
7375 run_test 56u "check lfs find -stripe-index works"
7376
7377 test_56v() {
7378         local mdt_idx=0
7379         local dir=$DIR/$tdir
7380
7381         setup_56 $dir $NUMFILES $NUMDIRS
7382
7383         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7384         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7385
7386         for file in $($LFS find -m $UUID $dir); do
7387                 file_midx=$($LFS getstripe -m $file)
7388                 [ $file_midx -eq $mdt_idx ] ||
7389                         error "lfs find -m $UUID != getstripe -m $file_midx"
7390         done
7391 }
7392 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7393
7394 test_56wa() {
7395         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7397
7398         local dir=$DIR/$tdir
7399
7400         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7401         stack_trap "rm -rf $dir"
7402
7403         local stripe_size=$($LFS getstripe -S -d $dir) ||
7404                 error "$LFS getstripe -S -d $dir failed"
7405         stripe_size=${stripe_size%% *}
7406
7407         local file_size=$((stripe_size * OSTCOUNT))
7408         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7409         local required_space=$((file_num * file_size))
7410         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7411                            head -n1)
7412         (( free_space >= required_space / 1024 )) ||
7413                 skip_env "need $required_space, have $free_space kbytes"
7414
7415         local dd_bs=65536
7416         local dd_count=$((file_size / dd_bs))
7417
7418         # write data into the files
7419         local i
7420         local j
7421         local file
7422
7423         for ((i = 1; i <= NUMFILES; i++ )); do
7424                 file=$dir/file$i
7425                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7426                         error "write data into $file failed"
7427         done
7428         for ((i = 1; i <= NUMDIRS; i++ )); do
7429                 for ((j = 1; j <= NUMFILES; j++ )); do
7430                         file=$dir/dir$i/file$j
7431                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7432                                 error "write data into $file failed"
7433                 done
7434         done
7435
7436         # $LFS_MIGRATE will fail if hard link migration is unsupported
7437         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7438                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7439                         error "creating links to $dir/dir1/file1 failed"
7440         fi
7441
7442         local expected=-1
7443
7444         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7445
7446         # lfs_migrate file
7447         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7448
7449         echo "$cmd"
7450         eval $cmd || error "$cmd failed"
7451
7452         check_stripe_count $dir/file1 $expected
7453
7454         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7455                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7456                 # OST 1 if it is on OST 0. This file is small enough to
7457                 # be on only one stripe.
7458                 file=$dir/migr_1_ost
7459                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7460                         error "write data into $file failed"
7461                 local obdidx=$($LFS getstripe -i $file)
7462                 local oldmd5=$(md5sum $file)
7463                 local newobdidx=0
7464
7465                 (( obdidx != 0 )) || newobdidx=1
7466                 cmd="$LFS migrate -i $newobdidx $file"
7467                 echo $cmd
7468                 eval $cmd || error "$cmd failed"
7469
7470                 local realobdix=$($LFS getstripe -i $file)
7471                 local newmd5=$(md5sum $file)
7472
7473                 (( $newobdidx == $realobdix )) ||
7474                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7475                 [[ "$oldmd5" == "$newmd5" ]] ||
7476                         error "md5sum differ: $oldmd5, $newmd5"
7477         fi
7478
7479         # lfs_migrate dir
7480         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7481         echo "$cmd"
7482         eval $cmd || error "$cmd failed"
7483
7484         for (( j = 1; j <= NUMFILES; j++ )); do
7485                 check_stripe_count $dir/dir1/file$j $expected
7486         done
7487
7488         # lfs_migrate works with lfs find
7489         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7490              $LFS_MIGRATE -y -c $expected"
7491         echo "$cmd"
7492         eval $cmd || error "$cmd failed"
7493
7494         for (( i = 2; i <= NUMFILES; i++ )); do
7495                 check_stripe_count $dir/file$i $expected
7496         done
7497         for (( i = 2; i <= NUMDIRS; i++ )); do
7498                 for (( j = 1; j <= NUMFILES; j++ )); do
7499                         check_stripe_count $dir/dir$i/file$j $expected
7500                 done
7501         done
7502 }
7503 run_test 56wa "check lfs_migrate -c stripe_count works"
7504
7505 test_56wb() {
7506         local file1=$DIR/$tdir/file1
7507         local create_pool=false
7508         local initial_pool=$($LFS getstripe -p $DIR)
7509         local pool_list=()
7510         local pool=""
7511
7512         echo -n "Creating test dir..."
7513         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7514         echo "done."
7515
7516         echo -n "Creating test file..."
7517         touch $file1 || error "cannot create file"
7518         echo "done."
7519
7520         echo -n "Detecting existing pools..."
7521         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7522
7523         if [ ${#pool_list[@]} -gt 0 ]; then
7524                 echo "${pool_list[@]}"
7525                 for thispool in "${pool_list[@]}"; do
7526                         if [[ -z "$initial_pool" ||
7527                               "$initial_pool" != "$thispool" ]]; then
7528                                 pool="$thispool"
7529                                 echo "Using existing pool '$pool'"
7530                                 break
7531                         fi
7532                 done
7533         else
7534                 echo "none detected."
7535         fi
7536         if [ -z "$pool" ]; then
7537                 pool=${POOL:-testpool}
7538                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7539                 echo -n "Creating pool '$pool'..."
7540                 create_pool=true
7541                 pool_add $pool &> /dev/null ||
7542                         error "pool_add failed"
7543                 echo "done."
7544
7545                 echo -n "Adding target to pool..."
7546                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7547                         error "pool_add_targets failed"
7548                 echo "done."
7549         fi
7550
7551         echo -n "Setting pool using -p option..."
7552         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7553                 error "migrate failed rc = $?"
7554         echo "done."
7555
7556         echo -n "Verifying test file is in pool after migrating..."
7557         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7558                 error "file was not migrated to pool $pool"
7559         echo "done."
7560
7561         echo -n "Removing test file from pool '$pool'..."
7562         # "lfs migrate $file" won't remove the file from the pool
7563         # until some striping information is changed.
7564         $LFS migrate -c 1 $file1 &> /dev/null ||
7565                 error "cannot remove from pool"
7566         [ "$($LFS getstripe -p $file1)" ] &&
7567                 error "pool still set"
7568         echo "done."
7569
7570         echo -n "Setting pool using --pool option..."
7571         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7572                 error "migrate failed rc = $?"
7573         echo "done."
7574
7575         # Clean up
7576         rm -f $file1
7577         if $create_pool; then
7578                 destroy_test_pools 2> /dev/null ||
7579                         error "destroy test pools failed"
7580         fi
7581 }
7582 run_test 56wb "check lfs_migrate pool support"
7583
7584 test_56wc() {
7585         local file1="$DIR/$tdir/$tfile"
7586         local md5
7587         local parent_ssize
7588         local parent_scount
7589         local cur_ssize
7590         local cur_scount
7591         local orig_ssize
7592         local new_scount
7593         local cur_comp
7594
7595         echo -n "Creating test dir..."
7596         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7597         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7598                 error "cannot set stripe by '-S 1M -c 1'"
7599         echo "done"
7600
7601         echo -n "Setting initial stripe for test file..."
7602         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7603                 error "cannot set stripe"
7604         cur_ssize=$($LFS getstripe -S "$file1")
7605         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7606         echo "done."
7607
7608         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7609         stack_trap "rm -f $file1"
7610         md5="$(md5sum $file1)"
7611
7612         # File currently set to -S 512K -c 1
7613
7614         # Ensure -c and -S options are rejected when -R is set
7615         echo -n "Verifying incompatible options are detected..."
7616         $LFS_MIGRATE -R -c 1 "$file1" &&
7617                 error "incompatible -R and -c options not detected"
7618         $LFS_MIGRATE -R -S 1M "$file1" &&
7619                 error "incompatible -R and -S options not detected"
7620         $LFS_MIGRATE -R -p pool "$file1" &&
7621                 error "incompatible -R and -p options not detected"
7622         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7623                 error "incompatible -R and -E options not detected"
7624         $LFS_MIGRATE -R -A "$file1" &&
7625                 error "incompatible -R and -A options not detected"
7626         $LFS_MIGRATE -A -c 1 "$file1" &&
7627                 error "incompatible -A and -c options not detected"
7628         $LFS_MIGRATE -A -S 1M "$file1" &&
7629                 error "incompatible -A and -S options not detected"
7630         $LFS_MIGRATE -A -p pool "$file1" &&
7631                 error "incompatible -A and -p options not detected"
7632         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7633                 error "incompatible -A and -E options not detected"
7634         echo "done."
7635
7636         # Ensure unrecognized options are passed through to 'lfs migrate'
7637         echo -n "Verifying -S option is passed through to lfs migrate..."
7638         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7639         cur_ssize=$($LFS getstripe -S "$file1")
7640         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7641         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7642         echo "done."
7643
7644         # File currently set to -S 1M -c 1
7645
7646         # Ensure long options are supported
7647         echo -n "Verifying long options supported..."
7648         $LFS_MIGRATE --non-block "$file1" ||
7649                 error "long option without argument not supported"
7650         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7651                 error "long option with argument not supported"
7652         cur_ssize=$($LFS getstripe -S "$file1")
7653         (( cur_ssize == 524288 )) ||
7654                 error "migrate --stripe-size $cur_ssize != 524288"
7655         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7656         echo "done."
7657
7658         # File currently set to -S 512K -c 1
7659
7660         if (( OSTCOUNT > 1 )); then
7661                 echo -n "Verifying explicit stripe count can be set..."
7662                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7663                 cur_scount=$($LFS getstripe -c "$file1")
7664                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7665                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7666                         error "file data has changed (3)"
7667                 echo "done."
7668         fi
7669
7670         # File currently set to -S 512K -c 1 or -S 512K -c 2
7671
7672         # Ensure parent striping is used if -R is set, and no stripe
7673         # count or size is specified
7674         echo -n "Setting stripe for parent directory..."
7675         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7676                 error "cannot set stripe '-S 2M -c 1'"
7677         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7678         echo "done."
7679
7680         echo -n "Verifying restripe option uses parent stripe settings..."
7681         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7682         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7683         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7684         cur_ssize=$($LFS getstripe -S "$file1")
7685         (( cur_ssize == parent_ssize )) ||
7686                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7687         cur_scount=$($LFS getstripe -c "$file1")
7688         (( cur_scount == parent_scount )) ||
7689                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7690         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7691         echo "done."
7692
7693         # File currently set to -S 1M -c 1
7694
7695         # Ensure striping is preserved if -R is not set, and no stripe
7696         # count or size is specified
7697         echo -n "Verifying striping size preserved when not specified..."
7698         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7699         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7700                 error "cannot set stripe on parent directory"
7701         $LFS_MIGRATE "$file1" || error "migrate failed"
7702         cur_ssize=$($LFS getstripe -S "$file1")
7703         (( cur_ssize == orig_ssize )) ||
7704                 error "migrate by default $cur_ssize != $orig_ssize"
7705         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7706         echo "done."
7707
7708         # Ensure file name properly detected when final option has no argument
7709         echo -n "Verifying file name properly detected..."
7710         $LFS_MIGRATE "$file1" ||
7711                 error "file name interpreted as option argument"
7712         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7713         echo "done."
7714
7715         # Ensure PFL arguments are passed through properly
7716         echo -n "Verifying PFL options passed through..."
7717         new_scount=$(((OSTCOUNT + 1) / 2))
7718         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7719                 error "migrate PFL arguments failed"
7720         cur_comp=$($LFS getstripe --comp-count $file1)
7721         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7722         cur_scount=$($LFS getstripe --stripe-count $file1)
7723         (( cur_scount == new_scount)) ||
7724                 error "PFL stripe count $cur_scount != $new_scount"
7725         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7726         echo "done."
7727 }
7728 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7729
7730 test_56wd() {
7731         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7732
7733         local file1=$DIR/$tdir/$tfile
7734
7735         echo -n "Creating test dir..."
7736         test_mkdir $DIR/$tdir || error "cannot create dir"
7737         echo "done."
7738
7739         echo -n "Creating test file..."
7740         echo "$tfile" > $file1
7741         echo "done."
7742
7743         # Ensure 'lfs migrate' will fail by using a non-existent option,
7744         # and make sure rsync is not called to recover
7745         echo -n "Make sure --no-rsync option works..."
7746         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7747                 grep -q 'refusing to fall back to rsync' ||
7748                 error "rsync was called with --no-rsync set"
7749         echo "done."
7750
7751         # Ensure rsync is called without trying 'lfs migrate' first
7752         echo -n "Make sure --rsync option works..."
7753         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7754                 grep -q 'falling back to rsync' &&
7755                 error "lfs migrate was called with --rsync set"
7756         echo "done."
7757 }
7758 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7759
7760 test_56we() {
7761         local td=$DIR/$tdir
7762         local tf=$td/$tfile
7763
7764         test_mkdir $td || error "cannot create $td"
7765         touch $tf || error "cannot touch $tf"
7766
7767         echo -n "Make sure --non-direct|-D works..."
7768         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7769                 grep -q "lfs migrate --non-direct" ||
7770                 error "--non-direct option cannot work correctly"
7771         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7772                 grep -q "lfs migrate -D" ||
7773                 error "-D option cannot work correctly"
7774         echo "done."
7775 }
7776 run_test 56we "check lfs_migrate --non-direct|-D support"
7777
7778 test_56x() {
7779         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7780         check_swap_layouts_support
7781
7782         local dir=$DIR/$tdir
7783         local ref1=/etc/passwd
7784         local file1=$dir/file1
7785
7786         test_mkdir $dir || error "creating dir $dir"
7787         $LFS setstripe -c 2 $file1
7788         cp $ref1 $file1
7789         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7790         stripe=$($LFS getstripe -c $file1)
7791         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7792         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7793
7794         # clean up
7795         rm -f $file1
7796 }
7797 run_test 56x "lfs migration support"
7798
7799 test_56xa() {
7800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7801         check_swap_layouts_support
7802
7803         local dir=$DIR/$tdir/$testnum
7804
7805         test_mkdir -p $dir
7806
7807         local ref1=/etc/passwd
7808         local file1=$dir/file1
7809
7810         $LFS setstripe -c 2 $file1
7811         cp $ref1 $file1
7812         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7813
7814         local stripe=$($LFS getstripe -c $file1)
7815
7816         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7817         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7818
7819         # clean up
7820         rm -f $file1
7821 }
7822 run_test 56xa "lfs migration --block support"
7823
7824 check_migrate_links() {
7825         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7826         local dir="$1"
7827         local file1="$dir/file1"
7828         local begin="$2"
7829         local count="$3"
7830         local runas="$4"
7831         local total_count=$(($begin + $count - 1))
7832         local symlink_count=10
7833         local uniq_count=10
7834
7835         if [ ! -f "$file1" ]; then
7836                 echo -n "creating initial file..."
7837                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7838                         error "cannot setstripe initial file"
7839                 echo "done"
7840
7841                 echo -n "creating symlinks..."
7842                 for s in $(seq 1 $symlink_count); do
7843                         ln -s "$file1" "$dir/slink$s" ||
7844                                 error "cannot create symlinks"
7845                 done
7846                 echo "done"
7847
7848                 echo -n "creating nonlinked files..."
7849                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7850                         error "cannot create nonlinked files"
7851                 echo "done"
7852         fi
7853
7854         # create hard links
7855         if [ ! -f "$dir/file$total_count" ]; then
7856                 echo -n "creating hard links $begin:$total_count..."
7857                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7858                         /dev/null || error "cannot create hard links"
7859                 echo "done"
7860         fi
7861
7862         echo -n "checking number of hard links listed in xattrs..."
7863         local fid=$($LFS getstripe -F "$file1")
7864         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7865
7866         echo "${#paths[*]}"
7867         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7868                         skip "hard link list has unexpected size, skipping test"
7869         fi
7870         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7871                         error "link names should exceed xattrs size"
7872         fi
7873
7874         echo -n "migrating files..."
7875         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7876         local rc=$?
7877         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7878         echo "done"
7879
7880         # make sure all links have been properly migrated
7881         echo -n "verifying files..."
7882         fid=$($LFS getstripe -F "$file1") ||
7883                 error "cannot get fid for file $file1"
7884         for i in $(seq 2 $total_count); do
7885                 local fid2=$($LFS getstripe -F $dir/file$i)
7886
7887                 [ "$fid2" == "$fid" ] ||
7888                         error "migrated hard link has mismatched FID"
7889         done
7890
7891         # make sure hard links were properly detected, and migration was
7892         # performed only once for the entire link set; nonlinked files should
7893         # also be migrated
7894         local actual=$(grep -c 'done' <<< "$migrate_out")
7895         local expected=$(($uniq_count + 1))
7896
7897         [ "$actual" -eq  "$expected" ] ||
7898                 error "hard links individually migrated ($actual != $expected)"
7899
7900         # make sure the correct number of hard links are present
7901         local hardlinks=$(stat -c '%h' "$file1")
7902
7903         [ $hardlinks -eq $total_count ] ||
7904                 error "num hard links $hardlinks != $total_count"
7905         echo "done"
7906
7907         return 0
7908 }
7909
7910 test_56xb() {
7911         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7912                 skip "Need MDS version at least 2.10.55"
7913
7914         local dir="$DIR/$tdir"
7915
7916         test_mkdir "$dir" || error "cannot create dir $dir"
7917
7918         echo "testing lfs migrate mode when all links fit within xattrs"
7919         check_migrate_links "$dir" 2 99
7920
7921         echo "testing rsync mode when all links fit within xattrs"
7922         check_migrate_links --rsync "$dir" 2 99
7923
7924         echo "testing lfs migrate mode when all links do not fit within xattrs"
7925         check_migrate_links "$dir" 101 100
7926
7927         echo "testing rsync mode when all links do not fit within xattrs"
7928         check_migrate_links --rsync "$dir" 101 100
7929
7930         chown -R $RUNAS_ID $dir
7931         echo "testing non-root lfs migrate mode when not all links are in xattr"
7932         check_migrate_links "$dir" 101 100 "$RUNAS"
7933
7934         # clean up
7935         rm -rf $dir
7936 }
7937 run_test 56xb "lfs migration hard link support"
7938
7939 test_56xc() {
7940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7941
7942         local dir="$DIR/$tdir"
7943
7944         test_mkdir "$dir" || error "cannot create dir $dir"
7945
7946         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7947         echo -n "Setting initial stripe for 20MB test file..."
7948         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7949                 error "cannot setstripe 20MB file"
7950         echo "done"
7951         echo -n "Sizing 20MB test file..."
7952         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7953         echo "done"
7954         echo -n "Verifying small file autostripe count is 1..."
7955         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7956                 error "cannot migrate 20MB file"
7957         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7958                 error "cannot get stripe for $dir/20mb"
7959         [ $stripe_count -eq 1 ] ||
7960                 error "unexpected stripe count $stripe_count for 20MB file"
7961         rm -f "$dir/20mb"
7962         echo "done"
7963
7964         # Test 2: File is small enough to fit within the available space on
7965         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7966         # have at least an additional 1KB for each desired stripe for test 3
7967         echo -n "Setting stripe for 1GB test file..."
7968         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7969         echo "done"
7970         echo -n "Sizing 1GB test file..."
7971         # File size is 1GB + 3KB
7972         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7973         echo "done"
7974
7975         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7976         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7977         if (( avail > 524288 * OSTCOUNT )); then
7978                 echo -n "Migrating 1GB file..."
7979                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7980                         error "cannot migrate 1GB file"
7981                 echo "done"
7982                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7983                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7984                         error "cannot getstripe for 1GB file"
7985                 [ $stripe_count -eq 2 ] ||
7986                         error "unexpected stripe count $stripe_count != 2"
7987                 echo "done"
7988         fi
7989
7990         # Test 3: File is too large to fit within the available space on
7991         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7992         if [ $OSTCOUNT -ge 3 ]; then
7993                 # The required available space is calculated as
7994                 # file size (1GB + 3KB) / OST count (3).
7995                 local kb_per_ost=349526
7996
7997                 echo -n "Migrating 1GB file with limit..."
7998                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7999                         error "cannot migrate 1GB file with limit"
8000                 echo "done"
8001
8002                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8003                 echo -n "Verifying 1GB autostripe count with limited space..."
8004                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8005                         error "unexpected stripe count $stripe_count (min 3)"
8006                 echo "done"
8007         fi
8008
8009         # clean up
8010         rm -rf $dir
8011 }
8012 run_test 56xc "lfs migration autostripe"
8013
8014 test_56xd() {
8015         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8016
8017         local dir=$DIR/$tdir
8018         local f_mgrt=$dir/$tfile.mgrt
8019         local f_yaml=$dir/$tfile.yaml
8020         local f_copy=$dir/$tfile.copy
8021         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8022         local layout_copy="-c 2 -S 2M -i 1"
8023         local yamlfile=$dir/yamlfile
8024         local layout_before;
8025         local layout_after;
8026
8027         test_mkdir "$dir" || error "cannot create dir $dir"
8028         stack_trap "rm -rf $dir"
8029         $LFS setstripe $layout_yaml $f_yaml ||
8030                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8031         $LFS getstripe --yaml $f_yaml > $yamlfile
8032         $LFS setstripe $layout_copy $f_copy ||
8033                 error "cannot setstripe $f_copy with layout $layout_copy"
8034         touch $f_mgrt
8035         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8036
8037         # 1. test option --yaml
8038         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8039                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8040         layout_before=$(get_layout_param $f_yaml)
8041         layout_after=$(get_layout_param $f_mgrt)
8042         [ "$layout_after" == "$layout_before" ] ||
8043                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8044
8045         # 2. test option --copy
8046         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8047                 error "cannot migrate $f_mgrt with --copy $f_copy"
8048         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8049         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8050         [ "$layout_after" == "$layout_before" ] ||
8051                 error "lfs_migrate --copy: $layout_after != $layout_before"
8052 }
8053 run_test 56xd "check lfs_migrate --yaml and --copy support"
8054
8055 test_56xe() {
8056         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8057
8058         local dir=$DIR/$tdir
8059         local f_comp=$dir/$tfile
8060         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8061         local layout_before=""
8062         local layout_after=""
8063
8064         test_mkdir "$dir" || error "cannot create dir $dir"
8065         stack_trap "rm -rf $dir"
8066         $LFS setstripe $layout $f_comp ||
8067                 error "cannot setstripe $f_comp with layout $layout"
8068         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8069         dd if=/dev/zero of=$f_comp bs=1M count=4
8070
8071         # 1. migrate a comp layout file by lfs_migrate
8072         $LFS_MIGRATE -y $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         # 2. migrate a comp layout file by lfs migrate
8078         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8079         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8080         [ "$layout_before" == "$layout_after" ] ||
8081                 error "lfs migrate: $layout_before != $layout_after"
8082 }
8083 run_test 56xe "migrate a composite layout file"
8084
8085 test_56xf() {
8086         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8087
8088         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8089                 skip "Need server version at least 2.13.53"
8090
8091         local dir=$DIR/$tdir
8092         local f_comp=$dir/$tfile
8093         local layout="-E 1M -c1 -E -1 -c2"
8094         local fid_before=""
8095         local fid_after=""
8096
8097         test_mkdir "$dir" || error "cannot create dir $dir"
8098         stack_trap "rm -rf $dir"
8099         $LFS setstripe $layout $f_comp ||
8100                 error "cannot setstripe $f_comp with layout $layout"
8101         fid_before=$($LFS getstripe --fid $f_comp)
8102         dd if=/dev/zero of=$f_comp bs=1M count=4
8103
8104         # 1. migrate a comp layout file to a comp layout
8105         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8106         fid_after=$($LFS getstripe --fid $f_comp)
8107         [ "$fid_before" == "$fid_after" ] ||
8108                 error "comp-to-comp migrate: $fid_before != $fid_after"
8109
8110         # 2. migrate a comp layout file to a plain layout
8111         $LFS migrate -c2 $f_comp ||
8112                 error "cannot migrate $f_comp by lfs migrate"
8113         fid_after=$($LFS getstripe --fid $f_comp)
8114         [ "$fid_before" == "$fid_after" ] ||
8115                 error "comp-to-plain migrate: $fid_before != $fid_after"
8116
8117         # 3. migrate a plain layout file to a comp layout
8118         $LFS migrate $layout $f_comp ||
8119                 error "cannot migrate $f_comp by lfs migrate"
8120         fid_after=$($LFS getstripe --fid $f_comp)
8121         [ "$fid_before" == "$fid_after" ] ||
8122                 error "plain-to-comp migrate: $fid_before != $fid_after"
8123 }
8124 run_test 56xf "FID is not lost during migration of a composite layout file"
8125
8126 check_file_ost_range() {
8127         local file="$1"
8128         shift
8129         local range="$*"
8130         local -a file_range
8131         local idx
8132
8133         file_range=($($LFS getstripe -y "$file" |
8134                 awk '/l_ost_idx:/ { print $NF }'))
8135
8136         if [[ "${#file_range[@]}" = 0 ]]; then
8137                 echo "No osts found for $file"
8138                 return 1
8139         fi
8140
8141         for idx in "${file_range[@]}"; do
8142                 [[ " $range " =~ " $idx " ]] ||
8143                         return 1
8144         done
8145
8146         return 0
8147 }
8148
8149 sub_test_56xg() {
8150         local stripe_opt="$1"
8151         local pool="$2"
8152         shift 2
8153         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8154
8155         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8156                 error "Fail to migrate $tfile on $pool"
8157         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8158                 error "$tfile is not in pool $pool"
8159         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8160                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8161 }
8162
8163 test_56xg() {
8164         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8165         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8166         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8167                 skip "Need MDS version newer than 2.14.52"
8168
8169         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8170         local -a pool_ranges=("0 0" "1 1" "0 1")
8171
8172         # init pools
8173         for i in "${!pool_names[@]}"; do
8174                 pool_add ${pool_names[$i]} ||
8175                         error "pool_add failed (pool: ${pool_names[$i]})"
8176                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8177                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8178         done
8179
8180         # init the file to migrate
8181         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8182                 error "Unable to create $tfile on OST1"
8183         stack_trap "rm -f $DIR/$tfile"
8184         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8185                 error "Unable to write on $tfile"
8186
8187         echo "1. migrate $tfile on pool ${pool_names[0]}"
8188         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8189
8190         echo "2. migrate $tfile on pool ${pool_names[2]}"
8191         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8192
8193         echo "3. migrate $tfile on pool ${pool_names[1]}"
8194         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8195
8196         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8197         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8198         echo
8199
8200         # Clean pools
8201         destroy_test_pools ||
8202                 error "pool_destroy failed"
8203 }
8204 run_test 56xg "lfs migrate pool support"
8205
8206 test_56xh() {
8207         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8208
8209         local size_mb=25
8210         local file1=$DIR/$tfile
8211         local tmp1=$TMP/$tfile.tmp
8212
8213         $LFS setstripe -c 2 $file1
8214
8215         stack_trap "rm -f $file1 $tmp1"
8216         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8217                         error "error creating $tmp1"
8218         ls -lsh $tmp1
8219         cp $tmp1 $file1
8220
8221         local start=$SECONDS
8222
8223         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8224                 error "migrate failed rc = $?"
8225
8226         local elapsed=$((SECONDS - start))
8227
8228         # with 1MB/s, elapsed should equal size_mb
8229         (( elapsed >= size_mb * 95 / 100 )) ||
8230                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8231
8232         (( elapsed <= size_mb * 120 / 100 )) ||
8233                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8234
8235         (( elapsed <= size_mb * 350 / 100 )) ||
8236                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8237
8238         stripe=$($LFS getstripe -c $file1)
8239         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8240         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8241
8242         # Clean up file (since it is multiple MB)
8243         rm -f $file1 $tmp1
8244 }
8245 run_test 56xh "lfs migrate bandwidth limitation support"
8246
8247 test_56xi() {
8248         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8249         verify_yaml_available || skip_env "YAML verification not installed"
8250
8251         local size_mb=5
8252         local file1=$DIR/$tfile.1
8253         local file2=$DIR/$tfile.2
8254         local file3=$DIR/$tfile.3
8255         local output_file=$DIR/$tfile.out
8256         local tmp1=$TMP/$tfile.tmp
8257
8258         $LFS setstripe -c 2 $file1
8259         $LFS setstripe -c 2 $file2
8260         $LFS setstripe -c 2 $file3
8261
8262         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8263         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8264                         error "error creating $tmp1"
8265         ls -lsh $tmp1
8266         cp $tmp1 $file1
8267         cp $tmp1 $file2
8268         cp $tmp1 $file3
8269
8270         $LFS migrate --stats --stats-interval=1 \
8271                 -c 1 $file1 $file2 $file3 1> $output_file ||
8272                 error "migrate failed rc = $?"
8273
8274         cat $output_file
8275         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8276
8277         # Clean up file (since it is multiple MB)
8278         rm -f $file1 $file2 $file3 $tmp1 $output_file
8279 }
8280 run_test 56xi "lfs migrate stats support"
8281
8282 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8283         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8284
8285         local file=$DIR/$tfile
8286         local linkdir=$DIR/$tdir
8287
8288         test_mkdir $linkdir || error "fail to create $linkdir"
8289         $LFS setstripe -i 0 -c 1 -S1M $file
8290         stack_trap "rm -rf $file $linkdir"
8291         dd if=/dev/urandom of=$file bs=1M count=10 ||
8292                 error "fail to create $file"
8293
8294         # Create file links
8295         local cpts
8296         local threads_max
8297         local nlinks
8298
8299         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8300         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8301         (( nlinks = thread_max * 3 / 2 / cpts))
8302
8303         echo "create $nlinks hard links of $file"
8304         createmany -l $file $linkdir/link $nlinks
8305
8306         # Parallel migrates (should not block)
8307         local i
8308         for ((i = 0; i < nlinks; i++)); do
8309                 echo $linkdir/link$i
8310         done | xargs -n1 -P $nlinks $LFS migrate -c2
8311
8312         local stripe_count
8313         stripe_count=$($LFS getstripe -c $file) ||
8314                 error "fail to get stripe count on $file"
8315
8316         ((stripe_count == 2)) ||
8317                 error "fail to migrate $file (stripe_count = $stripe_count)"
8318 }
8319 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8320
8321 test_56y() {
8322         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8323                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8324
8325         local res=""
8326         local dir=$DIR/$tdir
8327         local f1=$dir/file1
8328         local f2=$dir/file2
8329
8330         test_mkdir -p $dir || error "creating dir $dir"
8331         touch $f1 || error "creating std file $f1"
8332         $MULTIOP $f2 H2c || error "creating released file $f2"
8333
8334         # a directory can be raid0, so ask only for files
8335         res=$($LFS find $dir -L raid0 -type f | wc -l)
8336         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8337
8338         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8339         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8340
8341         # only files can be released, so no need to force file search
8342         res=$($LFS find $dir -L released)
8343         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8344
8345         res=$($LFS find $dir -type f \! -L released)
8346         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8347 }
8348 run_test 56y "lfs find -L raid0|released"
8349
8350 test_56z() { # LU-4824
8351         # This checks to make sure 'lfs find' continues after errors
8352         # There are two classes of errors that should be caught:
8353         # - If multiple paths are provided, all should be searched even if one
8354         #   errors out
8355         # - If errors are encountered during the search, it should not terminate
8356         #   early
8357         local dir=$DIR/$tdir
8358         local i
8359
8360         test_mkdir $dir
8361         for i in d{0..9}; do
8362                 test_mkdir $dir/$i
8363                 touch $dir/$i/$tfile
8364         done
8365         $LFS find $DIR/non_existent_dir $dir &&
8366                 error "$LFS find did not return an error"
8367         # Make a directory unsearchable. This should NOT be the last entry in
8368         # directory order.  Arbitrarily pick the 6th entry
8369         chmod 700 $($LFS find $dir -type d | sed '6!d')
8370
8371         $RUNAS $LFS find $DIR/non_existent $dir
8372         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8373
8374         # The user should be able to see 10 directories and 9 files
8375         (( count == 19 )) ||
8376                 error "$LFS find found $count != 19 entries after error"
8377 }
8378 run_test 56z "lfs find should continue after an error"
8379
8380 test_56aa() { # LU-5937
8381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8382
8383         local dir=$DIR/$tdir
8384
8385         mkdir $dir
8386         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8387
8388         createmany -o $dir/striped_dir/${tfile}- 1024
8389         local dirs=$($LFS find --size +8k $dir/)
8390
8391         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8392 }
8393 run_test 56aa "lfs find --size under striped dir"
8394
8395 test_56ab() { # LU-10705
8396         test_mkdir $DIR/$tdir
8397         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8398         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8399         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8400         # Flush writes to ensure valid blocks.  Need to be more thorough for
8401         # ZFS, since blocks are not allocated/returned to client immediately.
8402         sync_all_data
8403         wait_zfs_commit ost1 2
8404         cancel_lru_locks osc
8405         ls -ls $DIR/$tdir
8406
8407         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8408
8409         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8410
8411         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8412         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8413
8414         rm -f $DIR/$tdir/$tfile.[123]
8415 }
8416 run_test 56ab "lfs find --blocks"
8417
8418 # LU-11188
8419 test_56aca() {
8420         local dir="$DIR/$tdir"
8421         local perms=(001 002 003 004 005 006 007
8422                      010 020 030 040 050 060 070
8423                      100 200 300 400 500 600 700
8424                      111 222 333 444 555 666 777)
8425         local perm_minus=(8 8 4 8 4 4 2
8426                           8 8 4 8 4 4 2
8427                           8 8 4 8 4 4 2
8428                           4 4 2 4 2 2 1)
8429         local perm_slash=(8  8 12  8 12 12 14
8430                           8  8 12  8 12 12 14
8431                           8  8 12  8 12 12 14
8432                          16 16 24 16 24 24 28)
8433
8434         test_mkdir "$dir"
8435         for perm in ${perms[*]}; do
8436                 touch "$dir/$tfile.$perm"
8437                 chmod $perm "$dir/$tfile.$perm"
8438         done
8439
8440         for ((i = 0; i < ${#perms[*]}; i++)); do
8441                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8442                 (( $num == 1 )) ||
8443                         error "lfs find -perm ${perms[i]}:"\
8444                               "$num != 1"
8445
8446                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8447                 (( $num == ${perm_minus[i]} )) ||
8448                         error "lfs find -perm -${perms[i]}:"\
8449                               "$num != ${perm_minus[i]}"
8450
8451                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8452                 (( $num == ${perm_slash[i]} )) ||
8453                         error "lfs find -perm /${perms[i]}:"\
8454                               "$num != ${perm_slash[i]}"
8455         done
8456 }
8457 run_test 56aca "check lfs find -perm with octal representation"
8458
8459 test_56acb() {
8460         local dir=$DIR/$tdir
8461         # p is the permission of write and execute for user, group and other
8462         # without the umask. It is used to test +wx.
8463         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8464         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8465         local symbolic=(+t  a+t u+t g+t o+t
8466                         g+s u+s o+s +s o+sr
8467                         o=r,ug+o,u+w
8468                         u+ g+ o+ a+ ugo+
8469                         u- g- o- a- ugo-
8470                         u= g= o= a= ugo=
8471                         o=r,ug+o,u+w u=r,a+u,u+w
8472                         g=r,ugo=g,u+w u+x,+X +X
8473                         u+x,u+X u+X u+x,g+X o+r,+X
8474                         u+x,go+X +wx +rwx)
8475
8476         test_mkdir $dir
8477         for perm in ${perms[*]}; do
8478                 touch "$dir/$tfile.$perm"
8479                 chmod $perm "$dir/$tfile.$perm"
8480         done
8481
8482         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8483                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8484
8485                 (( $num == 1 )) ||
8486                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8487         done
8488 }
8489 run_test 56acb "check lfs find -perm with symbolic representation"
8490
8491 test_56acc() {
8492         local dir=$DIR/$tdir
8493         local tests="17777 787 789 abcd
8494                 ug=uu ug=a ug=gu uo=ou urw
8495                 u+xg+x a=r,u+x,"
8496
8497         test_mkdir $dir
8498         for err in $tests; do
8499                 if $LFS find $dir -perm $err 2>/dev/null; then
8500                         error "lfs find -perm $err: parsing should have failed"
8501                 fi
8502         done
8503 }
8504 run_test 56acc "check parsing error for lfs find -perm"
8505
8506 test_56ba() {
8507         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8508                 skip "Need MDS version at least 2.10.50"
8509
8510         # Create composite files with one component
8511         local dir=$DIR/$tdir
8512
8513         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8514         # Create composite files with three components
8515         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8516         # LU-16904 Create plain layout files
8517         lfs setstripe -c 1 $dir/$tfile-{1..10}
8518
8519         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8520
8521         [[ $nfiles == 10 ]] ||
8522                 error "lfs find -E 1M found $nfiles != 10 files"
8523
8524         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8525         [[ $nfiles == 25 ]] ||
8526                 error "lfs find ! -E 1M found $nfiles != 25 files"
8527
8528         # All files have a component that starts at 0
8529         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8530         [[ $nfiles == 35 ]] ||
8531                 error "lfs find --component-start 0 - $nfiles != 35 files"
8532
8533         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8534         [[ $nfiles == 15 ]] ||
8535                 error "lfs find --component-start 2M - $nfiles != 15 files"
8536
8537         # All files created here have a componenet that does not starts at 2M
8538         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8539         [[ $nfiles == 35 ]] ||
8540                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8541
8542         # Find files with a specified number of components
8543         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8544         [[ $nfiles == 15 ]] ||
8545                 error "lfs find --component-count 3 - $nfiles != 15 files"
8546
8547         # Remember non-composite files have a component count of zero
8548         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8549         [[ $nfiles == 10 ]] ||
8550                 error "lfs find --component-count 0 - $nfiles != 10 files"
8551
8552         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8553         [[ $nfiles == 20 ]] ||
8554                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8555
8556         # All files have a flag called "init"
8557         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8558         [[ $nfiles == 35 ]] ||
8559                 error "lfs find --component-flags init - $nfiles != 35 files"
8560
8561         # Multi-component files will have a component not initialized
8562         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8563         [[ $nfiles == 15 ]] ||
8564                 error "lfs find !--component-flags init - $nfiles != 15 files"
8565
8566         rm -rf $dir
8567
8568 }
8569 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8570
8571 test_56ca() {
8572         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8573                 skip "Need MDS version at least 2.10.57"
8574
8575         local td=$DIR/$tdir
8576         local tf=$td/$tfile
8577         local dir
8578         local nfiles
8579         local cmd
8580         local i
8581         local j
8582
8583         # create mirrored directories and mirrored files
8584         mkdir $td || error "mkdir $td failed"
8585         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8586         createmany -o $tf- 10 || error "create $tf- failed"
8587
8588         for i in $(seq 2); do
8589                 dir=$td/dir$i
8590                 mkdir $dir || error "mkdir $dir failed"
8591                 $LFS mirror create -N$((3 + i)) $dir ||
8592                         error "create mirrored dir $dir failed"
8593                 createmany -o $dir/$tfile- 10 ||
8594                         error "create $dir/$tfile- failed"
8595         done
8596
8597         # change the states of some mirrored files
8598         echo foo > $tf-6
8599         for i in $(seq 2); do
8600                 dir=$td/dir$i
8601                 for j in $(seq 4 9); do
8602                         echo foo > $dir/$tfile-$j
8603                 done
8604         done
8605
8606         # find mirrored files with specific mirror count
8607         cmd="$LFS find --mirror-count 3 --type f $td"
8608         nfiles=$($cmd | wc -l)
8609         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8610
8611         cmd="$LFS find ! --mirror-count 3 --type f $td"
8612         nfiles=$($cmd | wc -l)
8613         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8614
8615         cmd="$LFS find --mirror-count +2 --type f $td"
8616         nfiles=$($cmd | wc -l)
8617         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8618
8619         cmd="$LFS find --mirror-count -6 --type f $td"
8620         nfiles=$($cmd | wc -l)
8621         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8622
8623         # find mirrored files with specific file state
8624         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8625         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8626
8627         cmd="$LFS find --mirror-state=ro --type f $td"
8628         nfiles=$($cmd | wc -l)
8629         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8630
8631         cmd="$LFS find ! --mirror-state=ro --type f $td"
8632         nfiles=$($cmd | wc -l)
8633         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8634
8635         cmd="$LFS find --mirror-state=wp --type f $td"
8636         nfiles=$($cmd | wc -l)
8637         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8638
8639         cmd="$LFS find ! --mirror-state=sp --type f $td"
8640         nfiles=$($cmd | wc -l)
8641         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8642 }
8643 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8644
8645 test_56da() { # LU-14179
8646         local path=$DIR/$tdir
8647
8648         test_mkdir $path
8649         cd $path
8650
8651         local longdir=$(str_repeat 'a' 255)
8652
8653         for i in {1..15}; do
8654                 path=$path/$longdir
8655                 test_mkdir $longdir
8656                 cd $longdir
8657         done
8658
8659         local len=${#path}
8660         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8661
8662         test_mkdir $lastdir
8663         cd $lastdir
8664         # PATH_MAX-1
8665         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8666
8667         # NAME_MAX
8668         touch $(str_repeat 'f' 255)
8669
8670         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8671                 error "lfs find reported an error"
8672
8673         rm -rf $DIR/$tdir
8674 }
8675 run_test 56da "test lfs find with long paths"
8676
8677 test_56ea() { #LU-10378
8678         local path=$DIR/$tdir
8679         local pool=$TESTNAME
8680
8681         # Create ost pool
8682         pool_add $pool || error "pool_add $pool failed"
8683         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8684                 error "adding targets to $pool failed"
8685
8686         # Set default pool on directory before creating file
8687         mkdir $path || error "mkdir $path failed"
8688         $LFS setstripe -p $pool $path ||
8689                 error "set OST pool on $pool failed"
8690         touch $path/$tfile || error "touch $path/$tfile failed"
8691
8692         # Compare basic file attributes from -printf and stat
8693         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8694         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8695
8696         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8697                 error "Attrs from lfs find and stat don't match"
8698
8699         # Compare Lustre attributes from lfs find and lfs getstripe
8700         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8701         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8702         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8703         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8704         local fpool=$($LFS getstripe --pool $path/$tfile)
8705         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8706
8707         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8708                 error "Attrs from lfs find and lfs getstripe don't match"
8709
8710         # Verify behavior for unknown escape/format sequences
8711         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8712
8713         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8714                 error "Escape/format codes don't match"
8715 }
8716 run_test 56ea "test lfs find -printf option"
8717
8718 test_56eb() {
8719         local dir=$DIR/$tdir
8720         local subdir_1=$dir/subdir_1
8721
8722         test_mkdir -p $subdir_1
8723         ln -s subdir_1 $dir/link_1
8724
8725         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8726                 error "symlink is not followed"
8727
8728         $LFS getstripe --no-follow $dir |
8729                 grep "^$dir/link_1 has no stripe info$" ||
8730                 error "symlink should not have stripe info"
8731
8732         touch $dir/testfile
8733         ln -s testfile $dir/file_link_2
8734
8735         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8736                 error "symlink is not followed"
8737
8738         $LFS getstripe --no-follow $dir |
8739                 grep "^$dir/file_link_2 has no stripe info$" ||
8740                 error "symlink should not have stripe info"
8741 }
8742 run_test 56eb "check lfs getstripe on symlink"
8743
8744 test_56ec() {
8745         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8746         local dir=$DIR/$tdir
8747         local srcfile=$dir/srcfile
8748         local srcyaml=$dir/srcyaml
8749         local destfile=$dir/destfile
8750
8751         test_mkdir -p $dir
8752
8753         $LFS setstripe -i 1 $srcfile
8754         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8755         # if the setstripe yaml parsing fails for any reason, the command can
8756         # randomly assign the correct OST index, leading to an erroneous
8757         # success. but the chance of false success is low enough that a
8758         # regression should still be quickly caught.
8759         $LFS setstripe --yaml=$srcyaml $destfile
8760
8761         local srcindex=$($LFS getstripe -i $srcfile)
8762         local destindex=$($LFS getstripe -i $destfile)
8763
8764         if [[ ! $srcindex -eq $destindex ]]; then
8765                 error "setstripe did not set OST index correctly"
8766         fi
8767 }
8768 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8769
8770 test_56eda() {
8771         local dir=$DIR/$tdir
8772         local subdir=$dir/subdir
8773         local file1=$dir/$tfile
8774         local file2=$dir/$tfile\2
8775         local link=$dir/$tfile-link
8776         local nfiles
8777
8778         test_mkdir -p $dir
8779         $LFS setdirstripe -c1 $subdir
8780         touch $file1
8781         touch $file2
8782         ln $file2 $link
8783
8784         nfiles=$($LFS find --links 1 $dir | wc -l)
8785         (( $nfiles == 1 )) ||
8786                 error "lfs find --links expected 1 file, got $nfiles"
8787
8788         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8789         (( $nfiles == 2 )) ||
8790                 error "lfs find --links expected 2 files, got $nfiles"
8791
8792         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8793         (( $nfiles == 1 )) ||
8794                 error "lfs find --links expected 1 directory, got $nfiles"
8795 }
8796 run_test 56eda "check lfs find --links"
8797
8798 test_56edb() {
8799         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8800
8801         local dir=$DIR/$tdir
8802         local stripedir=$dir/stripedir
8803         local nfiles
8804
8805         test_mkdir -p $dir
8806
8807         $LFS setdirstripe -c2 $stripedir
8808
8809         $LFS getdirstripe $stripedir
8810
8811         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8812         (( $nfiles == 1 )) ||
8813                 error "lfs find --links expected 1 directory, got $nfiles"
8814 }
8815 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8816
8817 test_56ef() {
8818         local dir=$DIR/$tdir
8819         local dir1=$dir/d1
8820         local dir2=$dir/d2
8821         local nfiles
8822
8823         test_mkdir -p $dir
8824
8825         mkdir $dir1
8826         mkdir $dir2
8827
8828         touch $dir1/f
8829         touch $dir2/f
8830
8831         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8832         (( $nfiles == 2 )) ||
8833                 error "(1) lfs find expected 2 files, got $nfiles"
8834
8835         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8836         (( $nfiles == 2 )) ||
8837                 error "(2) lfs find expected 2 files, got $nfiles"
8838
8839         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8840         (( $nfiles == 2 )) ||
8841                 error "(3) lfs find expected 2 files, got $nfiles"
8842 }
8843 run_test 56ef "lfs find with multiple paths"
8844
8845 test_57a() {
8846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8847         # note test will not do anything if MDS is not local
8848         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8849                 skip_env "ldiskfs only test"
8850         fi
8851         remote_mds_nodsh && skip "remote MDS with nodsh"
8852
8853         local MNTDEV="osd*.*MDT*.mntdev"
8854         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8855         [ -z "$DEV" ] && error "can't access $MNTDEV"
8856         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8857                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8858                         error "can't access $DEV"
8859                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8860                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8861                 rm $TMP/t57a.dump
8862         done
8863 }
8864 run_test 57a "verify MDS filesystem created with large inodes =="
8865
8866 test_57b() {
8867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8868         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8869                 skip_env "ldiskfs only test"
8870         fi
8871         remote_mds_nodsh && skip "remote MDS with nodsh"
8872
8873         local dir=$DIR/$tdir
8874         local filecount=100
8875         local file1=$dir/f1
8876         local fileN=$dir/f$filecount
8877
8878         rm -rf $dir || error "removing $dir"
8879         test_mkdir -c1 $dir
8880         local mdtidx=$($LFS getstripe -m $dir)
8881         local mdtname=MDT$(printf %04x $mdtidx)
8882         local facet=mds$((mdtidx + 1))
8883
8884         echo "mcreating $filecount files"
8885         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8886
8887         # verify that files do not have EAs yet
8888         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8889                 error "$file1 has an EA"
8890         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8891                 error "$fileN has an EA"
8892
8893         sync
8894         sleep 1
8895         df $dir  #make sure we get new statfs data
8896         local mdsfree=$(do_facet $facet \
8897                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8898         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8899         local file
8900
8901         echo "opening files to create objects/EAs"
8902         for file in $(seq -f $dir/f%g 1 $filecount); do
8903                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8904                         error "opening $file"
8905         done
8906
8907         # verify that files have EAs now
8908         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
8909                 error "$file1 missing EA"
8910         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
8911                 error "$fileN missing EA"
8912
8913         sleep 1  #make sure we get new statfs data
8914         df $dir
8915         local mdsfree2=$(do_facet $facet \
8916                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8917         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8918
8919         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8920                 if [ "$mdsfree" != "$mdsfree2" ]; then
8921                         error "MDC before $mdcfree != after $mdcfree2"
8922                 else
8923                         echo "MDC before $mdcfree != after $mdcfree2"
8924                         echo "unable to confirm if MDS has large inodes"
8925                 fi
8926         fi
8927         rm -rf $dir
8928 }
8929 run_test 57b "default LOV EAs are stored inside large inodes ==="
8930
8931 test_58() {
8932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8933         [ -z "$(which wiretest 2>/dev/null)" ] &&
8934                         skip_env "could not find wiretest"
8935
8936         wiretest
8937 }
8938 run_test 58 "verify cross-platform wire constants =============="
8939
8940 test_59() {
8941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8942
8943         echo "touch 130 files"
8944         createmany -o $DIR/f59- 130
8945         echo "rm 130 files"
8946         unlinkmany $DIR/f59- 130
8947         sync
8948         # wait for commitment of removal
8949         wait_delete_completed
8950 }
8951 run_test 59 "verify cancellation of llog records async ========="
8952
8953 TEST60_HEAD="test_60 run $RANDOM"
8954 test_60a() {
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956         remote_mgs_nodsh && skip "remote MGS with nodsh"
8957         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8958                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8959                         skip_env "missing subtest run-llog.sh"
8960
8961         log "$TEST60_HEAD - from kernel mode"
8962         do_facet mgs "$LCTL dk > /dev/null"
8963         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8964         do_facet mgs $LCTL dk > $TMP/$tfile
8965
8966         # LU-6388: test llog_reader
8967         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8968         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8969         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8970                         skip_env "missing llog_reader"
8971         local fstype=$(facet_fstype mgs)
8972         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8973                 skip_env "Only for ldiskfs or zfs type mgs"
8974
8975         local mntpt=$(facet_mntpt mgs)
8976         local mgsdev=$(mgsdevname 1)
8977         local fid_list
8978         local fid
8979         local rec_list
8980         local rec
8981         local rec_type
8982         local obj_file
8983         local path
8984         local seq
8985         local oid
8986         local pass=true
8987
8988         #get fid and record list
8989         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8990                 tail -n 4))
8991         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8992                 tail -n 4))
8993         #remount mgs as ldiskfs or zfs type
8994         stop mgs || error "stop mgs failed"
8995         mount_fstype mgs || error "remount mgs failed"
8996         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8997                 fid=${fid_list[i]}
8998                 rec=${rec_list[i]}
8999                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9000                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9001                 oid=$((16#$oid))
9002
9003                 case $fstype in
9004                         ldiskfs )
9005                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9006                         zfs )
9007                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9008                 esac
9009                 echo "obj_file is $obj_file"
9010                 do_facet mgs $llog_reader $obj_file
9011
9012                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9013                         awk '{ print $3 }' | sed -e "s/^type=//g")
9014                 if [ $rec_type != $rec ]; then
9015                         echo "FAILED test_60a wrong record type $rec_type," \
9016                               "should be $rec"
9017                         pass=false
9018                         break
9019                 fi
9020
9021                 #check obj path if record type is LLOG_LOGID_MAGIC
9022                 if [ "$rec" == "1064553b" ]; then
9023                         path=$(do_facet mgs $llog_reader $obj_file |
9024                                 grep "path=" | awk '{ print $NF }' |
9025                                 sed -e "s/^path=//g")
9026                         if [ $obj_file != $mntpt/$path ]; then
9027                                 echo "FAILED test_60a wrong obj path" \
9028                                       "$montpt/$path, should be $obj_file"
9029                                 pass=false
9030                                 break
9031                         fi
9032                 fi
9033         done
9034         rm -f $TMP/$tfile
9035         #restart mgs before "error", otherwise it will block the next test
9036         stop mgs || error "stop mgs failed"
9037         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9038         $pass || error "test failed, see FAILED test_60a messages for specifics"
9039 }
9040 run_test 60a "llog_test run from kernel module and test llog_reader"
9041
9042 test_60b() { # bug 6411
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044
9045         dmesg > $DIR/$tfile
9046         LLOG_COUNT=$(do_facet mgs dmesg |
9047                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9048                           /llog_[a-z]*.c:[0-9]/ {
9049                                 if (marker)
9050                                         from_marker++
9051                                 from_begin++
9052                           }
9053                           END {
9054                                 if (marker)
9055                                         print from_marker
9056                                 else
9057                                         print from_begin
9058                           }")
9059
9060         [[ $LLOG_COUNT -gt 120 ]] &&
9061                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9062 }
9063 run_test 60b "limit repeated messages from CERROR/CWARN"
9064
9065 test_60c() {
9066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9067
9068         echo "create 5000 files"
9069         createmany -o $DIR/f60c- 5000
9070 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9071         lctl set_param fail_loc=0x80000137
9072         unlinkmany $DIR/f60c- 5000
9073         lctl set_param fail_loc=0
9074 }
9075 run_test 60c "unlink file when mds full"
9076
9077 test_60d() {
9078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9079
9080         SAVEPRINTK=$(lctl get_param -n printk)
9081         # verify "lctl mark" is even working"
9082         MESSAGE="test message ID $RANDOM $$"
9083         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9084         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9085
9086         lctl set_param printk=0 || error "set lnet.printk failed"
9087         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9088         MESSAGE="new test message ID $RANDOM $$"
9089         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9090         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9091         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9092
9093         lctl set_param -n printk="$SAVEPRINTK"
9094 }
9095 run_test 60d "test printk console message masking"
9096
9097 test_60e() {
9098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9099         remote_mds_nodsh && skip "remote MDS with nodsh"
9100
9101         touch $DIR/$tfile
9102 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9103         do_facet mds1 lctl set_param fail_loc=0x15b
9104         rm $DIR/$tfile
9105 }
9106 run_test 60e "no space while new llog is being created"
9107
9108 test_60f() {
9109         local old_path=$($LCTL get_param -n debug_path)
9110
9111         stack_trap "$LCTL set_param debug_path=$old_path"
9112         stack_trap "rm -f $TMP/$tfile*"
9113         rm -f $TMP/$tfile* 2> /dev/null
9114         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9115         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9116         test_mkdir $DIR/$tdir
9117         # retry in case the open is cached and not released
9118         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9119                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9120                 sleep 0.1
9121         done
9122         ls $TMP/$tfile*
9123         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9124 }
9125 run_test 60f "change debug_path works"
9126
9127 test_60g() {
9128         local pid
9129         local i
9130
9131         test_mkdir -c $MDSCOUNT $DIR/$tdir
9132
9133         (
9134                 local index=0
9135                 while true; do
9136                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9137                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9138                                 2>/dev/null
9139                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9140                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9141                         index=$((index + 1))
9142                 done
9143         ) &
9144
9145         pid=$!
9146
9147         for i in {0..100}; do
9148                 # define OBD_FAIL_OSD_TXN_START    0x19a
9149                 local index=$((i % MDSCOUNT + 1))
9150
9151                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9152                         > /dev/null
9153                 sleep 0.01
9154         done
9155
9156         kill -9 $pid
9157
9158         for i in $(seq $MDSCOUNT); do
9159                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9160         done
9161
9162         mkdir $DIR/$tdir/new || error "mkdir failed"
9163         rmdir $DIR/$tdir/new || error "rmdir failed"
9164
9165         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9166                 -t namespace
9167         for i in $(seq $MDSCOUNT); do
9168                 wait_update_facet mds$i "$LCTL get_param -n \
9169                         mdd.$(facet_svc mds$i).lfsck_namespace |
9170                         awk '/^status/ { print \\\$2 }'" "completed"
9171         done
9172
9173         ls -R $DIR/$tdir
9174         rm -rf $DIR/$tdir || error "rmdir failed"
9175 }
9176 run_test 60g "transaction abort won't cause MDT hung"
9177
9178 test_60h() {
9179         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9180                 skip "Need MDS version at least 2.12.52"
9181         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9182
9183         local f
9184
9185         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9186         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9187         for fail_loc in 0x80000188 0x80000189; do
9188                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9189                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9190                         error "mkdir $dir-$fail_loc failed"
9191                 for i in {0..10}; do
9192                         # create may fail on missing stripe
9193                         echo $i > $DIR/$tdir-$fail_loc/$i
9194                 done
9195                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9196                         error "getdirstripe $tdir-$fail_loc failed"
9197                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9198                         error "migrate $tdir-$fail_loc failed"
9199                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9200                         error "getdirstripe $tdir-$fail_loc failed"
9201                 pushd $DIR/$tdir-$fail_loc
9202                 for f in *; do
9203                         echo $f | cmp $f - || error "$f data mismatch"
9204                 done
9205                 popd
9206                 rm -rf $DIR/$tdir-$fail_loc
9207         done
9208 }
9209 run_test 60h "striped directory with missing stripes can be accessed"
9210
9211 function t60i_load() {
9212         mkdir $DIR/$tdir
9213         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9214         $LCTL set_param fail_loc=0x131c fail_val=1
9215         for ((i=0; i<5000; i++)); do
9216                 touch $DIR/$tdir/f$i
9217         done
9218 }
9219
9220 test_60i() {
9221         changelog_register || error "changelog_register failed"
9222         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9223         changelog_users $SINGLEMDS | grep -q $cl_user ||
9224                 error "User $cl_user not found in changelog_users"
9225         changelog_chmask "ALL"
9226         t60i_load &
9227         local PID=$!
9228         for((i=0; i<100; i++)); do
9229                 changelog_dump >/dev/null ||
9230                         error "can't read changelog"
9231         done
9232         kill $PID
9233         wait $PID
9234         changelog_deregister || error "changelog_deregister failed"
9235         $LCTL set_param fail_loc=0
9236 }
9237 run_test 60i "llog: new record vs reader race"
9238
9239 test_60j() {
9240         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9241                 skip "need MDS version at least 2.15.50"
9242         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9243         remote_mds_nodsh && skip "remote MDS with nodsh"
9244         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9245
9246         changelog_users $SINGLEMDS | grep "^cl" &&
9247                 skip "active changelog user"
9248
9249         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9250
9251         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9252                 skip_env "missing llog_reader"
9253
9254         mkdir_on_mdt0 $DIR/$tdir
9255
9256         local f=$DIR/$tdir/$tfile
9257         local mdt_dev
9258         local tmpfile
9259         local plain
9260
9261         changelog_register || error "cannot register changelog user"
9262
9263         # set changelog_mask to ALL
9264         changelog_chmask "ALL"
9265         changelog_clear
9266
9267         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9268         unlinkmany ${f}- 100 || error "unlinkmany failed"
9269
9270         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9271         mdt_dev=$(facet_device $SINGLEMDS)
9272
9273         do_facet $SINGLEMDS sync
9274         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9275                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9276                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9277
9278         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9279
9280         # if $tmpfile is not on EXT3 filesystem for some reason
9281         [[ ${plain:0:1} == 'O' ]] ||
9282                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9283
9284         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9285                 $mdt_dev; stat -c %s $tmpfile")
9286         echo "Truncate llog from $size to $((size - size % 8192))"
9287         size=$((size - size % 8192))
9288         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9289         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9290                 grep -c 'in bitmap only')
9291         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9292
9293         size=$((size - 9000))
9294         echo "Corrupt llog in the middle at $size"
9295         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9296                 count=333 conv=notrunc
9297         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9298                 grep -c 'next chunk')
9299         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9300 }
9301 run_test 60j "llog_reader reports corruptions"
9302
9303 test_61a() {
9304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9305
9306         f="$DIR/f61"
9307         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9308         cancel_lru_locks osc
9309         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9310         sync
9311 }
9312 run_test 61a "mmap() writes don't make sync hang ================"
9313
9314 test_61b() {
9315         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9316 }
9317 run_test 61b "mmap() of unstriped file is successful"
9318
9319 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9320 # Though this test is irrelevant anymore, it helped to reveal some
9321 # other grant bugs (LU-4482), let's keep it.
9322 test_63a() {   # was test_63
9323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9324
9325         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9326
9327         for i in `seq 10` ; do
9328                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9329                 sleep 5
9330                 kill $!
9331                 sleep 1
9332         done
9333
9334         rm -f $DIR/f63 || true
9335 }
9336 run_test 63a "Verify oig_wait interruption does not crash ======="
9337
9338 # bug 2248 - async write errors didn't return to application on sync
9339 # bug 3677 - async write errors left page locked
9340 test_63b() {
9341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9342
9343         debugsave
9344         lctl set_param debug=-1
9345
9346         # ensure we have a grant to do async writes
9347         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9348         rm $DIR/$tfile
9349
9350         sync    # sync lest earlier test intercept the fail_loc
9351
9352         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9353         lctl set_param fail_loc=0x80000406
9354         $MULTIOP $DIR/$tfile Owy && \
9355                 error "sync didn't return ENOMEM"
9356         sync; sleep 2; sync     # do a real sync this time to flush page
9357         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9358                 error "locked page left in cache after async error" || true
9359         debugrestore
9360 }
9361 run_test 63b "async write errors should be returned to fsync ==="
9362
9363 test_64a () {
9364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9365
9366         lfs df $DIR
9367         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9368 }
9369 run_test 64a "verify filter grant calculations (in kernel) ====="
9370
9371 test_64b () {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373
9374         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9375 }
9376 run_test 64b "check out-of-space detection on client"
9377
9378 test_64c() {
9379         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9380 }
9381 run_test 64c "verify grant shrink"
9382
9383 import_param() {
9384         local tgt=$1
9385         local param=$2
9386
9387         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9388 }
9389
9390 # this does exactly what osc_request.c:osc_announce_cached() does in
9391 # order to calculate max amount of grants to ask from server
9392 want_grant() {
9393         local tgt=$1
9394
9395         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9396         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9397
9398         ((rpc_in_flight++));
9399         nrpages=$((nrpages * rpc_in_flight))
9400
9401         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9402
9403         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9404
9405         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9406         local undirty=$((nrpages * PAGE_SIZE))
9407
9408         local max_extent_pages
9409         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9410         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9411         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9412         local grant_extent_tax
9413         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9414
9415         undirty=$((undirty + nrextents * grant_extent_tax))
9416
9417         echo $undirty
9418 }
9419
9420 # this is size of unit for grant allocation. It should be equal to
9421 # what tgt_grant.c:tgt_grant_chunk() calculates
9422 grant_chunk() {
9423         local tgt=$1
9424         local max_brw_size
9425         local grant_extent_tax
9426
9427         max_brw_size=$(import_param $tgt max_brw_size)
9428
9429         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9430
9431         echo $(((max_brw_size + grant_extent_tax) * 2))
9432 }
9433
9434 test_64d() {
9435         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9436                 skip "OST < 2.10.55 doesn't limit grants enough"
9437
9438         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9439
9440         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9441                 skip "no grant_param connect flag"
9442
9443         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9444
9445         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9446         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9447
9448
9449         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9450         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9451
9452         $LFS setstripe $DIR/$tfile -i 0 -c 1
9453         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9454         ddpid=$!
9455
9456         while kill -0 $ddpid; do
9457                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9458
9459                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9460                         kill $ddpid
9461                         error "cur_grant $cur_grant > $max_cur_granted"
9462                 fi
9463
9464                 sleep 1
9465         done
9466 }
9467 run_test 64d "check grant limit exceed"
9468
9469 check_grants() {
9470         local tgt=$1
9471         local expected=$2
9472         local msg=$3
9473         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9474
9475         ((cur_grants == expected)) ||
9476                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9477 }
9478
9479 round_up_p2() {
9480         echo $((($1 + $2 - 1) & ~($2 - 1)))
9481 }
9482
9483 test_64e() {
9484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9485         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9486                 skip "Need OSS version at least 2.11.56"
9487
9488         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9489         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9490         $LCTL set_param debug=+cache
9491
9492         # Remount client to reset grant
9493         remount_client $MOUNT || error "failed to remount client"
9494         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9495
9496         local init_grants=$(import_param $osc_tgt initial_grant)
9497
9498         check_grants $osc_tgt $init_grants "init grants"
9499
9500         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9501         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9502         local gbs=$(import_param $osc_tgt grant_block_size)
9503
9504         # write random number of bytes from max_brw_size / 4 to max_brw_size
9505         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9506         # align for direct io
9507         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9508         # round to grant consumption unit
9509         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9510
9511         local grants=$((wb_round_up + extent_tax))
9512
9513         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9514         stack_trap "rm -f $DIR/$tfile"
9515
9516         # define OBD_FAIL_TGT_NO_GRANT 0x725
9517         # make the server not grant more back
9518         do_facet ost1 $LCTL set_param fail_loc=0x725
9519         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9520
9521         do_facet ost1 $LCTL set_param fail_loc=0
9522
9523         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9524
9525         rm -f $DIR/$tfile || error "rm failed"
9526
9527         # Remount client to reset grant
9528         remount_client $MOUNT || error "failed to remount client"
9529         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9530
9531         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9532
9533         # define OBD_FAIL_TGT_NO_GRANT 0x725
9534         # make the server not grant more back
9535         do_facet ost1 $LCTL set_param fail_loc=0x725
9536         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9537         do_facet ost1 $LCTL set_param fail_loc=0
9538
9539         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9540 }
9541 run_test 64e "check grant consumption (no grant allocation)"
9542
9543 test_64f() {
9544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9545
9546         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9547         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9548         $LCTL set_param debug=+cache
9549
9550         # Remount client to reset grant
9551         remount_client $MOUNT || error "failed to remount client"
9552         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9553
9554         local init_grants=$(import_param $osc_tgt initial_grant)
9555         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9556         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9557         local gbs=$(import_param $osc_tgt grant_block_size)
9558         local chunk=$(grant_chunk $osc_tgt)
9559
9560         # write random number of bytes from max_brw_size / 4 to max_brw_size
9561         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9562         # align for direct io
9563         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9564         # round to grant consumption unit
9565         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9566
9567         local grants=$((wb_round_up + extent_tax))
9568
9569         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9570         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9571                 error "error writing to $DIR/$tfile"
9572
9573         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9574                 "direct io with grant allocation"
9575
9576         rm -f $DIR/$tfile || error "rm failed"
9577
9578         # Remount client to reset grant
9579         remount_client $MOUNT || error "failed to remount client"
9580         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9581
9582         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9583
9584         local cmd="oO_WRONLY:w${write_bytes}_yc"
9585
9586         $MULTIOP $DIR/$tfile $cmd &
9587         MULTIPID=$!
9588         sleep 1
9589
9590         check_grants $osc_tgt $((init_grants - grants)) \
9591                 "buffered io, not write rpc"
9592
9593         kill -USR1 $MULTIPID
9594         wait
9595
9596         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9597                 "buffered io, one RPC"
9598 }
9599 run_test 64f "check grant consumption (with grant allocation)"
9600
9601 test_64g() {
9602         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9603                 skip "Need MDS version at least 2.14.56"
9604
9605         local mdts=$(comma_list $(mdts_nodes))
9606
9607         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9608                         tr '\n' ' ')
9609         stack_trap "$LCTL set_param $old"
9610
9611         # generate dirty pages and increase dirty granted on MDT
9612         stack_trap "rm -f $DIR/$tfile-*"
9613         for (( i = 0; i < 10; i++)); do
9614                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9615                         error "can't set stripe"
9616                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9617                         error "can't dd"
9618                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9619                         $LFS getstripe $DIR/$tfile-$i
9620                         error "not DoM file"
9621                 }
9622         done
9623
9624         # flush dirty pages
9625         sync
9626
9627         # wait until grant shrink reset grant dirty on MDTs
9628         for ((i = 0; i < 120; i++)); do
9629                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9630                         awk '{sum=sum+$1} END {print sum}')
9631                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9632                 echo "$grant_dirty grants, $vm_dirty pages"
9633                 (( grant_dirty + vm_dirty == 0 )) && break
9634                 (( i == 3 )) && sync &&
9635                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9636                 sleep 1
9637         done
9638
9639         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9640                 awk '{sum=sum+$1} END {print sum}')
9641         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9642 }
9643 run_test 64g "grant shrink on MDT"
9644
9645 test_64h() {
9646         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9647                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9648
9649         local instance=$($LFS getname -i $DIR)
9650         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9651         local num_exps=$(do_facet ost1 \
9652             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9653         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9654         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9655         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9656
9657         # 10MiB is for file to be written, max_brw_size * 16 *
9658         # num_exps is space reserve so that tgt_grant_shrink() decided
9659         # to not shrink
9660         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9661         (( avail * 1024 < expect )) &&
9662                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9663
9664         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9665         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9666         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9667         $LCTL set_param osc.*OST0000*.grant_shrink=1
9668         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9669
9670         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9671         stack_trap "rm -f $DIR/$tfile"
9672         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9673
9674         # drop cache so that coming read would do rpc
9675         cancel_lru_locks osc
9676
9677         # shrink interval is set to 10, pause for 7 seconds so that
9678         # grant thread did not wake up yet but coming read entered
9679         # shrink mode for rpc (osc_should_shrink_grant())
9680         sleep 7
9681
9682         declare -a cur_grant_bytes
9683         declare -a tot_granted
9684         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9685         tot_granted[0]=$(do_facet ost1 \
9686             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9687
9688         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9689
9690         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9691         tot_granted[1]=$(do_facet ost1 \
9692             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9693
9694         # grant change should be equal on both sides
9695         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9696                 tot_granted[0] - tot_granted[1])) ||
9697                 error "grant change mismatch, "                                \
9698                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9699                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9700 }
9701 run_test 64h "grant shrink on read"
9702
9703 test_64i() {
9704         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9705                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9706
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708         remote_ost_nodsh && skip "remote OSTs with nodsh"
9709
9710         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9711         stack_trap "rm -f $DIR/$tfile"
9712
9713         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9714
9715         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9716         local instance=$($LFS getname -i $DIR)
9717
9718         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9719         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9720
9721         # shrink grants and simulate rpc loss
9722         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9723         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9724         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9725
9726         fail ost1
9727
9728         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9729
9730         local testid=$(echo $TESTNAME | tr '_' ' ')
9731
9732         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9733                 grep "GRANT, real grant" &&
9734                 error "client has more grants then it owns" || true
9735 }
9736 run_test 64i "shrink on reconnect"
9737
9738 # bug 1414 - set/get directories' stripe info
9739 test_65a() {
9740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9741
9742         test_mkdir $DIR/$tdir
9743         touch $DIR/$tdir/f1
9744         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9745 }
9746 run_test 65a "directory with no stripe info"
9747
9748 test_65b() {
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750
9751         test_mkdir $DIR/$tdir
9752         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9753
9754         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9755                                                 error "setstripe"
9756         touch $DIR/$tdir/f2
9757         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9758 }
9759 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9760
9761 test_65c() {
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9764
9765         test_mkdir $DIR/$tdir
9766         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9767
9768         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9769                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9770         touch $DIR/$tdir/f3
9771         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9772 }
9773 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9774
9775 test_65d() {
9776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9777
9778         test_mkdir $DIR/$tdir
9779         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9780         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9781
9782         if [[ $STRIPECOUNT -le 0 ]]; then
9783                 sc=1
9784         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9785                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9786                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9787         else
9788                 sc=$(($STRIPECOUNT - 1))
9789         fi
9790         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9791         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9792         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9793                 error "lverify failed"
9794 }
9795 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9796
9797 test_65e() {
9798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9799
9800         # LU-16904 delete layout when root is set as PFL layout
9801         save_layout_restore_at_exit $MOUNT
9802         $LFS setstripe -d $MOUNT || error "setstripe failed"
9803
9804         test_mkdir $DIR/$tdir
9805
9806         $LFS setstripe $DIR/$tdir || error "setstripe"
9807         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9808                                         error "no stripe info failed"
9809         touch $DIR/$tdir/f6
9810         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9811 }
9812 run_test 65e "directory setstripe defaults"
9813
9814 test_65f() {
9815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9816
9817         test_mkdir $DIR/${tdir}f
9818         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9819                 error "setstripe succeeded" || true
9820 }
9821 run_test 65f "dir setstripe permission (should return error) ==="
9822
9823 test_65g() {
9824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9825
9826         # LU-16904 delete layout when root is set as PFL layout
9827         save_layout_restore_at_exit $MOUNT
9828         $LFS setstripe -d $MOUNT || error "setstripe failed"
9829
9830         test_mkdir $DIR/$tdir
9831         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9832
9833         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9834                 error "setstripe -S failed"
9835         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9836         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9837                 error "delete default stripe failed"
9838 }
9839 run_test 65g "directory setstripe -d"
9840
9841 test_65h() {
9842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9843
9844         test_mkdir $DIR/$tdir
9845         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9846
9847         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9848                 error "setstripe -S failed"
9849         test_mkdir $DIR/$tdir/dd1
9850         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9851                 error "stripe info inherit failed"
9852 }
9853 run_test 65h "directory stripe info inherit ===================="
9854
9855 test_65i() {
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857
9858         save_layout_restore_at_exit $MOUNT
9859
9860         # bug6367: set non-default striping on root directory
9861         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9862
9863         # bug12836: getstripe on -1 default directory striping
9864         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9865
9866         # bug12836: getstripe -v on -1 default directory striping
9867         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9868
9869         # bug12836: new find on -1 default directory striping
9870         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9871 }
9872 run_test 65i "various tests to set root directory striping"
9873
9874 test_65j() { # bug6367
9875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9876
9877         sync; sleep 1
9878
9879         # if we aren't already remounting for each test, do so for this test
9880         if [ "$I_MOUNTED" = "yes" ]; then
9881                 cleanup || error "failed to unmount"
9882                 setup
9883         fi
9884
9885         save_layout_restore_at_exit $MOUNT
9886
9887         $LFS setstripe -d $MOUNT || error "setstripe failed"
9888 }
9889 run_test 65j "set default striping on root directory (bug 6367)="
9890
9891 cleanup_65k() {
9892         rm -rf $DIR/$tdir
9893         wait_delete_completed
9894         do_facet $SINGLEMDS "lctl set_param -n \
9895                 osp.$ost*MDT0000.max_create_count=$max_count"
9896         do_facet $SINGLEMDS "lctl set_param -n \
9897                 osp.$ost*MDT0000.create_count=$count"
9898         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9899         echo $INACTIVE_OSC "is Activate"
9900
9901         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9902 }
9903
9904 test_65k() { # bug11679
9905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9907         remote_mds_nodsh && skip "remote MDS with nodsh"
9908
9909         local disable_precreate=true
9910         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9911                 disable_precreate=false
9912
9913         echo "Check OST status: "
9914         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9915                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9916
9917         for OSC in $MDS_OSCS; do
9918                 echo $OSC "is active"
9919                 do_facet $SINGLEMDS lctl --device %$OSC activate
9920         done
9921
9922         for INACTIVE_OSC in $MDS_OSCS; do
9923                 local ost=$(osc_to_ost $INACTIVE_OSC)
9924                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9925                                lov.*md*.target_obd |
9926                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9927
9928                 mkdir -p $DIR/$tdir
9929                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9930                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9931
9932                 echo "Deactivate: " $INACTIVE_OSC
9933                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9934
9935                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9936                               osp.$ost*MDT0000.create_count")
9937                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9938                                   osp.$ost*MDT0000.max_create_count")
9939                 $disable_precreate &&
9940                         do_facet $SINGLEMDS "lctl set_param -n \
9941                                 osp.$ost*MDT0000.max_create_count=0"
9942
9943                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9944                         [ -f $DIR/$tdir/$idx ] && continue
9945                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9946                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9947                                 { cleanup_65k;
9948                                   error "setstripe $idx should succeed"; }
9949                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9950                 done
9951                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9952                 rmdir $DIR/$tdir
9953
9954                 do_facet $SINGLEMDS "lctl set_param -n \
9955                         osp.$ost*MDT0000.max_create_count=$max_count"
9956                 do_facet $SINGLEMDS "lctl set_param -n \
9957                         osp.$ost*MDT0000.create_count=$count"
9958                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9959                 echo $INACTIVE_OSC "is Activate"
9960
9961                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9962         done
9963 }
9964 run_test 65k "validate manual striping works properly with deactivated OSCs"
9965
9966 test_65l() { # bug 12836
9967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9968
9969         test_mkdir -p $DIR/$tdir/test_dir
9970         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9971         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9972 }
9973 run_test 65l "lfs find on -1 stripe dir ========================"
9974
9975 test_65m() {
9976         local layout=$(save_layout $MOUNT)
9977         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9978                 restore_layout $MOUNT $layout
9979                 error "setstripe should fail by non-root users"
9980         }
9981         true
9982 }
9983 run_test 65m "normal user can't set filesystem default stripe"
9984
9985 test_65n() {
9986         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9987         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9988                 skip "Need MDS version at least 2.12.50"
9989         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9990
9991         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9992         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9993         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9994
9995         save_layout_restore_at_exit $MOUNT
9996
9997         # new subdirectory under root directory should not inherit
9998         # the default layout from root
9999         # LU-16904 check if the root is set as PFL layout
10000         local numcomp=$($LFS getstripe --component-count $MOUNT)
10001
10002         if [[ $numcomp -eq 0 ]]; then
10003                 local dir1=$MOUNT/$tdir-1
10004                 mkdir $dir1 || error "mkdir $dir1 failed"
10005                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10006                         error "$dir1 shouldn't have LOV EA"
10007         fi
10008
10009         # delete the default layout on root directory
10010         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10011
10012         local dir2=$MOUNT/$tdir-2
10013         mkdir $dir2 || error "mkdir $dir2 failed"
10014         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10015                 error "$dir2 shouldn't have LOV EA"
10016
10017         # set a new striping pattern on root directory
10018         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10019         local new_def_stripe_size=$((def_stripe_size * 2))
10020         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10021                 error "set stripe size on $MOUNT failed"
10022
10023         # new file created in $dir2 should inherit the new stripe size from
10024         # the filesystem default
10025         local file2=$dir2/$tfile-2
10026         touch $file2 || error "touch $file2 failed"
10027
10028         local file2_stripe_size=$($LFS getstripe -S $file2)
10029         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10030         {
10031                 echo "file2_stripe_size: '$file2_stripe_size'"
10032                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10033                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10034         }
10035
10036         local dir3=$MOUNT/$tdir-3
10037         mkdir $dir3 || error "mkdir $dir3 failed"
10038         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10039         # the root layout, which is the actual default layout that will be used
10040         # when new files are created in $dir3.
10041         local dir3_layout=$(get_layout_param $dir3)
10042         local root_dir_layout=$(get_layout_param $MOUNT)
10043         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10044         {
10045                 echo "dir3_layout: '$dir3_layout'"
10046                 echo "root_dir_layout: '$root_dir_layout'"
10047                 error "$dir3 should show the default layout from $MOUNT"
10048         }
10049
10050         # set OST pool on root directory
10051         local pool=$TESTNAME
10052         pool_add $pool || error "add $pool failed"
10053         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10054                 error "add targets to $pool failed"
10055
10056         $LFS setstripe -p $pool $MOUNT ||
10057                 error "set OST pool on $MOUNT failed"
10058
10059         # new file created in $dir3 should inherit the pool from
10060         # the filesystem default
10061         local file3=$dir3/$tfile-3
10062         touch $file3 || error "touch $file3 failed"
10063
10064         local file3_pool=$($LFS getstripe -p $file3)
10065         [[ "$file3_pool" = "$pool" ]] ||
10066                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10067
10068         local dir4=$MOUNT/$tdir-4
10069         mkdir $dir4 || error "mkdir $dir4 failed"
10070         local dir4_layout=$(get_layout_param $dir4)
10071         root_dir_layout=$(get_layout_param $MOUNT)
10072         echo "$LFS getstripe -d $dir4"
10073         $LFS getstripe -d $dir4
10074         echo "$LFS getstripe -d $MOUNT"
10075         $LFS getstripe -d $MOUNT
10076         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10077         {
10078                 echo "dir4_layout: '$dir4_layout'"
10079                 echo "root_dir_layout: '$root_dir_layout'"
10080                 error "$dir4 should show the default layout from $MOUNT"
10081         }
10082
10083         # new file created in $dir4 should inherit the pool from
10084         # the filesystem default
10085         local file4=$dir4/$tfile-4
10086         touch $file4 || error "touch $file4 failed"
10087
10088         local file4_pool=$($LFS getstripe -p $file4)
10089         [[ "$file4_pool" = "$pool" ]] ||
10090                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10091
10092         # new subdirectory under non-root directory should inherit
10093         # the default layout from its parent directory
10094         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10095                 error "set directory layout on $dir4 failed"
10096
10097         local dir5=$dir4/$tdir-5
10098         mkdir $dir5 || error "mkdir $dir5 failed"
10099
10100         dir4_layout=$(get_layout_param $dir4)
10101         local dir5_layout=$(get_layout_param $dir5)
10102         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10103         {
10104                 echo "dir4_layout: '$dir4_layout'"
10105                 echo "dir5_layout: '$dir5_layout'"
10106                 error "$dir5 should inherit the default layout from $dir4"
10107         }
10108
10109         # though subdir under ROOT doesn't inherit default layout, but
10110         # its sub dir/file should be created with default layout.
10111         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10112         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10113                 skip "Need MDS version at least 2.12.59"
10114
10115         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10116         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10117         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10118
10119         if [ $default_lmv_hash == "none" ]; then
10120                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10121         else
10122                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10123                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10124         fi
10125
10126         $LFS setdirstripe -D -c 2 $MOUNT ||
10127                 error "setdirstripe -D -c 2 failed"
10128         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10129         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10130         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10131
10132         # $dir4 layout includes pool
10133         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10134         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10135                 error "pool lost on setstripe"
10136         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10137         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10138                 error "pool lost on compound layout setstripe"
10139 }
10140 run_test 65n "don't inherit default layout from root for new subdirectories"
10141
10142 test_65o() {
10143         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10144                 skip "need MDS version at least 2.14.57"
10145
10146         # set OST pool on root directory
10147         local pool=$TESTNAME
10148
10149         pool_add $pool || error "add $pool failed"
10150         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10151                 error "add targets to $pool failed"
10152
10153         local dir1=$MOUNT/$tdir
10154
10155         mkdir $dir1 || error "mkdir $dir1 failed"
10156
10157         # set a new striping pattern on root directory
10158         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10159
10160         $LFS setstripe -p $pool $dir1 ||
10161                 error "set directory layout on $dir1 failed"
10162
10163         # $dir1 layout includes pool
10164         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10165         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10166                 error "pool lost on setstripe"
10167         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10168         $LFS getstripe $dir1
10169         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10170                 error "pool lost on compound layout setstripe"
10171
10172         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10173                 error "setdirstripe failed on sub-dir with inherited pool"
10174         $LFS getstripe $dir1/dir2
10175         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10176                 error "pool lost on compound layout setdirstripe"
10177
10178         $LFS setstripe -E -1 -c 1 $dir1
10179         $LFS getstripe -d $dir1
10180         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10181                 error "pool lost on setstripe"
10182 }
10183 run_test 65o "pool inheritance for mdt component"
10184
10185 test_65p () { # LU-16152
10186         local src_dir=$DIR/$tdir/src_dir
10187         local dst_dir=$DIR/$tdir/dst_dir
10188         local yaml_file=$DIR/$tdir/layout.yaml
10189         local border
10190
10191         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10192                 skip "Need at least version 2.15.51"
10193
10194         test_mkdir -p $src_dir
10195         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10196                 error "failed to setstripe"
10197         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10198                 error "failed to getstripe"
10199
10200         test_mkdir -p $dst_dir
10201         $LFS setstripe --yaml $yaml_file $dst_dir ||
10202                 error "failed to setstripe with yaml file"
10203         border=$($LFS getstripe -d $dst_dir |
10204                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10205                 error "failed to getstripe"
10206
10207         # 2048M is 0x80000000, or 2147483648
10208         (( $border == 2147483648 )) ||
10209                 error "failed to handle huge number in yaml layout"
10210 }
10211 run_test 65p "setstripe with yaml file and huge number"
10212
10213 # bug 2543 - update blocks count on client
10214 test_66() {
10215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10216
10217         local COUNT=${COUNT:-8}
10218         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10219         sync; sync_all_data; sync; sync_all_data
10220         cancel_lru_locks osc
10221         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10222         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10223 }
10224 run_test 66 "update inode blocks count on client ==============="
10225
10226 meminfo() {
10227         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10228 }
10229
10230 swap_used() {
10231         swapon -s | awk '($1 == "'$1'") { print $4 }'
10232 }
10233
10234 # bug5265, obdfilter oa2dentry return -ENOENT
10235 # #define OBD_FAIL_SRV_ENOENT 0x217
10236 test_69() {
10237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10238         remote_ost_nodsh && skip "remote OST with nodsh"
10239
10240         f="$DIR/$tfile"
10241         $LFS setstripe -c 1 -i 0 $f
10242         stack_trap "rm -f $f ${f}.2"
10243
10244         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10245
10246         do_facet ost1 lctl set_param fail_loc=0x217
10247         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10248         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10249
10250         do_facet ost1 lctl set_param fail_loc=0
10251         $DIRECTIO write $f 0 2 || error "write error"
10252
10253         cancel_lru_locks osc
10254         $DIRECTIO read $f 0 1 || error "read error"
10255
10256         do_facet ost1 lctl set_param fail_loc=0x217
10257         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10258
10259         do_facet ost1 lctl set_param fail_loc=0
10260 }
10261 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10262
10263 test_71() {
10264         test_mkdir $DIR/$tdir
10265         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10266         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10267 }
10268 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10269
10270 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10272         [ "$RUNAS_ID" = "$UID" ] &&
10273                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10274         # Check that testing environment is properly set up. Skip if not
10275         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10276                 skip_env "User $RUNAS_ID does not exist - skipping"
10277
10278         touch $DIR/$tfile
10279         chmod 777 $DIR/$tfile
10280         chmod ug+s $DIR/$tfile
10281         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10282                 error "$RUNAS dd $DIR/$tfile failed"
10283         # See if we are still setuid/sgid
10284         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10285                 error "S/gid is not dropped on write"
10286         # Now test that MDS is updated too
10287         cancel_lru_locks mdc
10288         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10289                 error "S/gid is not dropped on MDS"
10290         rm -f $DIR/$tfile
10291 }
10292 run_test 72a "Test that remove suid works properly (bug5695) ===="
10293
10294 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10295         local perm
10296
10297         [ "$RUNAS_ID" = "$UID" ] &&
10298                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10299         [ "$RUNAS_ID" -eq 0 ] &&
10300                 skip_env "RUNAS_ID = 0 -- skipping"
10301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10302         # Check that testing environment is properly set up. Skip if not
10303         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10304                 skip_env "User $RUNAS_ID does not exist - skipping"
10305
10306         touch $DIR/${tfile}-f{g,u}
10307         test_mkdir $DIR/${tfile}-dg
10308         test_mkdir $DIR/${tfile}-du
10309         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10310         chmod g+s $DIR/${tfile}-{f,d}g
10311         chmod u+s $DIR/${tfile}-{f,d}u
10312         for perm in 777 2777 4777; do
10313                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10314                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10315                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10316                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10317         done
10318         true
10319 }
10320 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10321
10322 # bug 3462 - multiple simultaneous MDC requests
10323 test_73() {
10324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10325
10326         test_mkdir $DIR/d73-1
10327         test_mkdir $DIR/d73-2
10328         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10329         pid1=$!
10330
10331         lctl set_param fail_loc=0x80000129
10332         $MULTIOP $DIR/d73-1/f73-2 Oc &
10333         sleep 1
10334         lctl set_param fail_loc=0
10335
10336         $MULTIOP $DIR/d73-2/f73-3 Oc &
10337         pid3=$!
10338
10339         kill -USR1 $pid1
10340         wait $pid1 || return 1
10341
10342         sleep 25
10343
10344         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10345         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10346         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10347
10348         rm -rf $DIR/d73-*
10349 }
10350 run_test 73 "multiple MDC requests (should not deadlock)"
10351
10352 test_74a() { # bug 6149, 6184
10353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10354
10355         touch $DIR/f74a
10356         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10357         #
10358         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10359         # will spin in a tight reconnection loop
10360         $LCTL set_param fail_loc=0x8000030e
10361         # get any lock that won't be difficult - lookup works.
10362         ls $DIR/f74a
10363         $LCTL set_param fail_loc=0
10364         rm -f $DIR/f74a
10365         true
10366 }
10367 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10368
10369 test_74b() { # bug 13310
10370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10371
10372         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10373         #
10374         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10375         # will spin in a tight reconnection loop
10376         $LCTL set_param fail_loc=0x8000030e
10377         # get a "difficult" lock
10378         touch $DIR/f74b
10379         $LCTL set_param fail_loc=0
10380         rm -f $DIR/f74b
10381         true
10382 }
10383 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10384
10385 test_74c() {
10386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10387
10388         #define OBD_FAIL_LDLM_NEW_LOCK
10389         $LCTL set_param fail_loc=0x319
10390         touch $DIR/$tfile && error "touch successful"
10391         $LCTL set_param fail_loc=0
10392         true
10393 }
10394 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10395
10396 slab_lic=/sys/kernel/slab/lustre_inode_cache
10397 num_objects() {
10398         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10399         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10400                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10401 }
10402
10403 test_76a() { # Now for b=20433, added originally in b=1443
10404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10405
10406         cancel_lru_locks osc
10407         # there may be some slab objects cached per core
10408         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10409         local before=$(num_objects)
10410         local count=$((512 * cpus))
10411         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10412         local margin=$((count / 10))
10413         if [[ -f $slab_lic/aliases ]]; then
10414                 local aliases=$(cat $slab_lic/aliases)
10415                 (( aliases > 0 )) && margin=$((margin * aliases))
10416         fi
10417
10418         echo "before slab objects: $before"
10419         for i in $(seq $count); do
10420                 touch $DIR/$tfile
10421                 rm -f $DIR/$tfile
10422         done
10423         cancel_lru_locks osc
10424         local after=$(num_objects)
10425         echo "created: $count, after slab objects: $after"
10426         # shared slab counts are not very accurate, allow significant margin
10427         # the main goal is that the cache growth is not permanently > $count
10428         while (( after > before + margin )); do
10429                 sleep 1
10430                 after=$(num_objects)
10431                 wait=$((wait + 1))
10432                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10433                 if (( wait > 60 )); then
10434                         error "inode slab grew from $before+$margin to $after"
10435                 fi
10436         done
10437 }
10438 run_test 76a "confirm clients recycle inodes properly ===="
10439
10440 test_76b() {
10441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10442         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10443
10444         local count=512
10445         local before=$(num_objects)
10446
10447         for i in $(seq $count); do
10448                 mkdir $DIR/$tdir
10449                 rmdir $DIR/$tdir
10450         done
10451
10452         local after=$(num_objects)
10453         local wait=0
10454
10455         while (( after > before )); do
10456                 sleep 1
10457                 after=$(num_objects)
10458                 wait=$((wait + 1))
10459                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10460                 if (( wait > 60 )); then
10461                         error "inode slab grew from $before to $after"
10462                 fi
10463         done
10464
10465         echo "slab objects before: $before, after: $after"
10466 }
10467 run_test 76b "confirm clients recycle directory inodes properly ===="
10468
10469 export ORIG_CSUM=""
10470 set_checksums()
10471 {
10472         # Note: in sptlrpc modes which enable its own bulk checksum, the
10473         # original crc32_le bulk checksum will be automatically disabled,
10474         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10475         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10476         # In this case set_checksums() will not be no-op, because sptlrpc
10477         # bulk checksum will be enabled all through the test.
10478
10479         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10480         lctl set_param -n osc.*.checksums $1
10481         return 0
10482 }
10483
10484 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10485                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10486 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10487                              tr -d [] | head -n1)}
10488 set_checksum_type()
10489 {
10490         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10491         rc=$?
10492         log "set checksum type to $1, rc = $rc"
10493         return $rc
10494 }
10495
10496 get_osc_checksum_type()
10497 {
10498         # arugment 1: OST name, like OST0000
10499         ost=$1
10500         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10501                         sed 's/.*\[\(.*\)\].*/\1/g')
10502         rc=$?
10503         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10504         echo $checksum_type
10505 }
10506
10507 F77_TMP=$TMP/f77-temp
10508 F77SZ=8
10509 setup_f77() {
10510         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10511                 error "error writing to $F77_TMP"
10512 }
10513
10514 test_77a() { # bug 10889
10515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10516         $GSS && skip_env "could not run with gss"
10517
10518         [ ! -f $F77_TMP ] && setup_f77
10519         set_checksums 1
10520         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10521         set_checksums 0
10522         rm -f $DIR/$tfile
10523 }
10524 run_test 77a "normal checksum read/write operation"
10525
10526 test_77b() { # bug 10889
10527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10528         $GSS && skip_env "could not run with gss"
10529
10530         [ ! -f $F77_TMP ] && setup_f77
10531         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10532         $LCTL set_param fail_loc=0x80000409
10533         set_checksums 1
10534
10535         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10536                 error "dd error: $?"
10537         $LCTL set_param fail_loc=0
10538
10539         for algo in $CKSUM_TYPES; do
10540                 cancel_lru_locks osc
10541                 set_checksum_type $algo
10542                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10543                 $LCTL set_param fail_loc=0x80000408
10544                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10545                 $LCTL set_param fail_loc=0
10546         done
10547         set_checksums 0
10548         set_checksum_type $ORIG_CSUM_TYPE
10549         rm -f $DIR/$tfile
10550 }
10551 run_test 77b "checksum error on client write, read"
10552
10553 cleanup_77c() {
10554         trap 0
10555         set_checksums 0
10556         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10557         $check_ost &&
10558                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10559         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10560         $check_ost && [ -n "$ost_file_prefix" ] &&
10561                 do_facet ost1 rm -f ${ost_file_prefix}\*
10562 }
10563
10564 test_77c() {
10565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10566         $GSS && skip_env "could not run with gss"
10567         remote_ost_nodsh && skip "remote OST with nodsh"
10568
10569         local bad1
10570         local osc_file_prefix
10571         local osc_file
10572         local check_ost=false
10573         local ost_file_prefix
10574         local ost_file
10575         local orig_cksum
10576         local dump_cksum
10577         local fid
10578
10579         # ensure corruption will occur on first OSS/OST
10580         $LFS setstripe -i 0 $DIR/$tfile
10581
10582         [ ! -f $F77_TMP ] && setup_f77
10583         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10584                 error "dd write error: $?"
10585         fid=$($LFS path2fid $DIR/$tfile)
10586
10587         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10588         then
10589                 check_ost=true
10590                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10591                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10592         else
10593                 echo "OSS do not support bulk pages dump upon error"
10594         fi
10595
10596         osc_file_prefix=$($LCTL get_param -n debug_path)
10597         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10598
10599         trap cleanup_77c EXIT
10600
10601         set_checksums 1
10602         # enable bulk pages dump upon error on Client
10603         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10604         # enable bulk pages dump upon error on OSS
10605         $check_ost &&
10606                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10607
10608         # flush Client cache to allow next read to reach OSS
10609         cancel_lru_locks osc
10610
10611         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10612         $LCTL set_param fail_loc=0x80000408
10613         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10614         $LCTL set_param fail_loc=0
10615
10616         rm -f $DIR/$tfile
10617
10618         # check cksum dump on Client
10619         osc_file=$(ls ${osc_file_prefix}*)
10620         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10621         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10622         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10623         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10624         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10625                      cksum)
10626         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10627         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10628                 error "dump content does not match on Client"
10629
10630         $check_ost || skip "No need to check cksum dump on OSS"
10631
10632         # check cksum dump on OSS
10633         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10634         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10635         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10636         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10637         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10638                 error "dump content does not match on OSS"
10639
10640         cleanup_77c
10641 }
10642 run_test 77c "checksum error on client read with debug"
10643
10644 test_77d() { # bug 10889
10645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10646         $GSS && skip_env "could not run with gss"
10647
10648         stack_trap "rm -f $DIR/$tfile"
10649         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10650         $LCTL set_param fail_loc=0x80000409
10651         set_checksums 1
10652         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10653                 error "direct write: rc=$?"
10654         $LCTL set_param fail_loc=0
10655         set_checksums 0
10656
10657         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10658         $LCTL set_param fail_loc=0x80000408
10659         set_checksums 1
10660         cancel_lru_locks osc
10661         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10662                 error "direct read: rc=$?"
10663         $LCTL set_param fail_loc=0
10664         set_checksums 0
10665 }
10666 run_test 77d "checksum error on OST direct write, read"
10667
10668 test_77f() { # bug 10889
10669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10670         $GSS && skip_env "could not run with gss"
10671
10672         set_checksums 1
10673         stack_trap "rm -f $DIR/$tfile"
10674         for algo in $CKSUM_TYPES; do
10675                 cancel_lru_locks osc
10676                 set_checksum_type $algo
10677                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10678                 $LCTL set_param fail_loc=0x409
10679                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10680                         error "direct write succeeded"
10681                 $LCTL set_param fail_loc=0
10682         done
10683         set_checksum_type $ORIG_CSUM_TYPE
10684         set_checksums 0
10685 }
10686 run_test 77f "repeat checksum error on write (expect error)"
10687
10688 test_77g() { # bug 10889
10689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10690         $GSS && skip_env "could not run with gss"
10691         remote_ost_nodsh && skip "remote OST with nodsh"
10692
10693         [ ! -f $F77_TMP ] && setup_f77
10694
10695         local file=$DIR/$tfile
10696         stack_trap "rm -f $file" EXIT
10697
10698         $LFS setstripe -c 1 -i 0 $file
10699         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10700         do_facet ost1 lctl set_param fail_loc=0x8000021a
10701         set_checksums 1
10702         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10703                 error "write error: rc=$?"
10704         do_facet ost1 lctl set_param fail_loc=0
10705         set_checksums 0
10706
10707         cancel_lru_locks osc
10708         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10709         do_facet ost1 lctl set_param fail_loc=0x8000021b
10710         set_checksums 1
10711         cmp $F77_TMP $file || error "file compare failed"
10712         do_facet ost1 lctl set_param fail_loc=0
10713         set_checksums 0
10714 }
10715 run_test 77g "checksum error on OST write, read"
10716
10717 test_77k() { # LU-10906
10718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10719         $GSS && skip_env "could not run with gss"
10720
10721         local cksum_param="osc.$FSNAME*.checksums"
10722         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10723         local checksum
10724         local i
10725
10726         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10727         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10728         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10729
10730         for i in 0 1; do
10731                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10732                         error "failed to set checksum=$i on MGS"
10733                 wait_update $HOSTNAME "$get_checksum" $i
10734                 #remount
10735                 echo "remount client, checksum should be $i"
10736                 remount_client $MOUNT || error "failed to remount client"
10737                 checksum=$(eval $get_checksum)
10738                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10739         done
10740         # remove persistent param to avoid races with checksum mountopt below
10741         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10742                 error "failed to delete checksum on MGS"
10743
10744         for opt in "checksum" "nochecksum"; do
10745                 #remount with mount option
10746                 echo "remount client with option $opt, checksum should be $i"
10747                 umount_client $MOUNT || error "failed to umount client"
10748                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10749                         error "failed to mount client with option '$opt'"
10750                 checksum=$(eval $get_checksum)
10751                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10752                 i=$((i - 1))
10753         done
10754
10755         remount_client $MOUNT || error "failed to remount client"
10756 }
10757 run_test 77k "enable/disable checksum correctly"
10758
10759 test_77l() {
10760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10761         $GSS && skip_env "could not run with gss"
10762
10763         set_checksums 1
10764         stack_trap "set_checksums $ORIG_CSUM" EXIT
10765         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10766
10767         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10768
10769         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10770         for algo in $CKSUM_TYPES; do
10771                 set_checksum_type $algo || error "fail to set checksum type $algo"
10772                 osc_algo=$(get_osc_checksum_type OST0000)
10773                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10774
10775                 # no locks, no reqs to let the connection idle
10776                 cancel_lru_locks osc
10777                 lru_resize_disable osc
10778                 wait_osc_import_state client ost1 IDLE
10779
10780                 # ensure ost1 is connected
10781                 stat $DIR/$tfile >/dev/null || error "can't stat"
10782                 wait_osc_import_state client ost1 FULL
10783
10784                 osc_algo=$(get_osc_checksum_type OST0000)
10785                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10786         done
10787         return 0
10788 }
10789 run_test 77l "preferred checksum type is remembered after reconnected"
10790
10791 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10792 rm -f $F77_TMP
10793 unset F77_TMP
10794
10795 test_77m() {
10796         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10797                 skip "Need at least version 2.14.52"
10798         local param=checksum_speed
10799
10800         $LCTL get_param $param || error "reading $param failed"
10801
10802         csum_speeds=$($LCTL get_param -n $param)
10803
10804         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10805                 error "known checksum types are missing"
10806 }
10807 run_test 77m "Verify checksum_speed is correctly read"
10808
10809 check_filefrag_77n() {
10810         local nr_ext=0
10811         local starts=()
10812         local ends=()
10813
10814         while read extidx a b start end rest; do
10815                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10816                         nr_ext=$(( $nr_ext + 1 ))
10817                         starts+=( ${start%..} )
10818                         ends+=( ${end%:} )
10819                 fi
10820         done < <( filefrag -sv $1 )
10821
10822         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10823         return 1
10824 }
10825
10826 test_77n() {
10827         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10828
10829         touch $DIR/$tfile
10830         $TRUNCATE $DIR/$tfile 0
10831         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10832         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10833         check_filefrag_77n $DIR/$tfile ||
10834                 skip "$tfile blocks not contiguous around hole"
10835
10836         set_checksums 1
10837         stack_trap "set_checksums $ORIG_CSUM" EXIT
10838         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10839         stack_trap "rm -f $DIR/$tfile"
10840
10841         for algo in $CKSUM_TYPES; do
10842                 if [[ "$algo" =~ ^t10 ]]; then
10843                         set_checksum_type $algo ||
10844                                 error "fail to set checksum type $algo"
10845                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10846                                 error "fail to read $tfile with $algo"
10847                 fi
10848         done
10849         rm -f $DIR/$tfile
10850         return 0
10851 }
10852 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10853
10854 test_77o() {
10855         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10856                 skip "Need MDS version at least 2.14.55"
10857         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10858                 skip "Need OST version at least 2.14.55"
10859         local ofd=obdfilter
10860         local mdt=mdt
10861
10862         # print OST checksum_type
10863         echo "$ofd.$FSNAME-*.checksum_type:"
10864         do_nodes $(comma_list $(osts_nodes)) \
10865                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10866
10867         # print MDT checksum_type
10868         echo "$mdt.$FSNAME-*.checksum_type:"
10869         do_nodes $(comma_list $(mdts_nodes)) \
10870                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10871
10872         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10873                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10874
10875         (( $o_count == $OSTCOUNT )) ||
10876                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10877
10878         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10879                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10880
10881         (( $m_count == $MDSCOUNT )) ||
10882                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10883 }
10884 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10885
10886 cleanup_test_78() {
10887         trap 0
10888         rm -f $DIR/$tfile
10889 }
10890
10891 test_78() { # bug 10901
10892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10893         remote_ost || skip_env "local OST"
10894
10895         NSEQ=5
10896         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10897         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10898         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10899         echo "MemTotal: $MEMTOTAL"
10900
10901         # reserve 256MB of memory for the kernel and other running processes,
10902         # and then take 1/2 of the remaining memory for the read/write buffers.
10903         if [ $MEMTOTAL -gt 512 ] ;then
10904                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10905         else
10906                 # for those poor memory-starved high-end clusters...
10907                 MEMTOTAL=$((MEMTOTAL / 2))
10908         fi
10909         echo "Mem to use for directio: $MEMTOTAL"
10910
10911         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10912         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10913         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10914         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10915                 head -n1)
10916         echo "Smallest OST: $SMALLESTOST"
10917         [[ $SMALLESTOST -lt 10240 ]] &&
10918                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10919
10920         trap cleanup_test_78 EXIT
10921
10922         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10923                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10924
10925         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10926         echo "File size: $F78SIZE"
10927         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10928         for i in $(seq 1 $NSEQ); do
10929                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10930                 echo directIO rdwr round $i of $NSEQ
10931                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10932         done
10933
10934         cleanup_test_78
10935 }
10936 run_test 78 "handle large O_DIRECT writes correctly ============"
10937
10938 test_79() { # bug 12743
10939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10940
10941         wait_delete_completed
10942
10943         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10944         BKFREE=$(calc_osc_kbytes kbytesfree)
10945         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10946
10947         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10948         DFTOTAL=`echo $STRING | cut -d, -f1`
10949         DFUSED=`echo $STRING  | cut -d, -f2`
10950         DFAVAIL=`echo $STRING | cut -d, -f3`
10951         DFFREE=$(($DFTOTAL - $DFUSED))
10952
10953         ALLOWANCE=$((64 * $OSTCOUNT))
10954
10955         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10956            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10957                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10958         fi
10959         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10960            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10961                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10962         fi
10963         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10964            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10965                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10966         fi
10967 }
10968 run_test 79 "df report consistency check ======================="
10969
10970 test_80() { # bug 10718
10971         remote_ost_nodsh && skip "remote OST with nodsh"
10972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10973
10974         # relax strong synchronous semantics for slow backends like ZFS
10975         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10976                 local soc="obdfilter.*.sync_lock_cancel"
10977                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10978
10979                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10980                 if [ -z "$save" ]; then
10981                         soc="obdfilter.*.sync_on_lock_cancel"
10982                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10983                 fi
10984
10985                 if [ "$save" != "never" ]; then
10986                         local hosts=$(comma_list $(osts_nodes))
10987
10988                         do_nodes $hosts $LCTL set_param $soc=never
10989                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10990                 fi
10991         fi
10992
10993         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10994         sync; sleep 1; sync
10995         local before=$(date +%s)
10996         cancel_lru_locks osc
10997         local after=$(date +%s)
10998         local diff=$((after - before))
10999         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11000
11001         rm -f $DIR/$tfile
11002 }
11003 run_test 80 "Page eviction is equally fast at high offsets too"
11004
11005 test_81a() { # LU-456
11006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11007         remote_ost_nodsh && skip "remote OST with nodsh"
11008
11009         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11010         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11011         do_facet ost1 lctl set_param fail_loc=0x80000228
11012
11013         # write should trigger a retry and success
11014         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11015         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11016         RC=$?
11017         if [ $RC -ne 0 ] ; then
11018                 error "write should success, but failed for $RC"
11019         fi
11020 }
11021 run_test 81a "OST should retry write when get -ENOSPC ==============="
11022
11023 test_81b() { # LU-456
11024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11025         remote_ost_nodsh && skip "remote OST with nodsh"
11026
11027         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11028         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11029         do_facet ost1 lctl set_param fail_loc=0x228
11030
11031         # write should retry several times and return -ENOSPC finally
11032         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11033         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11034         RC=$?
11035         ENOSPC=28
11036         if [ $RC -ne $ENOSPC ] ; then
11037                 error "dd should fail for -ENOSPC, but succeed."
11038         fi
11039 }
11040 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11041
11042 test_99() {
11043         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11044
11045         test_mkdir $DIR/$tdir.cvsroot
11046         chown $RUNAS_ID $DIR/$tdir.cvsroot
11047
11048         cd $TMP
11049         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11050
11051         cd /etc/init.d
11052         # some versions of cvs import exit(1) when asked to import links or
11053         # files they can't read.  ignore those files.
11054         local toignore=$(find . -type l -printf '-I %f\n' -o \
11055                          ! -perm /4 -printf '-I %f\n')
11056         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11057                 $tdir.reposname vtag rtag
11058
11059         cd $DIR
11060         test_mkdir $DIR/$tdir.reposname
11061         chown $RUNAS_ID $DIR/$tdir.reposname
11062         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11063
11064         cd $DIR/$tdir.reposname
11065         $RUNAS touch foo99
11066         $RUNAS cvs add -m 'addmsg' foo99
11067         $RUNAS cvs update
11068         $RUNAS cvs commit -m 'nomsg' foo99
11069         rm -fr $DIR/$tdir.cvsroot
11070 }
11071 run_test 99 "cvs strange file/directory operations"
11072
11073 test_100() {
11074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11075         [[ "$NETTYPE" =~ tcp ]] ||
11076                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11077         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11078         remote_ost_nodsh && skip "remote OST with nodsh"
11079         remote_mds_nodsh && skip "remote MDS with nodsh"
11080         remote_servers || skip "useless for local single node setup"
11081
11082         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11083                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11084
11085                 rc=0
11086                 if (( ${LOCAL/*:/} >= 1024 )); then
11087                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11088                         ss -tna
11089                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11090                 fi
11091         done
11092         (( $rc == 0 )) || error "privileged port not found" )
11093 }
11094 run_test 100 "check local port using privileged port"
11095
11096 function get_named_value()
11097 {
11098     local tag=$1
11099
11100     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11101 }
11102
11103 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11104                    awk '/^max_cached_mb/ { print $2 }')
11105
11106 cleanup_101a() {
11107         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11108         trap 0
11109 }
11110
11111 test_101a() {
11112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11113
11114         local s
11115         local discard
11116         local nreads=10000
11117         local cache_limit=32
11118
11119         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11120         trap cleanup_101a EXIT
11121         $LCTL set_param -n llite.*.read_ahead_stats=0
11122         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11123
11124         #
11125         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11126         #
11127         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11128         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11129
11130         discard=0
11131         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11132                    get_named_value 'read.but.discarded'); do
11133                         discard=$(($discard + $s))
11134         done
11135         cleanup_101a
11136
11137         $LCTL get_param osc.*-osc*.rpc_stats
11138         $LCTL get_param llite.*.read_ahead_stats
11139
11140         # Discard is generally zero, but sometimes a few random reads line up
11141         # and trigger larger readahead, which is wasted & leads to discards.
11142         if [[ $(($discard)) -gt $nreads ]]; then
11143                 error "too many ($discard) discarded pages"
11144         fi
11145         rm -f $DIR/$tfile || true
11146 }
11147 run_test 101a "check read-ahead for random reads"
11148
11149 setup_test101bc() {
11150         test_mkdir $DIR/$tdir
11151         local ssize=$1
11152         local FILE_LENGTH=$2
11153         STRIPE_OFFSET=0
11154
11155         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11156
11157         local list=$(comma_list $(osts_nodes))
11158         set_osd_param $list '' read_cache_enable 0
11159         set_osd_param $list '' writethrough_cache_enable 0
11160
11161         trap cleanup_test101bc EXIT
11162         # prepare the read-ahead file
11163         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11164
11165         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11166                                 count=$FILE_SIZE_MB 2> /dev/null
11167
11168 }
11169
11170 cleanup_test101bc() {
11171         trap 0
11172         rm -rf $DIR/$tdir
11173         rm -f $DIR/$tfile
11174
11175         local list=$(comma_list $(osts_nodes))
11176         set_osd_param $list '' read_cache_enable 1
11177         set_osd_param $list '' writethrough_cache_enable 1
11178 }
11179
11180 calc_total() {
11181         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11182 }
11183
11184 ra_check_101() {
11185         local read_size=$1
11186         local stripe_size=$2
11187         local stride_length=$((stripe_size / read_size))
11188         local stride_width=$((stride_length * OSTCOUNT))
11189         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11190                                 (stride_width - stride_length) ))
11191         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11192                   get_named_value 'read.but.discarded' | calc_total)
11193
11194         if [[ $discard -gt $discard_limit ]]; then
11195                 $LCTL get_param llite.*.read_ahead_stats
11196                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11197         else
11198                 echo "Read-ahead success for size ${read_size}"
11199         fi
11200 }
11201
11202 test_101b() {
11203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11204         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11205
11206         local STRIPE_SIZE=1048576
11207         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11208
11209         if [ $SLOW == "yes" ]; then
11210                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11211         else
11212                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11213         fi
11214
11215         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11216
11217         # prepare the read-ahead file
11218         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11219         cancel_lru_locks osc
11220         for BIDX in 2 4 8 16 32 64 128 256
11221         do
11222                 local BSIZE=$((BIDX*4096))
11223                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11224                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11225                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11226                 $LCTL set_param -n llite.*.read_ahead_stats=0
11227                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11228                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11229                 cancel_lru_locks osc
11230                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11231         done
11232         cleanup_test101bc
11233         true
11234 }
11235 run_test 101b "check stride-io mode read-ahead ================="
11236
11237 test_101c() {
11238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11239
11240         local STRIPE_SIZE=1048576
11241         local FILE_LENGTH=$((STRIPE_SIZE*100))
11242         local nreads=10000
11243         local rsize=65536
11244         local osc_rpc_stats
11245
11246         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11247
11248         cancel_lru_locks osc
11249         $LCTL set_param osc.*.rpc_stats=0
11250         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11251         $LCTL get_param osc.*.rpc_stats
11252         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11253                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11254                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11255                 local size
11256
11257                 if [ $lines -le 20 ]; then
11258                         echo "continue debug"
11259                         continue
11260                 fi
11261                 for size in 1 2 4 8; do
11262                         local rpc=$(echo "$stats" |
11263                                     awk '($1 == "'$size':") {print $2; exit; }')
11264                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11265                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11266                 done
11267                 echo "$osc_rpc_stats check passed!"
11268         done
11269         cleanup_test101bc
11270         true
11271 }
11272 run_test 101c "check stripe_size aligned read-ahead"
11273
11274 test_101d() {
11275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11276
11277         local file=$DIR/$tfile
11278         local sz_MB=${FILESIZE_101d:-80}
11279         local ra_MB=${READAHEAD_MB:-40}
11280
11281         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11282         [ $free_MB -lt $sz_MB ] &&
11283                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11284
11285         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11286         $LFS setstripe -c -1 $file || error "setstripe failed"
11287
11288         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11289         echo Cancel LRU locks on lustre client to flush the client cache
11290         cancel_lru_locks osc
11291
11292         echo Disable read-ahead
11293         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11294         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11295         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11296         $LCTL get_param -n llite.*.max_read_ahead_mb
11297
11298         echo "Reading the test file $file with read-ahead disabled"
11299         local sz_KB=$((sz_MB * 1024 / 4))
11300         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11301         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11302         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11303                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11304
11305         echo "Cancel LRU locks on lustre client to flush the client cache"
11306         cancel_lru_locks osc
11307         echo Enable read-ahead with ${ra_MB}MB
11308         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11309
11310         echo "Reading the test file $file with read-ahead enabled"
11311         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11312                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11313
11314         echo "read-ahead disabled time read $raOFF"
11315         echo "read-ahead enabled time read $raON"
11316
11317         rm -f $file
11318         wait_delete_completed
11319
11320         # use awk for this check instead of bash because it handles decimals
11321         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11322                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11323 }
11324 run_test 101d "file read with and without read-ahead enabled"
11325
11326 test_101e() {
11327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11328
11329         local file=$DIR/$tfile
11330         local size_KB=500  #KB
11331         local count=100
11332         local bsize=1024
11333
11334         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11335         local need_KB=$((count * size_KB))
11336         [[ $free_KB -le $need_KB ]] &&
11337                 skip_env "Need free space $need_KB, have $free_KB"
11338
11339         echo "Creating $count ${size_KB}K test files"
11340         for ((i = 0; i < $count; i++)); do
11341                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11342         done
11343
11344         echo "Cancel LRU locks on lustre client to flush the client cache"
11345         cancel_lru_locks $OSC
11346
11347         echo "Reset readahead stats"
11348         $LCTL set_param -n llite.*.read_ahead_stats=0
11349
11350         for ((i = 0; i < $count; i++)); do
11351                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11352         done
11353
11354         $LCTL get_param llite.*.max_cached_mb
11355         $LCTL get_param llite.*.read_ahead_stats
11356         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11357                      get_named_value 'misses' | calc_total)
11358
11359         for ((i = 0; i < $count; i++)); do
11360                 rm -rf $file.$i 2>/dev/null
11361         done
11362
11363         #10000 means 20% reads are missing in readahead
11364         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11365 }
11366 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11367
11368 test_101f() {
11369         which iozone || skip_env "no iozone installed"
11370
11371         local old_debug=$($LCTL get_param debug)
11372         old_debug=${old_debug#*=}
11373         $LCTL set_param debug="reada mmap"
11374
11375         # create a test file
11376         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11377
11378         echo Cancel LRU locks on lustre client to flush the client cache
11379         cancel_lru_locks osc
11380
11381         echo Reset readahead stats
11382         $LCTL set_param -n llite.*.read_ahead_stats=0
11383
11384         echo mmap read the file with small block size
11385         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11386                 > /dev/null 2>&1
11387
11388         echo checking missing pages
11389         $LCTL get_param llite.*.read_ahead_stats
11390         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11391                         get_named_value 'misses' | calc_total)
11392
11393         $LCTL set_param debug="$old_debug"
11394         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11395         rm -f $DIR/$tfile
11396 }
11397 run_test 101f "check mmap read performance"
11398
11399 test_101g_brw_size_test() {
11400         local mb=$1
11401         local pages=$((mb * 1048576 / PAGE_SIZE))
11402         local file=$DIR/$tfile
11403
11404         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11405                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11406         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11407                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11408                         return 2
11409         done
11410
11411         stack_trap "rm -f $file" EXIT
11412         $LCTL set_param -n osc.*.rpc_stats=0
11413
11414         # 10 RPCs should be enough for the test
11415         local count=10
11416         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11417                 { error "dd write ${mb} MB blocks failed"; return 3; }
11418         cancel_lru_locks osc
11419         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11420                 { error "dd write ${mb} MB blocks failed"; return 4; }
11421
11422         # calculate number of full-sized read and write RPCs
11423         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11424                 sed -n '/pages per rpc/,/^$/p' |
11425                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11426                 END { print reads,writes }'))
11427         # allow one extra full-sized read RPC for async readahead
11428         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11429                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11430         [[ ${rpcs[1]} == $count ]] ||
11431                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11432 }
11433
11434 test_101g() {
11435         remote_ost_nodsh && skip "remote OST with nodsh"
11436
11437         local rpcs
11438         local osts=$(get_facets OST)
11439         local list=$(comma_list $(osts_nodes))
11440         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11441         local brw_size="obdfilter.*.brw_size"
11442
11443         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11444
11445         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11446
11447         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11448                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11449                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11450            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11451                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11452                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11453
11454                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11455                         suffix="M"
11456
11457                 if [[ $orig_mb -lt 16 ]]; then
11458                         save_lustre_params $osts "$brw_size" > $p
11459                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11460                                 error "set 16MB RPC size failed"
11461
11462                         echo "remount client to enable new RPC size"
11463                         remount_client $MOUNT || error "remount_client failed"
11464                 fi
11465
11466                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11467                 # should be able to set brw_size=12, but no rpc_stats for that
11468                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11469         fi
11470
11471         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11472
11473         if [[ $orig_mb -lt 16 ]]; then
11474                 restore_lustre_params < $p
11475                 remount_client $MOUNT || error "remount_client restore failed"
11476         fi
11477
11478         rm -f $p $DIR/$tfile
11479 }
11480 run_test 101g "Big bulk(4/16 MiB) readahead"
11481
11482 test_101h() {
11483         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11484
11485         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11486                 error "dd 70M file failed"
11487         echo Cancel LRU locks on lustre client to flush the client cache
11488         cancel_lru_locks osc
11489
11490         echo "Reset readahead stats"
11491         $LCTL set_param -n llite.*.read_ahead_stats 0
11492
11493         echo "Read 10M of data but cross 64M bundary"
11494         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11495         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11496                      get_named_value 'misses' | calc_total)
11497         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11498         rm -f $p $DIR/$tfile
11499 }
11500 run_test 101h "Readahead should cover current read window"
11501
11502 test_101i() {
11503         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11504                 error "dd 10M file failed"
11505
11506         local max_per_file_mb=$($LCTL get_param -n \
11507                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11508         cancel_lru_locks osc
11509         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11510         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11511                 error "set max_read_ahead_per_file_mb to 1 failed"
11512
11513         echo "Reset readahead stats"
11514         $LCTL set_param llite.*.read_ahead_stats=0
11515
11516         dd if=$DIR/$tfile of=/dev/null bs=2M
11517
11518         $LCTL get_param llite.*.read_ahead_stats
11519         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11520                      awk '/misses/ { print $2 }')
11521         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11522         rm -f $DIR/$tfile
11523 }
11524 run_test 101i "allow current readahead to exceed reservation"
11525
11526 test_101j() {
11527         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11528                 error "setstripe $DIR/$tfile failed"
11529         local file_size=$((1048576 * 16))
11530         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11531         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11532
11533         echo Disable read-ahead
11534         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11535
11536         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11537         for blk in $PAGE_SIZE 1048576 $file_size; do
11538                 cancel_lru_locks osc
11539                 echo "Reset readahead stats"
11540                 $LCTL set_param -n llite.*.read_ahead_stats=0
11541                 local count=$(($file_size / $blk))
11542                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11543                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11544                              get_named_value 'failed.to.fast.read' | calc_total)
11545                 $LCTL get_param -n llite.*.read_ahead_stats
11546                 [ $miss -eq $count ] || error "expected $count got $miss"
11547         done
11548
11549         rm -f $p $DIR/$tfile
11550 }
11551 run_test 101j "A complete read block should be submitted when no RA"
11552
11553 test_readahead_base() {
11554         local file=$DIR/$tfile
11555         local size=$1
11556         local iosz
11557         local ramax
11558         local ranum
11559
11560         $LCTL set_param -n llite.*.read_ahead_stats=0
11561         # The first page is not accounted into readahead
11562         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11563         iosz=$(((size + 1048575) / 1048576 * 1048576))
11564         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11565
11566         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11567         fallocate -l $size $file || error "failed to fallocate $file"
11568         cancel_lru_locks osc
11569         $MULTIOP $file or${iosz}c || error "failed to read $file"
11570         $LCTL get_param -n llite.*.read_ahead_stats
11571         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11572                 awk '/readahead.pages/ { print $7 }' | calc_total)
11573         (( $ranum <= $ramax )) ||
11574                 error "read-ahead pages is $ranum more than $ramax"
11575         rm -rf $file || error "failed to remove $file"
11576 }
11577
11578 test_101m()
11579 {
11580         local file=$DIR/$tfile
11581         local ramax
11582         local ranum
11583         local size
11584         local iosz
11585
11586         check_set_fallocate_or_skip
11587         stack_trap "rm -f $file" EXIT
11588
11589         test_readahead_base 4096
11590
11591         # file size: 16K = 16384
11592         test_readahead_base 16384
11593         test_readahead_base 16385
11594         test_readahead_base 16383
11595
11596         # file size: 1M + 1 = 1048576 + 1
11597         test_readahead_base 1048577
11598         # file size: 1M + 16K
11599         test_readahead_base $((1048576 + 16384))
11600
11601         # file size: stripe_size * (stripe_count - 1) + 16K
11602         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11603         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11604         # file size: stripe_size * stripe_count + 16K
11605         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11606         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11607         # file size: 2 * stripe_size * stripe_count + 16K
11608         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11609         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11610 }
11611 run_test 101m "read ahead for small file and last stripe of the file"
11612
11613 setup_test102() {
11614         test_mkdir $DIR/$tdir
11615         chown $RUNAS_ID $DIR/$tdir
11616         STRIPE_SIZE=65536
11617         STRIPE_OFFSET=1
11618         STRIPE_COUNT=$OSTCOUNT
11619         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11620
11621         trap cleanup_test102 EXIT
11622         cd $DIR
11623         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11624         cd $DIR/$tdir
11625         for num in 1 2 3 4; do
11626                 for count in $(seq 1 $STRIPE_COUNT); do
11627                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11628                                 local size=`expr $STRIPE_SIZE \* $num`
11629                                 local file=file"$num-$idx-$count"
11630                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11631                         done
11632                 done
11633         done
11634
11635         cd $DIR
11636         $1 tar cf $TMP/f102.tar $tdir --xattrs
11637 }
11638
11639 cleanup_test102() {
11640         trap 0
11641         rm -f $TMP/f102.tar
11642         rm -rf $DIR/d0.sanity/d102
11643 }
11644
11645 test_102a() {
11646         [ "$UID" != 0 ] && skip "must run as root"
11647         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11648                 skip_env "must have user_xattr"
11649
11650         [ -z "$(which setfattr 2>/dev/null)" ] &&
11651                 skip_env "could not find setfattr"
11652
11653         local testfile=$DIR/$tfile
11654
11655         touch $testfile
11656         echo "set/get xattr..."
11657         setfattr -n trusted.name1 -v value1 $testfile ||
11658                 error "setfattr -n trusted.name1=value1 $testfile failed"
11659         getfattr -n trusted.name1 $testfile 2> /dev/null |
11660           grep "trusted.name1=.value1" ||
11661                 error "$testfile missing trusted.name1=value1"
11662
11663         setfattr -n user.author1 -v author1 $testfile ||
11664                 error "setfattr -n user.author1=author1 $testfile failed"
11665         getfattr -n user.author1 $testfile 2> /dev/null |
11666           grep "user.author1=.author1" ||
11667                 error "$testfile missing trusted.author1=author1"
11668
11669         echo "listxattr..."
11670         setfattr -n trusted.name2 -v value2 $testfile ||
11671                 error "$testfile unable to set trusted.name2"
11672         setfattr -n trusted.name3 -v value3 $testfile ||
11673                 error "$testfile unable to set trusted.name3"
11674         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11675             grep "trusted.name" | wc -l) -eq 3 ] ||
11676                 error "$testfile missing 3 trusted.name xattrs"
11677
11678         setfattr -n user.author2 -v author2 $testfile ||
11679                 error "$testfile unable to set user.author2"
11680         setfattr -n user.author3 -v author3 $testfile ||
11681                 error "$testfile unable to set user.author3"
11682         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11683             grep "user.author" | wc -l) -eq 3 ] ||
11684                 error "$testfile missing 3 user.author xattrs"
11685
11686         echo "remove xattr..."
11687         setfattr -x trusted.name1 $testfile ||
11688                 error "$testfile error deleting trusted.name1"
11689         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11690                 error "$testfile did not delete trusted.name1 xattr"
11691
11692         setfattr -x user.author1 $testfile ||
11693                 error "$testfile error deleting user.author1"
11694         echo "set lustre special xattr ..."
11695         $LFS setstripe -c1 $testfile
11696         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11697                 awk -F "=" '/trusted.lov/ { print $2 }' )
11698         setfattr -n "trusted.lov" -v $lovea $testfile ||
11699                 error "$testfile doesn't ignore setting trusted.lov again"
11700         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11701                 error "$testfile allow setting invalid trusted.lov"
11702         rm -f $testfile
11703 }
11704 run_test 102a "user xattr test =================================="
11705
11706 check_102b_layout() {
11707         local layout="$*"
11708         local testfile=$DIR/$tfile
11709
11710         echo "test layout '$layout'"
11711         $LFS setstripe $layout $testfile || error "setstripe failed"
11712         $LFS getstripe -y $testfile
11713
11714         echo "get/set/list trusted.lov xattr ..." # b=10930
11715         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11716         [[ "$value" =~ "trusted.lov" ]] ||
11717                 error "can't get trusted.lov from $testfile"
11718         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11719                 error "getstripe failed"
11720
11721         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11722
11723         value=$(cut -d= -f2 <<<$value)
11724         # LU-13168: truncated xattr should fail if short lov_user_md header
11725         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11726                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11727         for len in $lens; do
11728                 echo "setfattr $len $testfile.2"
11729                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11730                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11731         done
11732         local stripe_size=$($LFS getstripe -S $testfile.2)
11733         local stripe_count=$($LFS getstripe -c $testfile.2)
11734         [[ $stripe_size -eq 65536 ]] ||
11735                 error "stripe size $stripe_size != 65536"
11736         [[ $stripe_count -eq $stripe_count_orig ]] ||
11737                 error "stripe count $stripe_count != $stripe_count_orig"
11738         rm $testfile $testfile.2
11739 }
11740
11741 test_102b() {
11742         [ -z "$(which setfattr 2>/dev/null)" ] &&
11743                 skip_env "could not find setfattr"
11744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11745
11746         # check plain layout
11747         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11748
11749         # and also check composite layout
11750         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11751
11752 }
11753 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11754
11755 test_102c() {
11756         [ -z "$(which setfattr 2>/dev/null)" ] &&
11757                 skip_env "could not find setfattr"
11758         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11759
11760         # b10930: get/set/list lustre.lov xattr
11761         echo "get/set/list lustre.lov xattr ..."
11762         test_mkdir $DIR/$tdir
11763         chown $RUNAS_ID $DIR/$tdir
11764         local testfile=$DIR/$tdir/$tfile
11765         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11766                 error "setstripe failed"
11767         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11768                 error "getstripe failed"
11769         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11770         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11771
11772         local testfile2=${testfile}2
11773         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11774                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11775
11776         $RUNAS $MCREATE $testfile2
11777         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11778         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11779         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11780         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11781         [ $stripe_count -eq $STRIPECOUNT ] ||
11782                 error "stripe count $stripe_count != $STRIPECOUNT"
11783 }
11784 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11785
11786 compare_stripe_info1() {
11787         local stripe_index_all_zero=true
11788
11789         for num in 1 2 3 4; do
11790                 for count in $(seq 1 $STRIPE_COUNT); do
11791                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11792                                 local size=$((STRIPE_SIZE * num))
11793                                 local file=file"$num-$offset-$count"
11794                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11795                                 [[ $stripe_size -ne $size ]] &&
11796                                     error "$file: size $stripe_size != $size"
11797                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11798                                 # allow fewer stripes to be created, ORI-601
11799                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11800                                     error "$file: count $stripe_count != $count"
11801                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11802                                 [[ $stripe_index -ne 0 ]] &&
11803                                         stripe_index_all_zero=false
11804                         done
11805                 done
11806         done
11807         $stripe_index_all_zero &&
11808                 error "all files are being extracted starting from OST index 0"
11809         return 0
11810 }
11811
11812 have_xattrs_include() {
11813         tar --help | grep -q xattrs-include &&
11814                 echo --xattrs-include="lustre.*"
11815 }
11816
11817 test_102d() {
11818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11819         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11820
11821         XINC=$(have_xattrs_include)
11822         setup_test102
11823         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11824         cd $DIR/$tdir/$tdir
11825         compare_stripe_info1
11826 }
11827 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11828
11829 test_102f() {
11830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11832
11833         XINC=$(have_xattrs_include)
11834         setup_test102
11835         test_mkdir $DIR/$tdir.restore
11836         cd $DIR
11837         tar cf - --xattrs $tdir | tar xf - \
11838                 -C $DIR/$tdir.restore --xattrs $XINC
11839         cd $DIR/$tdir.restore/$tdir
11840         compare_stripe_info1
11841 }
11842 run_test 102f "tar copy files, not keep osts"
11843
11844 grow_xattr() {
11845         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11846                 skip "must have user_xattr"
11847         [ -z "$(which setfattr 2>/dev/null)" ] &&
11848                 skip_env "could not find setfattr"
11849         [ -z "$(which getfattr 2>/dev/null)" ] &&
11850                 skip_env "could not find getfattr"
11851
11852         local xsize=${1:-1024}  # in bytes
11853         local file=$DIR/$tfile
11854         local value="$(generate_string $xsize)"
11855         local xbig=trusted.big
11856         local toobig=$2
11857
11858         touch $file
11859         log "save $xbig on $file"
11860         if [ -z "$toobig" ]
11861         then
11862                 setfattr -n $xbig -v $value $file ||
11863                         error "saving $xbig on $file failed"
11864         else
11865                 setfattr -n $xbig -v $value $file &&
11866                         error "saving $xbig on $file succeeded"
11867                 return 0
11868         fi
11869
11870         local orig=$(get_xattr_value $xbig $file)
11871         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11872
11873         local xsml=trusted.sml
11874         log "save $xsml on $file"
11875         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11876
11877         local new=$(get_xattr_value $xbig $file)
11878         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11879
11880         log "grow $xsml on $file"
11881         setfattr -n $xsml -v "$value" $file ||
11882                 error "growing $xsml on $file failed"
11883
11884         new=$(get_xattr_value $xbig $file)
11885         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11886         log "$xbig still valid after growing $xsml"
11887
11888         rm -f $file
11889 }
11890
11891 test_102h() { # bug 15777
11892         grow_xattr 1024
11893 }
11894 run_test 102h "grow xattr from inside inode to external block"
11895
11896 test_102ha() {
11897         large_xattr_enabled || skip_env "ea_inode feature disabled"
11898
11899         echo "setting xattr of max xattr size: $(max_xattr_size)"
11900         grow_xattr $(max_xattr_size)
11901
11902         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11903         echo "This should fail:"
11904         grow_xattr $(($(max_xattr_size) + 10)) 1
11905 }
11906 run_test 102ha "grow xattr from inside inode to external inode"
11907
11908 test_102i() { # bug 17038
11909         [ -z "$(which getfattr 2>/dev/null)" ] &&
11910                 skip "could not find getfattr"
11911
11912         touch $DIR/$tfile
11913         ln -s $DIR/$tfile $DIR/${tfile}link
11914         getfattr -n trusted.lov $DIR/$tfile ||
11915                 error "lgetxattr on $DIR/$tfile failed"
11916         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11917                 grep -i "no such attr" ||
11918                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11919         rm -f $DIR/$tfile $DIR/${tfile}link
11920 }
11921 run_test 102i "lgetxattr test on symbolic link ============"
11922
11923 test_102j() {
11924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11926
11927         XINC=$(have_xattrs_include)
11928         setup_test102 "$RUNAS"
11929         chown $RUNAS_ID $DIR/$tdir
11930         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11931         cd $DIR/$tdir/$tdir
11932         compare_stripe_info1 "$RUNAS"
11933 }
11934 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11935
11936 test_102k() {
11937         [ -z "$(which setfattr 2>/dev/null)" ] &&
11938                 skip "could not find setfattr"
11939
11940         touch $DIR/$tfile
11941         # b22187 just check that does not crash for regular file.
11942         setfattr -n trusted.lov $DIR/$tfile
11943         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11944         local test_kdir=$DIR/$tdir
11945         test_mkdir $test_kdir
11946         local default_size=$($LFS getstripe -S $test_kdir)
11947         local default_count=$($LFS getstripe -c $test_kdir)
11948         local default_offset=$($LFS getstripe -i $test_kdir)
11949         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11950                 error 'dir setstripe failed'
11951         setfattr -n trusted.lov $test_kdir
11952         local stripe_size=$($LFS getstripe -S $test_kdir)
11953         local stripe_count=$($LFS getstripe -c $test_kdir)
11954         local stripe_offset=$($LFS getstripe -i $test_kdir)
11955         [ $stripe_size -eq $default_size ] ||
11956                 error "stripe size $stripe_size != $default_size"
11957         [ $stripe_count -eq $default_count ] ||
11958                 error "stripe count $stripe_count != $default_count"
11959         [ $stripe_offset -eq $default_offset ] ||
11960                 error "stripe offset $stripe_offset != $default_offset"
11961         rm -rf $DIR/$tfile $test_kdir
11962 }
11963 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11964
11965 test_102l() {
11966         [ -z "$(which getfattr 2>/dev/null)" ] &&
11967                 skip "could not find getfattr"
11968
11969         # LU-532 trusted. xattr is invisible to non-root
11970         local testfile=$DIR/$tfile
11971
11972         touch $testfile
11973
11974         echo "listxattr as user..."
11975         chown $RUNAS_ID $testfile
11976         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11977             grep -q "trusted" &&
11978                 error "$testfile trusted xattrs are user visible"
11979
11980         return 0;
11981 }
11982 run_test 102l "listxattr size test =================================="
11983
11984 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11985         local path=$DIR/$tfile
11986         touch $path
11987
11988         listxattr_size_check $path || error "listattr_size_check $path failed"
11989 }
11990 run_test 102m "Ensure listxattr fails on small bufffer ========"
11991
11992 cleanup_test102
11993
11994 getxattr() { # getxattr path name
11995         # Return the base64 encoding of the value of xattr name on path.
11996         local path=$1
11997         local name=$2
11998
11999         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12000         # file: $path
12001         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12002         #
12003         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12004
12005         getfattr --absolute-names --encoding=base64 --name=$name $path |
12006                 awk -F= -v name=$name '$1 == name {
12007                         print substr($0, index($0, "=") + 1);
12008         }'
12009 }
12010
12011 test_102n() { # LU-4101 mdt: protect internal xattrs
12012         [ -z "$(which setfattr 2>/dev/null)" ] &&
12013                 skip "could not find setfattr"
12014         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12015         then
12016                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12017         fi
12018
12019         local file0=$DIR/$tfile.0
12020         local file1=$DIR/$tfile.1
12021         local xattr0=$TMP/$tfile.0
12022         local xattr1=$TMP/$tfile.1
12023         local namelist="lov lma lmv link fid version som hsm"
12024         local name
12025         local value
12026
12027         rm -rf $file0 $file1 $xattr0 $xattr1
12028         touch $file0 $file1
12029
12030         # Get 'before' xattrs of $file1.
12031         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12032
12033         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12034                 namelist+=" lfsck_namespace"
12035         for name in $namelist; do
12036                 # Try to copy xattr from $file0 to $file1.
12037                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12038
12039                 setfattr --name=trusted.$name --value="$value" $file1 ||
12040                         error "setxattr 'trusted.$name' failed"
12041
12042                 # Try to set a garbage xattr.
12043                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12044
12045                 if [[ x$name == "xlov" ]]; then
12046                         setfattr --name=trusted.lov --value="$value" $file1 &&
12047                         error "setxattr invalid 'trusted.lov' success"
12048                 else
12049                         setfattr --name=trusted.$name --value="$value" $file1 ||
12050                                 error "setxattr invalid 'trusted.$name' failed"
12051                 fi
12052
12053                 # Try to remove the xattr from $file1. We don't care if this
12054                 # appears to succeed or fail, we just don't want there to be
12055                 # any changes or crashes.
12056                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12057         done
12058
12059         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12060         then
12061                 name="lfsck_ns"
12062                 # Try to copy xattr from $file0 to $file1.
12063                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12064
12065                 setfattr --name=trusted.$name --value="$value" $file1 ||
12066                         error "setxattr 'trusted.$name' failed"
12067
12068                 # Try to set a garbage xattr.
12069                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12070
12071                 setfattr --name=trusted.$name --value="$value" $file1 ||
12072                         error "setxattr 'trusted.$name' failed"
12073
12074                 # Try to remove the xattr from $file1. We don't care if this
12075                 # appears to succeed or fail, we just don't want there to be
12076                 # any changes or crashes.
12077                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12078         fi
12079
12080         # Get 'after' xattrs of file1.
12081         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12082
12083         if ! diff $xattr0 $xattr1; then
12084                 error "before and after xattrs of '$file1' differ"
12085         fi
12086
12087         rm -rf $file0 $file1 $xattr0 $xattr1
12088
12089         return 0
12090 }
12091 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12092
12093 test_102p() { # LU-4703 setxattr did not check ownership
12094         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12095                 skip "MDS needs to be at least 2.5.56"
12096
12097         local testfile=$DIR/$tfile
12098
12099         touch $testfile
12100
12101         echo "setfacl as user..."
12102         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12103         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12104
12105         echo "setfattr as user..."
12106         setfacl -m "u:$RUNAS_ID:---" $testfile
12107         $RUNAS setfattr -x system.posix_acl_access $testfile
12108         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12109 }
12110 run_test 102p "check setxattr(2) correctly fails without permission"
12111
12112 test_102q() {
12113         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12114                 skip "MDS needs to be at least 2.6.92"
12115
12116         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12117 }
12118 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12119
12120 test_102r() {
12121         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12122                 skip "MDS needs to be at least 2.6.93"
12123
12124         touch $DIR/$tfile || error "touch"
12125         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12126         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12127         rm $DIR/$tfile || error "rm"
12128
12129         #normal directory
12130         mkdir -p $DIR/$tdir || error "mkdir"
12131         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12132         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12133         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12134                 error "$testfile error deleting user.author1"
12135         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12136                 grep "user.$(basename $tdir)" &&
12137                 error "$tdir did not delete user.$(basename $tdir)"
12138         rmdir $DIR/$tdir || error "rmdir"
12139
12140         #striped directory
12141         test_mkdir $DIR/$tdir
12142         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12143         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12144         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12145                 error "$testfile error deleting user.author1"
12146         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12147                 grep "user.$(basename $tdir)" &&
12148                 error "$tdir did not delete user.$(basename $tdir)"
12149         rmdir $DIR/$tdir || error "rm striped dir"
12150 }
12151 run_test 102r "set EAs with empty values"
12152
12153 test_102s() {
12154         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12155                 skip "MDS needs to be at least 2.11.52"
12156
12157         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12158
12159         save_lustre_params client "llite.*.xattr_cache" > $save
12160
12161         for cache in 0 1; do
12162                 lctl set_param llite.*.xattr_cache=$cache
12163
12164                 rm -f $DIR/$tfile
12165                 touch $DIR/$tfile || error "touch"
12166                 for prefix in lustre security system trusted user; do
12167                         # Note getxattr() may fail with 'Operation not
12168                         # supported' or 'No such attribute' depending
12169                         # on prefix and cache.
12170                         getfattr -n $prefix.n102s $DIR/$tfile &&
12171                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12172                 done
12173         done
12174
12175         restore_lustre_params < $save
12176 }
12177 run_test 102s "getting nonexistent xattrs should fail"
12178
12179 test_102t() {
12180         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12181                 skip "MDS needs to be at least 2.11.52"
12182
12183         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12184
12185         save_lustre_params client "llite.*.xattr_cache" > $save
12186
12187         for cache in 0 1; do
12188                 lctl set_param llite.*.xattr_cache=$cache
12189
12190                 for buf_size in 0 256; do
12191                         rm -f $DIR/$tfile
12192                         touch $DIR/$tfile || error "touch"
12193                         setfattr -n user.multiop $DIR/$tfile
12194                         $MULTIOP $DIR/$tfile oa$buf_size ||
12195                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12196                 done
12197         done
12198
12199         restore_lustre_params < $save
12200 }
12201 run_test 102t "zero length xattr values handled correctly"
12202
12203 run_acl_subtest()
12204 {
12205         local test=$LUSTRE/tests/acl/$1.test
12206         local tmp=$(mktemp -t $1-XXXXXX).test
12207         local bin=$2
12208         local dmn=$3
12209         local grp=$4
12210         local nbd=$5
12211         export LANG=C
12212
12213
12214         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12215         local sedgroups="-e s/:users/:$grp/g"
12216         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12217
12218         sed $sedusers $sedgroups < $test > $tmp
12219         stack_trap "rm -f $tmp"
12220         [[ -s $tmp ]] || error "sed failed to create test script"
12221
12222         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12223         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12224 }
12225
12226 test_103a() {
12227         [ "$UID" != 0 ] && skip "must run as root"
12228         $GSS && skip_env "could not run under gss"
12229         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12230                 skip_env "must have acl enabled"
12231         which setfacl || skip_env "could not find setfacl"
12232         remote_mds_nodsh && skip "remote MDS with nodsh"
12233
12234         local mdts=$(comma_list $(mdts_nodes))
12235         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12236
12237         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12238         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12239
12240         ACLBIN=${ACLBIN:-"bin"}
12241         ACLDMN=${ACLDMN:-"daemon"}
12242         ACLGRP=${ACLGRP:-"users"}
12243         ACLNBD=${ACLNBD:-"nobody"}
12244
12245         if ! id $ACLBIN ||
12246            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12247                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12248                 ACLBIN=$USER0
12249                 if ! id $ACLBIN ; then
12250                         cat /etc/passwd
12251                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12252                 fi
12253         fi
12254         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12255            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12256                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12257                 ACLDMN=$USER1
12258                 if ! id $ACLDMN ; then
12259                         cat /etc/passwd
12260                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12261                 fi
12262         fi
12263         if ! getent group $ACLGRP; then
12264                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12265                 ACLGRP="$TSTUSR"
12266                 if ! getent group $ACLGRP; then
12267                         echo "cannot find group '$ACLGRP', adding it"
12268                         cat /etc/group
12269                         add_group 60000 $ACLGRP
12270                 fi
12271         fi
12272
12273         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12274         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12275         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12276
12277         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12278                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12279                 ACLGRP="$TSTUSR"
12280                 if ! getent group $ACLGRP; then
12281                         echo "cannot find group '$ACLGRP', adding it"
12282                         cat /etc/group
12283                         add_group 60000 $ACLGRP
12284                 fi
12285                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12286                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12287                         cat /etc/group
12288                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12289                 fi
12290         fi
12291
12292         gpasswd -a $ACLDMN $ACLBIN ||
12293                 error "setting client group failed"             # LU-5641
12294         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12295                 error "setting MDS group failed"                # LU-5641
12296
12297         declare -a identity_old
12298
12299         for num in $(seq $MDSCOUNT); do
12300                 switch_identity $num true || identity_old[$num]=$?
12301         done
12302
12303         SAVE_UMASK=$(umask)
12304         umask 0022
12305         mkdir -p $DIR/$tdir
12306         cd $DIR/$tdir
12307
12308         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12309         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12310         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12311         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12312         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12313         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12314         if ! id -u $ACLNBD ||
12315            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12316                 ACLNBD="nfsnobody"
12317                 if ! id -u $ACLNBD; then
12318                         ACLNBD=""
12319                 fi
12320         fi
12321         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12322                 add_group $(id -u $ACLNBD) $ACLNBD
12323                 if ! getent group $ACLNBD; then
12324                         ACLNBD=""
12325                 fi
12326         fi
12327         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12328            [[ -n "$ACLNBD" ]] && which setfattr; then
12329                 run_acl_subtest permissions_xattr \
12330                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12331         elif [[ -z "$ACLNBD" ]]; then
12332                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12333         else
12334                 echo "skip 'permission_xattr' test - missing setfattr command"
12335         fi
12336         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12337
12338         # inheritance test got from HP
12339         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12340         chmod +x make-tree || error "chmod +x failed"
12341         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12342         rm -f make-tree
12343
12344         echo "LU-974 ignore umask when acl is enabled..."
12345         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12346         if [ $MDSCOUNT -ge 2 ]; then
12347                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12348         fi
12349
12350         echo "LU-2561 newly created file is same size as directory..."
12351         if [ "$mds1_FSTYPE" != "zfs" ]; then
12352                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12353         else
12354                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12355         fi
12356
12357         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12358
12359         cd $SAVE_PWD
12360         umask $SAVE_UMASK
12361
12362         for num in $(seq $MDSCOUNT); do
12363                 if [ "${identity_old[$num]}" = 1 ]; then
12364                         switch_identity $num false || identity_old[$num]=$?
12365                 fi
12366         done
12367 }
12368 run_test 103a "acl test"
12369
12370 test_103b() {
12371         declare -a pids
12372         local U
12373
12374         stack_trap "rm -f $DIR/$tfile.*"
12375         for U in {0..511}; do
12376                 {
12377                 local O=$(printf "%04o" $U)
12378
12379                 umask $(printf "%04o" $((511 ^ $O)))
12380                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12381                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12382
12383                 (( $S == ($O & 0666) )) ||
12384                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12385
12386                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12387                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12388                 (( $S == ($O & 0666) )) ||
12389                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12390
12391                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12392                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12393                 (( $S == ($O & 0666) )) ||
12394                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12395                 rm -f $DIR/$tfile.[smp]$0
12396                 } &
12397                 local pid=$!
12398
12399                 # limit the concurrently running threads to 64. LU-11878
12400                 local idx=$((U % 64))
12401                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12402                 pids[idx]=$pid
12403         done
12404         wait
12405 }
12406 run_test 103b "umask lfs setstripe"
12407
12408 test_103c() {
12409         mkdir -p $DIR/$tdir
12410         cp -rp $DIR/$tdir $DIR/$tdir.bak
12411
12412         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12413                 error "$DIR/$tdir shouldn't contain default ACL"
12414         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12415                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12416         true
12417 }
12418 run_test 103c "'cp -rp' won't set empty acl"
12419
12420 test_103e() {
12421         local numacl
12422         local fileacl
12423         local saved_debug=$($LCTL get_param -n debug)
12424
12425         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12426                 skip "MDS needs to be at least 2.14.52"
12427
12428         large_xattr_enabled || skip_env "ea_inode feature disabled"
12429
12430         mkdir -p $DIR/$tdir
12431         # add big LOV EA to cause reply buffer overflow earlier
12432         $LFS setstripe -C 1000 $DIR/$tdir
12433         lctl set_param mdc.*-mdc*.stats=clear
12434
12435         $LCTL set_param debug=0
12436         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12437         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12438
12439         # add a large number of default ACLs (expect 8000+ for 2.13+)
12440         for U in {2..7000}; do
12441                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12442                         error "Able to add just $U default ACLs"
12443         done
12444         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12445         echo "$numacl default ACLs created"
12446
12447         stat $DIR/$tdir || error "Cannot stat directory"
12448         # check file creation
12449         touch $DIR/$tdir/$tfile ||
12450                 error "failed to create $tfile with $numacl default ACLs"
12451         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12452         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12453         echo "$fileacl ACLs were inherited"
12454         (( $fileacl == $numacl )) ||
12455                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12456         # check that new ACLs creation adds new ACLs to inherited ACLs
12457         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12458                 error "Cannot set new ACL"
12459         numacl=$((numacl + 1))
12460         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12461         (( $fileacl == $numacl )) ||
12462                 error "failed to add new ACL: $fileacl != $numacl as expected"
12463         # adds more ACLs to a file to reach their maximum at 8000+
12464         numacl=0
12465         for U in {20000..25000}; do
12466                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12467                 numacl=$((numacl + 1))
12468         done
12469         echo "Added $numacl more ACLs to the file"
12470         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12471         echo "Total $fileacl ACLs in file"
12472         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12473         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12474         rmdir $DIR/$tdir || error "Cannot remove directory"
12475 }
12476 run_test 103e "inheritance of big amount of default ACLs"
12477
12478 test_103f() {
12479         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12480                 skip "MDS needs to be at least 2.14.51"
12481
12482         large_xattr_enabled || skip_env "ea_inode feature disabled"
12483
12484         # enable changelog to consume more internal MDD buffers
12485         changelog_register
12486
12487         mkdir -p $DIR/$tdir
12488         # add big LOV EA
12489         $LFS setstripe -C 1000 $DIR/$tdir
12490         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12491         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12492         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12493         rmdir $DIR/$tdir || error "Cannot remove directory"
12494 }
12495 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12496
12497 test_104a() {
12498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12499
12500         touch $DIR/$tfile
12501         lfs df || error "lfs df failed"
12502         lfs df -ih || error "lfs df -ih failed"
12503         lfs df -h $DIR || error "lfs df -h $DIR failed"
12504         lfs df -i $DIR || error "lfs df -i $DIR failed"
12505         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12506         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12507
12508         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12509         lctl --device %$OSC deactivate
12510         lfs df || error "lfs df with deactivated OSC failed"
12511         lctl --device %$OSC activate
12512         # wait the osc back to normal
12513         wait_osc_import_ready client ost
12514
12515         lfs df || error "lfs df with reactivated OSC failed"
12516         rm -f $DIR/$tfile
12517 }
12518 run_test 104a "lfs df [-ih] [path] test ========================="
12519
12520 test_104b() {
12521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12522         [ $RUNAS_ID -eq $UID ] &&
12523                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12524
12525         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12526                         grep "Permission denied" | wc -l)))
12527         if [ $denied_cnt -ne 0 ]; then
12528                 error "lfs check servers test failed"
12529         fi
12530 }
12531 run_test 104b "$RUNAS lfs check servers test ===================="
12532
12533 #
12534 # Verify $1 is within range of $2.
12535 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12536 # $1 is <= 2% of $2. Else Fail.
12537 #
12538 value_in_range() {
12539         # Strip all units (M, G, T)
12540         actual=$(echo $1 | tr -d A-Z)
12541         expect=$(echo $2 | tr -d A-Z)
12542
12543         expect_lo=$(($expect * 98 / 100)) # 2% below
12544         expect_hi=$(($expect * 102 / 100)) # 2% above
12545
12546         # permit 2% drift above and below
12547         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12548 }
12549
12550 test_104c() {
12551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12552         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12553
12554         local ost_param="osd-zfs.$FSNAME-OST0000."
12555         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12556         local ofacets=$(get_facets OST)
12557         local mfacets=$(get_facets MDS)
12558         local saved_ost_blocks=
12559         local saved_mdt_blocks=
12560
12561         echo "Before recordsize change"
12562         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12563         df=($(df -h | grep "$MOUNT"$))
12564
12565         # For checking.
12566         echo "lfs output : ${lfs_df[*]}"
12567         echo "df  output : ${df[*]}"
12568
12569         for facet in ${ofacets//,/ }; do
12570                 if [ -z $saved_ost_blocks ]; then
12571                         saved_ost_blocks=$(do_facet $facet \
12572                                 lctl get_param -n $ost_param.blocksize)
12573                         echo "OST Blocksize: $saved_ost_blocks"
12574                 fi
12575                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12576                 do_facet $facet zfs set recordsize=32768 $ost
12577         done
12578
12579         # BS too small. Sufficient for functional testing.
12580         for facet in ${mfacets//,/ }; do
12581                 if [ -z $saved_mdt_blocks ]; then
12582                         saved_mdt_blocks=$(do_facet $facet \
12583                                 lctl get_param -n $mdt_param.blocksize)
12584                         echo "MDT Blocksize: $saved_mdt_blocks"
12585                 fi
12586                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12587                 do_facet $facet zfs set recordsize=32768 $mdt
12588         done
12589
12590         # Give new values chance to reflect change
12591         sleep 2
12592
12593         echo "After recordsize change"
12594         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12595         df_after=($(df -h | grep "$MOUNT"$))
12596
12597         # For checking.
12598         echo "lfs output : ${lfs_df_after[*]}"
12599         echo "df  output : ${df_after[*]}"
12600
12601         # Verify lfs df
12602         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12603                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12604         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12605                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12606         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12607                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12608
12609         # Verify df
12610         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12611                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12612         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12613                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12614         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12615                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12616
12617         # Restore MDT recordize back to original
12618         for facet in ${mfacets//,/ }; do
12619                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12620                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12621         done
12622
12623         # Restore OST recordize back to original
12624         for facet in ${ofacets//,/ }; do
12625                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12626                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12627         done
12628
12629         return 0
12630 }
12631 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12632
12633 test_104d() {
12634         (( $RUNAS_ID != $UID )) ||
12635                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12636
12637         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12638                 skip "lustre version doesn't support lctl dl with non-root"
12639
12640         # debugfs only allows root users to access files, so the
12641         # previous move of the "devices" file to debugfs broke
12642         # "lctl dl" for non-root users. The LU-9680 Netlink
12643         # interface again allows non-root users to list devices.
12644         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12645                 error "lctl dl doesn't work for non root"
12646
12647         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12648         [ "$ost_count" -eq $OSTCOUNT ]  ||
12649                 error "lctl dl reports wrong number of OST devices"
12650
12651         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12652         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12653                 error "lctl dl reports wrong number of MDT devices"
12654 }
12655 run_test 104d "$RUNAS lctl dl test"
12656
12657 test_105a() {
12658         # doesn't work on 2.4 kernels
12659         touch $DIR/$tfile
12660         if $(flock_is_enabled); then
12661                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12662         else
12663                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12664         fi
12665         rm -f $DIR/$tfile
12666 }
12667 run_test 105a "flock when mounted without -o flock test ========"
12668
12669 test_105b() {
12670         touch $DIR/$tfile
12671         if $(flock_is_enabled); then
12672                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12673         else
12674                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12675         fi
12676         rm -f $DIR/$tfile
12677 }
12678 run_test 105b "fcntl when mounted without -o flock test ========"
12679
12680 test_105c() {
12681         touch $DIR/$tfile
12682         if $(flock_is_enabled); then
12683                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12684         else
12685                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12686         fi
12687         rm -f $DIR/$tfile
12688 }
12689 run_test 105c "lockf when mounted without -o flock test"
12690
12691 test_105d() { # bug 15924
12692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12693
12694         test_mkdir $DIR/$tdir
12695         flock_is_enabled || skip_env "mount w/o flock enabled"
12696         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12697         $LCTL set_param fail_loc=0x80000315
12698         flocks_test 2 $DIR/$tdir
12699 }
12700 run_test 105d "flock race (should not freeze) ========"
12701
12702 test_105e() { # bug 22660 && 22040
12703         flock_is_enabled || skip_env "mount w/o flock enabled"
12704
12705         touch $DIR/$tfile
12706         flocks_test 3 $DIR/$tfile
12707 }
12708 run_test 105e "Two conflicting flocks from same process"
12709
12710 test_106() { #bug 10921
12711         test_mkdir $DIR/$tdir
12712         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12713         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12714 }
12715 run_test 106 "attempt exec of dir followed by chown of that dir"
12716
12717 test_107() {
12718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12719
12720         CDIR=`pwd`
12721         local file=core
12722
12723         cd $DIR
12724         rm -f $file
12725
12726         local save_pattern=$(sysctl -n kernel.core_pattern)
12727         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12728         sysctl -w kernel.core_pattern=$file
12729         sysctl -w kernel.core_uses_pid=0
12730
12731         ulimit -c unlimited
12732         sleep 60 &
12733         SLEEPPID=$!
12734
12735         sleep 1
12736
12737         kill -s 11 $SLEEPPID
12738         wait $SLEEPPID
12739         if [ -e $file ]; then
12740                 size=`stat -c%s $file`
12741                 [ $size -eq 0 ] && error "Fail to create core file $file"
12742         else
12743                 error "Fail to create core file $file"
12744         fi
12745         rm -f $file
12746         sysctl -w kernel.core_pattern=$save_pattern
12747         sysctl -w kernel.core_uses_pid=$save_uses_pid
12748         cd $CDIR
12749 }
12750 run_test 107 "Coredump on SIG"
12751
12752 test_110() {
12753         test_mkdir $DIR/$tdir
12754         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12755         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12756                 error "mkdir with 256 char should fail, but did not"
12757         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12758                 error "create with 255 char failed"
12759         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12760                 error "create with 256 char should fail, but did not"
12761
12762         ls -l $DIR/$tdir
12763         rm -rf $DIR/$tdir
12764 }
12765 run_test 110 "filename length checking"
12766
12767 test_116a() { # was previously test_116()
12768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12770         remote_mds_nodsh && skip "remote MDS with nodsh"
12771
12772         echo -n "Free space priority "
12773         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12774                 head -n1
12775         declare -a AVAIL
12776         free_min_max
12777
12778         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12779         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12780         stack_trap simple_cleanup_common
12781
12782         # Check if we need to generate uneven OSTs
12783         test_mkdir -p $DIR/$tdir/OST${MINI}
12784         local FILL=$((MINV / 4))
12785         local DIFF=$((MAXV - MINV))
12786         local DIFF2=$((DIFF * 100 / MINV))
12787
12788         local threshold=$(do_facet $SINGLEMDS \
12789                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12790         threshold=${threshold%%%}
12791         echo -n "Check for uneven OSTs: "
12792         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12793
12794         if [[ $DIFF2 -gt $threshold ]]; then
12795                 echo "ok"
12796                 echo "Don't need to fill OST$MINI"
12797         else
12798                 # generate uneven OSTs. Write 2% over the QOS threshold value
12799                 echo "no"
12800                 DIFF=$((threshold - DIFF2 + 2))
12801                 DIFF2=$((MINV * DIFF / 100))
12802                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12803                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12804                         error "setstripe failed"
12805                 DIFF=$((DIFF2 / 2048))
12806                 i=0
12807                 while [ $i -lt $DIFF ]; do
12808                         i=$((i + 1))
12809                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12810                                 bs=2M count=1 2>/dev/null
12811                         echo -n .
12812                 done
12813                 echo .
12814                 sync
12815                 sleep_maxage
12816                 free_min_max
12817         fi
12818
12819         DIFF=$((MAXV - MINV))
12820         DIFF2=$((DIFF * 100 / MINV))
12821         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12822         if [ $DIFF2 -gt $threshold ]; then
12823                 echo "ok"
12824         else
12825                 skip "QOS imbalance criteria not met"
12826         fi
12827
12828         MINI1=$MINI
12829         MINV1=$MINV
12830         MAXI1=$MAXI
12831         MAXV1=$MAXV
12832
12833         # now fill using QOS
12834         $LFS setstripe -c 1 $DIR/$tdir
12835         FILL=$((FILL / 200))
12836         if [ $FILL -gt 600 ]; then
12837                 FILL=600
12838         fi
12839         echo "writing $FILL files to QOS-assigned OSTs"
12840         i=0
12841         while [ $i -lt $FILL ]; do
12842                 i=$((i + 1))
12843                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12844                         count=1 2>/dev/null
12845                 echo -n .
12846         done
12847         echo "wrote $i 200k files"
12848         sync
12849         sleep_maxage
12850
12851         echo "Note: free space may not be updated, so measurements might be off"
12852         free_min_max
12853         DIFF2=$((MAXV - MINV))
12854         echo "free space delta: orig $DIFF final $DIFF2"
12855         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12856         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12857         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12858         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12859         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12860         if [[ $DIFF -gt 0 ]]; then
12861                 FILL=$((DIFF2 * 100 / DIFF - 100))
12862                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12863         fi
12864
12865         # Figure out which files were written where
12866         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12867                awk '/'$MINI1': / {print $2; exit}')
12868         echo $UUID
12869         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12870         echo "$MINC files created on smaller OST $MINI1"
12871         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12872                awk '/'$MAXI1': / {print $2; exit}')
12873         echo $UUID
12874         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12875         echo "$MAXC files created on larger OST $MAXI1"
12876         if [[ $MINC -gt 0 ]]; then
12877                 FILL=$((MAXC * 100 / MINC - 100))
12878                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12879         fi
12880         [[ $MAXC -gt $MINC ]] ||
12881                 error_ignore LU-9 "stripe QOS didn't balance free space"
12882 }
12883 run_test 116a "stripe QOS: free space balance ==================="
12884
12885 test_116b() { # LU-2093
12886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12887         remote_mds_nodsh && skip "remote MDS with nodsh"
12888
12889 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12890         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12891                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12892         [ -z "$old_rr" ] && skip "no QOS"
12893         do_facet $SINGLEMDS lctl set_param \
12894                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12895         mkdir -p $DIR/$tdir
12896         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12897         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12898         do_facet $SINGLEMDS lctl set_param fail_loc=0
12899         rm -rf $DIR/$tdir
12900         do_facet $SINGLEMDS lctl set_param \
12901                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12902 }
12903 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12904
12905 test_117() # bug 10891
12906 {
12907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12908
12909         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12910         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12911         lctl set_param fail_loc=0x21e
12912         > $DIR/$tfile || error "truncate failed"
12913         lctl set_param fail_loc=0
12914         echo "Truncate succeeded."
12915         rm -f $DIR/$tfile
12916 }
12917 run_test 117 "verify osd extend =========="
12918
12919 NO_SLOW_RESENDCOUNT=4
12920 export OLD_RESENDCOUNT=""
12921 set_resend_count () {
12922         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12923         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12924         lctl set_param -n $PROC_RESENDCOUNT $1
12925         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12926 }
12927
12928 # for reduce test_118* time (b=14842)
12929 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12930
12931 # Reset async IO behavior after error case
12932 reset_async() {
12933         FILE=$DIR/reset_async
12934
12935         # Ensure all OSCs are cleared
12936         $LFS setstripe -c -1 $FILE
12937         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12938         sync
12939         rm $FILE
12940 }
12941
12942 test_118a() #bug 11710
12943 {
12944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12945
12946         reset_async
12947
12948         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12949         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12950         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12951
12952         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12953                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12954                 return 1;
12955         fi
12956         rm -f $DIR/$tfile
12957 }
12958 run_test 118a "verify O_SYNC works =========="
12959
12960 test_118b()
12961 {
12962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12963         remote_ost_nodsh && skip "remote OST with nodsh"
12964
12965         reset_async
12966
12967         #define OBD_FAIL_SRV_ENOENT 0x217
12968         set_nodes_failloc "$(osts_nodes)" 0x217
12969         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12970         RC=$?
12971         set_nodes_failloc "$(osts_nodes)" 0
12972         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12973         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12974                     grep -c writeback)
12975
12976         if [[ $RC -eq 0 ]]; then
12977                 error "Must return error due to dropped pages, rc=$RC"
12978                 return 1;
12979         fi
12980
12981         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12982                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12983                 return 1;
12984         fi
12985
12986         echo "Dirty pages not leaked on ENOENT"
12987
12988         # Due to the above error the OSC will issue all RPCs syncronously
12989         # until a subsequent RPC completes successfully without error.
12990         $MULTIOP $DIR/$tfile Ow4096yc
12991         rm -f $DIR/$tfile
12992
12993         return 0
12994 }
12995 run_test 118b "Reclaim dirty pages on fatal error =========="
12996
12997 test_118c()
12998 {
12999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13000
13001         # for 118c, restore the original resend count, LU-1940
13002         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13003                                 set_resend_count $OLD_RESENDCOUNT
13004         remote_ost_nodsh && skip "remote OST with nodsh"
13005
13006         reset_async
13007
13008         #define OBD_FAIL_OST_EROFS               0x216
13009         set_nodes_failloc "$(osts_nodes)" 0x216
13010
13011         # multiop should block due to fsync until pages are written
13012         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13013         MULTIPID=$!
13014         sleep 1
13015
13016         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13017                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13018         fi
13019
13020         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13021                     grep -c writeback)
13022         if [[ $WRITEBACK -eq 0 ]]; then
13023                 error "No page in writeback, writeback=$WRITEBACK"
13024         fi
13025
13026         set_nodes_failloc "$(osts_nodes)" 0
13027         wait $MULTIPID
13028         RC=$?
13029         if [[ $RC -ne 0 ]]; then
13030                 error "Multiop fsync failed, rc=$RC"
13031         fi
13032
13033         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13034         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13035                     grep -c writeback)
13036         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13037                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13038         fi
13039
13040         rm -f $DIR/$tfile
13041         echo "Dirty pages flushed via fsync on EROFS"
13042         return 0
13043 }
13044 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13045
13046 # continue to use small resend count to reduce test_118* time (b=14842)
13047 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13048
13049 test_118d()
13050 {
13051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13052         remote_ost_nodsh && skip "remote OST with nodsh"
13053
13054         reset_async
13055
13056         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13057         set_nodes_failloc "$(osts_nodes)" 0x214
13058         # multiop should block due to fsync until pages are written
13059         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13060         MULTIPID=$!
13061         sleep 1
13062
13063         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13064                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13065         fi
13066
13067         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13068                     grep -c writeback)
13069         if [[ $WRITEBACK -eq 0 ]]; then
13070                 error "No page in writeback, writeback=$WRITEBACK"
13071         fi
13072
13073         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13074         set_nodes_failloc "$(osts_nodes)" 0
13075
13076         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13077         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13078                     grep -c writeback)
13079         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13080                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13081         fi
13082
13083         rm -f $DIR/$tfile
13084         echo "Dirty pages gaurenteed flushed via fsync"
13085         return 0
13086 }
13087 run_test 118d "Fsync validation inject a delay of the bulk =========="
13088
13089 test_118f() {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091
13092         reset_async
13093
13094         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13095         lctl set_param fail_loc=0x8000040a
13096
13097         # Should simulate EINVAL error which is fatal
13098         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13099         RC=$?
13100         if [[ $RC -eq 0 ]]; then
13101                 error "Must return error due to dropped pages, rc=$RC"
13102         fi
13103
13104         lctl set_param fail_loc=0x0
13105
13106         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13107         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13109                     grep -c writeback)
13110         if [[ $LOCKED -ne 0 ]]; then
13111                 error "Locked pages remain in cache, locked=$LOCKED"
13112         fi
13113
13114         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13115                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13116         fi
13117
13118         rm -f $DIR/$tfile
13119         echo "No pages locked after fsync"
13120
13121         reset_async
13122         return 0
13123 }
13124 run_test 118f "Simulate unrecoverable OSC side error =========="
13125
13126 test_118g() {
13127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13128
13129         reset_async
13130
13131         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13132         lctl set_param fail_loc=0x406
13133
13134         # simulate local -ENOMEM
13135         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13136         RC=$?
13137
13138         lctl set_param fail_loc=0
13139         if [[ $RC -eq 0 ]]; then
13140                 error "Must return error due to dropped pages, rc=$RC"
13141         fi
13142
13143         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13144         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13145         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13146                         grep -c writeback)
13147         if [[ $LOCKED -ne 0 ]]; then
13148                 error "Locked pages remain in cache, locked=$LOCKED"
13149         fi
13150
13151         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13152                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13153         fi
13154
13155         rm -f $DIR/$tfile
13156         echo "No pages locked after fsync"
13157
13158         reset_async
13159         return 0
13160 }
13161 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13162
13163 test_118h() {
13164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13165         remote_ost_nodsh && skip "remote OST with nodsh"
13166
13167         reset_async
13168
13169         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13170         set_nodes_failloc "$(osts_nodes)" 0x20e
13171         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13172         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13173         RC=$?
13174
13175         set_nodes_failloc "$(osts_nodes)" 0
13176         if [[ $RC -eq 0 ]]; then
13177                 error "Must return error due to dropped pages, rc=$RC"
13178         fi
13179
13180         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13181         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13182         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13183                     grep -c writeback)
13184         if [[ $LOCKED -ne 0 ]]; then
13185                 error "Locked pages remain in cache, locked=$LOCKED"
13186         fi
13187
13188         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13189                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13190         fi
13191
13192         rm -f $DIR/$tfile
13193         echo "No pages locked after fsync"
13194
13195         return 0
13196 }
13197 run_test 118h "Verify timeout in handling recoverables errors  =========="
13198
13199 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13200
13201 test_118i() {
13202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13203         remote_ost_nodsh && skip "remote OST with nodsh"
13204
13205         reset_async
13206
13207         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13208         set_nodes_failloc "$(osts_nodes)" 0x20e
13209
13210         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13211         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13212         PID=$!
13213         sleep 5
13214         set_nodes_failloc "$(osts_nodes)" 0
13215
13216         wait $PID
13217         RC=$?
13218         if [[ $RC -ne 0 ]]; then
13219                 error "got error, but should be not, rc=$RC"
13220         fi
13221
13222         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13223         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13224         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13225         if [[ $LOCKED -ne 0 ]]; then
13226                 error "Locked pages remain in cache, locked=$LOCKED"
13227         fi
13228
13229         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13230                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13231         fi
13232
13233         rm -f $DIR/$tfile
13234         echo "No pages locked after fsync"
13235
13236         return 0
13237 }
13238 run_test 118i "Fix error before timeout in recoverable error  =========="
13239
13240 [ "$SLOW" = "no" ] && set_resend_count 4
13241
13242 test_118j() {
13243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13244         remote_ost_nodsh && skip "remote OST with nodsh"
13245
13246         reset_async
13247
13248         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13249         set_nodes_failloc "$(osts_nodes)" 0x220
13250
13251         # return -EIO from OST
13252         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13253         RC=$?
13254         set_nodes_failloc "$(osts_nodes)" 0x0
13255         if [[ $RC -eq 0 ]]; then
13256                 error "Must return error due to dropped pages, rc=$RC"
13257         fi
13258
13259         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13260         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13261         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13262         if [[ $LOCKED -ne 0 ]]; then
13263                 error "Locked pages remain in cache, locked=$LOCKED"
13264         fi
13265
13266         # in recoverable error on OST we want resend and stay until it finished
13267         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13268                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13269         fi
13270
13271         rm -f $DIR/$tfile
13272         echo "No pages locked after fsync"
13273
13274         return 0
13275 }
13276 run_test 118j "Simulate unrecoverable OST side error =========="
13277
13278 test_118k()
13279 {
13280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13281         remote_ost_nodsh && skip "remote OSTs with nodsh"
13282
13283         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13284         set_nodes_failloc "$(osts_nodes)" 0x20e
13285         test_mkdir $DIR/$tdir
13286
13287         for ((i=0;i<10;i++)); do
13288                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13289                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13290                 SLEEPPID=$!
13291                 sleep 0.500s
13292                 kill $SLEEPPID
13293                 wait $SLEEPPID
13294         done
13295
13296         set_nodes_failloc "$(osts_nodes)" 0
13297         rm -rf $DIR/$tdir
13298 }
13299 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13300
13301 test_118l() # LU-646
13302 {
13303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13304
13305         test_mkdir $DIR/$tdir
13306         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13307         rm -rf $DIR/$tdir
13308 }
13309 run_test 118l "fsync dir"
13310
13311 test_118m() # LU-3066
13312 {
13313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13314
13315         test_mkdir $DIR/$tdir
13316         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13317         rm -rf $DIR/$tdir
13318 }
13319 run_test 118m "fdatasync dir ========="
13320
13321 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13322
13323 test_118n()
13324 {
13325         local begin
13326         local end
13327
13328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13329         remote_ost_nodsh && skip "remote OSTs with nodsh"
13330
13331         # Sleep to avoid a cached response.
13332         #define OBD_STATFS_CACHE_SECONDS 1
13333         sleep 2
13334
13335         # Inject a 10 second delay in the OST_STATFS handler.
13336         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13337         set_nodes_failloc "$(osts_nodes)" 0x242
13338
13339         begin=$SECONDS
13340         stat --file-system $MOUNT > /dev/null
13341         end=$SECONDS
13342
13343         set_nodes_failloc "$(osts_nodes)" 0
13344
13345         if ((end - begin > 20)); then
13346             error "statfs took $((end - begin)) seconds, expected 10"
13347         fi
13348 }
13349 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13350
13351 test_119a() # bug 11737
13352 {
13353         BSIZE=$((512 * 1024))
13354         directio write $DIR/$tfile 0 1 $BSIZE
13355         # We ask to read two blocks, which is more than a file size.
13356         # directio will indicate an error when requested and actual
13357         # sizes aren't equeal (a normal situation in this case) and
13358         # print actual read amount.
13359         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13360         if [ "$NOB" != "$BSIZE" ]; then
13361                 error "read $NOB bytes instead of $BSIZE"
13362         fi
13363         rm -f $DIR/$tfile
13364 }
13365 run_test 119a "Short directIO read must return actual read amount"
13366
13367 test_119b() # bug 11737
13368 {
13369         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13370
13371         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13372         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13373         sync
13374         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13375                 error "direct read failed"
13376         rm -f $DIR/$tfile
13377 }
13378 run_test 119b "Sparse directIO read must return actual read amount"
13379
13380 test_119c() # bug 13099
13381 {
13382         BSIZE=1048576
13383         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13384         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13385         rm -f $DIR/$tfile
13386 }
13387 run_test 119c "Testing for direct read hitting hole"
13388
13389 test_120a() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         remote_mds_nodsh && skip "remote MDS with nodsh"
13392         test_mkdir -i0 -c1 $DIR/$tdir
13393         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13394                 skip_env "no early lock cancel on server"
13395
13396         lru_resize_disable mdc
13397         lru_resize_disable osc
13398         cancel_lru_locks mdc
13399         # asynchronous object destroy at MDT could cause bl ast to client
13400         cancel_lru_locks osc
13401
13402         stat $DIR/$tdir > /dev/null
13403         can1=$(do_facet mds1 \
13404                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13405                awk '/ldlm_cancel/ {print $2}')
13406         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13407                awk '/ldlm_bl_callback/ {print $2}')
13408         test_mkdir -i0 -c1 $DIR/$tdir/d1
13409         can2=$(do_facet mds1 \
13410                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13411                awk '/ldlm_cancel/ {print $2}')
13412         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13413                awk '/ldlm_bl_callback/ {print $2}')
13414         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13415         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13416         lru_resize_enable mdc
13417         lru_resize_enable osc
13418 }
13419 run_test 120a "Early Lock Cancel: mkdir test"
13420
13421 test_120b() {
13422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13423         remote_mds_nodsh && skip "remote MDS with nodsh"
13424         test_mkdir $DIR/$tdir
13425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13426                 skip_env "no early lock cancel on server"
13427
13428         lru_resize_disable mdc
13429         lru_resize_disable osc
13430         cancel_lru_locks mdc
13431         stat $DIR/$tdir > /dev/null
13432         can1=$(do_facet $SINGLEMDS \
13433                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13434                awk '/ldlm_cancel/ {print $2}')
13435         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13436                awk '/ldlm_bl_callback/ {print $2}')
13437         touch $DIR/$tdir/f1
13438         can2=$(do_facet $SINGLEMDS \
13439                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13440                awk '/ldlm_cancel/ {print $2}')
13441         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13442                awk '/ldlm_bl_callback/ {print $2}')
13443         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13444         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13445         lru_resize_enable mdc
13446         lru_resize_enable osc
13447 }
13448 run_test 120b "Early Lock Cancel: create test"
13449
13450 test_120c() {
13451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13452         remote_mds_nodsh && skip "remote MDS with nodsh"
13453         test_mkdir -i0 -c1 $DIR/$tdir
13454         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13455                 skip "no early lock cancel on server"
13456
13457         lru_resize_disable mdc
13458         lru_resize_disable osc
13459         test_mkdir -i0 -c1 $DIR/$tdir/d1
13460         test_mkdir -i0 -c1 $DIR/$tdir/d2
13461         touch $DIR/$tdir/d1/f1
13462         cancel_lru_locks mdc
13463         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13464         can1=$(do_facet mds1 \
13465                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13466                awk '/ldlm_cancel/ {print $2}')
13467         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13468                awk '/ldlm_bl_callback/ {print $2}')
13469         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13470         can2=$(do_facet mds1 \
13471                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13472                awk '/ldlm_cancel/ {print $2}')
13473         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13474                awk '/ldlm_bl_callback/ {print $2}')
13475         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13476         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13477         lru_resize_enable mdc
13478         lru_resize_enable osc
13479 }
13480 run_test 120c "Early Lock Cancel: link test"
13481
13482 test_120d() {
13483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13484         remote_mds_nodsh && skip "remote MDS with nodsh"
13485         test_mkdir -i0 -c1 $DIR/$tdir
13486         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13487                 skip_env "no early lock cancel on server"
13488
13489         lru_resize_disable mdc
13490         lru_resize_disable osc
13491         touch $DIR/$tdir
13492         cancel_lru_locks mdc
13493         stat $DIR/$tdir > /dev/null
13494         can1=$(do_facet mds1 \
13495                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13496                awk '/ldlm_cancel/ {print $2}')
13497         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13498                awk '/ldlm_bl_callback/ {print $2}')
13499         chmod a+x $DIR/$tdir
13500         can2=$(do_facet mds1 \
13501                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13502                awk '/ldlm_cancel/ {print $2}')
13503         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13504                awk '/ldlm_bl_callback/ {print $2}')
13505         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13506         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13507         lru_resize_enable mdc
13508         lru_resize_enable osc
13509 }
13510 run_test 120d "Early Lock Cancel: setattr test"
13511
13512 test_120e() {
13513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13514         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13515                 skip_env "no early lock cancel on server"
13516         remote_mds_nodsh && skip "remote MDS with nodsh"
13517
13518         local dlmtrace_set=false
13519
13520         test_mkdir -i0 -c1 $DIR/$tdir
13521         lru_resize_disable mdc
13522         lru_resize_disable osc
13523         ! $LCTL get_param debug | grep -q dlmtrace &&
13524                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13525         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13526         cancel_lru_locks mdc
13527         cancel_lru_locks osc
13528         dd if=$DIR/$tdir/f1 of=/dev/null
13529         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13530         # XXX client can not do early lock cancel of OST lock
13531         # during unlink (LU-4206), so cancel osc lock now.
13532         sleep 2
13533         cancel_lru_locks osc
13534         can1=$(do_facet mds1 \
13535                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13536                awk '/ldlm_cancel/ {print $2}')
13537         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13538                awk '/ldlm_bl_callback/ {print $2}')
13539         unlink $DIR/$tdir/f1
13540         sleep 5
13541         can2=$(do_facet mds1 \
13542                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13543                awk '/ldlm_cancel/ {print $2}')
13544         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13545                awk '/ldlm_bl_callback/ {print $2}')
13546         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13547                 $LCTL dk $TMP/cancel.debug.txt
13548         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13549                 $LCTL dk $TMP/blocking.debug.txt
13550         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13551         lru_resize_enable mdc
13552         lru_resize_enable osc
13553 }
13554 run_test 120e "Early Lock Cancel: unlink test"
13555
13556 test_120f() {
13557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13558         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13559                 skip_env "no early lock cancel on server"
13560         remote_mds_nodsh && skip "remote MDS with nodsh"
13561
13562         test_mkdir -i0 -c1 $DIR/$tdir
13563         lru_resize_disable mdc
13564         lru_resize_disable osc
13565         test_mkdir -i0 -c1 $DIR/$tdir/d1
13566         test_mkdir -i0 -c1 $DIR/$tdir/d2
13567         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13568         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13569         cancel_lru_locks mdc
13570         cancel_lru_locks osc
13571         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13572         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13573         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13574         # XXX client can not do early lock cancel of OST lock
13575         # during rename (LU-4206), so cancel osc lock now.
13576         sleep 2
13577         cancel_lru_locks osc
13578         can1=$(do_facet mds1 \
13579                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13580                awk '/ldlm_cancel/ {print $2}')
13581         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13582                awk '/ldlm_bl_callback/ {print $2}')
13583         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13584         sleep 5
13585         can2=$(do_facet mds1 \
13586                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13587                awk '/ldlm_cancel/ {print $2}')
13588         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13589                awk '/ldlm_bl_callback/ {print $2}')
13590         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13591         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13592         lru_resize_enable mdc
13593         lru_resize_enable osc
13594 }
13595 run_test 120f "Early Lock Cancel: rename test"
13596
13597 test_120g() {
13598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13599         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13600                 skip_env "no early lock cancel on server"
13601         remote_mds_nodsh && skip "remote MDS with nodsh"
13602
13603         lru_resize_disable mdc
13604         lru_resize_disable osc
13605         count=10000
13606         echo create $count files
13607         test_mkdir $DIR/$tdir
13608         cancel_lru_locks mdc
13609         cancel_lru_locks osc
13610         t0=$(date +%s)
13611
13612         can0=$(do_facet $SINGLEMDS \
13613                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13614                awk '/ldlm_cancel/ {print $2}')
13615         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13616                awk '/ldlm_bl_callback/ {print $2}')
13617         createmany -o $DIR/$tdir/f $count
13618         sync
13619         can1=$(do_facet $SINGLEMDS \
13620                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13621                awk '/ldlm_cancel/ {print $2}')
13622         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13623                awk '/ldlm_bl_callback/ {print $2}')
13624         t1=$(date +%s)
13625         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13626         echo rm $count files
13627         rm -r $DIR/$tdir
13628         sync
13629         can2=$(do_facet $SINGLEMDS \
13630                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13631                awk '/ldlm_cancel/ {print $2}')
13632         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13633                awk '/ldlm_bl_callback/ {print $2}')
13634         t2=$(date +%s)
13635         echo total: $count removes in $((t2-t1))
13636         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13637         sleep 2
13638         # wait for commitment of removal
13639         lru_resize_enable mdc
13640         lru_resize_enable osc
13641 }
13642 run_test 120g "Early Lock Cancel: performance test"
13643
13644 test_121() { #bug #10589
13645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13646
13647         rm -rf $DIR/$tfile
13648         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13649 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13650         lctl set_param fail_loc=0x310
13651         cancel_lru_locks osc > /dev/null
13652         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13653         lctl set_param fail_loc=0
13654         [[ $reads -eq $writes ]] ||
13655                 error "read $reads blocks, must be $writes blocks"
13656 }
13657 run_test 121 "read cancel race ========="
13658
13659 test_123a_base() { # was test 123, statahead(bug 11401)
13660         local lsx="$1"
13661
13662         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13663
13664         SLOWOK=0
13665         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13666                 log "testing UP system. Performance may be lower than expected."
13667                 SLOWOK=1
13668         fi
13669         running_in_vm && SLOWOK=1
13670
13671         $LCTL set_param mdc.*.batch_stats=0
13672
13673         rm -rf $DIR/$tdir
13674         test_mkdir $DIR/$tdir
13675         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13676         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13677         MULT=10
13678         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13679                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13680
13681                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13682                 lctl set_param -n llite.*.statahead_max 0
13683                 lctl get_param llite.*.statahead_max
13684                 cancel_lru_locks mdc
13685                 cancel_lru_locks osc
13686                 stime=$(date +%s)
13687                 time $lsx $DIR/$tdir | wc -l
13688                 etime=$(date +%s)
13689                 delta=$((etime - stime))
13690                 log "$lsx $i files without statahead: $delta sec"
13691                 lctl set_param llite.*.statahead_max=$max
13692
13693                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13694                          awk '/statahead.wrong:/ { print $NF }')
13695                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13696                 cancel_lru_locks mdc
13697                 cancel_lru_locks osc
13698                 stime=$(date +%s)
13699                 time $lsx $DIR/$tdir | wc -l
13700                 etime=$(date +%s)
13701                 delta_sa=$((etime - stime))
13702                 log "$lsx $i files with statahead: $delta_sa sec"
13703                 lctl get_param -n llite.*.statahead_stats
13704                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13705                          awk '/statahead.wrong:/ { print $NF }')
13706
13707                 [[ $swrong -lt $ewrong ]] &&
13708                         log "statahead was stopped, maybe too many locks held!"
13709                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13710
13711                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13712                         max=$(lctl get_param -n llite.*.statahead_max |
13713                                 head -n 1)
13714                         lctl set_param -n llite.*.statahead_max 0
13715                         lctl get_param llite.*.statahead_max
13716                         cancel_lru_locks mdc
13717                         cancel_lru_locks osc
13718                         stime=$(date +%s)
13719                         time $lsx $DIR/$tdir | wc -l
13720                         etime=$(date +%s)
13721                         delta=$((etime - stime))
13722                         log "$lsx $i files again without statahead: $delta sec"
13723                         lctl set_param llite.*.statahead_max=$max
13724                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13725                                 if [ $SLOWOK -eq 0 ]; then
13726                                         error "$lsx $i files is slower with statahead!"
13727                                 else
13728                                         log "$lsx $i files is slower with statahead!"
13729                                 fi
13730                                 break
13731                         fi
13732                 fi
13733
13734                 [ $delta -gt 20 ] && break
13735                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13736                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13737         done
13738         log "$lsx done"
13739
13740         stime=$(date +%s)
13741         rm -r $DIR/$tdir
13742         sync
13743         etime=$(date +%s)
13744         delta=$((etime - stime))
13745         log "rm -r $DIR/$tdir/: $delta seconds"
13746         log "rm done"
13747         lctl get_param -n llite.*.statahead_stats
13748         $LCTL get_param mdc.*.batch_stats
13749 }
13750
13751 test_123aa() {
13752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13753
13754         test_123a_base "ls -l"
13755 }
13756 run_test 123aa "verify statahead work"
13757
13758 test_123ab() {
13759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13760
13761         statx_supported || skip_env "Test must be statx() syscall supported"
13762
13763         test_123a_base "$STATX -l"
13764 }
13765 run_test 123ab "verify statahead work by using statx"
13766
13767 test_123ac() {
13768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13769
13770         statx_supported || skip_env "Test must be statx() syscall supported"
13771
13772         local rpcs_before
13773         local rpcs_after
13774         local agl_before
13775         local agl_after
13776
13777         cancel_lru_locks $OSC
13778         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13779         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13780                      awk '/agl.total:/ { print $NF }')
13781         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13782         test_123a_base "$STATX --cached=always -D"
13783         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13784                     awk '/agl.total:/ { print $NF }')
13785         [ $agl_before -eq $agl_after ] ||
13786                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13787         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13788         [ $rpcs_after -eq $rpcs_before ] ||
13789                 error "$STATX should not send glimpse RPCs to $OSC"
13790 }
13791 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13792
13793 test_batch_statahead() {
13794         local max=$1
13795         local batch_max=$2
13796         local num=10000
13797         local batch_rpcs
13798         local unbatch_rpcs
13799         local hit_total
13800
13801         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13802         $LCTL set_param mdc.*.batch_stats=0
13803         $LCTL set_param llite.*.statahead_max=$max
13804         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13805         # Verify that batched statahead is faster than one without statahead
13806         test_123a_base "ls -l"
13807
13808         stack_trap "rm -rf $DIR/$tdir" EXIT
13809         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13810         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13811
13812         # unbatched statahead
13813         $LCTL set_param llite.*.statahead_batch_max=0
13814         $LCTL set_param llite.*.statahead_stats=clear
13815         $LCTL set_param mdc.*.stats=clear
13816         cancel_lru_locks mdc
13817         cancel_lru_locks osc
13818         time ls -l $DIR/$tdir | wc -l
13819         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13820         sleep 2
13821         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13822                     awk '/hit.total:/ { print $NF }')
13823         # hit ratio should be larger than 75% (7500).
13824         (( $hit_total > 7500 )) ||
13825                 error "unbatched statahead hit count ($hit_total) is too low"
13826
13827         # batched statahead
13828         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13829         $LCTL set_param llite.*.statahead_stats=clear
13830         $LCTL set_param mdc.*.batch_stats=clear
13831         $LCTL set_param mdc.*.stats=clear
13832         cancel_lru_locks mdc
13833         cancel_lru_locks osc
13834         time ls -l $DIR/$tdir | wc -l
13835         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13836         # wait for statahead thread to quit and update statahead stats
13837         sleep 2
13838         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13839                     awk '/hit.total:/ { print $NF }')
13840         # hit ratio should be larger than 75% (7500).
13841         (( $hit_total > 7500 )) ||
13842                 error "batched statahead hit count ($hit_total) is too low"
13843
13844         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13845         (( $unbatch_rpcs > $batch_rpcs )) ||
13846                 error "batched statahead does not reduce RPC count"
13847         $LCTL get_param mdc.*.batch_stats
13848 }
13849
13850 test_123ad() {
13851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13852
13853         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13854                 skip "Need server version at least 2.15.53"
13855
13856         local max
13857         local batch_max
13858
13859         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13860         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13861
13862         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13863         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13864
13865         test_batch_statahead 32 32
13866         test_batch_statahead 2048 256
13867 }
13868 run_test 123ad "Verify batching statahead works correctly"
13869
13870 test_123b () { # statahead(bug 15027)
13871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13872
13873         test_mkdir $DIR/$tdir
13874         createmany -o $DIR/$tdir/$tfile-%d 1000
13875
13876         cancel_lru_locks mdc
13877         cancel_lru_locks osc
13878
13879 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13880         lctl set_param fail_loc=0x80000803
13881         ls -lR $DIR/$tdir > /dev/null
13882         log "ls done"
13883         lctl set_param fail_loc=0x0
13884         lctl get_param -n llite.*.statahead_stats
13885         rm -r $DIR/$tdir
13886         sync
13887
13888 }
13889 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13890
13891 test_123c() {
13892         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13893
13894         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13895         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13896         touch $DIR/$tdir.1/{1..3}
13897         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13898
13899         remount_client $MOUNT
13900
13901         $MULTIOP $DIR/$tdir.0 Q
13902
13903         # let statahead to complete
13904         ls -l $DIR/$tdir.0 > /dev/null
13905
13906         testid=$(echo $TESTNAME | tr '_' ' ')
13907         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13908                 error "statahead warning" || true
13909 }
13910 run_test 123c "Can not initialize inode warning on DNE statahead"
13911
13912 test_123d() {
13913         local num=100
13914         local swrong
13915         local ewrong
13916
13917         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13918         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13919                 error "setdirstripe $DIR/$tdir failed"
13920         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13921         remount_client $MOUNT
13922         $LCTL get_param llite.*.statahead_max
13923         $LCTL set_param llite.*.statahead_stats=0 ||
13924                 error "clear statahead_stats failed"
13925         swrong=$(lctl get_param -n llite.*.statahead_stats |
13926                  awk '/statahead.wrong:/ { print $NF }')
13927         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13928         # wait for statahead thread finished to update hit/miss stats.
13929         sleep 1
13930         $LCTL get_param -n llite.*.statahead_stats
13931         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13932                  awk '/statahead.wrong:/ { print $NF }')
13933         (( $swrong == $ewrong )) ||
13934                 log "statahead was stopped, maybe too many locks held!"
13935 }
13936 run_test 123d "Statahead on striped directories works correctly"
13937
13938 test_123e() {
13939         local max
13940         local batch_max
13941         local dir=$DIR/$tdir
13942
13943         mkdir $dir || error "mkdir $dir failed"
13944         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13945         stack_trap "rm -rf $dir"
13946
13947         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13948
13949         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13950         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13951         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13952         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13953
13954         $LCTL set_param llite.*.statahead_max=2048
13955         $LCTL set_param llite.*.statahead_batch_max=1024
13956
13957         ls -l $dir
13958         $LCTL get_param mdc.*.batch_stats
13959         $LCTL get_param llite.*.statahead_*
13960 }
13961 run_test 123e "statahead with large wide striping"
13962
13963 test_123f() {
13964         local max
13965         local batch_max
13966         local dir=$DIR/$tdir
13967
13968         mkdir $dir || error "mkdir $dir failed"
13969         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13970         stack_trap "rm -rf $dir"
13971
13972         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13973
13974         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13975         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13976
13977         $LCTL set_param llite.*.statahead_max=64
13978         $LCTL set_param llite.*.statahead_batch_max=64
13979
13980         ls -l $dir
13981         lctl get_param mdc.*.batch_stats
13982         lctl get_param llite.*.statahead_*
13983
13984         $LCTL set_param llite.*.statahead_max=$max
13985         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13986 }
13987 run_test 123f "Retry mechanism with large wide striping files"
13988
13989 test_124a() {
13990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13991         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13992                 skip_env "no lru resize on server"
13993
13994         local NR=2000
13995
13996         test_mkdir $DIR/$tdir
13997
13998         log "create $NR files at $DIR/$tdir"
13999         createmany -o $DIR/$tdir/f $NR ||
14000                 error "failed to create $NR files in $DIR/$tdir"
14001
14002         cancel_lru_locks mdc
14003         ls -l $DIR/$tdir > /dev/null
14004
14005         local NSDIR=""
14006         local LRU_SIZE=0
14007         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14008                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14009                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14010                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14011                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14012                         log "NSDIR=$NSDIR"
14013                         log "NS=$(basename $NSDIR)"
14014                         break
14015                 fi
14016         done
14017
14018         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14019                 skip "Not enough cached locks created!"
14020         fi
14021         log "LRU=$LRU_SIZE"
14022
14023         local SLEEP=30
14024
14025         # We know that lru resize allows one client to hold $LIMIT locks
14026         # for 10h. After that locks begin to be killed by client.
14027         local MAX_HRS=10
14028         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14029         log "LIMIT=$LIMIT"
14030         if [ $LIMIT -lt $LRU_SIZE ]; then
14031                 skip "Limit is too small $LIMIT"
14032         fi
14033
14034         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14035         # killing locks. Some time was spent for creating locks. This means
14036         # that up to the moment of sleep finish we must have killed some of
14037         # them (10-100 locks). This depends on how fast ther were created.
14038         # Many of them were touched in almost the same moment and thus will
14039         # be killed in groups.
14040         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14041
14042         # Use $LRU_SIZE_B here to take into account real number of locks
14043         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14044         local LRU_SIZE_B=$LRU_SIZE
14045         log "LVF=$LVF"
14046         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14047         log "OLD_LVF=$OLD_LVF"
14048         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14049
14050         # Let's make sure that we really have some margin. Client checks
14051         # cached locks every 10 sec.
14052         SLEEP=$((SLEEP+20))
14053         log "Sleep ${SLEEP} sec"
14054         local SEC=0
14055         while ((SEC<$SLEEP)); do
14056                 echo -n "..."
14057                 sleep 5
14058                 SEC=$((SEC+5))
14059                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14060                 echo -n "$LRU_SIZE"
14061         done
14062         echo ""
14063         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14064         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14065
14066         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14067                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14068                 unlinkmany $DIR/$tdir/f $NR
14069                 return
14070         }
14071
14072         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14073         log "unlink $NR files at $DIR/$tdir"
14074         unlinkmany $DIR/$tdir/f $NR
14075 }
14076 run_test 124a "lru resize ======================================="
14077
14078 get_max_pool_limit()
14079 {
14080         local limit=$($LCTL get_param \
14081                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14082         local max=0
14083         for l in $limit; do
14084                 if [[ $l -gt $max ]]; then
14085                         max=$l
14086                 fi
14087         done
14088         echo $max
14089 }
14090
14091 test_124b() {
14092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14093         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14094                 skip_env "no lru resize on server"
14095
14096         LIMIT=$(get_max_pool_limit)
14097
14098         NR=$(($(default_lru_size)*20))
14099         if [[ $NR -gt $LIMIT ]]; then
14100                 log "Limit lock number by $LIMIT locks"
14101                 NR=$LIMIT
14102         fi
14103
14104         IFree=$(mdsrate_inodes_available)
14105         if [ $IFree -lt $NR ]; then
14106                 log "Limit lock number by $IFree inodes"
14107                 NR=$IFree
14108         fi
14109
14110         lru_resize_disable mdc
14111         test_mkdir -p $DIR/$tdir/disable_lru_resize
14112
14113         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14114         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14115         cancel_lru_locks mdc
14116         stime=`date +%s`
14117         PID=""
14118         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14119         PID="$PID $!"
14120         sleep 2
14121         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14122         PID="$PID $!"
14123         sleep 2
14124         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14125         PID="$PID $!"
14126         wait $PID
14127         etime=`date +%s`
14128         nolruresize_delta=$((etime-stime))
14129         log "ls -la time: $nolruresize_delta seconds"
14130         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14131         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14132
14133         lru_resize_enable mdc
14134         test_mkdir -p $DIR/$tdir/enable_lru_resize
14135
14136         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14137         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14138         cancel_lru_locks mdc
14139         stime=`date +%s`
14140         PID=""
14141         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14142         PID="$PID $!"
14143         sleep 2
14144         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14145         PID="$PID $!"
14146         sleep 2
14147         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14148         PID="$PID $!"
14149         wait $PID
14150         etime=`date +%s`
14151         lruresize_delta=$((etime-stime))
14152         log "ls -la time: $lruresize_delta seconds"
14153         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14154
14155         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14156                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14157         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14158                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14159         else
14160                 log "lru resize performs the same with no lru resize"
14161         fi
14162         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14163 }
14164 run_test 124b "lru resize (performance test) ======================="
14165
14166 test_124c() {
14167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14168         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14169                 skip_env "no lru resize on server"
14170
14171         # cache ununsed locks on client
14172         local nr=100
14173         cancel_lru_locks mdc
14174         test_mkdir $DIR/$tdir
14175         createmany -o $DIR/$tdir/f $nr ||
14176                 error "failed to create $nr files in $DIR/$tdir"
14177         ls -l $DIR/$tdir > /dev/null
14178
14179         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14180         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14181         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14182         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14183         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14184
14185         # set lru_max_age to 1 sec
14186         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14187         echo "sleep $((recalc_p * 2)) seconds..."
14188         sleep $((recalc_p * 2))
14189
14190         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14191         # restore lru_max_age
14192         $LCTL set_param -n $nsdir.lru_max_age $max_age
14193         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14194         unlinkmany $DIR/$tdir/f $nr
14195 }
14196 run_test 124c "LRUR cancel very aged locks"
14197
14198 test_124d() {
14199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14200         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14201                 skip_env "no lru resize on server"
14202
14203         # cache ununsed locks on client
14204         local nr=100
14205
14206         lru_resize_disable mdc
14207         stack_trap "lru_resize_enable mdc" EXIT
14208
14209         cancel_lru_locks mdc
14210
14211         # asynchronous object destroy at MDT could cause bl ast to client
14212         test_mkdir $DIR/$tdir
14213         createmany -o $DIR/$tdir/f $nr ||
14214                 error "failed to create $nr files in $DIR/$tdir"
14215         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14216
14217         ls -l $DIR/$tdir > /dev/null
14218
14219         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14220         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14221         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14222         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14223
14224         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14225
14226         # set lru_max_age to 1 sec
14227         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14228         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14229
14230         echo "sleep $((recalc_p * 2)) seconds..."
14231         sleep $((recalc_p * 2))
14232
14233         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14234
14235         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14236 }
14237 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14238
14239 test_125() { # 13358
14240         $LCTL get_param -n llite.*.client_type | grep -q local ||
14241                 skip "must run as local client"
14242         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14243                 skip_env "must have acl enabled"
14244         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14245         id $USER0 || skip_env "missing user $USER0"
14246
14247         test_mkdir $DIR/$tdir
14248         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14249         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14250                 error "setfacl $DIR/$tdir failed"
14251         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14252 }
14253 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14254
14255 test_126() { # bug 12829/13455
14256         $GSS && skip_env "must run as gss disabled"
14257         $LCTL get_param -n llite.*.client_type | grep -q local ||
14258                 skip "must run as local client"
14259         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14260
14261         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14262         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14263         rm -f $DIR/$tfile
14264         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14265 }
14266 run_test 126 "check that the fsgid provided by the client is taken into account"
14267
14268 test_127a() { # bug 15521
14269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14270         local name count samp unit min max sum sumsq
14271         local tmpfile=$TMP/$tfile.tmp
14272
14273         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14274         echo "stats before reset"
14275         stack_trap "rm -f $tmpfile"
14276         local now=$(date +%s)
14277
14278         $LCTL get_param osc.*.stats | tee $tmpfile
14279
14280         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14281         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14282         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14283         local uptime=$(awk '{ print $1 }' /proc/uptime)
14284
14285         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14286         (( ${snapshot_time%\.*} >= $now - 5 &&
14287            ${snapshot_time%\.*} <= $now + 5 )) ||
14288                 error "snapshot_time=$snapshot_time != now=$now"
14289         # elapsed _should_ be from mount, but at least less than uptime
14290         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14291                 error "elapsed=$elapsed > uptime=$uptime"
14292         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14293            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14294                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14295
14296         $LCTL set_param osc.*.stats=0
14297         local reset=$(date +%s)
14298         local fsize=$((2048 * 1024))
14299
14300         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14301         cancel_lru_locks osc
14302         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14303
14304         now=$(date +%s)
14305         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14306         while read name count samp unit min max sum sumsq; do
14307                 [[ "$samp" == "samples" ]] || continue
14308
14309                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14310                 [ ! $min ] && error "Missing min value for $name proc entry"
14311                 eval $name=$count || error "Wrong proc format"
14312
14313                 case $name in
14314                 read_bytes|write_bytes)
14315                         [[ "$unit" =~ "bytes" ]] ||
14316                                 error "unit is not 'bytes': $unit"
14317                         (( $min >= 4096 )) || error "min is too small: $min"
14318                         (( $min <= $fsize )) || error "min is too big: $min"
14319                         (( $max >= 4096 )) || error "max is too small: $max"
14320                         (( $max <= $fsize )) || error "max is too big: $max"
14321                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14322                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14323                                 error "sumsquare is too small: $sumsq"
14324                         (( $sumsq <= $fsize * $fsize )) ||
14325                                 error "sumsquare is too big: $sumsq"
14326                         ;;
14327                 ost_read|ost_write)
14328                         [[ "$unit" =~ "usec" ]] ||
14329                                 error "unit is not 'usec': $unit"
14330                         ;;
14331                 *)      ;;
14332                 esac
14333         done < $tmpfile
14334
14335         #check that we actually got some stats
14336         [ "$read_bytes" ] || error "Missing read_bytes stats"
14337         [ "$write_bytes" ] || error "Missing write_bytes stats"
14338         [ "$read_bytes" != 0 ] || error "no read done"
14339         [ "$write_bytes" != 0 ] || error "no write done"
14340
14341         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14342         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14343         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14344
14345         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14346         (( ${snapshot_time%\.*} >= $now - 5 &&
14347            ${snapshot_time%\.*} <= $now + 5 )) ||
14348                 error "reset snapshot_time=$snapshot_time != now=$now"
14349         # elapsed should be from time of stats reset
14350         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14351            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14352                 error "reset elapsed=$elapsed > $now - $reset"
14353         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14354            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14355                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14356 }
14357 run_test 127a "verify the client stats are sane"
14358
14359 test_127b() { # bug LU-333
14360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14361         local name count samp unit min max sum sumsq
14362
14363         echo "stats before reset"
14364         $LCTL get_param llite.*.stats
14365         $LCTL set_param llite.*.stats=0
14366
14367         # perform 2 reads and writes so MAX is different from SUM.
14368         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14369         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14370         cancel_lru_locks osc
14371         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14372         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14373
14374         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14375         stack_trap "rm -f $TMP/$tfile.tmp"
14376         while read name count samp unit min max sum sumsq; do
14377                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14378                 eval $name=$count || error "Wrong proc format"
14379
14380                 case $name in
14381                 read_bytes|write_bytes)
14382                         [[ "$unit" =~ "bytes" ]] ||
14383                                 error "unit is not 'bytes': $unit"
14384                         (( $count == 2 )) || error "count is not 2: $count"
14385                         (( $min == $PAGE_SIZE )) ||
14386                                 error "min is not $PAGE_SIZE: $min"
14387                         (( $max == $PAGE_SIZE )) ||
14388                                 error "max is not $PAGE_SIZE: $max"
14389                         (( $sum == $PAGE_SIZE * 2 )) ||
14390                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14391                         ;;
14392                 read|write)
14393                         [[ "$unit" =~ "usec" ]] ||
14394                                 error "unit is not 'usec': $unit"
14395                         ;;
14396                 *)      ;;
14397                 esac
14398         done < $TMP/$tfile.tmp
14399
14400         #check that we actually got some stats
14401         [ "$read_bytes" ] || error "Missing read_bytes stats"
14402         [ "$write_bytes" ] || error "Missing write_bytes stats"
14403         [ "$read_bytes" != 0 ] || error "no read done"
14404         [ "$write_bytes" != 0 ] || error "no write done"
14405 }
14406 run_test 127b "verify the llite client stats are sane"
14407
14408 test_127c() { # LU-12394
14409         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14410         local size
14411         local bsize
14412         local reads
14413         local writes
14414         local count
14415
14416         $LCTL set_param llite.*.extents_stats=1
14417         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14418
14419         # Use two stripes so there is enough space in default config
14420         $LFS setstripe -c 2 $DIR/$tfile
14421
14422         # Extent stats start at 0-4K and go in power of two buckets
14423         # LL_HIST_START = 12 --> 2^12 = 4K
14424         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14425         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14426         # small configs
14427         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14428                 do
14429                 # Write and read, 2x each, second time at a non-zero offset
14430                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14431                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14432                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14433                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14434                 rm -f $DIR/$tfile
14435         done
14436
14437         $LCTL get_param llite.*.extents_stats
14438
14439         count=2
14440         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14441                 do
14442                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14443                                 grep -m 1 $bsize)
14444                 reads=$(echo $bucket | awk '{print $5}')
14445                 writes=$(echo $bucket | awk '{print $9}')
14446                 [ "$reads" -eq $count ] ||
14447                         error "$reads reads in < $bsize bucket, expect $count"
14448                 [ "$writes" -eq $count ] ||
14449                         error "$writes writes in < $bsize bucket, expect $count"
14450         done
14451
14452         # Test mmap write and read
14453         $LCTL set_param llite.*.extents_stats=c
14454         size=512
14455         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14456         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14457         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14458
14459         $LCTL get_param llite.*.extents_stats
14460
14461         count=$(((size*1024) / PAGE_SIZE))
14462
14463         bsize=$((2 * PAGE_SIZE / 1024))K
14464
14465         bucket=$($LCTL get_param -n llite.*.extents_stats |
14466                         grep -m 1 $bsize)
14467         reads=$(echo $bucket | awk '{print $5}')
14468         writes=$(echo $bucket | awk '{print $9}')
14469         # mmap writes fault in the page first, creating an additonal read
14470         [ "$reads" -eq $((2 * count)) ] ||
14471                 error "$reads reads in < $bsize bucket, expect $count"
14472         [ "$writes" -eq $count ] ||
14473                 error "$writes writes in < $bsize bucket, expect $count"
14474 }
14475 run_test 127c "test llite extent stats with regular & mmap i/o"
14476
14477 test_128() { # bug 15212
14478         touch $DIR/$tfile
14479         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14480                 find $DIR/$tfile
14481                 find $DIR/$tfile
14482         EOF
14483
14484         result=$(grep error $TMP/$tfile.log)
14485         rm -f $DIR/$tfile $TMP/$tfile.log
14486         [ -z "$result" ] ||
14487                 error "consecutive find's under interactive lfs failed"
14488 }
14489 run_test 128 "interactive lfs for 2 consecutive find's"
14490
14491 set_dir_limits () {
14492         local mntdev
14493         local canondev
14494         local node
14495
14496         local ldproc=/proc/fs/ldiskfs
14497         local facets=$(get_facets MDS)
14498
14499         for facet in ${facets//,/ }; do
14500                 canondev=$(ldiskfs_canon \
14501                            *.$(convert_facet2label $facet).mntdev $facet)
14502                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14503                         ldproc=/sys/fs/ldiskfs
14504                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14505                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14506         done
14507 }
14508
14509 check_mds_dmesg() {
14510         local facets=$(get_facets MDS)
14511         for facet in ${facets//,/ }; do
14512                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14513         done
14514         return 1
14515 }
14516
14517 test_129() {
14518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14519         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14520                 skip "Need MDS version with at least 2.5.56"
14521         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14522                 skip_env "ldiskfs only test"
14523         fi
14524         remote_mds_nodsh && skip "remote MDS with nodsh"
14525
14526         local ENOSPC=28
14527         local has_warning=false
14528
14529         rm -rf $DIR/$tdir
14530         mkdir -p $DIR/$tdir
14531
14532         # block size of mds1
14533         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14534         set_dir_limits $maxsize $((maxsize * 6 / 8))
14535         stack_trap "set_dir_limits 0 0"
14536         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14537         local dirsize=$(stat -c%s "$DIR/$tdir")
14538         local nfiles=0
14539         while (( $dirsize <= $maxsize )); do
14540                 $MCREATE $DIR/$tdir/file_base_$nfiles
14541                 rc=$?
14542                 # check two errors:
14543                 # ENOSPC for ext4 max_dir_size, which has been used since
14544                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14545                 if (( rc == ENOSPC )); then
14546                         set_dir_limits 0 0
14547                         echo "rc=$rc returned as expected after $nfiles files"
14548
14549                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14550                                 error "create failed w/o dir size limit"
14551
14552                         # messages may be rate limited if test is run repeatedly
14553                         check_mds_dmesg '"is approaching max"' ||
14554                                 echo "warning message should be output"
14555                         check_mds_dmesg '"has reached max"' ||
14556                                 echo "reached message should be output"
14557
14558                         dirsize=$(stat -c%s "$DIR/$tdir")
14559
14560                         [[ $dirsize -ge $maxsize ]] && return 0
14561                         error "dirsize $dirsize < $maxsize after $nfiles files"
14562                 elif (( rc != 0 )); then
14563                         break
14564                 fi
14565                 nfiles=$((nfiles + 1))
14566                 dirsize=$(stat -c%s "$DIR/$tdir")
14567         done
14568
14569         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14570 }
14571 run_test 129 "test directory size limit ========================"
14572
14573 OLDIFS="$IFS"
14574 cleanup_130() {
14575         trap 0
14576         IFS="$OLDIFS"
14577         rm -f $DIR/$tfile
14578 }
14579
14580 test_130a() {
14581         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14582         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14583
14584         trap cleanup_130 EXIT RETURN
14585
14586         local fm_file=$DIR/$tfile
14587         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14588         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14589                 error "dd failed for $fm_file"
14590
14591         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14592         filefrag -ves $fm_file
14593         local rc=$?
14594         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14595                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14596         (( $rc == 0 )) || error "filefrag $fm_file failed"
14597
14598         filefrag_op=$(filefrag -ve -k $fm_file |
14599                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14600         local lun=$($LFS getstripe -i $fm_file)
14601
14602         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14603         IFS=$'\n'
14604         local tot_len=0
14605         for line in $filefrag_op; do
14606                 local frag_lun=$(echo $line | cut -d: -f5)
14607                 local ext_len=$(echo $line | cut -d: -f4)
14608
14609                 if (( $frag_lun != $lun )); then
14610                         error "FIEMAP on 1-stripe file($fm_file) failed"
14611                         return
14612                 fi
14613                 (( tot_len += ext_len ))
14614         done
14615
14616         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14617                 error "FIEMAP on 1-stripe file($fm_file) failed"
14618                 return
14619         fi
14620
14621         echo "FIEMAP on single striped file succeeded"
14622 }
14623 run_test 130a "FIEMAP (1-stripe file)"
14624
14625 test_130b() {
14626         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14627
14628         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14629         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14630         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14631                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14632
14633         trap cleanup_130 EXIT RETURN
14634
14635         local fm_file=$DIR/$tfile
14636         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14637                 error "setstripe on $fm_file"
14638
14639         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14640                 error "dd failed on $fm_file"
14641
14642         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14643         filefrag_op=$(filefrag -ve -k $fm_file |
14644                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14645
14646         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14647                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14648
14649         IFS=$'\n'
14650         local tot_len=0
14651         local num_luns=1
14652
14653         for line in $filefrag_op; do
14654                 local frag_lun=$(echo $line | cut -d: -f5 |
14655                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14656                 local ext_len=$(echo $line | cut -d: -f4)
14657                 if (( $frag_lun != $last_lun )); then
14658                         if (( tot_len != 1024 )); then
14659                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14660                                 return
14661                         else
14662                                 (( num_luns += 1 ))
14663                                 tot_len=0
14664                         fi
14665                 fi
14666                 (( tot_len += ext_len ))
14667                 last_lun=$frag_lun
14668         done
14669         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14670                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14671                 return
14672         fi
14673
14674         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14675 }
14676 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14677
14678 test_130c() {
14679         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14680
14681         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14682         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14683         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14684                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14685
14686         trap cleanup_130 EXIT RETURN
14687
14688         local fm_file=$DIR/$tfile
14689         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14690
14691         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14692                 error "dd failed on $fm_file"
14693
14694         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14695         filefrag_op=$(filefrag -ve -k $fm_file |
14696                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14697
14698         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14699                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14700
14701         IFS=$'\n'
14702         local tot_len=0
14703         local num_luns=1
14704         for line in $filefrag_op; do
14705                 local frag_lun=$(echo $line | cut -d: -f5 |
14706                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14707                 local ext_len=$(echo $line | cut -d: -f4)
14708                 if (( $frag_lun != $last_lun )); then
14709                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14710                         if (( logical != 512 )); then
14711                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14712                                 return
14713                         fi
14714                         if (( tot_len != 512 )); then
14715                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14716                                 return
14717                         else
14718                                 (( num_luns += 1 ))
14719                                 tot_len=0
14720                         fi
14721                 fi
14722                 (( tot_len += ext_len ))
14723                 last_lun=$frag_lun
14724         done
14725         if (( num_luns != 2 || tot_len != 512 )); then
14726                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14727                 return
14728         fi
14729
14730         echo "FIEMAP on 2-stripe file with hole succeeded"
14731 }
14732 run_test 130c "FIEMAP (2-stripe file with hole)"
14733
14734 test_130d() {
14735         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14736
14737         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14738         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14739         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14740                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14741
14742         trap cleanup_130 EXIT RETURN
14743
14744         local fm_file=$DIR/$tfile
14745         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14746                         error "setstripe on $fm_file"
14747
14748         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14749         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14750                 error "dd failed on $fm_file"
14751
14752         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14753         filefrag_op=$(filefrag -ve -k $fm_file |
14754                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14755
14756         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14757                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14758
14759         IFS=$'\n'
14760         local tot_len=0
14761         local num_luns=1
14762         for line in $filefrag_op; do
14763                 local frag_lun=$(echo $line | cut -d: -f5 |
14764                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14765                 local ext_len=$(echo $line | cut -d: -f4)
14766                 if (( $frag_lun != $last_lun )); then
14767                         if (( tot_len != 1024 )); then
14768                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14769                                 return
14770                         else
14771                                 (( num_luns += 1 ))
14772                                 local tot_len=0
14773                         fi
14774                 fi
14775                 (( tot_len += ext_len ))
14776                 last_lun=$frag_lun
14777         done
14778         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14779                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14780                 return
14781         fi
14782
14783         echo "FIEMAP on N-stripe file succeeded"
14784 }
14785 run_test 130d "FIEMAP (N-stripe file)"
14786
14787 test_130e() {
14788         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14789
14790         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14791         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14792         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14793                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14794
14795         trap cleanup_130 EXIT RETURN
14796
14797         local fm_file=$DIR/$tfile
14798         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14799         stack_trap "rm -f $fm_file"
14800
14801         local num_blks=512
14802         local expected_len=$(( (num_blks / 2) * 64 ))
14803         for ((i = 0; i < $num_blks; i++)); do
14804                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14805                         conv=notrunc > /dev/null 2>&1
14806         done
14807
14808         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14809         filefrag_op=$(filefrag -ve -k $fm_file |
14810                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14811
14812         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14813
14814         IFS=$'\n'
14815         local tot_len=0
14816         local num_luns=1
14817         for line in $filefrag_op; do
14818                 local frag_lun=$(echo $line | cut -d: -f5)
14819                 local ext_len=$(echo $line | cut -d: -f4)
14820                 if (( $frag_lun != $last_lun )); then
14821                         if (( tot_len != $expected_len )); then
14822                                 error "OST$last_lun $tot_len != $expected_len"
14823                         else
14824                                 (( num_luns += 1 ))
14825                                 tot_len=0
14826                         fi
14827                 fi
14828                 (( tot_len += ext_len ))
14829                 last_lun=$frag_lun
14830         done
14831         if (( num_luns != 2 || tot_len != $expected_len )); then
14832                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14833         fi
14834
14835         echo "FIEMAP with continuation calls succeeded"
14836 }
14837 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14838
14839 test_130f() {
14840         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14841         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14842         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14843                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14844
14845         local fm_file=$DIR/$tfile
14846         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14847                 error "multiop create with lov_delay_create on $fm_file"
14848
14849         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14850         filefrag_extents=$(filefrag -vek $fm_file |
14851                            awk '/extents? found/ { print $2 }')
14852         if (( $filefrag_extents != 0 )); then
14853                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14854         fi
14855
14856         rm -f $fm_file
14857 }
14858 run_test 130f "FIEMAP (unstriped file)"
14859
14860 test_130g() {
14861         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14862                 skip "Need MDS version with at least 2.12.53 for overstriping"
14863         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14864         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14865         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14866                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14867
14868         local file=$DIR/$tfile
14869         local nr=$((OSTCOUNT * 100))
14870
14871         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14872
14873         stack_trap "rm -f $file"
14874         dd if=/dev/zero of=$file count=$nr bs=1M
14875         sync
14876         nr=$($LFS getstripe -c $file)
14877
14878         local extents=$(filefrag -v $file |
14879                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14880
14881         echo "filefrag list $extents extents in file with stripecount $nr"
14882         if (( extents < nr )); then
14883                 $LFS getstripe $file
14884                 filefrag -v $file
14885                 error "filefrag printed $extents < $nr extents"
14886         fi
14887 }
14888 run_test 130g "FIEMAP (overstripe file)"
14889
14890 # Test for writev/readv
14891 test_131a() {
14892         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14893                 error "writev test failed"
14894         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14895                 error "readv failed"
14896         rm -f $DIR/$tfile
14897 }
14898 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14899
14900 test_131b() {
14901         local fsize=$((524288 + 1048576 + 1572864))
14902         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14903                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14904                         error "append writev test failed"
14905
14906         ((fsize += 1572864 + 1048576))
14907         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14908                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14909                         error "append writev test failed"
14910         rm -f $DIR/$tfile
14911 }
14912 run_test 131b "test append writev"
14913
14914 test_131c() {
14915         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14916         error "NOT PASS"
14917 }
14918 run_test 131c "test read/write on file w/o objects"
14919
14920 test_131d() {
14921         rwv -f $DIR/$tfile -w -n 1 1572864
14922         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14923         if [ "$NOB" != 1572864 ]; then
14924                 error "Short read filed: read $NOB bytes instead of 1572864"
14925         fi
14926         rm -f $DIR/$tfile
14927 }
14928 run_test 131d "test short read"
14929
14930 test_131e() {
14931         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14932         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14933         error "read hitting hole failed"
14934         rm -f $DIR/$tfile
14935 }
14936 run_test 131e "test read hitting hole"
14937
14938 check_stats() {
14939         local facet=$1
14940         local op=$2
14941         local want=${3:-0}
14942         local res
14943
14944         # open             11 samples [usecs] 468 4793 13658 35791898
14945         case $facet in
14946         mds*) res=($(do_facet $facet \
14947                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14948                  ;;
14949         ost*) res=($(do_facet $facet \
14950                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14951                  ;;
14952         *) error "Wrong facet '$facet'" ;;
14953         esac
14954         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14955         # if $want is zero, it means any stat increment is ok.
14956         if (( $want > 0 )); then
14957                 local count=${res[1]}
14958
14959                 if (( $count != $want )); then
14960                         if [[ $facet =~ "mds" ]]; then
14961                                 do_nodes $(comma_list $(mdts_nodes)) \
14962                                         $LCTL get_param mdt.*.md_stats
14963                         else
14964                                 do_nodes $(comma_list $(osts-nodes)) \
14965                                         $LCTL get_param obdfilter.*.stats
14966                         fi
14967                         error "The $op counter on $facet is $count, not $want"
14968                 fi
14969         fi
14970 }
14971
14972 test_133a() {
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974         remote_ost_nodsh && skip "remote OST with nodsh"
14975         remote_mds_nodsh && skip "remote MDS with nodsh"
14976         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14977                 skip_env "MDS doesn't support rename stats"
14978
14979         local testdir=$DIR/${tdir}/stats_testdir
14980
14981         mkdir -p $DIR/${tdir}
14982
14983         # clear stats.
14984         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14985         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14986
14987         # verify mdt stats first.
14988         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14989         check_stats $SINGLEMDS "mkdir" 1
14990
14991         # clear "open" from "lfs mkdir" above
14992         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14993         touch ${testdir}/${tfile} || error "touch failed"
14994         check_stats $SINGLEMDS "open" 1
14995         check_stats $SINGLEMDS "close" 1
14996         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14997                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14998                 check_stats $SINGLEMDS "mknod" 2
14999         }
15000         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15001         check_stats $SINGLEMDS "unlink" 1
15002         rm -f ${testdir}/${tfile} || error "file remove failed"
15003         check_stats $SINGLEMDS "unlink" 2
15004
15005         # remove working dir and check mdt stats again.
15006         rmdir ${testdir} || error "rmdir failed"
15007         check_stats $SINGLEMDS "rmdir" 1
15008
15009         local testdir1=$DIR/${tdir}/stats_testdir1
15010         mkdir_on_mdt0 -p ${testdir}
15011         mkdir_on_mdt0 -p ${testdir1}
15012         touch ${testdir1}/test1
15013         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15014         check_stats $SINGLEMDS "crossdir_rename" 1
15015
15016         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15017         check_stats $SINGLEMDS "samedir_rename" 1
15018
15019         rm -rf $DIR/${tdir}
15020 }
15021 run_test 133a "Verifying MDT stats ========================================"
15022
15023 test_133b() {
15024         local res
15025
15026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15027         remote_ost_nodsh && skip "remote OST with nodsh"
15028         remote_mds_nodsh && skip "remote MDS with nodsh"
15029
15030         local testdir=$DIR/${tdir}/stats_testdir
15031
15032         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15033         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15034         touch ${testdir}/${tfile} || error "touch failed"
15035         cancel_lru_locks mdc
15036
15037         # clear stats.
15038         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15039         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15040
15041         # extra mdt stats verification.
15042         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15043         check_stats $SINGLEMDS "setattr" 1
15044         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15045         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15046         then            # LU-1740
15047                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15048                 check_stats $SINGLEMDS "getattr" 1
15049         fi
15050         rm -rf $DIR/${tdir}
15051
15052         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15053         # so the check below is not reliable
15054         [ $MDSCOUNT -eq 1 ] || return 0
15055
15056         # Sleep to avoid a cached response.
15057         #define OBD_STATFS_CACHE_SECONDS 1
15058         sleep 2
15059         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15060         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15061         $LFS df || error "lfs failed"
15062         check_stats $SINGLEMDS "statfs" 1
15063
15064         # check aggregated statfs (LU-10018)
15065         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15066                 return 0
15067         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15068                 return 0
15069         sleep 2
15070         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15071         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15072         df $DIR
15073         check_stats $SINGLEMDS "statfs" 1
15074
15075         # We want to check that the client didn't send OST_STATFS to
15076         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15077         # extra care is needed here.
15078         if remote_mds; then
15079                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15080                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15081
15082                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15083                 [ "$res" ] && error "OST got STATFS"
15084         fi
15085
15086         return 0
15087 }
15088 run_test 133b "Verifying extra MDT stats =================================="
15089
15090 test_133c() {
15091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15092         remote_ost_nodsh && skip "remote OST with nodsh"
15093         remote_mds_nodsh && skip "remote MDS with nodsh"
15094
15095         local testdir=$DIR/$tdir/stats_testdir
15096
15097         test_mkdir -p $testdir
15098
15099         # verify obdfilter stats.
15100         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15101         sync
15102         cancel_lru_locks osc
15103         wait_delete_completed
15104
15105         # clear stats.
15106         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15107         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15108
15109         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15110                 error "dd failed"
15111         sync
15112         cancel_lru_locks osc
15113         check_stats ost1 "write" 1
15114
15115         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15116         check_stats ost1 "read" 1
15117
15118         > $testdir/$tfile || error "truncate failed"
15119         check_stats ost1 "punch" 1
15120
15121         rm -f $testdir/$tfile || error "file remove failed"
15122         wait_delete_completed
15123         check_stats ost1 "destroy" 1
15124
15125         rm -rf $DIR/$tdir
15126 }
15127 run_test 133c "Verifying OST stats ========================================"
15128
15129 order_2() {
15130         local value=$1
15131         local orig=$value
15132         local order=1
15133
15134         while [ $value -ge 2 ]; do
15135                 order=$((order*2))
15136                 value=$((value/2))
15137         done
15138
15139         if [ $orig -gt $order ]; then
15140                 order=$((order*2))
15141         fi
15142         echo $order
15143 }
15144
15145 size_in_KMGT() {
15146     local value=$1
15147     local size=('K' 'M' 'G' 'T');
15148     local i=0
15149     local size_string=$value
15150
15151     while [ $value -ge 1024 ]; do
15152         if [ $i -gt 3 ]; then
15153             #T is the biggest unit we get here, if that is bigger,
15154             #just return XXXT
15155             size_string=${value}T
15156             break
15157         fi
15158         value=$((value >> 10))
15159         if [ $value -lt 1024 ]; then
15160             size_string=${value}${size[$i]}
15161             break
15162         fi
15163         i=$((i + 1))
15164     done
15165
15166     echo $size_string
15167 }
15168
15169 get_rename_size() {
15170         local size=$1
15171         local context=${2:-.}
15172         local sample=$(do_facet $SINGLEMDS $LCTL \
15173                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15174                 grep -A1 $context |
15175                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15176         echo $sample
15177 }
15178
15179 test_133d() {
15180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15181         remote_ost_nodsh && skip "remote OST with nodsh"
15182         remote_mds_nodsh && skip "remote MDS with nodsh"
15183         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15184                 skip_env "MDS doesn't support rename stats"
15185
15186         local testdir1=$DIR/${tdir}/stats_testdir1
15187         local testdir2=$DIR/${tdir}/stats_testdir2
15188         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15189
15190         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15191
15192         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15193         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15194
15195         createmany -o $testdir1/test 512 || error "createmany failed"
15196
15197         # check samedir rename size
15198         mv ${testdir1}/test0 ${testdir1}/test_0
15199
15200         local testdir1_size=$(ls -l $DIR/${tdir} |
15201                 awk '/stats_testdir1/ {print $5}')
15202         local testdir2_size=$(ls -l $DIR/${tdir} |
15203                 awk '/stats_testdir2/ {print $5}')
15204
15205         testdir1_size=$(order_2 $testdir1_size)
15206         testdir2_size=$(order_2 $testdir2_size)
15207
15208         testdir1_size=$(size_in_KMGT $testdir1_size)
15209         testdir2_size=$(size_in_KMGT $testdir2_size)
15210
15211         echo "source rename dir size: ${testdir1_size}"
15212         echo "target rename dir size: ${testdir2_size}"
15213
15214         local cmd="do_facet $SINGLEMDS $LCTL "
15215         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15216
15217         eval $cmd || error "$cmd failed"
15218         local samedir=$($cmd | grep 'same_dir')
15219         local same_sample=$(get_rename_size $testdir1_size)
15220         [ -z "$samedir" ] && error "samedir_rename_size count error"
15221         [[ $same_sample -eq 1 ]] ||
15222                 error "samedir_rename_size error $same_sample"
15223         echo "Check same dir rename stats success"
15224
15225         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15226
15227         # check crossdir rename size
15228         mv ${testdir1}/test_0 ${testdir2}/test_0
15229
15230         testdir1_size=$(ls -l $DIR/${tdir} |
15231                 awk '/stats_testdir1/ {print $5}')
15232         testdir2_size=$(ls -l $DIR/${tdir} |
15233                 awk '/stats_testdir2/ {print $5}')
15234
15235         testdir1_size=$(order_2 $testdir1_size)
15236         testdir2_size=$(order_2 $testdir2_size)
15237
15238         testdir1_size=$(size_in_KMGT $testdir1_size)
15239         testdir2_size=$(size_in_KMGT $testdir2_size)
15240
15241         echo "source rename dir size: ${testdir1_size}"
15242         echo "target rename dir size: ${testdir2_size}"
15243
15244         eval $cmd || error "$cmd failed"
15245         local crossdir=$($cmd | grep 'crossdir')
15246         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15247         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15248         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15249         [[ $src_sample -eq 1 ]] ||
15250                 error "crossdir_rename_size error $src_sample"
15251         [[ $tgt_sample -eq 1 ]] ||
15252                 error "crossdir_rename_size error $tgt_sample"
15253         echo "Check cross dir rename stats success"
15254         rm -rf $DIR/${tdir}
15255 }
15256 run_test 133d "Verifying rename_stats ========================================"
15257
15258 test_133e() {
15259         remote_mds_nodsh && skip "remote MDS with nodsh"
15260         remote_ost_nodsh && skip "remote OST with nodsh"
15261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15262
15263         local testdir=$DIR/${tdir}/stats_testdir
15264         local ctr f0 f1 bs=32768 count=42 sum
15265
15266         mkdir -p ${testdir} || error "mkdir failed"
15267
15268         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15269
15270         for ctr in {write,read}_bytes; do
15271                 sync
15272                 cancel_lru_locks osc
15273
15274                 do_facet ost1 $LCTL set_param -n \
15275                         "obdfilter.*.exports.clear=clear"
15276
15277                 if [ $ctr = write_bytes ]; then
15278                         f0=/dev/zero
15279                         f1=${testdir}/${tfile}
15280                 else
15281                         f0=${testdir}/${tfile}
15282                         f1=/dev/null
15283                 fi
15284
15285                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15286                         error "dd failed"
15287                 sync
15288                 cancel_lru_locks osc
15289
15290                 sum=$(do_facet ost1 $LCTL get_param \
15291                         "obdfilter.*.exports.*.stats" |
15292                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15293                                 $1 == ctr { sum += $7 }
15294                                 END { printf("%0.0f", sum) }')
15295
15296                 if ((sum != bs * count)); then
15297                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15298                 fi
15299         done
15300
15301         rm -rf $DIR/${tdir}
15302 }
15303 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15304
15305 test_133f() {
15306         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15307                 skip "too old lustre for get_param -R ($facet_ver)"
15308
15309         # verifying readability.
15310         $LCTL get_param -R '*' &> /dev/null
15311
15312         # Verifing writability with badarea_io.
15313         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15314         local skipped_params='force_lbug|changelog_mask|daemon_file'
15315         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15316                 egrep -v "$skipped_params" |
15317                 xargs -n 1 find $proc_dirs -name |
15318                 xargs -n 1 badarea_io ||
15319                 error "client badarea_io failed"
15320
15321         # remount the FS in case writes/reads /proc break the FS
15322         cleanup || error "failed to unmount"
15323         setup || error "failed to setup"
15324 }
15325 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15326
15327 test_133g() {
15328         remote_mds_nodsh && skip "remote MDS with nodsh"
15329         remote_ost_nodsh && skip "remote OST with nodsh"
15330
15331         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15332         local proc_dirs_str=$(eval echo $proc_dirs)
15333         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15334         local facet
15335         for facet in mds1 ost1; do
15336                 local facet_ver=$(lustre_version_code $facet)
15337                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15338                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15339                 else
15340                         log "$facet: too old lustre for get_param -R"
15341                 fi
15342                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15343                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15344                                 tr -d = | egrep -v $skipped_params |
15345                                 xargs -n 1 find $proc_dirs_str -name |
15346                                 xargs -n 1 badarea_io" ||
15347                                         error "$facet badarea_io failed"
15348                 else
15349                         skip_noexit "$facet: too old lustre for get_param -R"
15350                 fi
15351         done
15352
15353         # remount the FS in case writes/reads /proc break the FS
15354         cleanup || error "failed to unmount"
15355         setup || error "failed to setup"
15356 }
15357 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15358
15359 test_133h() {
15360         remote_mds_nodsh && skip "remote MDS with nodsh"
15361         remote_ost_nodsh && skip "remote OST with nodsh"
15362         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15363                 skip "Need MDS version at least 2.9.54"
15364
15365         local facet
15366         for facet in client mds1 ost1; do
15367                 # Get the list of files that are missing the terminating newline
15368                 local plist=$(do_facet $facet
15369                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15370                 local ent
15371                 for ent in $plist; do
15372                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15373                                 awk -v FS='\v' -v RS='\v\v' \
15374                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15375                                         print FILENAME}'" 2>/dev/null)
15376                         [ -z $missing ] || {
15377                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15378                                 error "file does not end with newline: $facet-$ent"
15379                         }
15380                 done
15381         done
15382 }
15383 run_test 133h "Proc files should end with newlines"
15384
15385 test_134a() {
15386         remote_mds_nodsh && skip "remote MDS with nodsh"
15387         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15388                 skip "Need MDS version at least 2.7.54"
15389
15390         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15391         cancel_lru_locks mdc
15392
15393         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15394         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15395         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15396
15397         local nr=1000
15398         createmany -o $DIR/$tdir/f $nr ||
15399                 error "failed to create $nr files in $DIR/$tdir"
15400         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15401
15402         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15403         do_facet mds1 $LCTL set_param fail_loc=0x327
15404         do_facet mds1 $LCTL set_param fail_val=500
15405         touch $DIR/$tdir/m
15406
15407         echo "sleep 10 seconds ..."
15408         sleep 10
15409         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15410
15411         do_facet mds1 $LCTL set_param fail_loc=0
15412         do_facet mds1 $LCTL set_param fail_val=0
15413         [ $lck_cnt -lt $unused ] ||
15414                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15415
15416         rm $DIR/$tdir/m
15417         unlinkmany $DIR/$tdir/f $nr
15418 }
15419 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15420
15421 test_134b() {
15422         remote_mds_nodsh && skip "remote MDS with nodsh"
15423         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15424                 skip "Need MDS version at least 2.7.54"
15425
15426         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15427         cancel_lru_locks mdc
15428
15429         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15430                         ldlm.lock_reclaim_threshold_mb)
15431         # disable reclaim temporarily
15432         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15433
15434         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15435         do_facet mds1 $LCTL set_param fail_loc=0x328
15436         do_facet mds1 $LCTL set_param fail_val=500
15437
15438         $LCTL set_param debug=+trace
15439
15440         local nr=600
15441         createmany -o $DIR/$tdir/f $nr &
15442         local create_pid=$!
15443
15444         echo "Sleep $TIMEOUT seconds ..."
15445         sleep $TIMEOUT
15446         if ! ps -p $create_pid  > /dev/null 2>&1; then
15447                 do_facet mds1 $LCTL set_param fail_loc=0
15448                 do_facet mds1 $LCTL set_param fail_val=0
15449                 do_facet mds1 $LCTL set_param \
15450                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15451                 error "createmany finished incorrectly!"
15452         fi
15453         do_facet mds1 $LCTL set_param fail_loc=0
15454         do_facet mds1 $LCTL set_param fail_val=0
15455         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15456         wait $create_pid || return 1
15457
15458         unlinkmany $DIR/$tdir/f $nr
15459 }
15460 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15461
15462 test_135() {
15463         remote_mds_nodsh && skip "remote MDS with nodsh"
15464         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15465                 skip "Need MDS version at least 2.13.50"
15466         local fname
15467
15468         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15469
15470 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15471         #set only one record at plain llog
15472         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15473
15474         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15475
15476         #fill already existed plain llog each 64767
15477         #wrapping whole catalog
15478         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15479
15480         createmany -o $DIR/$tdir/$tfile_ 64700
15481         for (( i = 0; i < 64700; i = i + 2 ))
15482         do
15483                 rm $DIR/$tdir/$tfile_$i &
15484                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15485                 local pid=$!
15486                 wait $pid
15487         done
15488
15489         #waiting osp synchronization
15490         wait_delete_completed
15491 }
15492 run_test 135 "Race catalog processing"
15493
15494 test_136() {
15495         remote_mds_nodsh && skip "remote MDS with nodsh"
15496         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15497                 skip "Need MDS version at least 2.13.50"
15498         local fname
15499
15500         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15501         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15502         #set only one record at plain llog
15503 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15504         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15505
15506         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15507
15508         #fill already existed 2 plain llogs each 64767
15509         #wrapping whole catalog
15510         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15511         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15512         wait_delete_completed
15513
15514         createmany -o $DIR/$tdir/$tfile_ 10
15515         sleep 25
15516
15517         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15518         for (( i = 0; i < 10; i = i + 3 ))
15519         do
15520                 rm $DIR/$tdir/$tfile_$i &
15521                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15522                 local pid=$!
15523                 wait $pid
15524                 sleep 7
15525                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15526         done
15527
15528         #waiting osp synchronization
15529         wait_delete_completed
15530 }
15531 run_test 136 "Race catalog processing 2"
15532
15533 test_140() { #bug-17379
15534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15535
15536         test_mkdir $DIR/$tdir
15537         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15538         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15539
15540         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15541         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15542         local i=0
15543         while i=$((i + 1)); do
15544                 test_mkdir $i
15545                 cd $i || error "Changing to $i"
15546                 ln -s ../stat stat || error "Creating stat symlink"
15547                 # Read the symlink until ELOOP present,
15548                 # not LBUGing the system is considered success,
15549                 # we didn't overrun the stack.
15550                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15551                 if [ $ret -ne 0 ]; then
15552                         if [ $ret -eq 40 ]; then
15553                                 break  # -ELOOP
15554                         else
15555                                 error "Open stat symlink"
15556                                         return
15557                         fi
15558                 fi
15559         done
15560         i=$((i - 1))
15561         echo "The symlink depth = $i"
15562         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15563                 error "Invalid symlink depth"
15564
15565         # Test recursive symlink
15566         ln -s symlink_self symlink_self
15567         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15568         echo "open symlink_self returns $ret"
15569         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15570 }
15571 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15572
15573 test_150a() {
15574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15575
15576         local TF="$TMP/$tfile"
15577
15578         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15579         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15580         cp $TF $DIR/$tfile
15581         cancel_lru_locks $OSC
15582         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15583         remount_client $MOUNT
15584         df -P $MOUNT
15585         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15586
15587         $TRUNCATE $TF 6000
15588         $TRUNCATE $DIR/$tfile 6000
15589         cancel_lru_locks $OSC
15590         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15591
15592         echo "12345" >>$TF
15593         echo "12345" >>$DIR/$tfile
15594         cancel_lru_locks $OSC
15595         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15596
15597         echo "12345" >>$TF
15598         echo "12345" >>$DIR/$tfile
15599         cancel_lru_locks $OSC
15600         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15601 }
15602 run_test 150a "truncate/append tests"
15603
15604 test_150b() {
15605         check_set_fallocate_or_skip
15606         local out
15607
15608         touch $DIR/$tfile
15609         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15610         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15611                 skip_eopnotsupp "$out|check_fallocate failed"
15612 }
15613 run_test 150b "Verify fallocate (prealloc) functionality"
15614
15615 test_150bb() {
15616         check_set_fallocate_or_skip
15617
15618         touch $DIR/$tfile
15619         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15620         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15621         > $DIR/$tfile
15622         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15623         # precomputed md5sum for 20MB of zeroes
15624         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15625         local sum=($(md5sum $DIR/$tfile))
15626
15627         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15628
15629         check_set_fallocate 1
15630
15631         > $DIR/$tfile
15632         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15633         sum=($(md5sum $DIR/$tfile))
15634
15635         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15636 }
15637 run_test 150bb "Verify fallocate modes both zero space"
15638
15639 test_150c() {
15640         check_set_fallocate_or_skip
15641         local striping="-c2"
15642
15643         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15644         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15645         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15646         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15647         local want=$((OSTCOUNT * 1048576))
15648
15649         # Must allocate all requested space, not more than 5% extra
15650         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15651                 error "bytes $bytes is not $want"
15652
15653         rm -f $DIR/$tfile
15654
15655         echo "verify fallocate on PFL file"
15656
15657         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15658
15659         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15660                 error "Create $DIR/$tfile failed"
15661         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15662         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15663         want=$((512 * 1048576))
15664
15665         # Must allocate all requested space, not more than 5% extra
15666         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15667                 error "bytes $bytes is not $want"
15668 }
15669 run_test 150c "Verify fallocate Size and Blocks"
15670
15671 test_150d() {
15672         check_set_fallocate_or_skip
15673         local striping="-c2"
15674
15675         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15676
15677         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15678         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15679                 error "setstripe failed"
15680         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15681         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15682         local want=$((OSTCOUNT * 1048576))
15683
15684         # Must allocate all requested space, not more than 5% extra
15685         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15686                 error "bytes $bytes is not $want"
15687 }
15688 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15689
15690 test_150e() {
15691         check_set_fallocate_or_skip
15692
15693         echo "df before:"
15694         $LFS df
15695         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15696         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15697                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15698
15699         # Find OST with Minimum Size
15700         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15701                        sort -un | head -1)
15702
15703         # Get 100MB per OST of the available space to reduce run time
15704         # else 60% of the available space if we are running SLOW tests
15705         if [ $SLOW == "no" ]; then
15706                 local space=$((1024 * 100 * OSTCOUNT))
15707         else
15708                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15709         fi
15710
15711         fallocate -l${space}k $DIR/$tfile ||
15712                 error "fallocate ${space}k $DIR/$tfile failed"
15713         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15714
15715         # get size immediately after fallocate. This should be correctly
15716         # updated
15717         local size=$(stat -c '%s' $DIR/$tfile)
15718         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15719
15720         # Sleep for a while for statfs to get updated. And not pull from cache.
15721         sleep 2
15722
15723         echo "df after fallocate:"
15724         $LFS df
15725
15726         (( size / 1024 == space )) || error "size $size != requested $space"
15727         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15728                 error "used $used < space $space"
15729
15730         rm $DIR/$tfile || error "rm failed"
15731         sync
15732         wait_delete_completed
15733
15734         echo "df after unlink:"
15735         $LFS df
15736 }
15737 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15738
15739 test_150f() {
15740         local size
15741         local blocks
15742         local want_size_before=20480 # in bytes
15743         local want_blocks_before=40 # 512 sized blocks
15744         local want_blocks_after=24  # 512 sized blocks
15745         local length=$(((want_blocks_before - want_blocks_after) * 512))
15746
15747         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15748                 skip "need at least 2.14.0 for fallocate punch"
15749
15750         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15751                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15752         fi
15753
15754         check_set_fallocate_or_skip
15755         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15756
15757         [[ "x$DOM" == "xyes" ]] &&
15758                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15759
15760         echo "Verify fallocate punch: Range within the file range"
15761         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15762                 error "dd failed for bs 4096 and count 5"
15763
15764         # Call fallocate with punch range which is within the file range
15765         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15766                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15767         # client must see changes immediately after fallocate
15768         size=$(stat -c '%s' $DIR/$tfile)
15769         blocks=$(stat -c '%b' $DIR/$tfile)
15770
15771         # Verify punch worked.
15772         (( blocks == want_blocks_after )) ||
15773                 error "punch failed: blocks $blocks != $want_blocks_after"
15774
15775         (( size == want_size_before )) ||
15776                 error "punch failed: size $size != $want_size_before"
15777
15778         # Verify there is hole in file
15779         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15780         # precomputed md5sum
15781         local expect="4a9a834a2db02452929c0a348273b4aa"
15782
15783         cksum=($(md5sum $DIR/$tfile))
15784         [[ "${cksum[0]}" == "$expect" ]] ||
15785                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15786
15787         # Start second sub-case for fallocate punch.
15788         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15789         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15790                 error "dd failed for bs 4096 and count 5"
15791
15792         # Punch range less than block size will have no change in block count
15793         want_blocks_after=40  # 512 sized blocks
15794
15795         # Punch overlaps two blocks and less than blocksize
15796         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15797                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15798         size=$(stat -c '%s' $DIR/$tfile)
15799         blocks=$(stat -c '%b' $DIR/$tfile)
15800
15801         # Verify punch worked.
15802         (( blocks == want_blocks_after )) ||
15803                 error "punch failed: blocks $blocks != $want_blocks_after"
15804
15805         (( size == want_size_before )) ||
15806                 error "punch failed: size $size != $want_size_before"
15807
15808         # Verify if range is really zero'ed out. We expect Zeros.
15809         # precomputed md5sum
15810         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15811         cksum=($(md5sum $DIR/$tfile))
15812         [[ "${cksum[0]}" == "$expect" ]] ||
15813                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15814 }
15815 run_test 150f "Verify fallocate punch functionality"
15816
15817 test_150g() {
15818         local space
15819         local size
15820         local blocks
15821         local blocks_after
15822         local size_after
15823         local BS=4096 # Block size in bytes
15824
15825         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15826                 skip "need at least 2.14.0 for fallocate punch"
15827
15828         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15829                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15830         fi
15831
15832         check_set_fallocate_or_skip
15833         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15834
15835         if [[ "x$DOM" == "xyes" ]]; then
15836                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15837                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15838         else
15839                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15840                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15841         fi
15842
15843         # Get 100MB per OST of the available space to reduce run time
15844         # else 60% of the available space if we are running SLOW tests
15845         if [ $SLOW == "no" ]; then
15846                 space=$((1024 * 100 * OSTCOUNT))
15847         else
15848                 # Find OST with Minimum Size
15849                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15850                         sort -un | head -1)
15851                 echo "min size OST: $space"
15852                 space=$(((space * 60)/100 * OSTCOUNT))
15853         fi
15854         # space in 1k units, round to 4k blocks
15855         local blkcount=$((space * 1024 / $BS))
15856
15857         echo "Verify fallocate punch: Very large Range"
15858         fallocate -l${space}k $DIR/$tfile ||
15859                 error "fallocate ${space}k $DIR/$tfile failed"
15860         # write 1M at the end, start and in the middle
15861         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15862                 error "dd failed: bs $BS count 256"
15863         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15864                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15865         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15866                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15867
15868         # Gather stats.
15869         size=$(stat -c '%s' $DIR/$tfile)
15870
15871         # gather punch length.
15872         local punch_size=$((size - (BS * 2)))
15873
15874         echo "punch_size = $punch_size"
15875         echo "size - punch_size: $((size - punch_size))"
15876         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15877
15878         # Call fallocate to punch all except 2 blocks. We leave the
15879         # first and the last block
15880         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15881         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15882                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15883
15884         size_after=$(stat -c '%s' $DIR/$tfile)
15885         blocks_after=$(stat -c '%b' $DIR/$tfile)
15886
15887         # Verify punch worked.
15888         # Size should be kept
15889         (( size == size_after )) ||
15890                 error "punch failed: size $size != $size_after"
15891
15892         # two 4k data blocks to remain plus possible 1 extra extent block
15893         (( blocks_after <= ((BS / 512) * 3) )) ||
15894                 error "too many blocks remains: $blocks_after"
15895
15896         # Verify that file has hole between the first and the last blocks
15897         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15898         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15899
15900         echo "Hole at [$hole_start, $hole_end)"
15901         (( hole_start == BS )) ||
15902                 error "no hole at offset $BS after punch"
15903
15904         (( hole_end == BS + punch_size )) ||
15905                 error "data at offset $hole_end < $((BS + punch_size))"
15906 }
15907 run_test 150g "Verify fallocate punch on large range"
15908
15909 test_150h() {
15910         local file=$DIR/$tfile
15911         local size
15912
15913         check_set_fallocate_or_skip
15914         statx_supported || skip_env "Test must be statx() syscall supported"
15915
15916         # fallocate() does not update the size information on the MDT
15917         fallocate -l 16K $file || error "failed to fallocate $file"
15918         cancel_lru_locks $OSC
15919         # STATX with cached-always mode will not send glimpse RPCs to OST,
15920         # it uses the caching attrs on the client side as much as possible.
15921         size=$($STATX --cached=always -c %s $file)
15922         [ $size == 16384 ] ||
15923                 error "size after fallocate() is $size, expected 16384"
15924 }
15925 run_test 150h "Verify extend fallocate updates the file size"
15926
15927 #LU-2902 roc_hit was not able to read all values from lproc
15928 function roc_hit_init() {
15929         local list=$(comma_list $(osts_nodes))
15930         local dir=$DIR/$tdir-check
15931         local file=$dir/$tfile
15932         local BEFORE
15933         local AFTER
15934         local idx
15935
15936         test_mkdir $dir
15937         #use setstripe to do a write to every ost
15938         for i in $(seq 0 $((OSTCOUNT-1))); do
15939                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15940                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15941                 idx=$(printf %04x $i)
15942                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15943                         awk '$1 == "cache_access" {sum += $7}
15944                                 END { printf("%0.0f", sum) }')
15945
15946                 cancel_lru_locks osc
15947                 cat $file >/dev/null
15948
15949                 AFTER=$(get_osd_param $list *OST*$idx stats |
15950                         awk '$1 == "cache_access" {sum += $7}
15951                                 END { printf("%0.0f", sum) }')
15952
15953                 echo BEFORE:$BEFORE AFTER:$AFTER
15954                 if ! let "AFTER - BEFORE == 4"; then
15955                         rm -rf $dir
15956                         error "roc_hit is not safe to use"
15957                 fi
15958                 rm $file
15959         done
15960
15961         rm -rf $dir
15962 }
15963
15964 function roc_hit() {
15965         local list=$(comma_list $(osts_nodes))
15966         echo $(get_osd_param $list '' stats |
15967                 awk '$1 == "cache_hit" {sum += $7}
15968                         END { printf("%0.0f", sum) }')
15969 }
15970
15971 function set_cache() {
15972         local on=1
15973
15974         if [ "$2" == "off" ]; then
15975                 on=0;
15976         fi
15977         local list=$(comma_list $(osts_nodes))
15978         set_osd_param $list '' $1_cache_enable $on
15979
15980         cancel_lru_locks osc
15981 }
15982
15983 test_151() {
15984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15985         remote_ost_nodsh && skip "remote OST with nodsh"
15986         (( CLIENT_VERSION == OST1_VERSION )) ||
15987                 skip "LU-13081: no interop testing for OSS cache"
15988
15989         local CPAGES=3
15990         local list=$(comma_list $(osts_nodes))
15991
15992         # check whether obdfilter is cache capable at all
15993         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15994                 skip "not cache-capable obdfilter"
15995         fi
15996
15997         # check cache is enabled on all obdfilters
15998         if get_osd_param $list '' read_cache_enable | grep 0; then
15999                 skip "oss cache is disabled"
16000         fi
16001
16002         set_osd_param $list '' writethrough_cache_enable 1
16003
16004         # check write cache is enabled on all obdfilters
16005         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16006                 skip "oss write cache is NOT enabled"
16007         fi
16008
16009         roc_hit_init
16010
16011         #define OBD_FAIL_OBD_NO_LRU  0x609
16012         do_nodes $list $LCTL set_param fail_loc=0x609
16013
16014         # pages should be in the case right after write
16015         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16016                 error "dd failed"
16017
16018         local BEFORE=$(roc_hit)
16019         cancel_lru_locks osc
16020         cat $DIR/$tfile >/dev/null
16021         local AFTER=$(roc_hit)
16022
16023         do_nodes $list $LCTL set_param fail_loc=0
16024
16025         if ! let "AFTER - BEFORE == CPAGES"; then
16026                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16027         fi
16028
16029         cancel_lru_locks osc
16030         # invalidates OST cache
16031         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16032         set_osd_param $list '' read_cache_enable 0
16033         cat $DIR/$tfile >/dev/null
16034
16035         # now data shouldn't be found in the cache
16036         BEFORE=$(roc_hit)
16037         cancel_lru_locks osc
16038         cat $DIR/$tfile >/dev/null
16039         AFTER=$(roc_hit)
16040         if let "AFTER - BEFORE != 0"; then
16041                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16042         fi
16043
16044         set_osd_param $list '' read_cache_enable 1
16045         rm -f $DIR/$tfile
16046 }
16047 run_test 151 "test cache on oss and controls ==============================="
16048
16049 test_152() {
16050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16051
16052         local TF="$TMP/$tfile"
16053
16054         # simulate ENOMEM during write
16055 #define OBD_FAIL_OST_NOMEM      0x226
16056         lctl set_param fail_loc=0x80000226
16057         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16058         cp $TF $DIR/$tfile
16059         sync || error "sync failed"
16060         lctl set_param fail_loc=0
16061
16062         # discard client's cache
16063         cancel_lru_locks osc
16064
16065         # simulate ENOMEM during read
16066         lctl set_param fail_loc=0x80000226
16067         cmp $TF $DIR/$tfile || error "cmp failed"
16068         lctl set_param fail_loc=0
16069
16070         rm -f $TF
16071 }
16072 run_test 152 "test read/write with enomem ============================"
16073
16074 test_153() {
16075         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16076 }
16077 run_test 153 "test if fdatasync does not crash ======================="
16078
16079 dot_lustre_fid_permission_check() {
16080         local fid=$1
16081         local ffid=$MOUNT/.lustre/fid/$fid
16082         local test_dir=$2
16083
16084         echo "stat fid $fid"
16085         stat $ffid || error "stat $ffid failed."
16086         echo "touch fid $fid"
16087         touch $ffid || error "touch $ffid failed."
16088         echo "write to fid $fid"
16089         cat /etc/hosts > $ffid || error "write $ffid failed."
16090         echo "read fid $fid"
16091         diff /etc/hosts $ffid || error "read $ffid failed."
16092         echo "append write to fid $fid"
16093         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16094         echo "rename fid $fid"
16095         mv $ffid $test_dir/$tfile.1 &&
16096                 error "rename $ffid to $tfile.1 should fail."
16097         touch $test_dir/$tfile.1
16098         mv $test_dir/$tfile.1 $ffid &&
16099                 error "rename $tfile.1 to $ffid should fail."
16100         rm -f $test_dir/$tfile.1
16101         echo "truncate fid $fid"
16102         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16103         echo "link fid $fid"
16104         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16105         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16106                 id $USER0 || skip_env "missing user $USER0"
16107                 echo "setfacl fid $fid"
16108                 setfacl -R -m u:$USER0:rwx $ffid ||
16109                         error "setfacl $ffid failed"
16110                 echo "getfacl fid $fid"
16111                 getfacl $ffid || error "getfacl $ffid failed."
16112         fi
16113         echo "unlink fid $fid"
16114         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16115         echo "mknod fid $fid"
16116         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16117
16118         fid=[0xf00000400:0x1:0x0]
16119         ffid=$MOUNT/.lustre/fid/$fid
16120
16121         echo "stat non-exist fid $fid"
16122         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16123         echo "write to non-exist fid $fid"
16124         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16125         echo "link new fid $fid"
16126         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16127
16128         mkdir -p $test_dir/$tdir
16129         touch $test_dir/$tdir/$tfile
16130         fid=$($LFS path2fid $test_dir/$tdir)
16131         rc=$?
16132         [ $rc -ne 0 ] &&
16133                 error "error: could not get fid for $test_dir/$dir/$tfile."
16134
16135         ffid=$MOUNT/.lustre/fid/$fid
16136
16137         echo "ls $fid"
16138         ls $ffid || error "ls $ffid failed."
16139         echo "touch $fid/$tfile.1"
16140         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16141
16142         echo "touch $MOUNT/.lustre/fid/$tfile"
16143         touch $MOUNT/.lustre/fid/$tfile && \
16144                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16145
16146         echo "setxattr to $MOUNT/.lustre/fid"
16147         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16148
16149         echo "listxattr for $MOUNT/.lustre/fid"
16150         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16151
16152         echo "delxattr from $MOUNT/.lustre/fid"
16153         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16154
16155         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16156         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16157                 error "touch invalid fid should fail."
16158
16159         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16160         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16161                 error "touch non-normal fid should fail."
16162
16163         echo "rename $tdir to $MOUNT/.lustre/fid"
16164         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16165                 error "rename to $MOUNT/.lustre/fid should fail."
16166
16167         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16168         then            # LU-3547
16169                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16170                 local new_obf_mode=777
16171
16172                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16173                 chmod $new_obf_mode $DIR/.lustre/fid ||
16174                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16175
16176                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16177                 [ $obf_mode -eq $new_obf_mode ] ||
16178                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16179
16180                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16181                 chmod $old_obf_mode $DIR/.lustre/fid ||
16182                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16183         fi
16184
16185         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16186         fid=$($LFS path2fid $test_dir/$tfile-2)
16187
16188         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16189         then # LU-5424
16190                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16191                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16192                         error "create lov data thru .lustre failed"
16193         fi
16194         echo "cp /etc/passwd $test_dir/$tfile-2"
16195         cp /etc/passwd $test_dir/$tfile-2 ||
16196                 error "copy to $test_dir/$tfile-2 failed."
16197         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16198         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16199                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16200
16201         rm -rf $test_dir/tfile.lnk
16202         rm -rf $test_dir/$tfile-2
16203 }
16204
16205 test_154A() {
16206         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16207                 skip "Need MDS version at least 2.4.1"
16208
16209         local tf=$DIR/$tfile
16210         touch $tf
16211
16212         local fid=$($LFS path2fid $tf)
16213         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16214
16215         # check that we get the same pathname back
16216         local rootpath
16217         local found
16218         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16219                 echo "$rootpath $fid"
16220                 found=$($LFS fid2path $rootpath "$fid")
16221                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16222                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16223         done
16224
16225         # check wrong root path format
16226         rootpath=$MOUNT"_wrong"
16227         found=$($LFS fid2path $rootpath "$fid")
16228         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16229 }
16230 run_test 154A "lfs path2fid and fid2path basic checks"
16231
16232 test_154B() {
16233         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16234                 skip "Need MDS version at least 2.4.1"
16235
16236         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16237         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16238         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16239         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16240
16241         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16242         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16243
16244         # check that we get the same pathname
16245         echo "PFID: $PFID, name: $name"
16246         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16247         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16248         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16249                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16250
16251         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16252 }
16253 run_test 154B "verify the ll_decode_linkea tool"
16254
16255 test_154a() {
16256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16257         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16258         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16259                 skip "Need MDS version at least 2.2.51"
16260         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16261
16262         cp /etc/hosts $DIR/$tfile
16263
16264         fid=$($LFS path2fid $DIR/$tfile)
16265         rc=$?
16266         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16267
16268         dot_lustre_fid_permission_check "$fid" $DIR ||
16269                 error "dot lustre permission check $fid failed"
16270
16271         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16272
16273         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16274
16275         touch $MOUNT/.lustre/file &&
16276                 error "creation is not allowed under .lustre"
16277
16278         mkdir $MOUNT/.lustre/dir &&
16279                 error "mkdir is not allowed under .lustre"
16280
16281         rm -rf $DIR/$tfile
16282 }
16283 run_test 154a "Open-by-FID"
16284
16285 test_154b() {
16286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16287         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16289         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16290                 skip "Need MDS version at least 2.2.51"
16291
16292         local remote_dir=$DIR/$tdir/remote_dir
16293         local MDTIDX=1
16294         local rc=0
16295
16296         mkdir -p $DIR/$tdir
16297         $LFS mkdir -i $MDTIDX $remote_dir ||
16298                 error "create remote directory failed"
16299
16300         cp /etc/hosts $remote_dir/$tfile
16301
16302         fid=$($LFS path2fid $remote_dir/$tfile)
16303         rc=$?
16304         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16305
16306         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16307                 error "dot lustre permission check $fid failed"
16308         rm -rf $DIR/$tdir
16309 }
16310 run_test 154b "Open-by-FID for remote directory"
16311
16312 test_154c() {
16313         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16314                 skip "Need MDS version at least 2.4.1"
16315
16316         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16317         local FID1=$($LFS path2fid $DIR/$tfile.1)
16318         local FID2=$($LFS path2fid $DIR/$tfile.2)
16319         local FID3=$($LFS path2fid $DIR/$tfile.3)
16320
16321         local N=1
16322         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16323                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16324                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16325                 local want=FID$N
16326                 [ "$FID" = "${!want}" ] ||
16327                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16328                 N=$((N + 1))
16329         done
16330
16331         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16332         do
16333                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16334                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16335                 N=$((N + 1))
16336         done
16337 }
16338 run_test 154c "lfs path2fid and fid2path multiple arguments"
16339
16340 test_154d() {
16341         remote_mds_nodsh && skip "remote MDS with nodsh"
16342         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16343                 skip "Need MDS version at least 2.5.53"
16344
16345         if remote_mds; then
16346                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16347         else
16348                 nid="0@lo"
16349         fi
16350         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16351         local fd
16352         local cmd
16353
16354         rm -f $DIR/$tfile
16355         touch $DIR/$tfile
16356
16357         local fid=$($LFS path2fid $DIR/$tfile)
16358         # Open the file
16359         fd=$(free_fd)
16360         cmd="exec $fd<$DIR/$tfile"
16361         eval $cmd
16362         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16363         echo "$fid_list" | grep "$fid"
16364         rc=$?
16365
16366         cmd="exec $fd>/dev/null"
16367         eval $cmd
16368         if [ $rc -ne 0 ]; then
16369                 error "FID $fid not found in open files list $fid_list"
16370         fi
16371 }
16372 run_test 154d "Verify open file fid"
16373
16374 test_154e()
16375 {
16376         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16377                 skip "Need MDS version at least 2.6.50"
16378
16379         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16380                 error ".lustre returned by readdir"
16381         fi
16382 }
16383 run_test 154e ".lustre is not returned by readdir"
16384
16385 test_154f() {
16386         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16387
16388         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16389         mkdir_on_mdt0 $DIR/$tdir
16390         # test dirs inherit from its stripe
16391         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16392         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16393         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16394         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16395         touch $DIR/f
16396
16397         # get fid of parents
16398         local FID0=$($LFS path2fid $DIR/$tdir)
16399         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16400         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16401         local FID3=$($LFS path2fid $DIR)
16402
16403         # check that path2fid --parents returns expected <parent_fid>/name
16404         # 1) test for a directory (single parent)
16405         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16406         [ "$parent" == "$FID0/foo1" ] ||
16407                 error "expected parent: $FID0/foo1, got: $parent"
16408
16409         # 2) test for a file with nlink > 1 (multiple parents)
16410         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16411         echo "$parent" | grep -F "$FID1/$tfile" ||
16412                 error "$FID1/$tfile not returned in parent list"
16413         echo "$parent" | grep -F "$FID2/link" ||
16414                 error "$FID2/link not returned in parent list"
16415
16416         # 3) get parent by fid
16417         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16418         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16419         echo "$parent" | grep -F "$FID1/$tfile" ||
16420                 error "$FID1/$tfile not returned in parent list (by fid)"
16421         echo "$parent" | grep -F "$FID2/link" ||
16422                 error "$FID2/link not returned in parent list (by fid)"
16423
16424         # 4) test for entry in root directory
16425         parent=$($LFS path2fid --parents $DIR/f)
16426         echo "$parent" | grep -F "$FID3/f" ||
16427                 error "$FID3/f not returned in parent list"
16428
16429         # 5) test it on root directory
16430         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16431                 error "$MOUNT should not have parents"
16432
16433         # enable xattr caching and check that linkea is correctly updated
16434         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16435         save_lustre_params client "llite.*.xattr_cache" > $save
16436         lctl set_param llite.*.xattr_cache 1
16437
16438         # 6.1) linkea update on rename
16439         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16440
16441         # get parents by fid
16442         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16443         # foo1 should no longer be returned in parent list
16444         echo "$parent" | grep -F "$FID1" &&
16445                 error "$FID1 should no longer be in parent list"
16446         # the new path should appear
16447         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16448                 error "$FID2/$tfile.moved is not in parent list"
16449
16450         # 6.2) linkea update on unlink
16451         rm -f $DIR/$tdir/foo2/link
16452         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16453         # foo2/link should no longer be returned in parent list
16454         echo "$parent" | grep -F "$FID2/link" &&
16455                 error "$FID2/link should no longer be in parent list"
16456         true
16457
16458         rm -f $DIR/f
16459         restore_lustre_params < $save
16460         rm -f $save
16461 }
16462 run_test 154f "get parent fids by reading link ea"
16463
16464 test_154g()
16465 {
16466         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16467            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16468                 skip "Need MDS version at least 2.6.92"
16469
16470         mkdir_on_mdt0 $DIR/$tdir
16471         llapi_fid_test -d $DIR/$tdir
16472 }
16473 run_test 154g "various llapi FID tests"
16474
16475 test_154h()
16476 {
16477         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16478                 skip "Need client at least version 2.15.55.1"
16479
16480         # Create an empty file
16481         touch $DIR/$tfile
16482
16483         # Get FID (interactive mode) and save under $TMP/$tfile.log
16484         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16485                 path2fid $DIR/$tfile
16486         EOF
16487
16488         fid=$(cat $TMP/$tfile.log)
16489         # $fid should not be empty
16490         [[ ! -z $fid ]] || error "FID is empty"
16491         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16492 }
16493 run_test 154h "Verify interactive path2fid"
16494
16495 test_155_small_load() {
16496     local temp=$TMP/$tfile
16497     local file=$DIR/$tfile
16498
16499     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16500         error "dd of=$temp bs=6096 count=1 failed"
16501     cp $temp $file
16502     cancel_lru_locks $OSC
16503     cmp $temp $file || error "$temp $file differ"
16504
16505     $TRUNCATE $temp 6000
16506     $TRUNCATE $file 6000
16507     cmp $temp $file || error "$temp $file differ (truncate1)"
16508
16509     echo "12345" >>$temp
16510     echo "12345" >>$file
16511     cmp $temp $file || error "$temp $file differ (append1)"
16512
16513     echo "12345" >>$temp
16514     echo "12345" >>$file
16515     cmp $temp $file || error "$temp $file differ (append2)"
16516
16517     rm -f $temp $file
16518     true
16519 }
16520
16521 test_155_big_load() {
16522         remote_ost_nodsh && skip "remote OST with nodsh"
16523
16524         local temp=$TMP/$tfile
16525         local file=$DIR/$tfile
16526
16527         free_min_max
16528         local cache_size=$(do_facet ost$((MAXI+1)) \
16529                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16530
16531         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16532         # pre-set value
16533         if [ -z "$cache_size" ]; then
16534                 cache_size=256
16535         fi
16536         local large_file_size=$((cache_size * 2))
16537
16538         echo "OSS cache size: $cache_size KB"
16539         echo "Large file size: $large_file_size KB"
16540
16541         [ $MAXV -le $large_file_size ] &&
16542                 skip_env "max available OST size needs > $large_file_size KB"
16543
16544         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16545
16546         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16547                 error "dd of=$temp bs=$large_file_size count=1k failed"
16548         cp $temp $file
16549         ls -lh $temp $file
16550         cancel_lru_locks osc
16551         cmp $temp $file || error "$temp $file differ"
16552
16553         rm -f $temp $file
16554         true
16555 }
16556
16557 save_writethrough() {
16558         local facets=$(get_facets OST)
16559
16560         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16561 }
16562
16563 test_155a() {
16564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16565
16566         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16567
16568         save_writethrough $p
16569
16570         set_cache read on
16571         set_cache writethrough on
16572         test_155_small_load
16573         restore_lustre_params < $p
16574         rm -f $p
16575 }
16576 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16577
16578 test_155b() {
16579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16580
16581         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16582
16583         save_writethrough $p
16584
16585         set_cache read on
16586         set_cache writethrough off
16587         test_155_small_load
16588         restore_lustre_params < $p
16589         rm -f $p
16590 }
16591 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16592
16593 test_155c() {
16594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16595
16596         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16597
16598         save_writethrough $p
16599
16600         set_cache read off
16601         set_cache writethrough on
16602         test_155_small_load
16603         restore_lustre_params < $p
16604         rm -f $p
16605 }
16606 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16607
16608 test_155d() {
16609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16610
16611         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16612
16613         save_writethrough $p
16614
16615         set_cache read off
16616         set_cache writethrough off
16617         test_155_small_load
16618         restore_lustre_params < $p
16619         rm -f $p
16620 }
16621 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16622
16623 test_155e() {
16624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16625
16626         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16627
16628         save_writethrough $p
16629
16630         set_cache read on
16631         set_cache writethrough on
16632         test_155_big_load
16633         restore_lustre_params < $p
16634         rm -f $p
16635 }
16636 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16637
16638 test_155f() {
16639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16640
16641         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16642
16643         save_writethrough $p
16644
16645         set_cache read on
16646         set_cache writethrough off
16647         test_155_big_load
16648         restore_lustre_params < $p
16649         rm -f $p
16650 }
16651 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16652
16653 test_155g() {
16654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16655
16656         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16657
16658         save_writethrough $p
16659
16660         set_cache read off
16661         set_cache writethrough on
16662         test_155_big_load
16663         restore_lustre_params < $p
16664         rm -f $p
16665 }
16666 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16667
16668 test_155h() {
16669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16670
16671         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16672
16673         save_writethrough $p
16674
16675         set_cache read off
16676         set_cache writethrough off
16677         test_155_big_load
16678         restore_lustre_params < $p
16679         rm -f $p
16680 }
16681 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16682
16683 test_156() {
16684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16685         remote_ost_nodsh && skip "remote OST with nodsh"
16686         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16687                 skip "stats not implemented on old servers"
16688         [ "$ost1_FSTYPE" = "zfs" ] &&
16689                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16690         (( CLIENT_VERSION == OST1_VERSION )) ||
16691                 skip "LU-13081: no interop testing for OSS cache"
16692
16693         local CPAGES=3
16694         local BEFORE
16695         local AFTER
16696         local file="$DIR/$tfile"
16697         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16698
16699         save_writethrough $p
16700         roc_hit_init
16701
16702         log "Turn on read and write cache"
16703         set_cache read on
16704         set_cache writethrough on
16705
16706         log "Write data and read it back."
16707         log "Read should be satisfied from the cache."
16708         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16709         BEFORE=$(roc_hit)
16710         cancel_lru_locks osc
16711         cat $file >/dev/null
16712         AFTER=$(roc_hit)
16713         if ! let "AFTER - BEFORE == CPAGES"; then
16714                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16715         else
16716                 log "cache hits: before: $BEFORE, after: $AFTER"
16717         fi
16718
16719         log "Read again; it should be satisfied from the cache."
16720         BEFORE=$AFTER
16721         cancel_lru_locks osc
16722         cat $file >/dev/null
16723         AFTER=$(roc_hit)
16724         if ! let "AFTER - BEFORE == CPAGES"; then
16725                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16726         else
16727                 log "cache hits:: before: $BEFORE, after: $AFTER"
16728         fi
16729
16730         log "Turn off the read cache and turn on the write cache"
16731         set_cache read off
16732         set_cache writethrough on
16733
16734         log "Read again; it should be satisfied from the cache."
16735         BEFORE=$(roc_hit)
16736         cancel_lru_locks osc
16737         cat $file >/dev/null
16738         AFTER=$(roc_hit)
16739         if ! let "AFTER - BEFORE == CPAGES"; then
16740                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16741         else
16742                 log "cache hits:: before: $BEFORE, after: $AFTER"
16743         fi
16744
16745         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16746                 # > 2.12.56 uses pagecache if cached
16747                 log "Read again; it should not be satisfied from the cache."
16748                 BEFORE=$AFTER
16749                 cancel_lru_locks osc
16750                 cat $file >/dev/null
16751                 AFTER=$(roc_hit)
16752                 if ! let "AFTER - BEFORE == 0"; then
16753                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16754                 else
16755                         log "cache hits:: before: $BEFORE, after: $AFTER"
16756                 fi
16757         fi
16758
16759         log "Write data and read it back."
16760         log "Read should be satisfied from the cache."
16761         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16762         BEFORE=$(roc_hit)
16763         cancel_lru_locks osc
16764         cat $file >/dev/null
16765         AFTER=$(roc_hit)
16766         if ! let "AFTER - BEFORE == CPAGES"; then
16767                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16768         else
16769                 log "cache hits:: before: $BEFORE, after: $AFTER"
16770         fi
16771
16772         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16773                 # > 2.12.56 uses pagecache if cached
16774                 log "Read again; it should not be satisfied from the cache."
16775                 BEFORE=$AFTER
16776                 cancel_lru_locks osc
16777                 cat $file >/dev/null
16778                 AFTER=$(roc_hit)
16779                 if ! let "AFTER - BEFORE == 0"; then
16780                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16781                 else
16782                         log "cache hits:: before: $BEFORE, after: $AFTER"
16783                 fi
16784         fi
16785
16786         log "Turn off read and write cache"
16787         set_cache read off
16788         set_cache writethrough off
16789
16790         log "Write data and read it back"
16791         log "It should not be satisfied from the cache."
16792         rm -f $file
16793         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16794         cancel_lru_locks osc
16795         BEFORE=$(roc_hit)
16796         cat $file >/dev/null
16797         AFTER=$(roc_hit)
16798         if ! let "AFTER - BEFORE == 0"; then
16799                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16800         else
16801                 log "cache hits:: before: $BEFORE, after: $AFTER"
16802         fi
16803
16804         log "Turn on the read cache and turn off the write cache"
16805         set_cache read on
16806         set_cache writethrough off
16807
16808         log "Write data and read it back"
16809         log "It should not be satisfied from the cache."
16810         rm -f $file
16811         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16812         BEFORE=$(roc_hit)
16813         cancel_lru_locks osc
16814         cat $file >/dev/null
16815         AFTER=$(roc_hit)
16816         if ! let "AFTER - BEFORE == 0"; then
16817                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16818         else
16819                 log "cache hits:: before: $BEFORE, after: $AFTER"
16820         fi
16821
16822         log "Read again; it should be satisfied from the cache."
16823         BEFORE=$(roc_hit)
16824         cancel_lru_locks osc
16825         cat $file >/dev/null
16826         AFTER=$(roc_hit)
16827         if ! let "AFTER - BEFORE == CPAGES"; then
16828                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16829         else
16830                 log "cache hits:: before: $BEFORE, after: $AFTER"
16831         fi
16832
16833         restore_lustre_params < $p
16834         rm -f $p $file
16835 }
16836 run_test 156 "Verification of tunables"
16837
16838 test_160a() {
16839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16840         remote_mds_nodsh && skip "remote MDS with nodsh"
16841         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16842                 skip "Need MDS version at least 2.2.0"
16843
16844         changelog_register || error "changelog_register failed"
16845         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16846         changelog_users $SINGLEMDS | grep -q $cl_user ||
16847                 error "User $cl_user not found in changelog_users"
16848
16849         mkdir_on_mdt0 $DIR/$tdir
16850
16851         # change something
16852         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16853         changelog_clear 0 || error "changelog_clear failed"
16854         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16855         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16856         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16857         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16858         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16859         rm $DIR/$tdir/pics/desktop.jpg
16860
16861         echo "verifying changelog mask"
16862         changelog_chmask "-MKDIR"
16863         changelog_chmask "-CLOSE"
16864
16865         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16866         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16867
16868         changelog_chmask "+MKDIR"
16869         changelog_chmask "+CLOSE"
16870
16871         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16872         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16873
16874         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16875         CLOSES=$(changelog_dump | grep -c "CLOSE")
16876         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16877         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16878
16879         # verify contents
16880         echo "verifying target fid"
16881         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16882         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16883         [ "$fidc" == "$fidf" ] ||
16884                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16885         echo "verifying parent fid"
16886         # The FID returned from the Changelog may be the directory shard on
16887         # a different MDT, and not the FID returned by path2fid on the parent.
16888         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16889         # since this is what will matter when recreating this file in the tree.
16890         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16891         local pathp=$($LFS fid2path $MOUNT "$fidp")
16892         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16893                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16894
16895         echo "getting records for $cl_user"
16896         changelog_users $SINGLEMDS
16897         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16898         local nclr=3
16899         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16900                 error "changelog_clear failed"
16901         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16902         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16903         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16904                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16905
16906         local min0_rec=$(changelog_users $SINGLEMDS |
16907                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16908         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16909                           awk '{ print $1; exit; }')
16910
16911         changelog_dump | tail -n 5
16912         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16913         [ $first_rec == $((min0_rec + 1)) ] ||
16914                 error "first index should be $min0_rec + 1 not $first_rec"
16915
16916         # LU-3446 changelog index reset on MDT restart
16917         local cur_rec1=$(changelog_users $SINGLEMDS |
16918                          awk '/^current.index:/ { print $NF }')
16919         changelog_clear 0 ||
16920                 error "clear all changelog records for $cl_user failed"
16921         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16922         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16923                 error "Fail to start $SINGLEMDS"
16924         local cur_rec2=$(changelog_users $SINGLEMDS |
16925                          awk '/^current.index:/ { print $NF }')
16926         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16927         [ $cur_rec1 == $cur_rec2 ] ||
16928                 error "current index should be $cur_rec1 not $cur_rec2"
16929
16930         echo "verifying users from this test are deregistered"
16931         changelog_deregister || error "changelog_deregister failed"
16932         changelog_users $SINGLEMDS | grep -q $cl_user &&
16933                 error "User '$cl_user' still in changelog_users"
16934
16935         # lctl get_param -n mdd.*.changelog_users
16936         # current_index: 144
16937         # ID    index (idle seconds)
16938         # cl3   144   (2) mask=<list>
16939         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16940                 # this is the normal case where all users were deregistered
16941                 # make sure no new records are added when no users are present
16942                 local last_rec1=$(changelog_users $SINGLEMDS |
16943                                   awk '/^current.index:/ { print $NF }')
16944                 touch $DIR/$tdir/chloe
16945                 local last_rec2=$(changelog_users $SINGLEMDS |
16946                                   awk '/^current.index:/ { print $NF }')
16947                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16948                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16949         else
16950                 # any changelog users must be leftovers from a previous test
16951                 changelog_users $SINGLEMDS
16952                 echo "other changelog users; can't verify off"
16953         fi
16954 }
16955 run_test 160a "changelog sanity"
16956
16957 test_160b() { # LU-3587
16958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16959         remote_mds_nodsh && skip "remote MDS with nodsh"
16960         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16961                 skip "Need MDS version at least 2.2.0"
16962
16963         changelog_register || error "changelog_register failed"
16964         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16965         changelog_users $SINGLEMDS | grep -q $cl_user ||
16966                 error "User '$cl_user' not found in changelog_users"
16967
16968         local longname1=$(str_repeat a 255)
16969         local longname2=$(str_repeat b 255)
16970
16971         cd $DIR
16972         echo "creating very long named file"
16973         touch $longname1 || error "create of '$longname1' failed"
16974         echo "renaming very long named file"
16975         mv $longname1 $longname2
16976
16977         changelog_dump | grep RENME | tail -n 5
16978         rm -f $longname2
16979 }
16980 run_test 160b "Verify that very long rename doesn't crash in changelog"
16981
16982 test_160c() {
16983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16984         remote_mds_nodsh && skip "remote MDS with nodsh"
16985
16986         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16987                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16988                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16989                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16990
16991         local rc=0
16992
16993         # Registration step
16994         changelog_register || error "changelog_register failed"
16995
16996         rm -rf $DIR/$tdir
16997         mkdir -p $DIR/$tdir
16998         $MCREATE $DIR/$tdir/foo_160c
16999         changelog_chmask "-TRUNC"
17000         $TRUNCATE $DIR/$tdir/foo_160c 200
17001         changelog_chmask "+TRUNC"
17002         $TRUNCATE $DIR/$tdir/foo_160c 199
17003         changelog_dump | tail -n 5
17004         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17005         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17006 }
17007 run_test 160c "verify that changelog log catch the truncate event"
17008
17009 test_160d() {
17010         remote_mds_nodsh && skip "remote MDS with nodsh"
17011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17013         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17014                 skip "Need MDS version at least 2.7.60"
17015
17016         # Registration step
17017         changelog_register || error "changelog_register failed"
17018
17019         mkdir -p $DIR/$tdir/migrate_dir
17020         changelog_clear 0 || error "changelog_clear failed"
17021
17022         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17023         changelog_dump | tail -n 5
17024         local migrates=$(changelog_dump | grep -c "MIGRT")
17025         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17026 }
17027 run_test 160d "verify that changelog log catch the migrate event"
17028
17029 test_160e() {
17030         remote_mds_nodsh && skip "remote MDS with nodsh"
17031
17032         # Create a user
17033         changelog_register || error "changelog_register failed"
17034
17035         local MDT0=$(facet_svc $SINGLEMDS)
17036         local rc
17037
17038         # No user (expect fail)
17039         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17040         rc=$?
17041         if [ $rc -eq 0 ]; then
17042                 error "Should fail without user"
17043         elif [ $rc -ne 4 ]; then
17044                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17045         fi
17046
17047         # Delete a future user (expect fail)
17048         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17049         rc=$?
17050         if [ $rc -eq 0 ]; then
17051                 error "Deleted non-existant user cl77"
17052         elif [ $rc -ne 2 ]; then
17053                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17054         fi
17055
17056         # Clear to a bad index (1 billion should be safe)
17057         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17058         rc=$?
17059
17060         if [ $rc -eq 0 ]; then
17061                 error "Successfully cleared to invalid CL index"
17062         elif [ $rc -ne 22 ]; then
17063                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17064         fi
17065 }
17066 run_test 160e "changelog negative testing (should return errors)"
17067
17068 test_160f() {
17069         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17070         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17071                 skip "Need MDS version at least 2.10.56"
17072
17073         local mdts=$(comma_list $(mdts_nodes))
17074
17075         # Create a user
17076         changelog_register || error "first changelog_register failed"
17077         changelog_register || error "second changelog_register failed"
17078         local cl_users
17079         declare -A cl_user1
17080         declare -A cl_user2
17081         local user_rec1
17082         local user_rec2
17083         local i
17084
17085         # generate some changelog records to accumulate on each MDT
17086         # use all_char because created files should be evenly distributed
17087         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17088                 error "test_mkdir $tdir failed"
17089         log "$(date +%s): creating first files"
17090         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17091                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17092                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17093         done
17094
17095         # check changelogs have been generated
17096         local start=$SECONDS
17097         local idle_time=$((MDSCOUNT * 5 + 5))
17098         local nbcl=$(changelog_dump | wc -l)
17099         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17100
17101         for param in "changelog_max_idle_time=$idle_time" \
17102                      "changelog_gc=1" \
17103                      "changelog_min_gc_interval=2" \
17104                      "changelog_min_free_cat_entries=3"; do
17105                 local MDT0=$(facet_svc $SINGLEMDS)
17106                 local var="${param%=*}"
17107                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17108
17109                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17110                 do_nodes $mdts $LCTL set_param mdd.*.$param
17111         done
17112
17113         # force cl_user2 to be idle (1st part), but also cancel the
17114         # cl_user1 records so that it is not evicted later in the test.
17115         local sleep1=$((idle_time / 2))
17116         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17117         sleep $sleep1
17118
17119         # simulate changelog catalog almost full
17120         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17121         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17122
17123         for i in $(seq $MDSCOUNT); do
17124                 cl_users=(${CL_USERS[mds$i]})
17125                 cl_user1[mds$i]="${cl_users[0]}"
17126                 cl_user2[mds$i]="${cl_users[1]}"
17127
17128                 [ -n "${cl_user1[mds$i]}" ] ||
17129                         error "mds$i: no user registered"
17130                 [ -n "${cl_user2[mds$i]}" ] ||
17131                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17132
17133                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17134                 [ -n "$user_rec1" ] ||
17135                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17136                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17137                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17138                 [ -n "$user_rec2" ] ||
17139                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17140                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17141                      "$user_rec1 + 2 == $user_rec2"
17142                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17143                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17144                               "$user_rec1 + 2, but is $user_rec2"
17145                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17146                 [ -n "$user_rec2" ] ||
17147                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17148                 [ $user_rec1 == $user_rec2 ] ||
17149                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17150                               "$user_rec1, but is $user_rec2"
17151         done
17152
17153         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17154         local sleep2=$((idle_time - (SECONDS - start) + 1))
17155         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17156         sleep $sleep2
17157
17158         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17159         # cl_user1 should be OK because it recently processed records.
17160         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17161         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17162                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17163                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17164         done
17165
17166         # ensure gc thread is done
17167         for i in $(mdts_nodes); do
17168                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17169                         error "$i: GC-thread not done"
17170         done
17171
17172         local first_rec
17173         for (( i = 1; i <= MDSCOUNT; i++ )); do
17174                 # check cl_user1 still registered
17175                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17176                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17177                 # check cl_user2 unregistered
17178                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17179                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17180
17181                 # check changelogs are present and starting at $user_rec1 + 1
17182                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17183                 [ -n "$user_rec1" ] ||
17184                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17185                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17186                             awk '{ print $1; exit; }')
17187
17188                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17189                 [ $((user_rec1 + 1)) == $first_rec ] ||
17190                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17191         done
17192 }
17193 run_test 160f "changelog garbage collect (timestamped users)"
17194
17195 test_160g() {
17196         remote_mds_nodsh && skip "remote MDS with nodsh"
17197         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17198                 skip "Need MDS version at least 2.14.55"
17199
17200         local mdts=$(comma_list $(mdts_nodes))
17201
17202         # Create a user
17203         changelog_register || error "first changelog_register failed"
17204         changelog_register || error "second changelog_register failed"
17205         local cl_users
17206         declare -A cl_user1
17207         declare -A cl_user2
17208         local user_rec1
17209         local user_rec2
17210         local i
17211
17212         # generate some changelog records to accumulate on each MDT
17213         # use all_char because created files should be evenly distributed
17214         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17215                 error "test_mkdir $tdir failed"
17216         for ((i = 0; i < MDSCOUNT; i++)); do
17217                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17218                         error "create $DIR/$tdir/d$i.1 failed"
17219         done
17220
17221         # check changelogs have been generated
17222         local nbcl=$(changelog_dump | wc -l)
17223         (( $nbcl > 0 )) || error "no changelogs found"
17224
17225         # reduce the max_idle_indexes value to make sure we exceed it
17226         for param in "changelog_max_idle_indexes=2" \
17227                      "changelog_gc=1" \
17228                      "changelog_min_gc_interval=2"; do
17229                 local MDT0=$(facet_svc $SINGLEMDS)
17230                 local var="${param%=*}"
17231                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17232
17233                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17234                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17235                         error "unable to set mdd.*.$param"
17236         done
17237
17238         local start=$SECONDS
17239         for i in $(seq $MDSCOUNT); do
17240                 cl_users=(${CL_USERS[mds$i]})
17241                 cl_user1[mds$i]="${cl_users[0]}"
17242                 cl_user2[mds$i]="${cl_users[1]}"
17243
17244                 [ -n "${cl_user1[mds$i]}" ] ||
17245                         error "mds$i: user1 is not registered"
17246                 [ -n "${cl_user2[mds$i]}" ] ||
17247                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17248
17249                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17250                 [ -n "$user_rec1" ] ||
17251                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17252                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17253                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17254                 [ -n "$user_rec2" ] ||
17255                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17256                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17257                      "$user_rec1 + 2 == $user_rec2"
17258                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17259                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17260                               "expected $user_rec1 + 2, but is $user_rec2"
17261                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17262                 [ -n "$user_rec2" ] ||
17263                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17264                 [ $user_rec1 == $user_rec2 ] ||
17265                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17266                               "expected $user_rec1, but is $user_rec2"
17267         done
17268
17269         # ensure we are past the previous changelog_min_gc_interval set above
17270         local sleep2=$((start + 2 - SECONDS))
17271         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17272         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17273         # cl_user1 should be OK because it recently processed records.
17274         for ((i = 0; i < MDSCOUNT; i++)); do
17275                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17276                         error "create $DIR/$tdir/d$i.3 failed"
17277         done
17278
17279         # ensure gc thread is done
17280         for i in $(mdts_nodes); do
17281                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17282                         error "$i: GC-thread not done"
17283         done
17284
17285         local first_rec
17286         for (( i = 1; i <= MDSCOUNT; i++ )); do
17287                 # check cl_user1 still registered
17288                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17289                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17290                 # check cl_user2 unregistered
17291                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17292                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17293
17294                 # check changelogs are present and starting at $user_rec1 + 1
17295                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17296                 [ -n "$user_rec1" ] ||
17297                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17298                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17299                             awk '{ print $1; exit; }')
17300
17301                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17302                 [ $((user_rec1 + 1)) == $first_rec ] ||
17303                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17304         done
17305 }
17306 run_test 160g "changelog garbage collect on idle records"
17307
17308 test_160h() {
17309         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17310         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17311                 skip "Need MDS version at least 2.10.56"
17312
17313         local mdts=$(comma_list $(mdts_nodes))
17314
17315         # Create a user
17316         changelog_register || error "first changelog_register failed"
17317         changelog_register || error "second changelog_register failed"
17318         local cl_users
17319         declare -A cl_user1
17320         declare -A cl_user2
17321         local user_rec1
17322         local user_rec2
17323         local i
17324
17325         # generate some changelog records to accumulate on each MDT
17326         # use all_char because created files should be evenly distributed
17327         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17328                 error "test_mkdir $tdir failed"
17329         for ((i = 0; i < MDSCOUNT; i++)); do
17330                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17331                         error "create $DIR/$tdir/d$i.1 failed"
17332         done
17333
17334         # check changelogs have been generated
17335         local nbcl=$(changelog_dump | wc -l)
17336         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17337
17338         for param in "changelog_max_idle_time=10" \
17339                      "changelog_gc=1" \
17340                      "changelog_min_gc_interval=2"; do
17341                 local MDT0=$(facet_svc $SINGLEMDS)
17342                 local var="${param%=*}"
17343                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17344
17345                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17346                 do_nodes $mdts $LCTL set_param mdd.*.$param
17347         done
17348
17349         # force cl_user2 to be idle (1st part)
17350         sleep 9
17351
17352         for i in $(seq $MDSCOUNT); do
17353                 cl_users=(${CL_USERS[mds$i]})
17354                 cl_user1[mds$i]="${cl_users[0]}"
17355                 cl_user2[mds$i]="${cl_users[1]}"
17356
17357                 [ -n "${cl_user1[mds$i]}" ] ||
17358                         error "mds$i: no user registered"
17359                 [ -n "${cl_user2[mds$i]}" ] ||
17360                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17361
17362                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17363                 [ -n "$user_rec1" ] ||
17364                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17365                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17366                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17367                 [ -n "$user_rec2" ] ||
17368                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17369                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17370                      "$user_rec1 + 2 == $user_rec2"
17371                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17372                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17373                               "$user_rec1 + 2, but is $user_rec2"
17374                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17375                 [ -n "$user_rec2" ] ||
17376                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17377                 [ $user_rec1 == $user_rec2 ] ||
17378                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17379                               "$user_rec1, but is $user_rec2"
17380         done
17381
17382         # force cl_user2 to be idle (2nd part) and to reach
17383         # changelog_max_idle_time
17384         sleep 2
17385
17386         # force each GC-thread start and block then
17387         # one per MDT/MDD, set fail_val accordingly
17388         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17389         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17390
17391         # generate more changelogs to trigger fail_loc
17392         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17393                 error "create $DIR/$tdir/${tfile}bis failed"
17394
17395         # stop MDT to stop GC-thread, should be done in back-ground as it will
17396         # block waiting for the thread to be released and exit
17397         declare -A stop_pids
17398         for i in $(seq $MDSCOUNT); do
17399                 stop mds$i &
17400                 stop_pids[mds$i]=$!
17401         done
17402
17403         for i in $(mdts_nodes); do
17404                 local facet
17405                 local nb=0
17406                 local facets=$(facets_up_on_host $i)
17407
17408                 for facet in ${facets//,/ }; do
17409                         if [[ $facet == mds* ]]; then
17410                                 nb=$((nb + 1))
17411                         fi
17412                 done
17413                 # ensure each MDS's gc threads are still present and all in "R"
17414                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17415                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17416                         error "$i: expected $nb GC-thread"
17417                 wait_update $i \
17418                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17419                         "R" 20 ||
17420                         error "$i: GC-thread not found in R-state"
17421                 # check umounts of each MDT on MDS have reached kthread_stop()
17422                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17423                         error "$i: expected $nb umount"
17424                 wait_update $i \
17425                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17426                         error "$i: umount not found in D-state"
17427         done
17428
17429         # release all GC-threads
17430         do_nodes $mdts $LCTL set_param fail_loc=0
17431
17432         # wait for MDT stop to complete
17433         for i in $(seq $MDSCOUNT); do
17434                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17435         done
17436
17437         # XXX
17438         # may try to check if any orphan changelog records are present
17439         # via ldiskfs/zfs and llog_reader...
17440
17441         # re-start/mount MDTs
17442         for i in $(seq $MDSCOUNT); do
17443                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17444                         error "Fail to start mds$i"
17445         done
17446
17447         local first_rec
17448         for i in $(seq $MDSCOUNT); do
17449                 # check cl_user1 still registered
17450                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17451                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17452                 # check cl_user2 unregistered
17453                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17454                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17455
17456                 # check changelogs are present and starting at $user_rec1 + 1
17457                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17458                 [ -n "$user_rec1" ] ||
17459                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17460                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17461                             awk '{ print $1; exit; }')
17462
17463                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17464                 [ $((user_rec1 + 1)) == $first_rec ] ||
17465                         error "mds$i: first index should be $user_rec1 + 1, " \
17466                               "but is $first_rec"
17467         done
17468 }
17469 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17470               "during mount"
17471
17472 test_160i() {
17473
17474         local mdts=$(comma_list $(mdts_nodes))
17475
17476         changelog_register || error "first changelog_register failed"
17477
17478         # generate some changelog records to accumulate on each MDT
17479         # use all_char because created files should be evenly distributed
17480         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17481                 error "test_mkdir $tdir failed"
17482         for ((i = 0; i < MDSCOUNT; i++)); do
17483                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17484                         error "create $DIR/$tdir/d$i.1 failed"
17485         done
17486
17487         # check changelogs have been generated
17488         local nbcl=$(changelog_dump | wc -l)
17489         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17490
17491         # simulate race between register and unregister
17492         # XXX as fail_loc is set per-MDS, with DNE configs the race
17493         # simulation will only occur for one MDT per MDS and for the
17494         # others the normal race scenario will take place
17495         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17496         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17497         do_nodes $mdts $LCTL set_param fail_val=1
17498
17499         # unregister 1st user
17500         changelog_deregister &
17501         local pid1=$!
17502         # wait some time for deregister work to reach race rdv
17503         sleep 2
17504         # register 2nd user
17505         changelog_register || error "2nd user register failed"
17506
17507         wait $pid1 || error "1st user deregister failed"
17508
17509         local i
17510         local last_rec
17511         declare -A LAST_REC
17512         for i in $(seq $MDSCOUNT); do
17513                 if changelog_users mds$i | grep "^cl"; then
17514                         # make sure new records are added with one user present
17515                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17516                                           awk '/^current.index:/ { print $NF }')
17517                 else
17518                         error "mds$i has no user registered"
17519                 fi
17520         done
17521
17522         # generate more changelog records to accumulate on each MDT
17523         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17524                 error "create $DIR/$tdir/${tfile}bis failed"
17525
17526         for i in $(seq $MDSCOUNT); do
17527                 last_rec=$(changelog_users $SINGLEMDS |
17528                            awk '/^current.index:/ { print $NF }')
17529                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17530                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17531                         error "changelogs are off on mds$i"
17532         done
17533 }
17534 run_test 160i "changelog user register/unregister race"
17535
17536 test_160j() {
17537         remote_mds_nodsh && skip "remote MDS with nodsh"
17538         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17539                 skip "Need MDS version at least 2.12.56"
17540
17541         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17542         stack_trap "umount $MOUNT2" EXIT
17543
17544         changelog_register || error "first changelog_register failed"
17545         stack_trap "changelog_deregister" EXIT
17546
17547         # generate some changelog
17548         # use all_char because created files should be evenly distributed
17549         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17550                 error "mkdir $tdir failed"
17551         for ((i = 0; i < MDSCOUNT; i++)); do
17552                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17553                         error "create $DIR/$tdir/d$i.1 failed"
17554         done
17555
17556         # open the changelog device
17557         exec 3>/dev/changelog-$FSNAME-MDT0000
17558         stack_trap "exec 3>&-" EXIT
17559         exec 4</dev/changelog-$FSNAME-MDT0000
17560         stack_trap "exec 4<&-" EXIT
17561
17562         # umount the first lustre mount
17563         umount $MOUNT
17564         stack_trap "mount_client $MOUNT" EXIT
17565
17566         # read changelog, which may or may not fail, but should not crash
17567         cat <&4 >/dev/null
17568
17569         # clear changelog
17570         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17571         changelog_users $SINGLEMDS | grep -q $cl_user ||
17572                 error "User $cl_user not found in changelog_users"
17573
17574         printf 'clear:'$cl_user':0' >&3
17575 }
17576 run_test 160j "client can be umounted while its chanangelog is being used"
17577
17578 test_160k() {
17579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17580         remote_mds_nodsh && skip "remote MDS with nodsh"
17581
17582         mkdir -p $DIR/$tdir/1/1
17583
17584         changelog_register || error "changelog_register failed"
17585         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17586
17587         changelog_users $SINGLEMDS | grep -q $cl_user ||
17588                 error "User '$cl_user' not found in changelog_users"
17589 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17590         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17591         rmdir $DIR/$tdir/1/1 & sleep 1
17592         mkdir $DIR/$tdir/2
17593         touch $DIR/$tdir/2/2
17594         rm -rf $DIR/$tdir/2
17595
17596         wait
17597         sleep 4
17598
17599         changelog_dump | grep rmdir || error "rmdir not recorded"
17600 }
17601 run_test 160k "Verify that changelog records are not lost"
17602
17603 # Verifies that a file passed as a parameter has recently had an operation
17604 # performed on it that has generated an MTIME changelog which contains the
17605 # correct parent FID. As files might reside on a different MDT from the
17606 # parent directory in DNE configurations, the FIDs are translated to paths
17607 # before being compared, which should be identical
17608 compare_mtime_changelog() {
17609         local file="${1}"
17610         local mdtidx
17611         local mtime
17612         local cl_fid
17613         local pdir
17614         local dir
17615
17616         mdtidx=$($LFS getstripe --mdt-index $file)
17617         mdtidx=$(printf "%04x" $mdtidx)
17618
17619         # Obtain the parent FID from the MTIME changelog
17620         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17621         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17622
17623         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17624         [ -z "$cl_fid" ] && error "parent FID not present"
17625
17626         # Verify that the path for the parent FID is the same as the path for
17627         # the test directory
17628         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17629
17630         dir=$(dirname $1)
17631
17632         [[ "${pdir%/}" == "$dir" ]] ||
17633                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17634 }
17635
17636 test_160l() {
17637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17638
17639         remote_mds_nodsh && skip "remote MDS with nodsh"
17640         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17641                 skip "Need MDS version at least 2.13.55"
17642
17643         local cl_user
17644
17645         changelog_register || error "changelog_register failed"
17646         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17647
17648         changelog_users $SINGLEMDS | grep -q $cl_user ||
17649                 error "User '$cl_user' not found in changelog_users"
17650
17651         # Clear some types so that MTIME changelogs are generated
17652         changelog_chmask "-CREAT"
17653         changelog_chmask "-CLOSE"
17654
17655         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17656
17657         # Test CL_MTIME during setattr
17658         touch $DIR/$tdir/$tfile
17659         compare_mtime_changelog $DIR/$tdir/$tfile
17660
17661         # Test CL_MTIME during close
17662         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17663         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17664 }
17665 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17666
17667 test_160m() {
17668         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17669         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17670                 skip "Need MDS version at least 2.14.51"
17671         local cl_users
17672         local cl_user1
17673         local cl_user2
17674         local pid1
17675
17676         # Create a user
17677         changelog_register || error "first changelog_register failed"
17678         changelog_register || error "second changelog_register failed"
17679
17680         cl_users=(${CL_USERS[mds1]})
17681         cl_user1="${cl_users[0]}"
17682         cl_user2="${cl_users[1]}"
17683         # generate some changelog records to accumulate on MDT0
17684         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17685         createmany -m $DIR/$tdir/$tfile 50 ||
17686                 error "create $DIR/$tdir/$tfile failed"
17687         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17688         rm -f $DIR/$tdir
17689
17690         # check changelogs have been generated
17691         local nbcl=$(changelog_dump | wc -l)
17692         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17693
17694 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17695         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17696
17697         __changelog_clear mds1 $cl_user1 +10
17698         __changelog_clear mds1 $cl_user2 0 &
17699         pid1=$!
17700         sleep 2
17701         __changelog_clear mds1 $cl_user1 0 ||
17702                 error "fail to cancel record for $cl_user1"
17703         wait $pid1
17704         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17705 }
17706 run_test 160m "Changelog clear race"
17707
17708 test_160n() {
17709         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17710         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17711                 skip "Need MDS version at least 2.14.51"
17712         local cl_users
17713         local cl_user1
17714         local cl_user2
17715         local pid1
17716         local first_rec
17717         local last_rec=0
17718
17719         # Create a user
17720         changelog_register || error "first changelog_register failed"
17721
17722         cl_users=(${CL_USERS[mds1]})
17723         cl_user1="${cl_users[0]}"
17724
17725         # generate some changelog records to accumulate on MDT0
17726         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17727         first_rec=$(changelog_users $SINGLEMDS |
17728                         awk '/^current.index:/ { print $NF }')
17729         while (( last_rec < (( first_rec + 65000)) )); do
17730                 createmany -m $DIR/$tdir/$tfile 10000 ||
17731                         error "create $DIR/$tdir/$tfile failed"
17732
17733                 for i in $(seq 0 10000); do
17734                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17735                                 > /dev/null
17736                 done
17737
17738                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17739                         error "unlinkmany failed unlink"
17740                 last_rec=$(changelog_users $SINGLEMDS |
17741                         awk '/^current.index:/ { print $NF }')
17742                 echo last record $last_rec
17743                 (( last_rec == 0 )) && error "no changelog found"
17744         done
17745
17746 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17747         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17748
17749         __changelog_clear mds1 $cl_user1 0 &
17750         pid1=$!
17751         sleep 2
17752         __changelog_clear mds1 $cl_user1 0 ||
17753                 error "fail to cancel record for $cl_user1"
17754         wait $pid1
17755         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17756 }
17757 run_test 160n "Changelog destroy race"
17758
17759 test_160o() {
17760         local mdt="$(facet_svc $SINGLEMDS)"
17761
17762         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17763         remote_mds_nodsh && skip "remote MDS with nodsh"
17764         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17765                 skip "Need MDS version at least 2.14.52"
17766
17767         changelog_register --user test_160o -m unlnk+close+open ||
17768                 error "changelog_register failed"
17769
17770         do_facet $SINGLEMDS $LCTL --device $mdt \
17771                                 changelog_register -u "Tt3_-#" &&
17772                 error "bad symbols in name should fail"
17773
17774         do_facet $SINGLEMDS $LCTL --device $mdt \
17775                                 changelog_register -u test_160o &&
17776                 error "the same name registration should fail"
17777
17778         do_facet $SINGLEMDS $LCTL --device $mdt \
17779                         changelog_register -u test_160toolongname &&
17780                 error "too long name registration should fail"
17781
17782         changelog_chmask "MARK+HSM"
17783         lctl get_param mdd.*.changelog*mask
17784         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17785         changelog_users $SINGLEMDS | grep -q $cl_user ||
17786                 error "User $cl_user not found in changelog_users"
17787         #verify username
17788         echo $cl_user | grep -q test_160o ||
17789                 error "User $cl_user has no specific name 'test160o'"
17790
17791         # change something
17792         changelog_clear 0 || error "changelog_clear failed"
17793         # generate some changelog records to accumulate on MDT0
17794         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17795         touch $DIR/$tdir/$tfile                 # open 1
17796
17797         OPENS=$(changelog_dump | grep -c "OPEN")
17798         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17799
17800         # must be no MKDIR it wasn't set as user mask
17801         MKDIR=$(changelog_dump | grep -c "MKDIR")
17802         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17803
17804         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17805                                 mdd.$mdt.changelog_current_mask -n)
17806         # register maskless user
17807         changelog_register || error "changelog_register failed"
17808         # effective mask should be not changed because it is not minimal
17809         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17810                                 mdd.$mdt.changelog_current_mask -n)
17811         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17812         # set server mask to minimal value
17813         changelog_chmask "MARK"
17814         # check effective mask again, should be treated as DEFMASK now
17815         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17816                                 mdd.$mdt.changelog_current_mask -n)
17817         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17818
17819         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17820                 # set server mask back to some value
17821                 changelog_chmask "CLOSE,UNLNK"
17822                 # check effective mask again, should not remain as DEFMASK
17823                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17824                                 mdd.$mdt.changelog_current_mask -n)
17825                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17826         fi
17827
17828         do_facet $SINGLEMDS $LCTL --device $mdt \
17829                                 changelog_deregister -u test_160o ||
17830                 error "cannot deregister by name"
17831 }
17832 run_test 160o "changelog user name and mask"
17833
17834 test_160p() {
17835         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17836         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17837                 skip "Need MDS version at least 2.14.51"
17838         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17839         local cl_users
17840         local cl_user1
17841         local entry_count
17842
17843         # Create a user
17844         changelog_register || error "first changelog_register failed"
17845
17846         cl_users=(${CL_USERS[mds1]})
17847         cl_user1="${cl_users[0]}"
17848
17849         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17850         createmany -m $DIR/$tdir/$tfile 50 ||
17851                 error "create $DIR/$tdir/$tfile failed"
17852         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17853         rm -rf $DIR/$tdir
17854
17855         # check changelogs have been generated
17856         entry_count=$(changelog_dump | wc -l)
17857         ((entry_count != 0)) || error "no changelog entries found"
17858
17859         # remove changelog_users and check that orphan entries are removed
17860         stop mds1
17861         local dev=$(mdsdevname 1)
17862         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17863         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17864         entry_count=$(changelog_dump | wc -l)
17865         ((entry_count == 0)) ||
17866                 error "found $entry_count changelog entries, expected none"
17867 }
17868 run_test 160p "Changelog orphan cleanup with no users"
17869
17870 test_160q() {
17871         local mdt="$(facet_svc $SINGLEMDS)"
17872         local clu
17873
17874         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17875         remote_mds_nodsh && skip "remote MDS with nodsh"
17876         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17877                 skip "Need MDS version at least 2.14.54"
17878
17879         # set server mask to minimal value like server init does
17880         changelog_chmask "MARK"
17881         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17882                 error "changelog_register failed"
17883         # check effective mask again, should be treated as DEFMASK now
17884         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17885                                 mdd.$mdt.changelog_current_mask -n)
17886         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17887                 error "changelog_deregister failed"
17888         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17889 }
17890 run_test 160q "changelog effective mask is DEFMASK if not set"
17891
17892 test_160s() {
17893         remote_mds_nodsh && skip "remote MDS with nodsh"
17894         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17895                 skip "Need MDS version at least 2.14.55"
17896
17897         local mdts=$(comma_list $(mdts_nodes))
17898
17899         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17900         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17901                                        fail_val=$((24 * 3600 * 10))
17902
17903         # Create a user which is 10 days old
17904         changelog_register || error "first changelog_register failed"
17905         local cl_users
17906         declare -A cl_user1
17907         local i
17908
17909         # generate some changelog records to accumulate on each MDT
17910         # use all_char because created files should be evenly distributed
17911         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17912                 error "test_mkdir $tdir failed"
17913         for ((i = 0; i < MDSCOUNT; i++)); do
17914                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17915                         error "create $DIR/$tdir/d$i.1 failed"
17916         done
17917
17918         # check changelogs have been generated
17919         local nbcl=$(changelog_dump | wc -l)
17920         (( nbcl > 0 )) || error "no changelogs found"
17921
17922         # reduce the max_idle_indexes value to make sure we exceed it
17923         for param in "changelog_max_idle_indexes=2097446912" \
17924                      "changelog_max_idle_time=2592000" \
17925                      "changelog_gc=1" \
17926                      "changelog_min_gc_interval=2"; do
17927                 local MDT0=$(facet_svc $SINGLEMDS)
17928                 local var="${param%=*}"
17929                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17930
17931                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17932                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17933                         error "unable to set mdd.*.$param"
17934         done
17935
17936         local start=$SECONDS
17937         for i in $(seq $MDSCOUNT); do
17938                 cl_users=(${CL_USERS[mds$i]})
17939                 cl_user1[mds$i]="${cl_users[0]}"
17940
17941                 [[ -n "${cl_user1[mds$i]}" ]] ||
17942                         error "mds$i: no user registered"
17943         done
17944
17945         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17946         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17947
17948         # ensure we are past the previous changelog_min_gc_interval set above
17949         local sleep2=$((start + 2 - SECONDS))
17950         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17951
17952         # Generate one more changelog to trigger GC
17953         for ((i = 0; i < MDSCOUNT; i++)); do
17954                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17955                         error "create $DIR/$tdir/d$i.3 failed"
17956         done
17957
17958         # ensure gc thread is done
17959         for node in $(mdts_nodes); do
17960                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17961                         error "$node: GC-thread not done"
17962         done
17963
17964         do_nodes $mdts $LCTL set_param fail_loc=0
17965
17966         for (( i = 1; i <= MDSCOUNT; i++ )); do
17967                 # check cl_user1 is purged
17968                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17969                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17970         done
17971         return 0
17972 }
17973 run_test 160s "changelog garbage collect on idle records * time"
17974
17975 test_160t() {
17976         remote_mds_nodsh && skip "remote MDS with nodsh"
17977         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17978                 skip "Need MDS version at least 2.15.50"
17979
17980         local MDT0=$(facet_svc $SINGLEMDS)
17981         local cl_users
17982         local cl_user1
17983         local cl_user2
17984         local start
17985
17986         changelog_register --user user1 -m all ||
17987                 error "user1 failed to register"
17988
17989         mkdir_on_mdt0 $DIR/$tdir
17990         # create default overstripe to maximize changelog size
17991         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17992         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17993         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17994
17995         # user2 consumes less records so less space
17996         changelog_register --user user2 || error "user2 failed to register"
17997         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17998         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17999
18000         # check changelogs have been generated
18001         local nbcl=$(changelog_dump | wc -l)
18002         (( nbcl > 0 )) || error "no changelogs found"
18003
18004         # reduce the changelog_min_gc_interval to force check
18005         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18006                 local var="${param%=*}"
18007                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18008
18009                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18010                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18011                         error "unable to set mdd.*.$param"
18012         done
18013
18014         start=$SECONDS
18015         cl_users=(${CL_USERS[mds1]})
18016         cl_user1="${cl_users[0]}"
18017         cl_user2="${cl_users[1]}"
18018
18019         [[ -n $cl_user1 ]] ||
18020                 error "mds1: user #1 isn't registered"
18021         [[ -n $cl_user2 ]] ||
18022                 error "mds1: user #2 isn't registered"
18023
18024         # ensure we are past the previous changelog_min_gc_interval set above
18025         local sleep2=$((start + 2 - SECONDS))
18026         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18027
18028         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18029         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18030                         fail_val=$(((llog_size1 + llog_size2) / 2))
18031
18032         # Generate more changelog to trigger GC
18033         createmany -o $DIR/$tdir/u3_ 4 ||
18034                 error "create failed for more files"
18035
18036         # ensure gc thread is done
18037         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18038                 error "mds1: GC-thread not done"
18039
18040         do_facet mds1 $LCTL set_param fail_loc=0
18041
18042         # check cl_user1 is purged
18043         changelog_users mds1 | grep -q "$cl_user1" &&
18044                 error "User $cl_user1 is registered"
18045         # check cl_user2 is not purged
18046         changelog_users mds1 | grep -q "$cl_user2" ||
18047                 error "User $cl_user2 is not registered"
18048 }
18049 run_test 160t "changelog garbage collect on lack of space"
18050
18051 test_161a() {
18052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18053
18054         test_mkdir -c1 $DIR/$tdir
18055         cp /etc/hosts $DIR/$tdir/$tfile
18056         test_mkdir -c1 $DIR/$tdir/foo1
18057         test_mkdir -c1 $DIR/$tdir/foo2
18058         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18059         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18060         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18061         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18062         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18063         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18064                 $LFS fid2path $DIR $FID
18065                 error "bad link ea"
18066         fi
18067         # middle
18068         rm $DIR/$tdir/foo2/zachary
18069         # last
18070         rm $DIR/$tdir/foo2/thor
18071         # first
18072         rm $DIR/$tdir/$tfile
18073         # rename
18074         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18075         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18076                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18077         rm $DIR/$tdir/foo2/maggie
18078
18079         # overflow the EA
18080         local longname=$tfile.avg_len_is_thirty_two_
18081         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18082                 error_noexit 'failed to unlink many hardlinks'" EXIT
18083         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18084                 error "failed to hardlink many files"
18085         links=$($LFS fid2path $DIR $FID | wc -l)
18086         echo -n "${links}/1000 links in link EA"
18087         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18088 }
18089 run_test 161a "link ea sanity"
18090
18091 test_161b() {
18092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18093         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18094
18095         local MDTIDX=1
18096         local remote_dir=$DIR/$tdir/remote_dir
18097
18098         mkdir -p $DIR/$tdir
18099         $LFS mkdir -i $MDTIDX $remote_dir ||
18100                 error "create remote directory failed"
18101
18102         cp /etc/hosts $remote_dir/$tfile
18103         mkdir -p $remote_dir/foo1
18104         mkdir -p $remote_dir/foo2
18105         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18106         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18107         ln $remote_dir/$tfile $remote_dir/foo1/luna
18108         ln $remote_dir/$tfile $remote_dir/foo2/thor
18109
18110         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18111                      tr -d ']')
18112         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18113                 $LFS fid2path $DIR $FID
18114                 error "bad link ea"
18115         fi
18116         # middle
18117         rm $remote_dir/foo2/zachary
18118         # last
18119         rm $remote_dir/foo2/thor
18120         # first
18121         rm $remote_dir/$tfile
18122         # rename
18123         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18124         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18125         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18126                 $LFS fid2path $DIR $FID
18127                 error "bad link rename"
18128         fi
18129         rm $remote_dir/foo2/maggie
18130
18131         # overflow the EA
18132         local longname=filename_avg_len_is_thirty_two_
18133         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18134                 error "failed to hardlink many files"
18135         links=$($LFS fid2path $DIR $FID | wc -l)
18136         echo -n "${links}/1000 links in link EA"
18137         [[ ${links} -gt 60 ]] ||
18138                 error "expected at least 60 links in link EA"
18139         unlinkmany $remote_dir/foo2/$longname 1000 ||
18140         error "failed to unlink many hardlinks"
18141 }
18142 run_test 161b "link ea sanity under remote directory"
18143
18144 test_161c() {
18145         remote_mds_nodsh && skip "remote MDS with nodsh"
18146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18147         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18148                 skip "Need MDS version at least 2.1.5"
18149
18150         # define CLF_RENAME_LAST 0x0001
18151         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18152         changelog_register || error "changelog_register failed"
18153
18154         rm -rf $DIR/$tdir
18155         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18156         touch $DIR/$tdir/foo_161c
18157         touch $DIR/$tdir/bar_161c
18158         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18159         changelog_dump | grep RENME | tail -n 5
18160         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18161         changelog_clear 0 || error "changelog_clear failed"
18162         if [ x$flags != "x0x1" ]; then
18163                 error "flag $flags is not 0x1"
18164         fi
18165
18166         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18167         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18168         touch $DIR/$tdir/foo_161c
18169         touch $DIR/$tdir/bar_161c
18170         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18171         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18172         changelog_dump | grep RENME | tail -n 5
18173         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18174         changelog_clear 0 || error "changelog_clear failed"
18175         if [ x$flags != "x0x0" ]; then
18176                 error "flag $flags is not 0x0"
18177         fi
18178         echo "rename overwrite a target having nlink > 1," \
18179                 "changelog record has flags of $flags"
18180
18181         # rename doesn't overwrite a target (changelog flag 0x0)
18182         touch $DIR/$tdir/foo_161c
18183         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18184         changelog_dump | grep RENME | tail -n 5
18185         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18186         changelog_clear 0 || error "changelog_clear failed"
18187         if [ x$flags != "x0x0" ]; then
18188                 error "flag $flags is not 0x0"
18189         fi
18190         echo "rename doesn't overwrite a target," \
18191                 "changelog record has flags of $flags"
18192
18193         # define CLF_UNLINK_LAST 0x0001
18194         # unlink a file having nlink = 1 (changelog flag 0x1)
18195         rm -f $DIR/$tdir/foo2_161c
18196         changelog_dump | grep UNLNK | tail -n 5
18197         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18198         changelog_clear 0 || error "changelog_clear failed"
18199         if [ x$flags != "x0x1" ]; then
18200                 error "flag $flags is not 0x1"
18201         fi
18202         echo "unlink a file having nlink = 1," \
18203                 "changelog record has flags of $flags"
18204
18205         # unlink a file having nlink > 1 (changelog flag 0x0)
18206         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18207         rm -f $DIR/$tdir/foobar_161c
18208         changelog_dump | grep UNLNK | tail -n 5
18209         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18210         changelog_clear 0 || error "changelog_clear failed"
18211         if [ x$flags != "x0x0" ]; then
18212                 error "flag $flags is not 0x0"
18213         fi
18214         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18215 }
18216 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18217
18218 test_161d() {
18219         remote_mds_nodsh && skip "remote MDS with nodsh"
18220         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18221
18222         local pid
18223         local fid
18224
18225         changelog_register || error "changelog_register failed"
18226
18227         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18228         # interfer with $MOUNT/.lustre/fid/ access
18229         mkdir $DIR/$tdir
18230         [[ $? -eq 0 ]] || error "mkdir failed"
18231
18232         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18233         $LCTL set_param fail_loc=0x8000140c
18234         # 5s pause
18235         $LCTL set_param fail_val=5
18236
18237         # create file
18238         echo foofoo > $DIR/$tdir/$tfile &
18239         pid=$!
18240
18241         # wait for create to be delayed
18242         sleep 2
18243
18244         ps -p $pid
18245         [[ $? -eq 0 ]] || error "create should be blocked"
18246
18247         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18248         stack_trap "rm -f $tempfile"
18249         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18250         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18251         # some delay may occur during ChangeLog publishing and file read just
18252         # above, that could allow file write to happen finally
18253         [[ -s $tempfile ]] && echo "file should be empty"
18254
18255         $LCTL set_param fail_loc=0
18256
18257         wait $pid
18258         [[ $? -eq 0 ]] || error "create failed"
18259 }
18260 run_test 161d "create with concurrent .lustre/fid access"
18261
18262 check_path() {
18263         local expected="$1"
18264         shift
18265         local fid="$2"
18266
18267         local path
18268         path=$($LFS fid2path "$@")
18269         local rc=$?
18270
18271         if [ $rc -ne 0 ]; then
18272                 error "path looked up of '$expected' failed: rc=$rc"
18273         elif [ "$path" != "$expected" ]; then
18274                 error "path looked up '$path' instead of '$expected'"
18275         else
18276                 echo "FID '$fid' resolves to path '$path' as expected"
18277         fi
18278 }
18279
18280 test_162a() { # was test_162
18281         test_mkdir -p -c1 $DIR/$tdir/d2
18282         touch $DIR/$tdir/d2/$tfile
18283         touch $DIR/$tdir/d2/x1
18284         touch $DIR/$tdir/d2/x2
18285         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18286         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18287         # regular file
18288         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18289         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18290
18291         # softlink
18292         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18293         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18294         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18295
18296         # softlink to wrong file
18297         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18298         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18299         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18300
18301         # hardlink
18302         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18303         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18304         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18305         # fid2path dir/fsname should both work
18306         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18307         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18308
18309         # hardlink count: check that there are 2 links
18310         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18311         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18312
18313         # hardlink indexing: remove the first link
18314         rm $DIR/$tdir/d2/p/q/r/hlink
18315         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18316 }
18317 run_test 162a "path lookup sanity"
18318
18319 test_162b() {
18320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18321         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18322
18323         mkdir $DIR/$tdir
18324         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18325                                 error "create striped dir failed"
18326
18327         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18328                                         tail -n 1 | awk '{print $2}')
18329         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18330
18331         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18332         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18333
18334         # regular file
18335         for ((i=0;i<5;i++)); do
18336                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18337                         error "get fid for f$i failed"
18338                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18339
18340                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18341                         error "get fid for d$i failed"
18342                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18343         done
18344
18345         return 0
18346 }
18347 run_test 162b "striped directory path lookup sanity"
18348
18349 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18350 test_162c() {
18351         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18352                 skip "Need MDS version at least 2.7.51"
18353
18354         local lpath=$tdir.local
18355         local rpath=$tdir.remote
18356
18357         test_mkdir $DIR/$lpath
18358         test_mkdir $DIR/$rpath
18359
18360         for ((i = 0; i <= 101; i++)); do
18361                 lpath="$lpath/$i"
18362                 mkdir $DIR/$lpath
18363                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18364                         error "get fid for local directory $DIR/$lpath failed"
18365                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18366
18367                 rpath="$rpath/$i"
18368                 test_mkdir $DIR/$rpath
18369                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18370                         error "get fid for remote directory $DIR/$rpath failed"
18371                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18372         done
18373
18374         return 0
18375 }
18376 run_test 162c "fid2path works with paths 100 or more directories deep"
18377
18378 oalr_event_count() {
18379         local event="${1}"
18380         local trace="${2}"
18381
18382         awk -v name="${FSNAME}-OST0000" \
18383             -v event="${event}" \
18384             '$1 == "TRACE" && $2 == event && $3 == name' \
18385             "${trace}" |
18386         wc -l
18387 }
18388
18389 oalr_expect_event_count() {
18390         local event="${1}"
18391         local trace="${2}"
18392         local expect="${3}"
18393         local count
18394
18395         count=$(oalr_event_count "${event}" "${trace}")
18396         if ((count == expect)); then
18397                 return 0
18398         fi
18399
18400         error_noexit "${event} event count was '${count}', expected ${expect}"
18401         cat "${trace}" >&2
18402         exit 1
18403 }
18404
18405 cleanup_165() {
18406         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18407         stop ost1
18408         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18409 }
18410
18411 setup_165() {
18412         sync # Flush previous IOs so we can count log entries.
18413         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18414         stack_trap cleanup_165 EXIT
18415 }
18416
18417 test_165a() {
18418         local trace="/tmp/${tfile}.trace"
18419         local rc
18420         local count
18421
18422         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18423                 skip "OFD access log unsupported"
18424
18425         setup_165
18426         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18427         sleep 5
18428
18429         do_facet ost1 ofd_access_log_reader --list
18430         stop ost1
18431
18432         do_facet ost1 killall -TERM ofd_access_log_reader
18433         wait
18434         rc=$?
18435
18436         if ((rc != 0)); then
18437                 error "ofd_access_log_reader exited with rc = '${rc}'"
18438         fi
18439
18440         # Parse trace file for discovery events:
18441         oalr_expect_event_count alr_log_add "${trace}" 1
18442         oalr_expect_event_count alr_log_eof "${trace}" 1
18443         oalr_expect_event_count alr_log_free "${trace}" 1
18444 }
18445 run_test 165a "ofd access log discovery"
18446
18447 test_165b() {
18448         local trace="/tmp/${tfile}.trace"
18449         local file="${DIR}/${tfile}"
18450         local pfid1
18451         local pfid2
18452         local -a entry
18453         local rc
18454         local count
18455         local size
18456         local flags
18457
18458         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18459                 skip "OFD access log unsupported"
18460
18461         setup_165
18462         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18463         sleep 5
18464
18465         do_facet ost1 ofd_access_log_reader --list
18466
18467         lfs setstripe -c 1 -i 0 "${file}"
18468         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18469                 error "cannot create '${file}'"
18470
18471         sleep 5
18472         do_facet ost1 killall -TERM ofd_access_log_reader
18473         wait
18474         rc=$?
18475
18476         if ((rc != 0)); then
18477                 error "ofd_access_log_reader exited with rc = '${rc}'"
18478         fi
18479
18480         oalr_expect_event_count alr_log_entry "${trace}" 1
18481
18482         pfid1=$($LFS path2fid "${file}")
18483
18484         # 1     2             3   4    5     6   7    8    9     10
18485         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18486         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18487
18488         echo "entry = '${entry[*]}'" >&2
18489
18490         pfid2=${entry[4]}
18491         if [[ "${pfid1}" != "${pfid2}" ]]; then
18492                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18493         fi
18494
18495         size=${entry[8]}
18496         if ((size != 1048576)); then
18497                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18498         fi
18499
18500         flags=${entry[10]}
18501         if [[ "${flags}" != "w" ]]; then
18502                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18503         fi
18504
18505         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18506         sleep 5
18507
18508         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18509                 error "cannot read '${file}'"
18510         sleep 5
18511
18512         do_facet ost1 killall -TERM ofd_access_log_reader
18513         wait
18514         rc=$?
18515
18516         if ((rc != 0)); then
18517                 error "ofd_access_log_reader exited with rc = '${rc}'"
18518         fi
18519
18520         oalr_expect_event_count alr_log_entry "${trace}" 1
18521
18522         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18523         echo "entry = '${entry[*]}'" >&2
18524
18525         pfid2=${entry[4]}
18526         if [[ "${pfid1}" != "${pfid2}" ]]; then
18527                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18528         fi
18529
18530         size=${entry[8]}
18531         if ((size != 524288)); then
18532                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18533         fi
18534
18535         flags=${entry[10]}
18536         if [[ "${flags}" != "r" ]]; then
18537                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18538         fi
18539 }
18540 run_test 165b "ofd access log entries are produced and consumed"
18541
18542 test_165c() {
18543         local trace="/tmp/${tfile}.trace"
18544         local file="${DIR}/${tdir}/${tfile}"
18545
18546         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18547                 skip "OFD access log unsupported"
18548
18549         test_mkdir "${DIR}/${tdir}"
18550
18551         setup_165
18552         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18553         sleep 5
18554
18555         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18556
18557         # 4096 / 64 = 64. Create twice as many entries.
18558         for ((i = 0; i < 128; i++)); do
18559                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18560                         error "cannot create file"
18561         done
18562
18563         sync
18564
18565         do_facet ost1 killall -TERM ofd_access_log_reader
18566         wait
18567         rc=$?
18568         if ((rc != 0)); then
18569                 error "ofd_access_log_reader exited with rc = '${rc}'"
18570         fi
18571
18572         unlinkmany  "${file}-%d" 128
18573 }
18574 run_test 165c "full ofd access logs do not block IOs"
18575
18576 oal_get_read_count() {
18577         local stats="$1"
18578
18579         # STATS lustre-OST0001 alr_read_count 1
18580
18581         do_facet ost1 cat "${stats}" |
18582         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18583              END { print count; }'
18584 }
18585
18586 oal_expect_read_count() {
18587         local stats="$1"
18588         local count
18589         local expect="$2"
18590
18591         # Ask ofd_access_log_reader to write stats.
18592         do_facet ost1 killall -USR1 ofd_access_log_reader
18593
18594         # Allow some time for things to happen.
18595         sleep 1
18596
18597         count=$(oal_get_read_count "${stats}")
18598         if ((count == expect)); then
18599                 return 0
18600         fi
18601
18602         error_noexit "bad read count, got ${count}, expected ${expect}"
18603         do_facet ost1 cat "${stats}" >&2
18604         exit 1
18605 }
18606
18607 test_165d() {
18608         local stats="/tmp/${tfile}.stats"
18609         local file="${DIR}/${tdir}/${tfile}"
18610         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18611
18612         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18613                 skip "OFD access log unsupported"
18614
18615         test_mkdir "${DIR}/${tdir}"
18616
18617         setup_165
18618         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18619         sleep 5
18620
18621         lfs setstripe -c 1 -i 0 "${file}"
18622
18623         do_facet ost1 lctl set_param "${param}=rw"
18624         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18625                 error "cannot create '${file}'"
18626         oal_expect_read_count "${stats}" 1
18627
18628         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18629                 error "cannot read '${file}'"
18630         oal_expect_read_count "${stats}" 2
18631
18632         do_facet ost1 lctl set_param "${param}=r"
18633         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18634                 error "cannot create '${file}'"
18635         oal_expect_read_count "${stats}" 2
18636
18637         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18638                 error "cannot read '${file}'"
18639         oal_expect_read_count "${stats}" 3
18640
18641         do_facet ost1 lctl set_param "${param}=w"
18642         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18643                 error "cannot create '${file}'"
18644         oal_expect_read_count "${stats}" 4
18645
18646         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18647                 error "cannot read '${file}'"
18648         oal_expect_read_count "${stats}" 4
18649
18650         do_facet ost1 lctl set_param "${param}=0"
18651         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18652                 error "cannot create '${file}'"
18653         oal_expect_read_count "${stats}" 4
18654
18655         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18656                 error "cannot read '${file}'"
18657         oal_expect_read_count "${stats}" 4
18658
18659         do_facet ost1 killall -TERM ofd_access_log_reader
18660         wait
18661         rc=$?
18662         if ((rc != 0)); then
18663                 error "ofd_access_log_reader exited with rc = '${rc}'"
18664         fi
18665 }
18666 run_test 165d "ofd_access_log mask works"
18667
18668 test_165e() {
18669         local stats="/tmp/${tfile}.stats"
18670         local file0="${DIR}/${tdir}-0/${tfile}"
18671         local file1="${DIR}/${tdir}-1/${tfile}"
18672
18673         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18674                 skip "OFD access log unsupported"
18675
18676         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18677
18678         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18679         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18680
18681         lfs setstripe -c 1 -i 0 "${file0}"
18682         lfs setstripe -c 1 -i 0 "${file1}"
18683
18684         setup_165
18685         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18686         sleep 5
18687
18688         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18689                 error "cannot create '${file0}'"
18690         sync
18691         oal_expect_read_count "${stats}" 0
18692
18693         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18694                 error "cannot create '${file1}'"
18695         sync
18696         oal_expect_read_count "${stats}" 1
18697
18698         do_facet ost1 killall -TERM ofd_access_log_reader
18699         wait
18700         rc=$?
18701         if ((rc != 0)); then
18702                 error "ofd_access_log_reader exited with rc = '${rc}'"
18703         fi
18704 }
18705 run_test 165e "ofd_access_log MDT index filter works"
18706
18707 test_165f() {
18708         local trace="/tmp/${tfile}.trace"
18709         local rc
18710         local count
18711
18712         setup_165
18713         do_facet ost1 timeout 60 ofd_access_log_reader \
18714                 --exit-on-close --debug=- --trace=- > "${trace}" &
18715         sleep 5
18716         stop ost1
18717
18718         wait
18719         rc=$?
18720
18721         if ((rc != 0)); then
18722                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18723                 cat "${trace}"
18724                 exit 1
18725         fi
18726 }
18727 run_test 165f "ofd_access_log_reader --exit-on-close works"
18728
18729 test_169() {
18730         # do directio so as not to populate the page cache
18731         log "creating a 10 Mb file"
18732         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18733                 error "multiop failed while creating a file"
18734         log "starting reads"
18735         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18736         log "truncating the file"
18737         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18738                 error "multiop failed while truncating the file"
18739         log "killing dd"
18740         kill %+ || true # reads might have finished
18741         echo "wait until dd is finished"
18742         wait
18743         log "removing the temporary file"
18744         rm -rf $DIR/$tfile || error "tmp file removal failed"
18745 }
18746 run_test 169 "parallel read and truncate should not deadlock"
18747
18748 test_170() {
18749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18750
18751         $LCTL clear     # bug 18514
18752         $LCTL debug_daemon start $TMP/${tfile}_log_good
18753         touch $DIR/$tfile
18754         $LCTL debug_daemon stop
18755         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18756                 error "sed failed to read log_good"
18757
18758         $LCTL debug_daemon start $TMP/${tfile}_log_good
18759         rm -rf $DIR/$tfile
18760         $LCTL debug_daemon stop
18761
18762         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18763                error "lctl df log_bad failed"
18764
18765         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18766         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18767
18768         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18769         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18770
18771         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18772                 error "bad_line good_line1 good_line2 are empty"
18773
18774         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18775         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18776         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18777
18778         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18779         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18780         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18781
18782         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18783                 error "bad_line_new good_line_new are empty"
18784
18785         local expected_good=$((good_line1 + good_line2*2))
18786
18787         rm -f $TMP/${tfile}*
18788         # LU-231, short malformed line may not be counted into bad lines
18789         if [ $bad_line -ne $bad_line_new ] &&
18790                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18791                 error "expected $bad_line bad lines, but got $bad_line_new"
18792                 return 1
18793         fi
18794
18795         if [ $expected_good -ne $good_line_new ]; then
18796                 error "expected $expected_good good lines, but got $good_line_new"
18797                 return 2
18798         fi
18799         true
18800 }
18801 run_test 170 "test lctl df to handle corrupted log ====================="
18802
18803 test_171() { # bug20592
18804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18805
18806         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18807         $LCTL set_param fail_loc=0x50e
18808         $LCTL set_param fail_val=3000
18809         multiop_bg_pause $DIR/$tfile O_s || true
18810         local MULTIPID=$!
18811         kill -USR1 $MULTIPID
18812         # cause log dump
18813         sleep 3
18814         wait $MULTIPID
18815         if dmesg | grep "recursive fault"; then
18816                 error "caught a recursive fault"
18817         fi
18818         $LCTL set_param fail_loc=0
18819         true
18820 }
18821 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18822
18823 test_172() {
18824
18825         #define OBD_FAIL_OBD_CLEANUP  0x60e
18826         $LCTL set_param fail_loc=0x60e
18827         umount $MOUNT || error "umount $MOUNT failed"
18828         stack_trap "mount_client $MOUNT"
18829
18830         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18831                 error "no client OBDs are remained"
18832
18833         $LCTL dl | while read devno state type name foo; do
18834                 case $type in
18835                 lov|osc|lmv|mdc)
18836                         $LCTL --device $name cleanup
18837                         $LCTL --device $name detach
18838                         ;;
18839                 *)
18840                         # skip server devices
18841                         ;;
18842                 esac
18843         done
18844
18845         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18846                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18847                 error "some client OBDs are still remained"
18848         fi
18849
18850 }
18851 run_test 172 "manual device removal with lctl cleanup/detach ======"
18852
18853 # it would be good to share it with obdfilter-survey/iokit-libecho code
18854 setup_obdecho_osc () {
18855         local rc=0
18856         local ost_nid=$1
18857         local obdfilter_name=$2
18858         echo "Creating new osc for $obdfilter_name on $ost_nid"
18859         # make sure we can find loopback nid
18860         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18861
18862         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18863                            ${obdfilter_name}_osc_UUID || rc=2; }
18864         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18865                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18866         return $rc
18867 }
18868
18869 cleanup_obdecho_osc () {
18870         local obdfilter_name=$1
18871         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18872         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18873         return 0
18874 }
18875
18876 obdecho_test() {
18877         local OBD=$1
18878         local node=$2
18879         local pages=${3:-64}
18880         local rc=0
18881         local id
18882
18883         local count=10
18884         local obd_size=$(get_obd_size $node $OBD)
18885         local page_size=$(get_page_size $node)
18886         if [[ -n "$obd_size" ]]; then
18887                 local new_count=$((obd_size / (pages * page_size / 1024)))
18888                 [[ $new_count -ge $count ]] || count=$new_count
18889         fi
18890
18891         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18892         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18893                            rc=2; }
18894         if [ $rc -eq 0 ]; then
18895             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18896             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18897         fi
18898         echo "New object id is $id"
18899         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18900                            rc=4; }
18901         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18902                            "test_brw $count w v $pages $id" || rc=4; }
18903         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18904                            rc=4; }
18905         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18906                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18907         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18908                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18909         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18910         return $rc
18911 }
18912
18913 test_180a() {
18914         skip "obdecho on osc is no longer supported"
18915 }
18916 run_test 180a "test obdecho on osc"
18917
18918 test_180b() {
18919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18920         remote_ost_nodsh && skip "remote OST with nodsh"
18921
18922         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18923                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18924                 error "failed to load module obdecho"
18925
18926         local target=$(do_facet ost1 $LCTL dl |
18927                        awk '/obdfilter/ { print $4; exit; }')
18928
18929         if [ -n "$target" ]; then
18930                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18931         else
18932                 do_facet ost1 $LCTL dl
18933                 error "there is no obdfilter target on ost1"
18934         fi
18935 }
18936 run_test 180b "test obdecho directly on obdfilter"
18937
18938 test_180c() { # LU-2598
18939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18940         remote_ost_nodsh && skip "remote OST with nodsh"
18941         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18942                 skip "Need MDS version at least 2.4.0"
18943
18944         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18945                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18946                 error "failed to load module obdecho"
18947
18948         local target=$(do_facet ost1 $LCTL dl |
18949                        awk '/obdfilter/ { print $4; exit; }')
18950
18951         if [ -n "$target" ]; then
18952                 local pages=16384 # 64MB bulk I/O RPC size
18953
18954                 obdecho_test "$target" ost1 "$pages" ||
18955                         error "obdecho_test with pages=$pages failed with $?"
18956         else
18957                 do_facet ost1 $LCTL dl
18958                 error "there is no obdfilter target on ost1"
18959         fi
18960 }
18961 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18962
18963 test_181() { # bug 22177
18964         test_mkdir $DIR/$tdir
18965         # create enough files to index the directory
18966         createmany -o $DIR/$tdir/foobar 4000
18967         # print attributes for debug purpose
18968         lsattr -d .
18969         # open dir
18970         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18971         MULTIPID=$!
18972         # remove the files & current working dir
18973         unlinkmany $DIR/$tdir/foobar 4000
18974         rmdir $DIR/$tdir
18975         kill -USR1 $MULTIPID
18976         wait $MULTIPID
18977         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18978         return 0
18979 }
18980 run_test 181 "Test open-unlinked dir ========================"
18981
18982 test_182a() {
18983         local fcount=1000
18984         local tcount=10
18985
18986         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18987
18988         $LCTL set_param mdc.*.rpc_stats=clear
18989
18990         for (( i = 0; i < $tcount; i++ )) ; do
18991                 mkdir $DIR/$tdir/$i
18992         done
18993
18994         for (( i = 0; i < $tcount; i++ )) ; do
18995                 createmany -o $DIR/$tdir/$i/f- $fcount &
18996         done
18997         wait
18998
18999         for (( i = 0; i < $tcount; i++ )) ; do
19000                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19001         done
19002         wait
19003
19004         $LCTL get_param mdc.*.rpc_stats
19005
19006         rm -rf $DIR/$tdir
19007 }
19008 run_test 182a "Test parallel modify metadata operations from mdc"
19009
19010 test_182b() {
19011         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19012         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19013         local dcount=1000
19014         local tcount=10
19015         local stime
19016         local etime
19017         local delta
19018
19019         do_facet mds1 $LCTL list_param \
19020                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19021                 skip "MDS lacks parallel RPC handling"
19022
19023         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19024
19025         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19026                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19027
19028         stime=$(date +%s)
19029         createmany -i 0 -d $DIR/$tdir/t- $tcount
19030
19031         for (( i = 0; i < $tcount; i++ )) ; do
19032                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19033         done
19034         wait
19035         etime=$(date +%s)
19036         delta=$((etime - stime))
19037         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19038
19039         stime=$(date +%s)
19040         for (( i = 0; i < $tcount; i++ )) ; do
19041                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19042         done
19043         wait
19044         etime=$(date +%s)
19045         delta=$((etime - stime))
19046         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19047
19048         rm -rf $DIR/$tdir
19049
19050         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19051
19052         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19053
19054         stime=$(date +%s)
19055         createmany -i 0 -d $DIR/$tdir/t- $tcount
19056
19057         for (( i = 0; i < $tcount; i++ )) ; do
19058                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19059         done
19060         wait
19061         etime=$(date +%s)
19062         delta=$((etime - stime))
19063         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19064
19065         stime=$(date +%s)
19066         for (( i = 0; i < $tcount; i++ )) ; do
19067                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19068         done
19069         wait
19070         etime=$(date +%s)
19071         delta=$((etime - stime))
19072         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19073
19074         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19075 }
19076 run_test 182b "Test parallel modify metadata operations from osp"
19077
19078 test_183() { # LU-2275
19079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19080         remote_mds_nodsh && skip "remote MDS with nodsh"
19081         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19082                 skip "Need MDS version at least 2.3.56"
19083
19084         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19085         echo aaa > $DIR/$tdir/$tfile
19086
19087 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19088         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19089
19090         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19091         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19092
19093         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19094
19095         # Flush negative dentry cache
19096         touch $DIR/$tdir/$tfile
19097
19098         # We are not checking for any leaked references here, they'll
19099         # become evident next time we do cleanup with module unload.
19100         rm -rf $DIR/$tdir
19101 }
19102 run_test 183 "No crash or request leak in case of strange dispositions ========"
19103
19104 # test suite 184 is for LU-2016, LU-2017
19105 test_184a() {
19106         check_swap_layouts_support
19107
19108         dir0=$DIR/$tdir/$testnum
19109         test_mkdir -p -c1 $dir0
19110         ref1=/etc/passwd
19111         ref2=/etc/group
19112         file1=$dir0/f1
19113         file2=$dir0/f2
19114         $LFS setstripe -c1 $file1
19115         cp $ref1 $file1
19116         $LFS setstripe -c2 $file2
19117         cp $ref2 $file2
19118         gen1=$($LFS getstripe -g $file1)
19119         gen2=$($LFS getstripe -g $file2)
19120
19121         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19122         gen=$($LFS getstripe -g $file1)
19123         [[ $gen1 != $gen ]] ||
19124                 error "Layout generation on $file1 does not change"
19125         gen=$($LFS getstripe -g $file2)
19126         [[ $gen2 != $gen ]] ||
19127                 error "Layout generation on $file2 does not change"
19128
19129         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19130         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19131
19132         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19133 }
19134 run_test 184a "Basic layout swap"
19135
19136 test_184b() {
19137         check_swap_layouts_support
19138
19139         dir0=$DIR/$tdir/$testnum
19140         mkdir -p $dir0 || error "creating dir $dir0"
19141         file1=$dir0/f1
19142         file2=$dir0/f2
19143         file3=$dir0/f3
19144         dir1=$dir0/d1
19145         dir2=$dir0/d2
19146         mkdir $dir1 $dir2
19147         $LFS setstripe -c1 $file1
19148         $LFS setstripe -c2 $file2
19149         $LFS setstripe -c1 $file3
19150         chown $RUNAS_ID $file3
19151         gen1=$($LFS getstripe -g $file1)
19152         gen2=$($LFS getstripe -g $file2)
19153
19154         $LFS swap_layouts $dir1 $dir2 &&
19155                 error "swap of directories layouts should fail"
19156         $LFS swap_layouts $dir1 $file1 &&
19157                 error "swap of directory and file layouts should fail"
19158         $RUNAS $LFS swap_layouts $file1 $file2 &&
19159                 error "swap of file we cannot write should fail"
19160         $LFS swap_layouts $file1 $file3 &&
19161                 error "swap of file with different owner should fail"
19162         /bin/true # to clear error code
19163 }
19164 run_test 184b "Forbidden layout swap (will generate errors)"
19165
19166 test_184c() {
19167         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19168         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19169         check_swap_layouts_support
19170         check_swap_layout_no_dom $DIR
19171
19172         local dir0=$DIR/$tdir/$testnum
19173         mkdir -p $dir0 || error "creating dir $dir0"
19174
19175         local ref1=$dir0/ref1
19176         local ref2=$dir0/ref2
19177         local file1=$dir0/file1
19178         local file2=$dir0/file2
19179         # create a file large enough for the concurrent test
19180         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19181         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19182         echo "ref file size: ref1($(stat -c %s $ref1))," \
19183              "ref2($(stat -c %s $ref2))"
19184
19185         cp $ref2 $file2
19186         dd if=$ref1 of=$file1 bs=16k &
19187         local DD_PID=$!
19188
19189         # Make sure dd starts to copy file, but wait at most 5 seconds
19190         local loops=0
19191         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19192
19193         $LFS swap_layouts $file1 $file2
19194         local rc=$?
19195         wait $DD_PID
19196         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19197         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19198
19199         # how many bytes copied before swapping layout
19200         local copied=$(stat -c %s $file2)
19201         local remaining=$(stat -c %s $ref1)
19202         remaining=$((remaining - copied))
19203         echo "Copied $copied bytes before swapping layout..."
19204
19205         cmp -n $copied $file1 $ref2 | grep differ &&
19206                 error "Content mismatch [0, $copied) of ref2 and file1"
19207         cmp -n $copied $file2 $ref1 ||
19208                 error "Content mismatch [0, $copied) of ref1 and file2"
19209         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19210                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19211
19212         # clean up
19213         rm -f $ref1 $ref2 $file1 $file2
19214 }
19215 run_test 184c "Concurrent write and layout swap"
19216
19217 test_184d() {
19218         check_swap_layouts_support
19219         check_swap_layout_no_dom $DIR
19220         [ -z "$(which getfattr 2>/dev/null)" ] &&
19221                 skip_env "no getfattr command"
19222
19223         local file1=$DIR/$tdir/$tfile-1
19224         local file2=$DIR/$tdir/$tfile-2
19225         local file3=$DIR/$tdir/$tfile-3
19226         local lovea1
19227         local lovea2
19228
19229         mkdir -p $DIR/$tdir
19230         touch $file1 || error "create $file1 failed"
19231         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19232                 error "create $file2 failed"
19233         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19234                 error "create $file3 failed"
19235         lovea1=$(get_layout_param $file1)
19236
19237         $LFS swap_layouts $file2 $file3 ||
19238                 error "swap $file2 $file3 layouts failed"
19239         $LFS swap_layouts $file1 $file2 ||
19240                 error "swap $file1 $file2 layouts failed"
19241
19242         lovea2=$(get_layout_param $file2)
19243         echo "$lovea1"
19244         echo "$lovea2"
19245         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19246
19247         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19248         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19249 }
19250 run_test 184d "allow stripeless layouts swap"
19251
19252 test_184e() {
19253         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19254                 skip "Need MDS version at least 2.6.94"
19255         check_swap_layouts_support
19256         check_swap_layout_no_dom $DIR
19257         [ -z "$(which getfattr 2>/dev/null)" ] &&
19258                 skip_env "no getfattr command"
19259
19260         local file1=$DIR/$tdir/$tfile-1
19261         local file2=$DIR/$tdir/$tfile-2
19262         local file3=$DIR/$tdir/$tfile-3
19263         local lovea
19264
19265         mkdir -p $DIR/$tdir
19266         touch $file1 || error "create $file1 failed"
19267         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19268                 error "create $file2 failed"
19269         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19270                 error "create $file3 failed"
19271
19272         $LFS swap_layouts $file1 $file2 ||
19273                 error "swap $file1 $file2 layouts failed"
19274
19275         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19276         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19277
19278         echo 123 > $file1 || error "Should be able to write into $file1"
19279
19280         $LFS swap_layouts $file1 $file3 ||
19281                 error "swap $file1 $file3 layouts failed"
19282
19283         echo 123 > $file1 || error "Should be able to write into $file1"
19284
19285         rm -rf $file1 $file2 $file3
19286 }
19287 run_test 184e "Recreate layout after stripeless layout swaps"
19288
19289 test_184f() {
19290         # Create a file with name longer than sizeof(struct stat) ==
19291         # 144 to see if we can get chars from the file name to appear
19292         # in the returned striping. Note that 'f' == 0x66.
19293         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19294
19295         mkdir -p $DIR/$tdir
19296         mcreate $DIR/$tdir/$file
19297         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19298                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19299         fi
19300 }
19301 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19302
19303 test_185() { # LU-2441
19304         # LU-3553 - no volatile file support in old servers
19305         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19306                 skip "Need MDS version at least 2.3.60"
19307
19308         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19309         touch $DIR/$tdir/spoo
19310         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19311         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19312                 error "cannot create/write a volatile file"
19313         [ "$FILESET" == "" ] &&
19314         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19315                 error "FID is still valid after close"
19316
19317         multiop_bg_pause $DIR/$tdir Vw4096_c
19318         local multi_pid=$!
19319
19320         local OLD_IFS=$IFS
19321         IFS=":"
19322         local fidv=($fid)
19323         IFS=$OLD_IFS
19324         # assume that the next FID for this client is sequential, since stdout
19325         # is unfortunately eaten by multiop_bg_pause
19326         local n=$((${fidv[1]} + 1))
19327         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19328         if [ "$FILESET" == "" ]; then
19329                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19330                         error "FID is missing before close"
19331         fi
19332         kill -USR1 $multi_pid
19333         # 1 second delay, so if mtime change we will see it
19334         sleep 1
19335         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19336         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19337 }
19338 run_test 185 "Volatile file support"
19339
19340 function create_check_volatile() {
19341         local idx=$1
19342         local tgt
19343
19344         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19345         local PID=$!
19346         sleep 1
19347         local FID=$(cat /tmp/${tfile}.fid)
19348         [ "$FID" == "" ] && error "can't get FID for volatile"
19349         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19350         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19351         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19352         kill -USR1 $PID
19353         wait
19354         sleep 1
19355         cancel_lru_locks mdc # flush opencache
19356         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19357         return 0
19358 }
19359
19360 test_185a(){
19361         # LU-12516 - volatile creation via .lustre
19362         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19363                 skip "Need MDS version at least 2.3.55"
19364
19365         create_check_volatile 0
19366         [ $MDSCOUNT -lt 2 ] && return 0
19367
19368         # DNE case
19369         create_check_volatile 1
19370
19371         return 0
19372 }
19373 run_test 185a "Volatile file creation in .lustre/fid/"
19374
19375 test_187a() {
19376         remote_mds_nodsh && skip "remote MDS with nodsh"
19377         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19378                 skip "Need MDS version at least 2.3.0"
19379
19380         local dir0=$DIR/$tdir/$testnum
19381         mkdir -p $dir0 || error "creating dir $dir0"
19382
19383         local file=$dir0/file1
19384         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19385         stack_trap "rm -f $file"
19386         local dv1=$($LFS data_version $file)
19387         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19388         local dv2=$($LFS data_version $file)
19389         [[ $dv1 != $dv2 ]] ||
19390                 error "data version did not change on write $dv1 == $dv2"
19391 }
19392 run_test 187a "Test data version change"
19393
19394 test_187b() {
19395         remote_mds_nodsh && skip "remote MDS with nodsh"
19396         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19397                 skip "Need MDS version at least 2.3.0"
19398
19399         local dir0=$DIR/$tdir/$testnum
19400         mkdir -p $dir0 || error "creating dir $dir0"
19401
19402         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19403         [[ ${DV[0]} != ${DV[1]} ]] ||
19404                 error "data version did not change on write"\
19405                       " ${DV[0]} == ${DV[1]}"
19406
19407         # clean up
19408         rm -f $file1
19409 }
19410 run_test 187b "Test data version change on volatile file"
19411
19412 test_200() {
19413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19414         remote_mgs_nodsh && skip "remote MGS with nodsh"
19415         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19416
19417         local POOL=${POOL:-cea1}
19418         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19419         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19420         # Pool OST targets
19421         local first_ost=0
19422         local last_ost=$(($OSTCOUNT - 1))
19423         local ost_step=2
19424         local ost_list=$(seq $first_ost $ost_step $last_ost)
19425         local ost_range="$first_ost $last_ost $ost_step"
19426         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19427         local file_dir=$POOL_ROOT/file_tst
19428         local subdir=$test_path/subdir
19429         local rc=0
19430
19431         while : ; do
19432                 # former test_200a test_200b
19433                 pool_add $POOL                          || { rc=$? ; break; }
19434                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19435                 # former test_200c test_200d
19436                 mkdir -p $test_path
19437                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19438                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19439                 mkdir -p $subdir
19440                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19441                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19442                                                         || { rc=$? ; break; }
19443                 # former test_200e test_200f
19444                 local files=$((OSTCOUNT*3))
19445                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19446                                                         || { rc=$? ; break; }
19447                 pool_create_files $POOL $file_dir $files "$ost_list" \
19448                                                         || { rc=$? ; break; }
19449                 # former test_200g test_200h
19450                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19451                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19452
19453                 # former test_201a test_201b test_201c
19454                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19455
19456                 local f=$test_path/$tfile
19457                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19458                 pool_remove $POOL $f                    || { rc=$? ; break; }
19459                 break
19460         done
19461
19462         destroy_test_pools
19463
19464         return $rc
19465 }
19466 run_test 200 "OST pools"
19467
19468 # usage: default_attr <count | size | offset>
19469 default_attr() {
19470         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19471 }
19472
19473 # usage: check_default_stripe_attr
19474 check_default_stripe_attr() {
19475         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19476         case $1 in
19477         --stripe-count|-c)
19478                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19479         --stripe-size|-S)
19480                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19481         --stripe-index|-i)
19482                 EXPECTED=-1;;
19483         *)
19484                 error "unknown getstripe attr '$1'"
19485         esac
19486
19487         [ $ACTUAL == $EXPECTED ] ||
19488                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19489 }
19490
19491 test_204a() {
19492         test_mkdir $DIR/$tdir
19493         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19494
19495         check_default_stripe_attr --stripe-count
19496         check_default_stripe_attr --stripe-size
19497         check_default_stripe_attr --stripe-index
19498 }
19499 run_test 204a "Print default stripe attributes"
19500
19501 test_204b() {
19502         test_mkdir $DIR/$tdir
19503         $LFS setstripe --stripe-count 1 $DIR/$tdir
19504
19505         check_default_stripe_attr --stripe-size
19506         check_default_stripe_attr --stripe-index
19507 }
19508 run_test 204b "Print default stripe size and offset"
19509
19510 test_204c() {
19511         test_mkdir $DIR/$tdir
19512         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19513
19514         check_default_stripe_attr --stripe-count
19515         check_default_stripe_attr --stripe-index
19516 }
19517 run_test 204c "Print default stripe count and offset"
19518
19519 test_204d() {
19520         test_mkdir $DIR/$tdir
19521         $LFS setstripe --stripe-index 0 $DIR/$tdir
19522
19523         check_default_stripe_attr --stripe-count
19524         check_default_stripe_attr --stripe-size
19525 }
19526 run_test 204d "Print default stripe count and size"
19527
19528 test_204e() {
19529         test_mkdir $DIR/$tdir
19530         $LFS setstripe -d $DIR/$tdir
19531
19532         # LU-16904 check if root is set as PFL layout
19533         local numcomp=$($LFS getstripe --component-count $MOUNT)
19534
19535         if [[ $numcomp -gt 0 ]]; then
19536                 check_default_stripe_attr --stripe-count
19537         else
19538                 check_default_stripe_attr --stripe-count --raw
19539         fi
19540         check_default_stripe_attr --stripe-size --raw
19541         check_default_stripe_attr --stripe-index --raw
19542 }
19543 run_test 204e "Print raw stripe attributes"
19544
19545 test_204f() {
19546         test_mkdir $DIR/$tdir
19547         $LFS setstripe --stripe-count 1 $DIR/$tdir
19548
19549         check_default_stripe_attr --stripe-size --raw
19550         check_default_stripe_attr --stripe-index --raw
19551 }
19552 run_test 204f "Print raw stripe size and offset"
19553
19554 test_204g() {
19555         test_mkdir $DIR/$tdir
19556         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19557
19558         check_default_stripe_attr --stripe-count --raw
19559         check_default_stripe_attr --stripe-index --raw
19560 }
19561 run_test 204g "Print raw stripe count and offset"
19562
19563 test_204h() {
19564         test_mkdir $DIR/$tdir
19565         $LFS setstripe --stripe-index 0 $DIR/$tdir
19566
19567         check_default_stripe_attr --stripe-count --raw
19568         check_default_stripe_attr --stripe-size --raw
19569 }
19570 run_test 204h "Print raw stripe count and size"
19571
19572 # Figure out which job scheduler is being used, if any,
19573 # or use a fake one
19574 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19575         JOBENV=SLURM_JOB_ID
19576 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19577         JOBENV=LSB_JOBID
19578 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19579         JOBENV=PBS_JOBID
19580 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19581         JOBENV=LOADL_STEP_ID
19582 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19583         JOBENV=JOB_ID
19584 else
19585         $LCTL list_param jobid_name > /dev/null 2>&1
19586         if [ $? -eq 0 ]; then
19587                 JOBENV=nodelocal
19588         else
19589                 JOBENV=FAKE_JOBID
19590         fi
19591 fi
19592 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19593
19594 verify_jobstats() {
19595         local cmd=($1)
19596         shift
19597         local facets="$@"
19598
19599 # we don't really need to clear the stats for this test to work, since each
19600 # command has a unique jobid, but it makes debugging easier if needed.
19601 #       for facet in $facets; do
19602 #               local dev=$(convert_facet2label $facet)
19603 #               # clear old jobstats
19604 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19605 #       done
19606
19607         # use a new JobID for each test, or we might see an old one
19608         [ "$JOBENV" = "FAKE_JOBID" ] &&
19609                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19610
19611         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19612
19613         [ "$JOBENV" = "nodelocal" ] && {
19614                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19615                 $LCTL set_param jobid_name=$FAKE_JOBID
19616                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19617         }
19618
19619         log "Test: ${cmd[*]}"
19620         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19621
19622         if [ $JOBENV = "FAKE_JOBID" ]; then
19623                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19624         else
19625                 ${cmd[*]}
19626         fi
19627
19628         # all files are created on OST0000
19629         for facet in $facets; do
19630                 local stats="*.$(convert_facet2label $facet).job_stats"
19631
19632                 # strip out libtool wrappers for in-tree executables
19633                 if (( $(do_facet $facet lctl get_param $stats |
19634                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19635                         do_facet $facet lctl get_param $stats
19636                         error "No jobstats for $JOBVAL found on $facet::$stats"
19637                 fi
19638         done
19639 }
19640
19641 jobstats_set() {
19642         local new_jobenv=$1
19643
19644         set_persistent_param_and_check client "jobid_var" \
19645                 "$FSNAME.sys.jobid_var" $new_jobenv
19646 }
19647
19648 test_205a() { # Job stats
19649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19650         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19651                 skip "Need MDS version with at least 2.7.1"
19652         remote_mgs_nodsh && skip "remote MGS with nodsh"
19653         remote_mds_nodsh && skip "remote MDS with nodsh"
19654         remote_ost_nodsh && skip "remote OST with nodsh"
19655         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19656                 skip "Server doesn't support jobstats"
19657         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19658
19659         local old_jobenv=$($LCTL get_param -n jobid_var)
19660         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19661         stack_trap "jobstats_set $old_jobenv" EXIT
19662
19663         changelog_register
19664
19665         local old_jobid_name=$($LCTL get_param jobid_name)
19666         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19667
19668         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19669                                 mdt.*.job_cleanup_interval | head -n 1)
19670         local new_interval=5
19671         do_facet $SINGLEMDS \
19672                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19673         stack_trap "do_facet $SINGLEMDS \
19674                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19675         local start=$SECONDS
19676
19677         local cmd
19678         # mkdir
19679         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19680         verify_jobstats "$cmd" "$SINGLEMDS"
19681         # rmdir
19682         cmd="rmdir $DIR/$tdir"
19683         verify_jobstats "$cmd" "$SINGLEMDS"
19684         # mkdir on secondary MDT
19685         if [ $MDSCOUNT -gt 1 ]; then
19686                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19687                 verify_jobstats "$cmd" "mds2"
19688         fi
19689         # mknod
19690         cmd="mknod $DIR/$tfile c 1 3"
19691         verify_jobstats "$cmd" "$SINGLEMDS"
19692         # unlink
19693         cmd="rm -f $DIR/$tfile"
19694         verify_jobstats "$cmd" "$SINGLEMDS"
19695         # create all files on OST0000 so verify_jobstats can find OST stats
19696         # open & close
19697         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19698         verify_jobstats "$cmd" "$SINGLEMDS"
19699         # setattr
19700         cmd="touch $DIR/$tfile"
19701         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19702         # write
19703         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19704         verify_jobstats "$cmd" "ost1"
19705         # read
19706         cancel_lru_locks osc
19707         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19708         verify_jobstats "$cmd" "ost1"
19709         # truncate
19710         cmd="$TRUNCATE $DIR/$tfile 0"
19711         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19712         # rename
19713         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19714         verify_jobstats "$cmd" "$SINGLEMDS"
19715         # jobstats expiry - sleep until old stats should be expired
19716         local left=$((new_interval + 5 - (SECONDS - start)))
19717         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19718                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19719                         "0" $left
19720         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19721         verify_jobstats "$cmd" "$SINGLEMDS"
19722         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19723             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19724
19725         # Ensure that jobid are present in changelog (if supported by MDS)
19726         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19727                 changelog_dump | tail -10
19728                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19729                 [ $jobids -eq 9 ] ||
19730                         error "Wrong changelog jobid count $jobids != 9"
19731
19732                 # LU-5862
19733                 JOBENV="disable"
19734                 jobstats_set $JOBENV
19735                 touch $DIR/$tfile
19736                 changelog_dump | grep $tfile
19737                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19738                 [ $jobids -eq 0 ] ||
19739                         error "Unexpected jobids when jobid_var=$JOBENV"
19740         fi
19741
19742         # test '%j' access to environment variable - if supported
19743         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19744                 JOBENV="JOBCOMPLEX"
19745                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19746
19747                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19748         fi
19749
19750         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19751                 JOBENV="JOBCOMPLEX"
19752                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19753
19754                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19755         fi
19756
19757         # test '%j' access to per-session jobid - if supported
19758         if lctl list_param jobid_this_session > /dev/null 2>&1
19759         then
19760                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19761                 lctl set_param jobid_this_session=$USER
19762
19763                 JOBENV="JOBCOMPLEX"
19764                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19765
19766                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19767         fi
19768 }
19769 run_test 205a "Verify job stats"
19770
19771 # LU-13117, LU-13597, LU-16599
19772 test_205b() {
19773         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19774                 skip "Need MDS version at least 2.13.54.91"
19775
19776         local job_stats="mdt.*.job_stats"
19777         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19778
19779         do_facet mds1 $LCTL set_param $job_stats=clear
19780
19781         # Setting jobid_var to USER might not be supported
19782         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19783         $LCTL set_param jobid_var=USER || true
19784         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19785         $LCTL set_param jobid_name="%j.%e.%u"
19786
19787         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19788         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19789                 { do_facet mds1 $LCTL get_param $job_stats;
19790                   error "Unexpected jobid found"; }
19791         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19792                 { do_facet mds1 $LCTL get_param $job_stats;
19793                   error "wrong job_stats format found"; }
19794
19795         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19796                 echo "MDS does not yet escape jobid" && return 0
19797
19798         mkdir_on_mdt0 $DIR/$tdir
19799         $LCTL set_param jobid_var=TEST205b
19800         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19801         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19802                       awk '/has\\x20sp/ {print $3}')
19803         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19804                   error "jobid not escaped"; }
19805
19806         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19807                 # need to run such a command on mds1:
19808                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19809                 #
19810                 # there might be multiple MDTs on single mds server, so need to
19811                 # specifiy MDT0000. Or the command will fail due to other MDTs
19812                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19813                         error "cannot clear escaped jobid in job_stats";
19814         else
19815                 echo "MDS does not support clearing escaped jobid"
19816         fi
19817 }
19818 run_test 205b "Verify job stats jobid and output format"
19819
19820 # LU-13733
19821 test_205c() {
19822         $LCTL set_param llite.*.stats=0
19823         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19824         $LCTL get_param llite.*.stats
19825         $LCTL get_param llite.*.stats | grep \
19826                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19827                         error "wrong client stats format found"
19828 }
19829 run_test 205c "Verify client stats format"
19830
19831 test_205d() {
19832         local file=$DIR/$tdir/$tfile
19833
19834         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19835                 skip "need lustre >= 2.15.53 for lljobstat"
19836         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19837                 skip "need lustre >= 2.15.53 for lljobstat"
19838         verify_yaml_available || skip_env "YAML verification not installed"
19839
19840         test_mkdir -i 0 $DIR/$tdir
19841         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19842         stack_trap "rm -rf $DIR/$tdir"
19843
19844         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19845                 error "failed to write data to $file"
19846         mv $file $file.2
19847
19848         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19849         echo -n 'verify rename_stats...'
19850         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19851                 verify_yaml || error "rename_stats is not valid YAML"
19852         echo " OK"
19853
19854         echo -n 'verify mdt job_stats...'
19855         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19856                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19857         echo " OK"
19858
19859         echo -n 'verify ost job_stats...'
19860         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19861                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19862         echo " OK"
19863 }
19864 run_test 205d "verify the format of some stats files"
19865
19866 test_205e() {
19867         local ops_comma
19868         local file=$DIR/$tdir/$tfile
19869         local -a cli_params
19870
19871         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19872                 skip "need lustre >= 2.15.53 for lljobstat"
19873         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19874                 skip "need lustre >= 2.15.53 for lljobstat"
19875         verify_yaml_available || skip_env "YAML verification not installed"
19876
19877         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19878         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19879         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19880
19881         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19882         stack_trap "rm -rf $DIR/$tdir"
19883
19884         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19885                 error "failed to create $file on ost1"
19886         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19887                 error "failed to write data to $file"
19888
19889         do_facet mds1 "$LCTL get_param *.*.job_stats"
19890         do_facet ost1 "$LCTL get_param *.*.job_stats"
19891
19892         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19893         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19894                 error "The output of lljobstat is not an valid YAML"
19895
19896         # verify that job dd.0 does exist and has some ops on ost1
19897         # typically this line is like:
19898         # - 205e.dd.0:            {ops: 20, ...}
19899         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19900                     awk '$2=="205e.dd.0:" {print $4}')
19901
19902         (( ${ops_comma%,} >= 10 )) ||
19903                 error "cannot find job 205e.dd.0 with ops >= 10"
19904 }
19905 run_test 205e "verify the output of lljobstat"
19906
19907 test_205f() {
19908         verify_yaml_available || skip_env "YAML verification not installed"
19909
19910         # check both qos_ost_weights and qos_mdt_weights
19911         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19912         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19913                 error "qos_ost_weights is not valid YAML"
19914 }
19915 run_test 205f "verify qos_ost_weights YAML format "
19916
19917 __test_205_jobstats_dump() {
19918         local -a pids
19919         local nbr_instance=$1
19920
19921         while true; do
19922                 if (( ${#pids[@]} >= nbr_instance )); then
19923                         wait ${pids[@]}
19924                         pids=()
19925                 fi
19926
19927                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19928                 pids+=( $! )
19929         done
19930 }
19931
19932 __test_205_cleanup() {
19933         kill $@
19934         # Clear all job entries
19935         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19936 }
19937
19938 test_205g() {
19939         local -a mds1_params
19940         local -a cli_params
19941         local pids
19942         local interval=5
19943
19944         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19945         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19946         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19947
19948         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19949         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19950         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19951
19952         # start jobs loop
19953         export TEST205G_ID=205g
19954         stack_trap "unset TEST205G_ID" EXIT
19955         while true; do
19956                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19957         done & pids="$! "
19958
19959         __test_205_jobstats_dump 4 & pids+="$! "
19960         stack_trap "__test_205_cleanup $pids" EXIT INT
19961
19962         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19963 }
19964 run_test 205g "stress test for job_stats procfile"
19965
19966 test_205h() {
19967         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
19968
19969         local dir=$DIR/$tdir
19970         local f=$dir/$tfile
19971         local f2=$dir/$tfile-2
19972         local f3=$dir/$tfile-3
19973         local subdir=$DIR/dir
19974         local val
19975
19976         local mdts=$(comma_list $(mdts_nodes))
19977         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
19978         local client_saved=$($LCTL get_param -n jobid_var)
19979
19980         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
19981         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
19982
19983         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
19984                 error "failed to set job_xattr parameter to user.job"
19985         $LCTL set_param jobid_var=procname.uid ||
19986                 error "failed to set jobid_var parameter"
19987
19988         test_mkdir $dir
19989
19990         touch $f
19991         val=$(getfattr -n user.job $f | grep user.job)
19992         [[ $val = user.job=\"touch.0\" ]] ||
19993                 error "expected user.job=\"touch.0\", got '$val'"
19994
19995         mkdir $subdir
19996         val=$(getfattr -n user.job $subdir | grep user.job)
19997         [[ $val = user.job=\"mkdir.0\" ]] ||
19998                 error "expected user.job=\"mkdir.0\", got '$val'"
19999
20000         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20001                 error "failed to set job_xattr parameter to NONE"
20002
20003         touch $f2
20004         val=$(getfattr -d $f2)
20005         [[ -z $val ]] ||
20006                 error "expected no user xattr, got '$val'"
20007
20008         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20009                 error "failed to set job_xattr parameter to trusted.job"
20010
20011         touch $f3
20012         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20013         [[ $val = trusted.job=\"touch.0\" ]] ||
20014                 error "expected trusted.job=\"touch.0\", got '$val'"
20015 }
20016 run_test 205h "check jobid xattr is stored correctly"
20017
20018 test_205i() {
20019         local mdts=$(comma_list $(mdts_nodes))
20020         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20021
20022         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20023
20024         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20025                 error "failed to set mdt.*.job_xattr to user.1234567"
20026
20027         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20028                 error "failed to reject too long job_xattr name"
20029
20030         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20031                 error "failed to reject job_xattr name in bad format"
20032
20033         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20034                 error "failed to reject job_xattr name with invalid character"
20035
20036         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20037                         xargs $LCTL set_param" &&
20038                 error "failed to reject job_xattr name with non-ascii character"
20039
20040         return 0
20041 }
20042 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20043
20044 # LU-1480, LU-1773 and LU-1657
20045 test_206() {
20046         mkdir -p $DIR/$tdir
20047         $LFS setstripe -c -1 $DIR/$tdir
20048 #define OBD_FAIL_LOV_INIT 0x1403
20049         $LCTL set_param fail_loc=0xa0001403
20050         $LCTL set_param fail_val=1
20051         touch $DIR/$tdir/$tfile || true
20052 }
20053 run_test 206 "fail lov_init_raid0() doesn't lbug"
20054
20055 test_207a() {
20056         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20057         local fsz=`stat -c %s $DIR/$tfile`
20058         cancel_lru_locks mdc
20059
20060         # do not return layout in getattr intent
20061 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20062         $LCTL set_param fail_loc=0x170
20063         local sz=`stat -c %s $DIR/$tfile`
20064
20065         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20066
20067         rm -rf $DIR/$tfile
20068 }
20069 run_test 207a "can refresh layout at glimpse"
20070
20071 test_207b() {
20072         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20073         local cksum=`md5sum $DIR/$tfile`
20074         local fsz=`stat -c %s $DIR/$tfile`
20075         cancel_lru_locks mdc
20076         cancel_lru_locks osc
20077
20078         # do not return layout in getattr intent
20079 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20080         $LCTL set_param fail_loc=0x171
20081
20082         # it will refresh layout after the file is opened but before read issues
20083         echo checksum is "$cksum"
20084         echo "$cksum" |md5sum -c --quiet || error "file differs"
20085
20086         rm -rf $DIR/$tfile
20087 }
20088 run_test 207b "can refresh layout at open"
20089
20090 test_208() {
20091         # FIXME: in this test suite, only RD lease is used. This is okay
20092         # for now as only exclusive open is supported. After generic lease
20093         # is done, this test suite should be revised. - Jinshan
20094
20095         remote_mds_nodsh && skip "remote MDS with nodsh"
20096         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20097                 skip "Need MDS version at least 2.4.52"
20098
20099         echo "==== test 1: verify get lease work"
20100         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20101
20102         echo "==== test 2: verify lease can be broken by upcoming open"
20103         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20104         local PID=$!
20105         sleep 2
20106
20107         $MULTIOP $DIR/$tfile oO_RDWR:c
20108         kill -USR1 $PID && wait $PID || error "break lease error"
20109
20110         echo "==== test 3: verify lease can't be granted if an open already exists"
20111         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20112         local PID=$!
20113         sleep 2
20114
20115         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20116         kill -USR1 $PID && wait $PID || error "open file error"
20117
20118         echo "==== test 4: lease can sustain over recovery"
20119         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20120         PID=$!
20121         sleep 2
20122
20123         fail mds1
20124
20125         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20126
20127         echo "==== test 5: lease broken can't be regained by replay"
20128         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20129         PID=$!
20130         sleep 2
20131
20132         # open file to break lease and then recovery
20133         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20134         fail mds1
20135
20136         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20137
20138         rm -f $DIR/$tfile
20139 }
20140 run_test 208 "Exclusive open"
20141
20142 test_209() {
20143         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20144                 skip_env "must have disp_stripe"
20145
20146         touch $DIR/$tfile
20147         sync; sleep 5; sync;
20148
20149         echo 3 > /proc/sys/vm/drop_caches
20150         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20151                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20152         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20153
20154         # open/close 500 times
20155         for i in $(seq 500); do
20156                 cat $DIR/$tfile
20157         done
20158
20159         echo 3 > /proc/sys/vm/drop_caches
20160         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20161                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20162         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20163
20164         echo "before: $req_before, after: $req_after"
20165         [ $((req_after - req_before)) -ge 300 ] &&
20166                 error "open/close requests are not freed"
20167         return 0
20168 }
20169 run_test 209 "read-only open/close requests should be freed promptly"
20170
20171 test_210() {
20172         local pid
20173
20174         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_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         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20183         pid=$!
20184         sleep 1
20185
20186         $LFS getstripe $DIR/$tfile
20187         kill -USR1 $pid
20188         wait $pid || error "multiop failed"
20189 }
20190 run_test 210 "lfs getstripe does not break leases"
20191
20192 test_212() {
20193         size=`date +%s`
20194         size=$((size % 8192 + 1))
20195         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20196         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20197         rm -f $DIR/f212 $DIR/f212.xyz
20198 }
20199 run_test 212 "Sendfile test ============================================"
20200
20201 test_213() {
20202         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20203         cancel_lru_locks osc
20204         lctl set_param fail_loc=0x8000040f
20205         # generate a read lock
20206         cat $DIR/$tfile > /dev/null
20207         # write to the file, it will try to cancel the above read lock.
20208         cat /etc/hosts >> $DIR/$tfile
20209 }
20210 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20211
20212 test_214() { # for bug 20133
20213         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20214         for (( i=0; i < 340; i++ )) ; do
20215                 touch $DIR/$tdir/d214c/a$i
20216         done
20217
20218         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20219         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20220         ls $DIR/d214c || error "ls $DIR/d214c failed"
20221         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20222         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20223 }
20224 run_test 214 "hash-indexed directory test - bug 20133"
20225
20226 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20227 create_lnet_proc_files() {
20228         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20229 }
20230
20231 # counterpart of create_lnet_proc_files
20232 remove_lnet_proc_files() {
20233         rm -f $TMP/lnet_$1.sys
20234 }
20235
20236 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20237 # 3rd arg as regexp for body
20238 check_lnet_proc_stats() {
20239         local l=$(cat "$TMP/lnet_$1" |wc -l)
20240         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20241
20242         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20243 }
20244
20245 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20246 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20247 # optional and can be regexp for 2nd line (lnet.routes case)
20248 check_lnet_proc_entry() {
20249         local blp=2          # blp stands for 'position of 1st line of body'
20250         [ -z "$5" ] || blp=3 # lnet.routes case
20251
20252         local l=$(cat "$TMP/lnet_$1" |wc -l)
20253         # subtracting one from $blp because the body can be empty
20254         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20255
20256         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20257                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20258
20259         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20260                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20261
20262         # bail out if any unexpected line happened
20263         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20264         [ "$?" != 0 ] || error "$2 misformatted"
20265 }
20266
20267 test_215() { # for bugs 18102, 21079, 21517
20268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20269
20270         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20271         local P='[1-9][0-9]*'           # positive numeric
20272         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20273         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20274         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20275         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20276
20277         local L1 # regexp for 1st line
20278         local L2 # regexp for 2nd line (optional)
20279         local BR # regexp for the rest (body)
20280
20281         # lnet.stats should look as 11 space-separated non-negative numerics
20282         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20283         create_lnet_proc_files "stats"
20284         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20285         remove_lnet_proc_files "stats"
20286
20287         # lnet.routes should look like this:
20288         # Routing disabled/enabled
20289         # net hops priority state router
20290         # where net is a string like tcp0, hops > 0, priority >= 0,
20291         # state is up/down,
20292         # router is a string like 192.168.1.1@tcp2
20293         L1="^Routing (disabled|enabled)$"
20294         L2="^net +hops +priority +state +router$"
20295         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20296         create_lnet_proc_files "routes"
20297         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20298         remove_lnet_proc_files "routes"
20299
20300         # lnet.routers should look like this:
20301         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20302         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20303         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20304         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20305         L1="^ref +rtr_ref +alive +router$"
20306         BR="^$P +$P +(up|down) +$NID$"
20307         create_lnet_proc_files "routers"
20308         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20309         remove_lnet_proc_files "routers"
20310
20311         # lnet.peers should look like this:
20312         # nid refs state last max rtr min tx min queue
20313         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20314         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20315         # numeric (0 or >0 or <0), queue >= 0.
20316         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20317         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20318         create_lnet_proc_files "peers"
20319         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20320         remove_lnet_proc_files "peers"
20321
20322         # lnet.buffers  should look like this:
20323         # pages count credits min
20324         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20325         L1="^pages +count +credits +min$"
20326         BR="^ +$N +$N +$I +$I$"
20327         create_lnet_proc_files "buffers"
20328         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20329         remove_lnet_proc_files "buffers"
20330
20331         # lnet.nis should look like this:
20332         # nid status alive refs peer rtr max tx min
20333         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20334         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20335         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20336         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20337         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20338         create_lnet_proc_files "nis"
20339         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20340         remove_lnet_proc_files "nis"
20341
20342         # can we successfully write to lnet.stats?
20343         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20344 }
20345 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20346
20347 test_216() { # bug 20317
20348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20349         remote_ost_nodsh && skip "remote OST with nodsh"
20350
20351         local node
20352         local facets=$(get_facets OST)
20353         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20354
20355         save_lustre_params client "osc.*.contention_seconds" > $p
20356         save_lustre_params $facets \
20357                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20358         save_lustre_params $facets \
20359                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20360         save_lustre_params $facets \
20361                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20362         clear_stats osc.*.osc_stats
20363
20364         # agressive lockless i/o settings
20365         do_nodes $(comma_list $(osts_nodes)) \
20366                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20367                         ldlm.namespaces.filter-*.contended_locks=0 \
20368                         ldlm.namespaces.filter-*.contention_seconds=60"
20369         lctl set_param -n osc.*.contention_seconds=60
20370
20371         $DIRECTIO write $DIR/$tfile 0 10 4096
20372         $CHECKSTAT -s 40960 $DIR/$tfile
20373
20374         # disable lockless i/o
20375         do_nodes $(comma_list $(osts_nodes)) \
20376                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20377                         ldlm.namespaces.filter-*.contended_locks=32 \
20378                         ldlm.namespaces.filter-*.contention_seconds=0"
20379         lctl set_param -n osc.*.contention_seconds=0
20380         clear_stats osc.*.osc_stats
20381
20382         dd if=/dev/zero of=$DIR/$tfile count=0
20383         $CHECKSTAT -s 0 $DIR/$tfile
20384
20385         restore_lustre_params <$p
20386         rm -f $p
20387         rm $DIR/$tfile
20388 }
20389 run_test 216 "check lockless direct write updates file size and kms correctly"
20390
20391 test_217() { # bug 22430
20392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20393
20394         local node
20395
20396         for node in $(nodes_list); do
20397                 local nid=$(host_nids_address $node $NETTYPE)
20398                 local node_ip=$(do_node $node getent ahostsv4 $node |
20399                                 awk '{ print $1; exit; }')
20400
20401                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20402                 # if hostname matches any NID, use hostname for better testing
20403                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20404                         echo "lctl ping node $node@$NETTYPE"
20405                         lctl ping $node@$NETTYPE
20406                 else # otherwise, at least test 'lctl ping' is working
20407                         echo "lctl ping nid $(h2nettype $nid)"
20408                         lctl ping $(h2nettype $nid)
20409                         echo "skipping $node (no hyphen detected)"
20410                 fi
20411         done
20412 }
20413 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20414
20415 test_218() {
20416         # do directio so as not to populate the page cache
20417         log "creating a 10 Mb file"
20418         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20419                 error "multiop failed while creating a file"
20420         log "starting reads"
20421         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20422         log "truncating the file"
20423         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20424                 error "multiop failed while truncating the file"
20425         log "killing dd"
20426         kill %+ || true # reads might have finished
20427         echo "wait until dd is finished"
20428         wait
20429         log "removing the temporary file"
20430         rm -rf $DIR/$tfile || error "tmp file removal failed"
20431 }
20432 run_test 218 "parallel read and truncate should not deadlock"
20433
20434 test_219() {
20435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20436
20437         # write one partial page
20438         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20439         # set no grant so vvp_io_commit_write will do sync write
20440         $LCTL set_param fail_loc=0x411
20441         # write a full page at the end of file
20442         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20443
20444         $LCTL set_param fail_loc=0
20445         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20446         $LCTL set_param fail_loc=0x411
20447         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20448
20449         # LU-4201
20450         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20451         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20452 }
20453 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20454
20455 test_220() { #LU-325
20456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20457         remote_ost_nodsh && skip "remote OST with nodsh"
20458         remote_mds_nodsh && skip "remote MDS with nodsh"
20459         remote_mgs_nodsh && skip "remote MGS with nodsh"
20460
20461         local OSTIDX=0
20462
20463         # create on MDT0000 so the last_id and next_id are correct
20464         mkdir_on_mdt0 $DIR/$tdir
20465         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20466         OST=${OST%_UUID}
20467
20468         # on the mdt's osc
20469         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20470         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20471                         osp.$mdtosc_proc1.prealloc_last_id)
20472         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20473                         osp.$mdtosc_proc1.prealloc_next_id)
20474
20475         $LFS df -i
20476
20477         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20478         #define OBD_FAIL_OST_ENOINO              0x229
20479         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20480         create_pool $FSNAME.$TESTNAME || return 1
20481         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20482
20483         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20484
20485         MDSOBJS=$((last_id - next_id))
20486         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20487
20488         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20489         echo "OST still has $count kbytes free"
20490
20491         echo "create $MDSOBJS files @next_id..."
20492         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20493
20494         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20495                         osp.$mdtosc_proc1.prealloc_last_id)
20496         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20497                         osp.$mdtosc_proc1.prealloc_next_id)
20498
20499         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20500         $LFS df -i
20501
20502         echo "cleanup..."
20503
20504         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20505         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20506
20507         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20508                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20509         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20510                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20511         echo "unlink $MDSOBJS files @$next_id..."
20512         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20513 }
20514 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20515
20516 test_221() {
20517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20518
20519         dd if=`which date` of=$MOUNT/date oflag=sync
20520         chmod +x $MOUNT/date
20521
20522         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20523         $LCTL set_param fail_loc=0x80001401
20524
20525         $MOUNT/date > /dev/null
20526         rm -f $MOUNT/date
20527 }
20528 run_test 221 "make sure fault and truncate race to not cause OOM"
20529
20530 test_222a () {
20531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20532
20533         rm -rf $DIR/$tdir
20534         test_mkdir $DIR/$tdir
20535         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20536         createmany -o $DIR/$tdir/$tfile 10
20537         cancel_lru_locks mdc
20538         cancel_lru_locks osc
20539         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20540         $LCTL set_param fail_loc=0x31a
20541         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20542         $LCTL set_param fail_loc=0
20543         rm -r $DIR/$tdir
20544 }
20545 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20546
20547 test_222b () {
20548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20549
20550         rm -rf $DIR/$tdir
20551         test_mkdir $DIR/$tdir
20552         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20553         createmany -o $DIR/$tdir/$tfile 10
20554         cancel_lru_locks mdc
20555         cancel_lru_locks osc
20556         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20557         $LCTL set_param fail_loc=0x31a
20558         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20559         $LCTL set_param fail_loc=0
20560 }
20561 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20562
20563 test_223 () {
20564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20565
20566         rm -rf $DIR/$tdir
20567         test_mkdir $DIR/$tdir
20568         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20569         createmany -o $DIR/$tdir/$tfile 10
20570         cancel_lru_locks mdc
20571         cancel_lru_locks osc
20572         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20573         $LCTL set_param fail_loc=0x31b
20574         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20575         $LCTL set_param fail_loc=0
20576         rm -r $DIR/$tdir
20577 }
20578 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20579
20580 test_224a() { # LU-1039, MRP-303
20581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20582         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20583         $LCTL set_param fail_loc=0x508
20584         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20585         $LCTL set_param fail_loc=0
20586         df $DIR
20587 }
20588 run_test 224a "Don't panic on bulk IO failure"
20589
20590 test_224bd_sub() { # LU-1039, MRP-303
20591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20592         local timeout=$1
20593
20594         shift
20595         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20596
20597         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20598
20599         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20600         cancel_lru_locks osc
20601         set_checksums 0
20602         stack_trap "set_checksums $ORIG_CSUM" EXIT
20603         local at_max_saved=0
20604
20605         # adaptive timeouts may prevent seeing the issue
20606         if at_is_enabled; then
20607                 at_max_saved=$(at_max_get mds)
20608                 at_max_set 0 mds client
20609                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20610         fi
20611
20612         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20613         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20614         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20615
20616         do_facet ost1 $LCTL set_param fail_loc=0
20617         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20618         df $DIR
20619 }
20620
20621 test_224b() {
20622         test_224bd_sub 3 error "dd failed"
20623 }
20624 run_test 224b "Don't panic on bulk IO failure"
20625
20626 test_224c() { # LU-6441
20627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20628         remote_mds_nodsh && skip "remote MDS with nodsh"
20629
20630         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20631         save_writethrough $p
20632         set_cache writethrough on
20633
20634         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20635         local at_max=$($LCTL get_param -n at_max)
20636         local timeout=$($LCTL get_param -n timeout)
20637         local test_at="at_max"
20638         local param_at="$FSNAME.sys.at_max"
20639         local test_timeout="timeout"
20640         local param_timeout="$FSNAME.sys.timeout"
20641
20642         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20643
20644         set_persistent_param_and_check client "$test_at" "$param_at" 0
20645         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20646
20647         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20648         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20649         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20650         stack_trap "rm -f $DIR/$tfile"
20651         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20652         sync
20653         do_facet ost1 "$LCTL set_param fail_loc=0"
20654
20655         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20656         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20657                 $timeout
20658
20659         $LCTL set_param -n $pages_per_rpc
20660         restore_lustre_params < $p
20661         rm -f $p
20662 }
20663 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20664
20665 test_224d() { # LU-11169
20666         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20667 }
20668 run_test 224d "Don't corrupt data on bulk IO timeout"
20669
20670 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20671 test_225a () {
20672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20673         if [ -z ${MDSSURVEY} ]; then
20674                 skip_env "mds-survey not found"
20675         fi
20676         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20677                 skip "Need MDS version at least 2.2.51"
20678
20679         local mds=$(facet_host $SINGLEMDS)
20680         local target=$(do_nodes $mds 'lctl dl' |
20681                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20682
20683         local cmd1="file_count=1000 thrhi=4"
20684         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20685         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20686         local cmd="$cmd1 $cmd2 $cmd3"
20687
20688         rm -f ${TMP}/mds_survey*
20689         echo + $cmd
20690         eval $cmd || error "mds-survey with zero-stripe failed"
20691         cat ${TMP}/mds_survey*
20692         rm -f ${TMP}/mds_survey*
20693 }
20694 run_test 225a "Metadata survey sanity with zero-stripe"
20695
20696 test_225b () {
20697         if [ -z ${MDSSURVEY} ]; then
20698                 skip_env "mds-survey not found"
20699         fi
20700         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20701                 skip "Need MDS version at least 2.2.51"
20702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20703         remote_mds_nodsh && skip "remote MDS with nodsh"
20704         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20705                 skip_env "Need to mount OST to test"
20706         fi
20707
20708         local mds=$(facet_host $SINGLEMDS)
20709         local target=$(do_nodes $mds 'lctl dl' |
20710                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20711
20712         local cmd1="file_count=1000 thrhi=4"
20713         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20714         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20715         local cmd="$cmd1 $cmd2 $cmd3"
20716
20717         rm -f ${TMP}/mds_survey*
20718         echo + $cmd
20719         eval $cmd || error "mds-survey with stripe_count failed"
20720         cat ${TMP}/mds_survey*
20721         rm -f ${TMP}/mds_survey*
20722 }
20723 run_test 225b "Metadata survey sanity with stripe_count = 1"
20724
20725 mcreate_path2fid () {
20726         local mode=$1
20727         local major=$2
20728         local minor=$3
20729         local name=$4
20730         local desc=$5
20731         local path=$DIR/$tdir/$name
20732         local fid
20733         local rc
20734         local fid_path
20735
20736         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20737                 error "cannot create $desc"
20738
20739         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20740         rc=$?
20741         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20742
20743         fid_path=$($LFS fid2path $MOUNT $fid)
20744         rc=$?
20745         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20746
20747         [ "$path" == "$fid_path" ] ||
20748                 error "fid2path returned $fid_path, expected $path"
20749
20750         echo "pass with $path and $fid"
20751 }
20752
20753 test_226a () {
20754         rm -rf $DIR/$tdir
20755         mkdir -p $DIR/$tdir
20756
20757         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20758         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20759         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20760         mcreate_path2fid 0040666 0 0 dir "directory"
20761         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20762         mcreate_path2fid 0100666 0 0 file "regular file"
20763         mcreate_path2fid 0120666 0 0 link "symbolic link"
20764         mcreate_path2fid 0140666 0 0 sock "socket"
20765 }
20766 run_test 226a "call path2fid and fid2path on files of all type"
20767
20768 test_226b () {
20769         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20770
20771         local MDTIDX=1
20772
20773         rm -rf $DIR/$tdir
20774         mkdir -p $DIR/$tdir
20775         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20776                 error "create remote directory failed"
20777         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20778         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20779                                 "character special file (null)"
20780         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20781                                 "character special file (no device)"
20782         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20783         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20784                                 "block special file (loop)"
20785         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20786         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20787         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20788 }
20789 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20790
20791 test_226c () {
20792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20793         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20794                 skip "Need MDS version at least 2.13.55"
20795
20796         local submnt=/mnt/submnt
20797         local srcfile=/etc/passwd
20798         local dstfile=$submnt/passwd
20799         local path
20800         local fid
20801
20802         rm -rf $DIR/$tdir
20803         rm -rf $submnt
20804         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20805                 error "create remote directory failed"
20806         mkdir -p $submnt || error "create $submnt failed"
20807         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20808                 error "mount $submnt failed"
20809         stack_trap "umount $submnt" EXIT
20810
20811         cp $srcfile $dstfile
20812         fid=$($LFS path2fid $dstfile)
20813         path=$($LFS fid2path $submnt "$fid")
20814         [ "$path" = "$dstfile" ] ||
20815                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20816 }
20817 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20818
20819 test_226e () {
20820         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
20821                 skip "Need client at least version 2.15.56"
20822
20823         # Define filename with 'newline' and a space
20824         local testfile="Test"$'\n'"file 01"
20825         # Define link name with multiple 'newline' and a space
20826         local linkfile="Link"$'\n'"file "$'\n'"01"
20827         # Remove prior hard link
20828         rm -f $DIR/"$linkfile"
20829
20830         # Create file
20831         touch $DIR/"$testfile"
20832         # Create link
20833         ln $DIR/"$testfile" $DIR/"$linkfile"
20834
20835         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
20836                 error "getstripe failed on $DIR/$testfile"
20837
20838         # Call with -0 option
20839         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
20840                 echo "FILE:" | grep -c "FILE:")
20841
20842         # With -0 option the output should be exactly 2 lines.
20843         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
20844 }
20845 run_test 226e "Verify path2fid -0 option with newline and space"
20846
20847 # LU-1299 Executing or running ldd on a truncated executable does not
20848 # cause an out-of-memory condition.
20849 test_227() {
20850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20851         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20852
20853         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20854         chmod +x $MOUNT/date
20855
20856         $MOUNT/date > /dev/null
20857         ldd $MOUNT/date > /dev/null
20858         rm -f $MOUNT/date
20859 }
20860 run_test 227 "running truncated executable does not cause OOM"
20861
20862 # LU-1512 try to reuse idle OI blocks
20863 test_228a() {
20864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20865         remote_mds_nodsh && skip "remote MDS with nodsh"
20866         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20867
20868         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20869         local myDIR=$DIR/$tdir
20870
20871         mkdir -p $myDIR
20872         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20873         $LCTL set_param fail_loc=0x80001002
20874         createmany -o $myDIR/t- 10000
20875         $LCTL set_param fail_loc=0
20876         # The guard is current the largest FID holder
20877         touch $myDIR/guard
20878         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20879                     tr -d '[')
20880         local IDX=$(($SEQ % 64))
20881
20882         do_facet $SINGLEMDS sync
20883         # Make sure journal flushed.
20884         sleep 6
20885         local blk1=$(do_facet $SINGLEMDS \
20886                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20887                      grep Blockcount | awk '{print $4}')
20888
20889         # Remove old files, some OI blocks will become idle.
20890         unlinkmany $myDIR/t- 10000
20891         # Create new files, idle OI blocks should be reused.
20892         createmany -o $myDIR/t- 2000
20893         do_facet $SINGLEMDS sync
20894         # Make sure journal flushed.
20895         sleep 6
20896         local blk2=$(do_facet $SINGLEMDS \
20897                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20898                      grep Blockcount | awk '{print $4}')
20899
20900         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20901 }
20902 run_test 228a "try to reuse idle OI blocks"
20903
20904 test_228b() {
20905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20906         remote_mds_nodsh && skip "remote MDS with nodsh"
20907         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20908
20909         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20910         local myDIR=$DIR/$tdir
20911
20912         mkdir -p $myDIR
20913         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20914         $LCTL set_param fail_loc=0x80001002
20915         createmany -o $myDIR/t- 10000
20916         $LCTL set_param fail_loc=0
20917         # The guard is current the largest FID holder
20918         touch $myDIR/guard
20919         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20920                     tr -d '[')
20921         local IDX=$(($SEQ % 64))
20922
20923         do_facet $SINGLEMDS sync
20924         # Make sure journal flushed.
20925         sleep 6
20926         local blk1=$(do_facet $SINGLEMDS \
20927                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20928                      grep Blockcount | awk '{print $4}')
20929
20930         # Remove old files, some OI blocks will become idle.
20931         unlinkmany $myDIR/t- 10000
20932
20933         # stop the MDT
20934         stop $SINGLEMDS || error "Fail to stop MDT."
20935         # remount the MDT
20936         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20937                 error "Fail to start MDT."
20938
20939         client_up || error "Fail to df."
20940         # Create new files, idle OI blocks should be reused.
20941         createmany -o $myDIR/t- 2000
20942         do_facet $SINGLEMDS sync
20943         # Make sure journal flushed.
20944         sleep 6
20945         local blk2=$(do_facet $SINGLEMDS \
20946                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20947                      grep Blockcount | awk '{print $4}')
20948
20949         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20950 }
20951 run_test 228b "idle OI blocks can be reused after MDT restart"
20952
20953 #LU-1881
20954 test_228c() {
20955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20956         remote_mds_nodsh && skip "remote MDS with nodsh"
20957         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20958
20959         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20960         local myDIR=$DIR/$tdir
20961
20962         mkdir -p $myDIR
20963         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20964         $LCTL set_param fail_loc=0x80001002
20965         # 20000 files can guarantee there are index nodes in the OI file
20966         createmany -o $myDIR/t- 20000
20967         $LCTL set_param fail_loc=0
20968         # The guard is current the largest FID holder
20969         touch $myDIR/guard
20970         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20971                     tr -d '[')
20972         local IDX=$(($SEQ % 64))
20973
20974         do_facet $SINGLEMDS sync
20975         # Make sure journal flushed.
20976         sleep 6
20977         local blk1=$(do_facet $SINGLEMDS \
20978                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20979                      grep Blockcount | awk '{print $4}')
20980
20981         # Remove old files, some OI blocks will become idle.
20982         unlinkmany $myDIR/t- 20000
20983         rm -f $myDIR/guard
20984         # The OI file should become empty now
20985
20986         # Create new files, idle OI blocks should be reused.
20987         createmany -o $myDIR/t- 2000
20988         do_facet $SINGLEMDS sync
20989         # Make sure journal flushed.
20990         sleep 6
20991         local blk2=$(do_facet $SINGLEMDS \
20992                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20993                      grep Blockcount | awk '{print $4}')
20994
20995         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20996 }
20997 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20998
20999 test_229() { # LU-2482, LU-3448
21000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21001         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21002         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21003                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21004
21005         rm -f $DIR/$tfile
21006
21007         # Create a file with a released layout and stripe count 2.
21008         $MULTIOP $DIR/$tfile H2c ||
21009                 error "failed to create file with released layout"
21010
21011         $LFS getstripe -v $DIR/$tfile
21012
21013         local pattern=$($LFS getstripe -L $DIR/$tfile)
21014         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21015
21016         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21017                 error "getstripe"
21018         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21019         stat $DIR/$tfile || error "failed to stat released file"
21020
21021         chown $RUNAS_ID $DIR/$tfile ||
21022                 error "chown $RUNAS_ID $DIR/$tfile failed"
21023
21024         chgrp $RUNAS_ID $DIR/$tfile ||
21025                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21026
21027         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21028         rm $DIR/$tfile || error "failed to remove released file"
21029 }
21030 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21031
21032 test_230a() {
21033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21034         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21035         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21036                 skip "Need MDS version at least 2.11.52"
21037
21038         local MDTIDX=1
21039
21040         test_mkdir $DIR/$tdir
21041         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21042         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21043         [ $mdt_idx -ne 0 ] &&
21044                 error "create local directory on wrong MDT $mdt_idx"
21045
21046         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21047                         error "create remote directory failed"
21048         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21049         [ $mdt_idx -ne $MDTIDX ] &&
21050                 error "create remote directory on wrong MDT $mdt_idx"
21051
21052         createmany -o $DIR/$tdir/test_230/t- 10 ||
21053                 error "create files on remote directory failed"
21054         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21055         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21056         rm -r $DIR/$tdir || error "unlink remote directory failed"
21057 }
21058 run_test 230a "Create remote directory and files under the remote directory"
21059
21060 test_230b() {
21061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21063         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21064                 skip "Need MDS version at least 2.11.52"
21065
21066         local MDTIDX=1
21067         local mdt_index
21068         local i
21069         local file
21070         local pid
21071         local stripe_count
21072         local migrate_dir=$DIR/$tdir/migrate_dir
21073         local other_dir=$DIR/$tdir/other_dir
21074
21075         test_mkdir $DIR/$tdir
21076         test_mkdir -i0 -c1 $migrate_dir
21077         test_mkdir -i0 -c1 $other_dir
21078         for ((i=0; i<10; i++)); do
21079                 mkdir -p $migrate_dir/dir_${i}
21080                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21081                         error "create files under remote dir failed $i"
21082         done
21083
21084         cp /etc/passwd $migrate_dir/$tfile
21085         cp /etc/passwd $other_dir/$tfile
21086         chattr +SAD $migrate_dir
21087         chattr +SAD $migrate_dir/$tfile
21088
21089         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21090         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21091         local old_dir_mode=$(stat -c%f $migrate_dir)
21092         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21093
21094         mkdir -p $migrate_dir/dir_default_stripe2
21095         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21096         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21097
21098         mkdir -p $other_dir
21099         ln $migrate_dir/$tfile $other_dir/luna
21100         ln $migrate_dir/$tfile $migrate_dir/sofia
21101         ln $other_dir/$tfile $migrate_dir/david
21102         ln -s $migrate_dir/$tfile $other_dir/zachary
21103         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21104         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21105
21106         local len
21107         local lnktgt
21108
21109         # inline symlink
21110         for len in 58 59 60; do
21111                 lnktgt=$(str_repeat 'l' $len)
21112                 touch $migrate_dir/$lnktgt
21113                 ln -s $lnktgt $migrate_dir/${len}char_ln
21114         done
21115
21116         # PATH_MAX
21117         for len in 4094 4095; do
21118                 lnktgt=$(str_repeat 'l' $len)
21119                 ln -s $lnktgt $migrate_dir/${len}char_ln
21120         done
21121
21122         # NAME_MAX
21123         for len in 254 255; do
21124                 touch $migrate_dir/$(str_repeat 'l' $len)
21125         done
21126
21127         $LFS migrate -m $MDTIDX $migrate_dir ||
21128                 error "fails on migrating remote dir to MDT1"
21129
21130         echo "migratate to MDT1, then checking.."
21131         for ((i = 0; i < 10; i++)); do
21132                 for file in $(find $migrate_dir/dir_${i}); do
21133                         mdt_index=$($LFS getstripe -m $file)
21134                         # broken symlink getstripe will fail
21135                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21136                                 error "$file is not on MDT${MDTIDX}"
21137                 done
21138         done
21139
21140         # the multiple link file should still in MDT0
21141         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21142         [ $mdt_index == 0 ] ||
21143                 error "$file is not on MDT${MDTIDX}"
21144
21145         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21146         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21147                 error " expect $old_dir_flag get $new_dir_flag"
21148
21149         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21150         [ "$old_file_flag" = "$new_file_flag" ] ||
21151                 error " expect $old_file_flag get $new_file_flag"
21152
21153         local new_dir_mode=$(stat -c%f $migrate_dir)
21154         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21155                 error "expect mode $old_dir_mode get $new_dir_mode"
21156
21157         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21158         [ "$old_file_mode" = "$new_file_mode" ] ||
21159                 error "expect mode $old_file_mode get $new_file_mode"
21160
21161         diff /etc/passwd $migrate_dir/$tfile ||
21162                 error "$tfile different after migration"
21163
21164         diff /etc/passwd $other_dir/luna ||
21165                 error "luna different after migration"
21166
21167         diff /etc/passwd $migrate_dir/sofia ||
21168                 error "sofia different after migration"
21169
21170         diff /etc/passwd $migrate_dir/david ||
21171                 error "david different after migration"
21172
21173         diff /etc/passwd $other_dir/zachary ||
21174                 error "zachary different after migration"
21175
21176         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21177                 error "${tfile}_ln different after migration"
21178
21179         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21180                 error "${tfile}_ln_other different after migration"
21181
21182         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21183         [ $stripe_count = 2 ] ||
21184                 error "dir strpe_count $d != 2 after migration."
21185
21186         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21187         [ $stripe_count = 2 ] ||
21188                 error "file strpe_count $d != 2 after migration."
21189
21190         #migrate back to MDT0
21191         MDTIDX=0
21192
21193         $LFS migrate -m $MDTIDX $migrate_dir ||
21194                 error "fails on migrating remote dir to MDT0"
21195
21196         echo "migrate back to MDT0, checking.."
21197         for file in $(find $migrate_dir); do
21198                 mdt_index=$($LFS getstripe -m $file)
21199                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21200                         error "$file is not on MDT${MDTIDX}"
21201         done
21202
21203         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21204         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21205                 error " expect $old_dir_flag get $new_dir_flag"
21206
21207         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21208         [ "$old_file_flag" = "$new_file_flag" ] ||
21209                 error " expect $old_file_flag get $new_file_flag"
21210
21211         local new_dir_mode=$(stat -c%f $migrate_dir)
21212         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21213                 error "expect mode $old_dir_mode get $new_dir_mode"
21214
21215         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21216         [ "$old_file_mode" = "$new_file_mode" ] ||
21217                 error "expect mode $old_file_mode get $new_file_mode"
21218
21219         diff /etc/passwd ${migrate_dir}/$tfile ||
21220                 error "$tfile different after migration"
21221
21222         diff /etc/passwd ${other_dir}/luna ||
21223                 error "luna different after migration"
21224
21225         diff /etc/passwd ${migrate_dir}/sofia ||
21226                 error "sofia different after migration"
21227
21228         diff /etc/passwd ${other_dir}/zachary ||
21229                 error "zachary different after migration"
21230
21231         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21232                 error "${tfile}_ln different after migration"
21233
21234         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21235                 error "${tfile}_ln_other different after migration"
21236
21237         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21238         [ $stripe_count = 2 ] ||
21239                 error "dir strpe_count $d != 2 after migration."
21240
21241         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21242         [ $stripe_count = 2 ] ||
21243                 error "file strpe_count $d != 2 after migration."
21244
21245         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21246 }
21247 run_test 230b "migrate directory"
21248
21249 test_230c() {
21250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21251         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21252         remote_mds_nodsh && skip "remote MDS with nodsh"
21253         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21254                 skip "Need MDS version at least 2.11.52"
21255
21256         local MDTIDX=1
21257         local total=3
21258         local mdt_index
21259         local file
21260         local migrate_dir=$DIR/$tdir/migrate_dir
21261
21262         #If migrating directory fails in the middle, all entries of
21263         #the directory is still accessiable.
21264         test_mkdir $DIR/$tdir
21265         test_mkdir -i0 -c1 $migrate_dir
21266         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21267         stat $migrate_dir
21268         createmany -o $migrate_dir/f $total ||
21269                 error "create files under ${migrate_dir} failed"
21270
21271         # fail after migrating top dir, and this will fail only once, so the
21272         # first sub file migration will fail (currently f3), others succeed.
21273         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21274         do_facet mds1 lctl set_param fail_loc=0x1801
21275         local t=$(ls $migrate_dir | wc -l)
21276         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21277                 error "migrate should fail"
21278         local u=$(ls $migrate_dir | wc -l)
21279         [ "$u" == "$t" ] || error "$u != $t during migration"
21280
21281         # add new dir/file should succeed
21282         mkdir $migrate_dir/dir ||
21283                 error "mkdir failed under migrating directory"
21284         touch $migrate_dir/file ||
21285                 error "create file failed under migrating directory"
21286
21287         # add file with existing name should fail
21288         for file in $migrate_dir/f*; do
21289                 stat $file > /dev/null || error "stat $file failed"
21290                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21291                         error "open(O_CREAT|O_EXCL) $file should fail"
21292                 $MULTIOP $file m && error "create $file should fail"
21293                 touch $DIR/$tdir/remote_dir/$tfile ||
21294                         error "touch $tfile failed"
21295                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21296                         error "link $file should fail"
21297                 mdt_index=$($LFS getstripe -m $file)
21298                 if [ $mdt_index == 0 ]; then
21299                         # file failed to migrate is not allowed to rename to
21300                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21301                                 error "rename to $file should fail"
21302                 else
21303                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21304                                 error "rename to $file failed"
21305                 fi
21306                 echo hello >> $file || error "write $file failed"
21307         done
21308
21309         # resume migration with different options should fail
21310         $LFS migrate -m 0 $migrate_dir &&
21311                 error "migrate -m 0 $migrate_dir should fail"
21312
21313         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21314                 error "migrate -c 2 $migrate_dir should fail"
21315
21316         # resume migration should succeed
21317         $LFS migrate -m $MDTIDX $migrate_dir ||
21318                 error "migrate $migrate_dir failed"
21319
21320         echo "Finish migration, then checking.."
21321         for file in $(find $migrate_dir); do
21322                 mdt_index=$($LFS getstripe -m $file)
21323                 [ $mdt_index == $MDTIDX ] ||
21324                         error "$file is not on MDT${MDTIDX}"
21325         done
21326
21327         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21328 }
21329 run_test 230c "check directory accessiblity if migration failed"
21330
21331 test_230d() {
21332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21335                 skip "Need MDS version at least 2.11.52"
21336         # LU-11235
21337         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21338
21339         local migrate_dir=$DIR/$tdir/migrate_dir
21340         local old_index
21341         local new_index
21342         local old_count
21343         local new_count
21344         local new_hash
21345         local mdt_index
21346         local i
21347         local j
21348
21349         old_index=$((RANDOM % MDSCOUNT))
21350         old_count=$((MDSCOUNT - old_index))
21351         new_index=$((RANDOM % MDSCOUNT))
21352         new_count=$((MDSCOUNT - new_index))
21353         new_hash=1 # for all_char
21354
21355         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21356         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21357
21358         test_mkdir $DIR/$tdir
21359         test_mkdir -i $old_index -c $old_count $migrate_dir
21360
21361         for ((i=0; i<100; i++)); do
21362                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21363                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21364                         error "create files under remote dir failed $i"
21365         done
21366
21367         echo -n "Migrate from MDT$old_index "
21368         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21369         echo -n "to MDT$new_index"
21370         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21371         echo
21372
21373         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21374         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21375                 error "migrate remote dir error"
21376
21377         echo "Finish migration, then checking.."
21378         for file in $(find $migrate_dir -maxdepth 1); do
21379                 mdt_index=$($LFS getstripe -m $file)
21380                 if [ $mdt_index -lt $new_index ] ||
21381                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21382                         error "$file is on MDT$mdt_index"
21383                 fi
21384         done
21385
21386         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21387 }
21388 run_test 230d "check migrate big directory"
21389
21390 test_230e() {
21391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21393         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21394                 skip "Need MDS version at least 2.11.52"
21395
21396         local i
21397         local j
21398         local a_fid
21399         local b_fid
21400
21401         mkdir_on_mdt0 $DIR/$tdir
21402         mkdir $DIR/$tdir/migrate_dir
21403         mkdir $DIR/$tdir/other_dir
21404         touch $DIR/$tdir/migrate_dir/a
21405         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21406         ls $DIR/$tdir/other_dir
21407
21408         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21409                 error "migrate dir fails"
21410
21411         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21412         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21413
21414         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21415         [ $mdt_index == 0 ] || error "a is not on MDT0"
21416
21417         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21418                 error "migrate dir fails"
21419
21420         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21421         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21422
21423         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21424         [ $mdt_index == 1 ] || error "a is not on MDT1"
21425
21426         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21427         [ $mdt_index == 1 ] || error "b is not on MDT1"
21428
21429         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21430         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21431
21432         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21433
21434         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21435 }
21436 run_test 230e "migrate mulitple local link files"
21437
21438 test_230f() {
21439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21441         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21442                 skip "Need MDS version at least 2.11.52"
21443
21444         local a_fid
21445         local ln_fid
21446
21447         mkdir -p $DIR/$tdir
21448         mkdir $DIR/$tdir/migrate_dir
21449         $LFS mkdir -i1 $DIR/$tdir/other_dir
21450         touch $DIR/$tdir/migrate_dir/a
21451         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21452         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21453         ls $DIR/$tdir/other_dir
21454
21455         # a should be migrated to MDT1, since no other links on MDT0
21456         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21457                 error "#1 migrate dir fails"
21458         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21459         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21460         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21461         [ $mdt_index == 1 ] || error "a is not on MDT1"
21462
21463         # a should stay on MDT1, because it is a mulitple link file
21464         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21465                 error "#2 migrate dir fails"
21466         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21467         [ $mdt_index == 1 ] || error "a is not on MDT1"
21468
21469         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21470                 error "#3 migrate dir fails"
21471
21472         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21473         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21474         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21475
21476         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21477         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21478
21479         # a should be migrated to MDT0, since no other links on MDT1
21480         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21481                 error "#4 migrate dir fails"
21482         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21483         [ $mdt_index == 0 ] || error "a is not on MDT0"
21484
21485         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21486 }
21487 run_test 230f "migrate mulitple remote link files"
21488
21489 test_230g() {
21490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21492         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21493                 skip "Need MDS version at least 2.11.52"
21494
21495         mkdir -p $DIR/$tdir/migrate_dir
21496
21497         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21498                 error "migrating dir to non-exist MDT succeeds"
21499         true
21500 }
21501 run_test 230g "migrate dir to non-exist MDT"
21502
21503 test_230h() {
21504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21505         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21506         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21507                 skip "Need MDS version at least 2.11.52"
21508
21509         local mdt_index
21510
21511         mkdir -p $DIR/$tdir/migrate_dir
21512
21513         $LFS migrate -m1 $DIR &&
21514                 error "migrating mountpoint1 should fail"
21515
21516         $LFS migrate -m1 $DIR/$tdir/.. &&
21517                 error "migrating mountpoint2 should fail"
21518
21519         # same as mv
21520         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21521                 error "migrating $tdir/migrate_dir/.. should fail"
21522
21523         true
21524 }
21525 run_test 230h "migrate .. and root"
21526
21527 test_230i() {
21528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21530         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21531                 skip "Need MDS version at least 2.11.52"
21532
21533         mkdir -p $DIR/$tdir/migrate_dir
21534
21535         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21536                 error "migration fails with a tailing slash"
21537
21538         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21539                 error "migration fails with two tailing slashes"
21540 }
21541 run_test 230i "lfs migrate -m tolerates trailing slashes"
21542
21543 test_230j() {
21544         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21545         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21546                 skip "Need MDS version at least 2.11.52"
21547
21548         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21549         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21550                 error "create $tfile failed"
21551         cat /etc/passwd > $DIR/$tdir/$tfile
21552
21553         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21554
21555         cmp /etc/passwd $DIR/$tdir/$tfile ||
21556                 error "DoM file mismatch after migration"
21557 }
21558 run_test 230j "DoM file data not changed after dir migration"
21559
21560 test_230k() {
21561         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21562         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21563                 skip "Need MDS version at least 2.11.56"
21564
21565         local total=20
21566         local files_on_starting_mdt=0
21567
21568         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21569         $LFS getdirstripe $DIR/$tdir
21570         for i in $(seq $total); do
21571                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21572                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21573                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21574         done
21575
21576         echo "$files_on_starting_mdt files on MDT0"
21577
21578         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21579         $LFS getdirstripe $DIR/$tdir
21580
21581         files_on_starting_mdt=0
21582         for i in $(seq $total); do
21583                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21584                         error "file $tfile.$i mismatch after migration"
21585                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21586                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21587         done
21588
21589         echo "$files_on_starting_mdt files on MDT1 after migration"
21590         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21591
21592         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21593         $LFS getdirstripe $DIR/$tdir
21594
21595         files_on_starting_mdt=0
21596         for i in $(seq $total); do
21597                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21598                         error "file $tfile.$i mismatch after 2nd migration"
21599                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21600                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21601         done
21602
21603         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21604         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21605
21606         true
21607 }
21608 run_test 230k "file data not changed after dir migration"
21609
21610 test_230l() {
21611         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21612         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21613                 skip "Need MDS version at least 2.11.56"
21614
21615         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21616         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21617                 error "create files under remote dir failed $i"
21618         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21619 }
21620 run_test 230l "readdir between MDTs won't crash"
21621
21622 test_230m() {
21623         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21624         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21625                 skip "Need MDS version at least 2.11.56"
21626
21627         local MDTIDX=1
21628         local mig_dir=$DIR/$tdir/migrate_dir
21629         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21630         local shortstr="b"
21631         local val
21632
21633         echo "Creating files and dirs with xattrs"
21634         test_mkdir $DIR/$tdir
21635         test_mkdir -i0 -c1 $mig_dir
21636         mkdir $mig_dir/dir
21637         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21638                 error "cannot set xattr attr1 on dir"
21639         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21640                 error "cannot set xattr attr2 on dir"
21641         touch $mig_dir/dir/f0
21642         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21643                 error "cannot set xattr attr1 on file"
21644         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21645                 error "cannot set xattr attr2 on file"
21646         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21647         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21648         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21649         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21650         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21651         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21652         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21653         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21654         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21655
21656         echo "Migrating to MDT1"
21657         $LFS migrate -m $MDTIDX $mig_dir ||
21658                 error "fails on migrating dir to MDT1"
21659
21660         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21661         echo "Checking xattrs"
21662         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21663         [ "$val" = $longstr ] ||
21664                 error "expecting xattr1 $longstr on dir, found $val"
21665         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21666         [ "$val" = $shortstr ] ||
21667                 error "expecting xattr2 $shortstr on dir, found $val"
21668         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21669         [ "$val" = $longstr ] ||
21670                 error "expecting xattr1 $longstr on file, found $val"
21671         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21672         [ "$val" = $shortstr ] ||
21673                 error "expecting xattr2 $shortstr on file, found $val"
21674 }
21675 run_test 230m "xattrs not changed after dir migration"
21676
21677 test_230n() {
21678         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21679         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21680                 skip "Need MDS version at least 2.13.53"
21681
21682         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21683         cat /etc/hosts > $DIR/$tdir/$tfile
21684         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21685         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21686
21687         cmp /etc/hosts $DIR/$tdir/$tfile ||
21688                 error "File data mismatch after migration"
21689 }
21690 run_test 230n "Dir migration with mirrored file"
21691
21692 test_230o() {
21693         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21694         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21695                 skip "Need MDS version at least 2.13.52"
21696
21697         local mdts=$(comma_list $(mdts_nodes))
21698         local timeout=100
21699         local restripe_status
21700         local delta
21701         local i
21702
21703         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21704
21705         # in case "crush" hash type is not set
21706         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21707
21708         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21709                            mdt.*MDT0000.enable_dir_restripe)
21710         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21711         stack_trap "do_nodes $mdts $LCTL set_param \
21712                     mdt.*.enable_dir_restripe=$restripe_status"
21713
21714         mkdir $DIR/$tdir
21715         createmany -m $DIR/$tdir/f 100 ||
21716                 error "create files under remote dir failed $i"
21717         createmany -d $DIR/$tdir/d 100 ||
21718                 error "create dirs under remote dir failed $i"
21719
21720         for i in $(seq 2 $MDSCOUNT); do
21721                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21722                 $LFS setdirstripe -c $i $DIR/$tdir ||
21723                         error "split -c $i $tdir failed"
21724                 wait_update $HOSTNAME \
21725                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21726                         error "dir split not finished"
21727                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21728                         awk '/migrate/ {sum += $2} END { print sum }')
21729                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21730                 # delta is around total_files/stripe_count
21731                 (( $delta < 200 / (i - 1) + 4 )) ||
21732                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21733         done
21734 }
21735 run_test 230o "dir split"
21736
21737 test_230p() {
21738         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21739         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21740                 skip "Need MDS version at least 2.13.52"
21741
21742         local mdts=$(comma_list $(mdts_nodes))
21743         local timeout=100
21744         local restripe_status
21745         local delta
21746         local c
21747
21748         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21749
21750         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21751
21752         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21753                            mdt.*MDT0000.enable_dir_restripe)
21754         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21755         stack_trap "do_nodes $mdts $LCTL set_param \
21756                     mdt.*.enable_dir_restripe=$restripe_status"
21757
21758         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21759         createmany -m $DIR/$tdir/f 100 ||
21760                 error "create files under remote dir failed"
21761         createmany -d $DIR/$tdir/d 100 ||
21762                 error "create dirs under remote dir failed"
21763
21764         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21765                 local mdt_hash="crush"
21766
21767                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21768                 $LFS setdirstripe -c $c $DIR/$tdir ||
21769                         error "split -c $c $tdir failed"
21770                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21771                         mdt_hash="$mdt_hash,fixed"
21772                 elif [ $c -eq 1 ]; then
21773                         mdt_hash="none"
21774                 fi
21775                 wait_update $HOSTNAME \
21776                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21777                         error "dir merge not finished"
21778                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21779                         awk '/migrate/ {sum += $2} END { print sum }')
21780                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21781                 # delta is around total_files/stripe_count
21782                 (( delta < 200 / c + 4 )) ||
21783                         error "$delta files migrated >= $((200 / c + 4))"
21784         done
21785 }
21786 run_test 230p "dir merge"
21787
21788 test_230q() {
21789         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21790         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21791                 skip "Need MDS version at least 2.13.52"
21792
21793         local mdts=$(comma_list $(mdts_nodes))
21794         local saved_threshold=$(do_facet mds1 \
21795                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21796         local saved_delta=$(do_facet mds1 \
21797                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21798         local threshold=100
21799         local delta=2
21800         local total=0
21801         local stripe_count=0
21802         local stripe_index
21803         local nr_files
21804         local create
21805
21806         # test with fewer files on ZFS
21807         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21808
21809         stack_trap "do_nodes $mdts $LCTL set_param \
21810                     mdt.*.dir_split_count=$saved_threshold"
21811         stack_trap "do_nodes $mdts $LCTL set_param \
21812                     mdt.*.dir_split_delta=$saved_delta"
21813         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21814         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21815         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21816         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21817         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21818         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21819
21820         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21821         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21822
21823         create=$((threshold * 3 / 2))
21824         while [ $stripe_count -lt $MDSCOUNT ]; do
21825                 createmany -m $DIR/$tdir/f $total $create ||
21826                         error "create sub files failed"
21827                 stat $DIR/$tdir > /dev/null
21828                 total=$((total + create))
21829                 stripe_count=$((stripe_count + delta))
21830                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21831
21832                 wait_update $HOSTNAME \
21833                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21834                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21835
21836                 wait_update $HOSTNAME \
21837                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21838                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21839
21840                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21841                 echo "$nr_files/$total files on MDT$stripe_index after split"
21842                 # allow 10% margin of imbalance with crush hash
21843                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21844                         error "$nr_files files on MDT$stripe_index after split"
21845
21846                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21847                 [ $nr_files -eq $total ] ||
21848                         error "total sub files $nr_files != $total"
21849         done
21850
21851         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21852
21853         echo "fixed layout directory won't auto split"
21854         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21855         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21856                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21857         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21858                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21859 }
21860 run_test 230q "dir auto split"
21861
21862 test_230r() {
21863         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21864         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21865         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21866                 skip "Need MDS version at least 2.13.54"
21867
21868         # maximum amount of local locks:
21869         # parent striped dir - 2 locks
21870         # new stripe in parent to migrate to - 1 lock
21871         # source and target - 2 locks
21872         # Total 5 locks for regular file
21873         mkdir -p $DIR/$tdir
21874         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21875         touch $DIR/$tdir/dir1/eee
21876
21877         # create 4 hardlink for 4 more locks
21878         # Total: 9 locks > RS_MAX_LOCKS (8)
21879         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21880         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21881         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21882         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21883         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21884         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21885         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21886         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21887
21888         cancel_lru_locks mdc
21889
21890         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21891                 error "migrate dir fails"
21892
21893         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21894 }
21895 run_test 230r "migrate with too many local locks"
21896
21897 test_230s() {
21898         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21899                 skip "Need MDS version at least 2.14.52"
21900
21901         local mdts=$(comma_list $(mdts_nodes))
21902         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21903                                 mdt.*MDT0000.enable_dir_restripe)
21904
21905         stack_trap "do_nodes $mdts $LCTL set_param \
21906                     mdt.*.enable_dir_restripe=$restripe_status"
21907
21908         local st
21909         for st in 0 1; do
21910                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21911                 test_mkdir $DIR/$tdir
21912                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21913                         error "$LFS mkdir should return EEXIST if target exists"
21914                 rmdir $DIR/$tdir
21915         done
21916 }
21917 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21918
21919 test_230t()
21920 {
21921         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21922         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21923                 skip "Need MDS version at least 2.14.50"
21924
21925         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21926         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21927         $LFS project -p 1 -s $DIR/$tdir ||
21928                 error "set $tdir project id failed"
21929         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21930                 error "set subdir project id failed"
21931         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21932 }
21933 run_test 230t "migrate directory with project ID set"
21934
21935 test_230u()
21936 {
21937         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21938         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21939                 skip "Need MDS version at least 2.14.53"
21940
21941         local count
21942
21943         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21944         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21945         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21946         for i in $(seq 0 $((MDSCOUNT - 1))); do
21947                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21948                 echo "$count dirs migrated to MDT$i"
21949         done
21950         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21951         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21952 }
21953 run_test 230u "migrate directory by QOS"
21954
21955 test_230v()
21956 {
21957         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21958         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21959                 skip "Need MDS version at least 2.14.53"
21960
21961         local count
21962
21963         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21964         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21965         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21966         for i in $(seq 0 $((MDSCOUNT - 1))); do
21967                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21968                 echo "$count subdirs migrated to MDT$i"
21969                 (( i == 3 )) && (( count > 0 )) &&
21970                         error "subdir shouldn't be migrated to MDT3"
21971         done
21972         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21973         (( count == 3 )) || error "dirs migrated to $count MDTs"
21974 }
21975 run_test 230v "subdir migrated to the MDT where its parent is located"
21976
21977 test_230w() {
21978         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21979         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21980                 skip "Need MDS version at least 2.15.0"
21981
21982         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21983         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21984         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21985
21986         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21987                 error "migrate failed"
21988
21989         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21990                 error "$tdir stripe count mismatch"
21991
21992         for i in $(seq 0 9); do
21993                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21994                         error "d$i is striped"
21995         done
21996 }
21997 run_test 230w "non-recursive mode dir migration"
21998
21999 test_230x() {
22000         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22001         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22002                 skip "Need MDS version at least 2.15.0"
22003
22004         mkdir -p $DIR/$tdir || error "mkdir failed"
22005         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22006
22007         local mdt_name=$(mdtname_from_index 0)
22008         local low=$(do_facet mds2 $LCTL get_param -n \
22009                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22010         local high=$(do_facet mds2 $LCTL get_param -n \
22011                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22012         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22013         local maxage=$(do_facet mds2 $LCTL get_param -n \
22014                 osp.*$mdt_name-osp-MDT0001.maxage)
22015
22016         stack_trap "do_facet mds2 $LCTL set_param -n \
22017                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22018                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22019         stack_trap "do_facet mds2 $LCTL set_param -n \
22020                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22021
22022         do_facet mds2 $LCTL set_param -n \
22023                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22024         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22025         sleep 4
22026         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22027                 error "migrate $tdir should fail"
22028
22029         do_facet mds2 $LCTL set_param -n \
22030                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22031         do_facet mds2 $LCTL set_param -n \
22032                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22033         sleep 4
22034         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22035                 error "migrate failed"
22036         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22037                 error "$tdir stripe count mismatch"
22038 }
22039 run_test 230x "dir migration check space"
22040
22041 test_230y() {
22042         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22043         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22044                 skip "Need MDS version at least 2.15.55.45"
22045
22046         local pid
22047
22048         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22049         $LFS getdirstripe $DIR/$tdir
22050         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22051         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22052         pid=$!
22053         sleep 1
22054
22055         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22056         do_facet mds2 lctl set_param fail_loc=0x1802
22057
22058         wait $pid
22059         do_facet mds2 lctl set_param fail_loc=0
22060         $LFS getdirstripe $DIR/$tdir
22061         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22062         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22063 }
22064 run_test 230y "unlink dir with bad hash type"
22065
22066 test_230z() {
22067         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22068         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22069                 skip "Need MDS version at least 2.15.55.45"
22070
22071         local pid
22072
22073         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22074         $LFS getdirstripe $DIR/$tdir
22075         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22076         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22077         pid=$!
22078         sleep 1
22079
22080         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22081         do_facet mds2 lctl set_param fail_loc=0x1802
22082
22083         wait $pid
22084         do_facet mds2 lctl set_param fail_loc=0
22085         $LFS getdirstripe $DIR/$tdir
22086
22087         # resume migration
22088         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22089                 error "resume migration failed"
22090         $LFS getdirstripe $DIR/$tdir
22091         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22092                 error "migration is not finished"
22093 }
22094 run_test 230z "resume dir migration with bad hash type"
22095
22096 test_231a()
22097 {
22098         # For simplicity this test assumes that max_pages_per_rpc
22099         # is the same across all OSCs
22100         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22101         local bulk_size=$((max_pages * PAGE_SIZE))
22102         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22103                                        head -n 1)
22104
22105         mkdir -p $DIR/$tdir
22106         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22107                 error "failed to set stripe with -S ${brw_size}M option"
22108         stack_trap "rm -rf $DIR/$tdir"
22109
22110         # clear the OSC stats
22111         $LCTL set_param osc.*.stats=0 &>/dev/null
22112         stop_writeback
22113
22114         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22115         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22116                 oflag=direct &>/dev/null || error "dd failed"
22117
22118         sync; sleep 1; sync # just to be safe
22119         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22120         if [ x$nrpcs != "x1" ]; then
22121                 $LCTL get_param osc.*.stats
22122                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22123         fi
22124
22125         start_writeback
22126         # Drop the OSC cache, otherwise we will read from it
22127         cancel_lru_locks osc
22128
22129         # clear the OSC stats
22130         $LCTL set_param osc.*.stats=0 &>/dev/null
22131
22132         # Client reads $bulk_size.
22133         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22134                 iflag=direct &>/dev/null || error "dd failed"
22135
22136         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22137         if [ x$nrpcs != "x1" ]; then
22138                 $LCTL get_param osc.*.stats
22139                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22140         fi
22141 }
22142 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22143
22144 test_231b() {
22145         mkdir -p $DIR/$tdir
22146         stack_trap "rm -rf $DIR/$tdir"
22147         local i
22148         for i in {0..1023}; do
22149                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22150                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22151                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22152         done
22153         sync
22154 }
22155 run_test 231b "must not assert on fully utilized OST request buffer"
22156
22157 test_232a() {
22158         mkdir -p $DIR/$tdir
22159         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22160
22161         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22162         do_facet ost1 $LCTL set_param fail_loc=0x31c
22163
22164         # ignore dd failure
22165         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22166         stack_trap "rm -f $DIR/$tdir/$tfile"
22167
22168         do_facet ost1 $LCTL set_param fail_loc=0
22169         umount_client $MOUNT || error "umount failed"
22170         mount_client $MOUNT || error "mount failed"
22171         stop ost1 || error "cannot stop ost1"
22172         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22173 }
22174 run_test 232a "failed lock should not block umount"
22175
22176 test_232b() {
22177         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22178                 skip "Need MDS version at least 2.10.58"
22179
22180         mkdir -p $DIR/$tdir
22181         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22182         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22183         stack_trap "rm -f $DIR/$tdir/$tfile"
22184         sync
22185         cancel_lru_locks osc
22186
22187         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22188         do_facet ost1 $LCTL set_param fail_loc=0x31c
22189
22190         # ignore failure
22191         $LFS data_version $DIR/$tdir/$tfile || true
22192
22193         do_facet ost1 $LCTL set_param fail_loc=0
22194         umount_client $MOUNT || error "umount failed"
22195         mount_client $MOUNT || error "mount failed"
22196         stop ost1 || error "cannot stop ost1"
22197         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22198 }
22199 run_test 232b "failed data version lock should not block umount"
22200
22201 test_233a() {
22202         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22203                 skip "Need MDS version at least 2.3.64"
22204         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22205
22206         local fid=$($LFS path2fid $MOUNT)
22207
22208         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22209                 error "cannot access $MOUNT using its FID '$fid'"
22210 }
22211 run_test 233a "checking that OBF of the FS root succeeds"
22212
22213 test_233b() {
22214         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22215                 skip "Need MDS version at least 2.5.90"
22216         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22217
22218         local fid=$($LFS path2fid $MOUNT/.lustre)
22219
22220         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22221                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22222
22223         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22224         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22225                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22226 }
22227 run_test 233b "checking that OBF of the FS .lustre succeeds"
22228
22229 test_234() {
22230         local p="$TMP/sanityN-$TESTNAME.parameters"
22231         save_lustre_params client "llite.*.xattr_cache" > $p
22232         lctl set_param llite.*.xattr_cache 1 ||
22233                 skip_env "xattr cache is not supported"
22234
22235         mkdir -p $DIR/$tdir || error "mkdir failed"
22236         touch $DIR/$tdir/$tfile || error "touch failed"
22237         # OBD_FAIL_LLITE_XATTR_ENOMEM
22238         $LCTL set_param fail_loc=0x1405
22239         getfattr -n user.attr $DIR/$tdir/$tfile &&
22240                 error "getfattr should have failed with ENOMEM"
22241         $LCTL set_param fail_loc=0x0
22242         rm -rf $DIR/$tdir
22243
22244         restore_lustre_params < $p
22245         rm -f $p
22246 }
22247 run_test 234 "xattr cache should not crash on ENOMEM"
22248
22249 test_235() {
22250         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22251                 skip "Need MDS version at least 2.4.52"
22252
22253         flock_deadlock $DIR/$tfile
22254         local RC=$?
22255         case $RC in
22256                 0)
22257                 ;;
22258                 124) error "process hangs on a deadlock"
22259                 ;;
22260                 *) error "error executing flock_deadlock $DIR/$tfile"
22261                 ;;
22262         esac
22263 }
22264 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22265
22266 #LU-2935
22267 test_236() {
22268         check_swap_layouts_support
22269
22270         local ref1=/etc/passwd
22271         local ref2=/etc/group
22272         local file1=$DIR/$tdir/f1
22273         local file2=$DIR/$tdir/f2
22274
22275         test_mkdir -c1 $DIR/$tdir
22276         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22277         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22278         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22279         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22280         local fd=$(free_fd)
22281         local cmd="exec $fd<>$file2"
22282         eval $cmd
22283         rm $file2
22284         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22285                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22286         cmd="exec $fd>&-"
22287         eval $cmd
22288         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22289
22290         #cleanup
22291         rm -rf $DIR/$tdir
22292 }
22293 run_test 236 "Layout swap on open unlinked file"
22294
22295 # LU-4659 linkea consistency
22296 test_238() {
22297         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22298                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22299                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22300                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22301
22302         touch $DIR/$tfile
22303         ln $DIR/$tfile $DIR/$tfile.lnk
22304         touch $DIR/$tfile.new
22305         mv $DIR/$tfile.new $DIR/$tfile
22306         local fid1=$($LFS path2fid $DIR/$tfile)
22307         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22308         local path1=$($LFS fid2path $FSNAME "$fid1")
22309         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22310         local path2=$($LFS fid2path $FSNAME "$fid2")
22311         [ $tfile.lnk == $path2 ] ||
22312                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22313         rm -f $DIR/$tfile*
22314 }
22315 run_test 238 "Verify linkea consistency"
22316
22317 test_239A() { # was test_239
22318         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22319                 skip "Need MDS version at least 2.5.60"
22320
22321         local list=$(comma_list $(mdts_nodes))
22322
22323         mkdir -p $DIR/$tdir
22324         createmany -o $DIR/$tdir/f- 5000
22325         unlinkmany $DIR/$tdir/f- 5000
22326         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22327                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22328         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22329                         osp.*MDT*.sync_in_flight" | calc_sum)
22330         [ "$changes" -eq 0 ] || error "$changes not synced"
22331 }
22332 run_test 239A "osp_sync test"
22333
22334 test_239a() { #LU-5297
22335         remote_mds_nodsh && skip "remote MDS with nodsh"
22336
22337         touch $DIR/$tfile
22338         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22339         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22340         chgrp $RUNAS_GID $DIR/$tfile
22341         wait_delete_completed
22342 }
22343 run_test 239a "process invalid osp sync record correctly"
22344
22345 test_239b() { #LU-5297
22346         remote_mds_nodsh && skip "remote MDS with nodsh"
22347
22348         touch $DIR/$tfile1
22349         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22350         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22351         chgrp $RUNAS_GID $DIR/$tfile1
22352         wait_delete_completed
22353         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22354         touch $DIR/$tfile2
22355         chgrp $RUNAS_GID $DIR/$tfile2
22356         wait_delete_completed
22357 }
22358 run_test 239b "process osp sync record with ENOMEM error correctly"
22359
22360 test_240() {
22361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22362         remote_mds_nodsh && skip "remote MDS with nodsh"
22363
22364         mkdir -p $DIR/$tdir
22365
22366         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22367                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22368         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22369                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22370
22371         umount_client $MOUNT || error "umount failed"
22372         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22373         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22374         mount_client $MOUNT || error "failed to mount client"
22375
22376         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22377         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22378 }
22379 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22380
22381 test_241_bio() {
22382         local count=$1
22383         local bsize=$2
22384
22385         for LOOP in $(seq $count); do
22386                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22387                 cancel_lru_locks $OSC || true
22388         done
22389 }
22390
22391 test_241_dio() {
22392         local count=$1
22393         local bsize=$2
22394
22395         for LOOP in $(seq $1); do
22396                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22397                         2>/dev/null
22398         done
22399 }
22400
22401 test_241a() { # was test_241
22402         local bsize=$PAGE_SIZE
22403
22404         (( bsize < 40960 )) && bsize=40960
22405         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22406         ls -la $DIR/$tfile
22407         cancel_lru_locks $OSC
22408         test_241_bio 1000 $bsize &
22409         PID=$!
22410         test_241_dio 1000 $bsize
22411         wait $PID
22412 }
22413 run_test 241a "bio vs dio"
22414
22415 test_241b() {
22416         local bsize=$PAGE_SIZE
22417
22418         (( bsize < 40960 )) && bsize=40960
22419         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22420         ls -la $DIR/$tfile
22421         test_241_dio 1000 $bsize &
22422         PID=$!
22423         test_241_dio 1000 $bsize
22424         wait $PID
22425 }
22426 run_test 241b "dio vs dio"
22427
22428 test_242() {
22429         remote_mds_nodsh && skip "remote MDS with nodsh"
22430
22431         mkdir_on_mdt0 $DIR/$tdir
22432         touch $DIR/$tdir/$tfile
22433
22434         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22435         do_facet mds1 lctl set_param fail_loc=0x105
22436         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22437
22438         do_facet mds1 lctl set_param fail_loc=0
22439         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22440 }
22441 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22442
22443 test_243()
22444 {
22445         test_mkdir $DIR/$tdir
22446         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22447 }
22448 run_test 243 "various group lock tests"
22449
22450 test_244a()
22451 {
22452         test_mkdir $DIR/$tdir
22453         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22454         sendfile_grouplock $DIR/$tdir/$tfile || \
22455                 error "sendfile+grouplock failed"
22456         rm -rf $DIR/$tdir
22457 }
22458 run_test 244a "sendfile with group lock tests"
22459
22460 test_244b()
22461 {
22462         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22463
22464         local threads=50
22465         local size=$((1024*1024))
22466
22467         test_mkdir $DIR/$tdir
22468         for i in $(seq 1 $threads); do
22469                 local file=$DIR/$tdir/file_$((i / 10))
22470                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22471                 local pids[$i]=$!
22472         done
22473         for i in $(seq 1 $threads); do
22474                 wait ${pids[$i]}
22475         done
22476 }
22477 run_test 244b "multi-threaded write with group lock"
22478
22479 test_245a() {
22480         local flagname="multi_mod_rpcs"
22481         local connect_data_name="max_mod_rpcs"
22482         local out
22483
22484         # check if multiple modify RPCs flag is set
22485         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22486                 grep "connect_flags:")
22487         echo "$out"
22488
22489         echo "$out" | grep -qw $flagname
22490         if [ $? -ne 0 ]; then
22491                 echo "connect flag $flagname is not set"
22492                 return
22493         fi
22494
22495         # check if multiple modify RPCs data is set
22496         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22497         echo "$out"
22498
22499         echo "$out" | grep -qw $connect_data_name ||
22500                 error "import should have connect data $connect_data_name"
22501 }
22502 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22503
22504 test_245b() {
22505         local flagname="multi_mod_rpcs"
22506         local connect_data_name="max_mod_rpcs"
22507         local out
22508
22509         remote_mds_nodsh && skip "remote MDS with nodsh"
22510         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22511
22512         # check if multiple modify RPCs flag is set
22513         out=$(do_facet mds1 \
22514               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22515               grep "connect_flags:")
22516         echo "$out"
22517
22518         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22519
22520         # check if multiple modify RPCs data is set
22521         out=$(do_facet mds1 \
22522               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22523
22524         [[ "$out" =~ $connect_data_name ]] ||
22525                 {
22526                         echo "$out"
22527                         error "missing connect data $connect_data_name"
22528                 }
22529 }
22530 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22531
22532 cleanup_247() {
22533         local submount=$1
22534
22535         trap 0
22536         umount_client $submount
22537         rmdir $submount
22538 }
22539
22540 test_247a() {
22541         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22542                 grep -q subtree ||
22543                 skip_env "Fileset feature is not supported"
22544
22545         local submount=${MOUNT}_$tdir
22546
22547         mkdir $MOUNT/$tdir
22548         mkdir -p $submount || error "mkdir $submount failed"
22549         FILESET="$FILESET/$tdir" mount_client $submount ||
22550                 error "mount $submount failed"
22551         trap "cleanup_247 $submount" EXIT
22552         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22553         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22554                 error "read $MOUNT/$tdir/$tfile failed"
22555         cleanup_247 $submount
22556 }
22557 run_test 247a "mount subdir as fileset"
22558
22559 test_247b() {
22560         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22561                 skip_env "Fileset feature is not supported"
22562
22563         local submount=${MOUNT}_$tdir
22564
22565         rm -rf $MOUNT/$tdir
22566         mkdir -p $submount || error "mkdir $submount failed"
22567         SKIP_FILESET=1
22568         FILESET="$FILESET/$tdir" mount_client $submount &&
22569                 error "mount $submount should fail"
22570         rmdir $submount
22571 }
22572 run_test 247b "mount subdir that dose not exist"
22573
22574 test_247c() {
22575         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22576                 skip_env "Fileset feature is not supported"
22577
22578         local submount=${MOUNT}_$tdir
22579
22580         mkdir -p $MOUNT/$tdir/dir1
22581         mkdir -p $submount || error "mkdir $submount failed"
22582         trap "cleanup_247 $submount" EXIT
22583         FILESET="$FILESET/$tdir" mount_client $submount ||
22584                 error "mount $submount failed"
22585         local fid=$($LFS path2fid $MOUNT/)
22586         $LFS fid2path $submount $fid && error "fid2path should fail"
22587         cleanup_247 $submount
22588 }
22589 run_test 247c "running fid2path outside subdirectory root"
22590
22591 test_247d() {
22592         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22593                 skip "Fileset feature is not supported"
22594
22595         local submount=${MOUNT}_$tdir
22596
22597         mkdir -p $MOUNT/$tdir/dir1
22598         mkdir -p $submount || error "mkdir $submount failed"
22599         FILESET="$FILESET/$tdir" mount_client $submount ||
22600                 error "mount $submount failed"
22601         trap "cleanup_247 $submount" EXIT
22602
22603         local td=$submount/dir1
22604         local fid=$($LFS path2fid $td)
22605         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22606
22607         # check that we get the same pathname back
22608         local rootpath
22609         local found
22610         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22611                 echo "$rootpath $fid"
22612                 found=$($LFS fid2path $rootpath "$fid")
22613                 [ -n "$found" ] || error "fid2path should succeed"
22614                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22615         done
22616         # check wrong root path format
22617         rootpath=$submount"_wrong"
22618         found=$($LFS fid2path $rootpath "$fid")
22619         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22620
22621         cleanup_247 $submount
22622 }
22623 run_test 247d "running fid2path inside subdirectory root"
22624
22625 # LU-8037
22626 test_247e() {
22627         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22628                 grep -q subtree ||
22629                 skip "Fileset feature is not supported"
22630
22631         local submount=${MOUNT}_$tdir
22632
22633         mkdir $MOUNT/$tdir
22634         mkdir -p $submount || error "mkdir $submount failed"
22635         FILESET="$FILESET/.." mount_client $submount &&
22636                 error "mount $submount should fail"
22637         rmdir $submount
22638 }
22639 run_test 247e "mount .. as fileset"
22640
22641 test_247f() {
22642         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22643         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22644                 skip "Need at least version 2.14.50.162"
22645         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22646                 skip "Fileset feature is not supported"
22647
22648         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22649         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22650                 error "mkdir remote failed"
22651         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22652                 error "mkdir remote/subdir failed"
22653         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22654                 error "mkdir striped failed"
22655         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22656
22657         local submount=${MOUNT}_$tdir
22658
22659         mkdir -p $submount || error "mkdir $submount failed"
22660         stack_trap "rmdir $submount"
22661
22662         local dir
22663         local fileset=$FILESET
22664         local mdts=$(comma_list $(mdts_nodes))
22665
22666         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22667         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22668                 $tdir/striped/subdir $tdir/striped/.; do
22669                 FILESET="$fileset/$dir" mount_client $submount ||
22670                         error "mount $dir failed"
22671                 umount_client $submount
22672         done
22673 }
22674 run_test 247f "mount striped or remote directory as fileset"
22675
22676 test_subdir_mount_lock()
22677 {
22678         local testdir=$1
22679         local submount=${MOUNT}_$(basename $testdir)
22680
22681         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22682
22683         mkdir -p $submount || error "mkdir $submount failed"
22684         stack_trap "rmdir $submount"
22685
22686         FILESET="$fileset/$testdir" mount_client $submount ||
22687                 error "mount $FILESET failed"
22688         stack_trap "umount $submount"
22689
22690         local mdts=$(comma_list $(mdts_nodes))
22691
22692         local nrpcs
22693
22694         stat $submount > /dev/null || error "stat $submount failed"
22695         cancel_lru_locks $MDC
22696         stat $submount > /dev/null || error "stat $submount failed"
22697         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22698         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22699         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22700         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22701                 awk '/getattr/ {sum += $2} END {print sum}')
22702
22703         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22704 }
22705
22706 test_247g() {
22707         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22708
22709         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22710                 error "mkdir $tdir failed"
22711         test_subdir_mount_lock $tdir
22712 }
22713 run_test 247g "striped directory submount revalidate ROOT from cache"
22714
22715 test_247h() {
22716         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22717         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22718                 skip "Need MDS version at least 2.15.51"
22719
22720         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22721         test_subdir_mount_lock $tdir
22722         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22723         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22724                 error "mkdir $tdir.1 failed"
22725         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22726 }
22727 run_test 247h "remote directory submount revalidate ROOT from cache"
22728
22729 test_248a() {
22730         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22731         [ -z "$fast_read_sav" ] && skip "no fast read support"
22732
22733         # create a large file for fast read verification
22734         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22735
22736         # make sure the file is created correctly
22737         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22738                 { rm -f $DIR/$tfile; skip "file creation error"; }
22739
22740         echo "Test 1: verify that fast read is 4 times faster on cache read"
22741
22742         # small read with fast read enabled
22743         $LCTL set_param -n llite.*.fast_read=1
22744         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22745                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22746                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22747         # small read with fast read disabled
22748         $LCTL set_param -n llite.*.fast_read=0
22749         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22750                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22751                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22752
22753         # verify that fast read is 4 times faster for cache read
22754         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22755                 error_not_in_vm "fast read was not 4 times faster: " \
22756                            "$t_fast vs $t_slow"
22757
22758         echo "Test 2: verify the performance between big and small read"
22759         $LCTL set_param -n llite.*.fast_read=1
22760
22761         # 1k non-cache read
22762         cancel_lru_locks osc
22763         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22764                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22765                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22766
22767         # 1M non-cache read
22768         cancel_lru_locks osc
22769         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22770                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22771                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22772
22773         # verify that big IO is not 4 times faster than small IO
22774         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22775                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22776
22777         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22778         rm -f $DIR/$tfile
22779 }
22780 run_test 248a "fast read verification"
22781
22782 test_248b() {
22783         # Default short_io_bytes=16384, try both smaller and larger sizes.
22784         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22785         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22786         echo "bs=53248 count=113 normal buffered write"
22787         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22788                 error "dd of initial data file failed"
22789         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22790
22791         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22792         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22793                 error "dd with sync normal writes failed"
22794         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22795
22796         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22797         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22798                 error "dd with sync small writes failed"
22799         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22800
22801         cancel_lru_locks osc
22802
22803         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22804         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22805         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22806         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22807                 iflag=direct || error "dd with O_DIRECT small read failed"
22808         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22809         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22810                 error "compare $TMP/$tfile.1 failed"
22811
22812         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22813         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22814
22815         # just to see what the maximum tunable value is, and test parsing
22816         echo "test invalid parameter 2MB"
22817         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22818                 error "too-large short_io_bytes allowed"
22819         echo "test maximum parameter 512KB"
22820         # if we can set a larger short_io_bytes, run test regardless of version
22821         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22822                 # older clients may not allow setting it this large, that's OK
22823                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22824                         skip "Need at least client version 2.13.50"
22825                 error "medium short_io_bytes failed"
22826         fi
22827         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22828         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22829
22830         echo "test large parameter 64KB"
22831         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22832         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22833
22834         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22835         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22836                 error "dd with sync large writes failed"
22837         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22838
22839         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22840         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22841         num=$((113 * 4096 / PAGE_SIZE))
22842         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22843         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22844                 error "dd with O_DIRECT large writes failed"
22845         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22846                 error "compare $DIR/$tfile.3 failed"
22847
22848         cancel_lru_locks osc
22849
22850         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22851         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22852                 error "dd with O_DIRECT large read failed"
22853         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22854                 error "compare $TMP/$tfile.2 failed"
22855
22856         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22857         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22858                 error "dd with O_DIRECT large read failed"
22859         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22860                 error "compare $TMP/$tfile.3 failed"
22861 }
22862 run_test 248b "test short_io read and write for both small and large sizes"
22863
22864 test_249() { # LU-7890
22865         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22866                 skip "Need at least version 2.8.54"
22867
22868         rm -f $DIR/$tfile
22869         $LFS setstripe -c 1 $DIR/$tfile
22870         # Offset 2T == 4k * 512M
22871         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22872                 error "dd to 2T offset failed"
22873 }
22874 run_test 249 "Write above 2T file size"
22875
22876 test_250() {
22877         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22878          && skip "no 16TB file size limit on ZFS"
22879
22880         $LFS setstripe -c 1 $DIR/$tfile
22881         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22882         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22883         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22884         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22885                 conv=notrunc,fsync && error "append succeeded"
22886         return 0
22887 }
22888 run_test 250 "Write above 16T limit"
22889
22890 test_251() {
22891         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22892
22893         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22894         #Skip once - writing the first stripe will succeed
22895         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22896         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22897                 error "short write happened"
22898
22899         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22900         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22901                 error "short read happened"
22902
22903         rm -f $DIR/$tfile
22904 }
22905 run_test 251 "Handling short read and write correctly"
22906
22907 test_252() {
22908         remote_mds_nodsh && skip "remote MDS with nodsh"
22909         remote_ost_nodsh && skip "remote OST with nodsh"
22910         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22911                 skip_env "ldiskfs only test"
22912         fi
22913
22914         local tgt
22915         local dev
22916         local out
22917         local uuid
22918         local num
22919         local gen
22920
22921         # check lr_reader on OST0000
22922         tgt=ost1
22923         dev=$(facet_device $tgt)
22924         out=$(do_facet $tgt $LR_READER $dev)
22925         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22926         echo "$out"
22927         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22928         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22929                 error "Invalid uuid returned by $LR_READER on target $tgt"
22930         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22931
22932         # check lr_reader -c on MDT0000
22933         tgt=mds1
22934         dev=$(facet_device $tgt)
22935         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22936                 skip "$LR_READER does not support additional options"
22937         fi
22938         out=$(do_facet $tgt $LR_READER -c $dev)
22939         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22940         echo "$out"
22941         num=$(echo "$out" | grep -c "mdtlov")
22942         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22943                 error "Invalid number of mdtlov clients returned by $LR_READER"
22944         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22945
22946         # check lr_reader -cr on MDT0000
22947         out=$(do_facet $tgt $LR_READER -cr $dev)
22948         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22949         echo "$out"
22950         echo "$out" | grep -q "^reply_data:$" ||
22951                 error "$LR_READER should have returned 'reply_data' section"
22952         num=$(echo "$out" | grep -c "client_generation")
22953         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22954 }
22955 run_test 252 "check lr_reader tool"
22956
22957 test_253() {
22958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22959         remote_mds_nodsh && skip "remote MDS with nodsh"
22960         remote_mgs_nodsh && skip "remote MGS with nodsh"
22961
22962         local ostidx=0
22963         local rc=0
22964         local ost_name=$(ostname_from_index $ostidx)
22965
22966         # on the mdt's osc
22967         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22968         do_facet $SINGLEMDS $LCTL get_param -n \
22969                 osp.$mdtosc_proc1.reserved_mb_high ||
22970                 skip  "remote MDS does not support reserved_mb_high"
22971
22972         rm -rf $DIR/$tdir
22973         wait_mds_ost_sync
22974         wait_delete_completed
22975         mkdir $DIR/$tdir
22976         stack_trap "rm -rf $DIR/$tdir"
22977
22978         pool_add $TESTNAME || error "Pool creation failed"
22979         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22980
22981         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22982                 error "Setstripe failed"
22983
22984         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22985
22986         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22987                     grep "watermarks")
22988         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22989
22990         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22991                         osp.$mdtosc_proc1.prealloc_status)
22992         echo "prealloc_status $oa_status"
22993
22994         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22995                 error "File creation should fail"
22996
22997         #object allocation was stopped, but we still able to append files
22998         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22999                 oflag=append || error "Append failed"
23000
23001         rm -f $DIR/$tdir/$tfile.0
23002
23003         # For this test, we want to delete the files we created to go out of
23004         # space but leave the watermark, so we remain nearly out of space
23005         ost_watermarks_enospc_delete_files $tfile $ostidx
23006
23007         wait_delete_completed
23008
23009         sleep_maxage
23010
23011         for i in $(seq 10 12); do
23012                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23013                         2>/dev/null || error "File creation failed after rm"
23014         done
23015
23016         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23017                         osp.$mdtosc_proc1.prealloc_status)
23018         echo "prealloc_status $oa_status"
23019
23020         if (( oa_status != 0 )); then
23021                 error "Object allocation still disable after rm"
23022         fi
23023 }
23024 run_test 253 "Check object allocation limit"
23025
23026 test_254() {
23027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23028         remote_mds_nodsh && skip "remote MDS with nodsh"
23029
23030         local mdt=$(facet_svc $SINGLEMDS)
23031
23032         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23033                 skip "MDS does not support changelog_size"
23034
23035         local cl_user
23036
23037         changelog_register || error "changelog_register failed"
23038
23039         changelog_clear 0 || error "changelog_clear failed"
23040
23041         local size1=$(do_facet $SINGLEMDS \
23042                       $LCTL get_param -n mdd.$mdt.changelog_size)
23043         echo "Changelog size $size1"
23044
23045         rm -rf $DIR/$tdir
23046         $LFS mkdir -i 0 $DIR/$tdir
23047         # change something
23048         mkdir -p $DIR/$tdir/pics/2008/zachy
23049         touch $DIR/$tdir/pics/2008/zachy/timestamp
23050         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23051         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23052         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23053         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23054         rm $DIR/$tdir/pics/desktop.jpg
23055
23056         local size2=$(do_facet $SINGLEMDS \
23057                       $LCTL get_param -n mdd.$mdt.changelog_size)
23058         echo "Changelog size after work $size2"
23059
23060         (( $size2 > $size1 )) ||
23061                 error "new Changelog size=$size2 less than old size=$size1"
23062 }
23063 run_test 254 "Check changelog size"
23064
23065 ladvise_no_type()
23066 {
23067         local type=$1
23068         local file=$2
23069
23070         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23071                 awk -F: '{print $2}' | grep $type > /dev/null
23072         if [ $? -ne 0 ]; then
23073                 return 0
23074         fi
23075         return 1
23076 }
23077
23078 ladvise_no_ioctl()
23079 {
23080         local file=$1
23081
23082         lfs ladvise -a willread $file > /dev/null 2>&1
23083         if [ $? -eq 0 ]; then
23084                 return 1
23085         fi
23086
23087         lfs ladvise -a willread $file 2>&1 |
23088                 grep "Inappropriate ioctl for device" > /dev/null
23089         if [ $? -eq 0 ]; then
23090                 return 0
23091         fi
23092         return 1
23093 }
23094
23095 percent() {
23096         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23097 }
23098
23099 # run a random read IO workload
23100 # usage: random_read_iops <filename> <filesize> <iosize>
23101 random_read_iops() {
23102         local file=$1
23103         local fsize=$2
23104         local iosize=${3:-4096}
23105
23106         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23107                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23108 }
23109
23110 drop_file_oss_cache() {
23111         local file="$1"
23112         local nodes="$2"
23113
23114         $LFS ladvise -a dontneed $file 2>/dev/null ||
23115                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23116 }
23117
23118 ladvise_willread_performance()
23119 {
23120         local repeat=10
23121         local average_origin=0
23122         local average_cache=0
23123         local average_ladvise=0
23124
23125         for ((i = 1; i <= $repeat; i++)); do
23126                 echo "Iter $i/$repeat: reading without willread hint"
23127                 cancel_lru_locks osc
23128                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23129                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23130                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23131                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23132
23133                 cancel_lru_locks osc
23134                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23135                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23136                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23137
23138                 cancel_lru_locks osc
23139                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23140                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23141                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23142                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23143                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23144         done
23145         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23146         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23147         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23148
23149         speedup_cache=$(percent $average_cache $average_origin)
23150         speedup_ladvise=$(percent $average_ladvise $average_origin)
23151
23152         echo "Average uncached read: $average_origin"
23153         echo "Average speedup with OSS cached read: " \
23154                 "$average_cache = +$speedup_cache%"
23155         echo "Average speedup with ladvise willread: " \
23156                 "$average_ladvise = +$speedup_ladvise%"
23157
23158         local lowest_speedup=20
23159         if (( ${average_cache%.*} < $lowest_speedup )); then
23160                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23161                      " got $average_cache%. Skipping ladvise willread check."
23162                 return 0
23163         fi
23164
23165         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23166         # it is still good to run until then to exercise 'ladvise willread'
23167         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23168                 [ "$ost1_FSTYPE" = "zfs" ] &&
23169                 echo "osd-zfs does not support dontneed or drop_caches" &&
23170                 return 0
23171
23172         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23173         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23174                 error_not_in_vm "Speedup with willread is less than " \
23175                         "$lowest_speedup%, got $average_ladvise%"
23176 }
23177
23178 test_255a() {
23179         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23180                 skip "lustre < 2.8.54 does not support ladvise "
23181         remote_ost_nodsh && skip "remote OST with nodsh"
23182
23183         stack_trap "rm -f $DIR/$tfile"
23184         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23185
23186         ladvise_no_type willread $DIR/$tfile &&
23187                 skip "willread ladvise is not supported"
23188
23189         ladvise_no_ioctl $DIR/$tfile &&
23190                 skip "ladvise ioctl is not supported"
23191
23192         local size_mb=100
23193         local size=$((size_mb * 1048576))
23194         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23195                 error "dd to $DIR/$tfile failed"
23196
23197         lfs ladvise -a willread $DIR/$tfile ||
23198                 error "Ladvise failed with no range argument"
23199
23200         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23201                 error "Ladvise failed with no -l or -e argument"
23202
23203         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23204                 error "Ladvise failed with only -e argument"
23205
23206         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23207                 error "Ladvise failed with only -l argument"
23208
23209         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23210                 error "End offset should not be smaller than start offset"
23211
23212         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23213                 error "End offset should not be equal to start offset"
23214
23215         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23216                 error "Ladvise failed with overflowing -s argument"
23217
23218         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23219                 error "Ladvise failed with overflowing -e argument"
23220
23221         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23222                 error "Ladvise failed with overflowing -l argument"
23223
23224         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23225                 error "Ladvise succeeded with conflicting -l and -e arguments"
23226
23227         echo "Synchronous ladvise should wait"
23228         local delay=8
23229 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23230         do_nodes $(comma_list $(osts_nodes)) \
23231                 $LCTL set_param fail_val=$delay fail_loc=0x237
23232         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23233                 $LCTL set_param fail_loc=0"
23234
23235         local start_ts=$SECONDS
23236         lfs ladvise -a willread $DIR/$tfile ||
23237                 error "Ladvise failed with no range argument"
23238         local end_ts=$SECONDS
23239         local inteval_ts=$((end_ts - start_ts))
23240
23241         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23242                 error "Synchronous advice didn't wait reply"
23243         fi
23244
23245         echo "Asynchronous ladvise shouldn't wait"
23246         local start_ts=$SECONDS
23247         lfs ladvise -a willread -b $DIR/$tfile ||
23248                 error "Ladvise failed with no range argument"
23249         local end_ts=$SECONDS
23250         local inteval_ts=$((end_ts - start_ts))
23251
23252         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23253                 error "Asynchronous advice blocked"
23254         fi
23255
23256         ladvise_willread_performance
23257 }
23258 run_test 255a "check 'lfs ladvise -a willread'"
23259
23260 facet_meminfo() {
23261         local facet=$1
23262         local info=$2
23263
23264         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23265 }
23266
23267 test_255b() {
23268         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23269                 skip "lustre < 2.8.54 does not support ladvise "
23270         remote_ost_nodsh && skip "remote OST with nodsh"
23271
23272         stack_trap "rm -f $DIR/$tfile"
23273         lfs setstripe -c 1 -i 0 $DIR/$tfile
23274
23275         ladvise_no_type dontneed $DIR/$tfile &&
23276                 skip "dontneed ladvise is not supported"
23277
23278         ladvise_no_ioctl $DIR/$tfile &&
23279                 skip "ladvise ioctl is not supported"
23280
23281         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23282                 [ "$ost1_FSTYPE" = "zfs" ] &&
23283                 skip "zfs-osd does not support 'ladvise dontneed'"
23284
23285         local size_mb=100
23286         local size=$((size_mb * 1048576))
23287         # In order to prevent disturbance of other processes, only check 3/4
23288         # of the memory usage
23289         local kibibytes=$((size_mb * 1024 * 3 / 4))
23290
23291         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23292                 error "dd to $DIR/$tfile failed"
23293
23294         #force write to complete before dropping OST cache & checking memory
23295         sync
23296
23297         local total=$(facet_meminfo ost1 MemTotal)
23298         echo "Total memory: $total KiB"
23299
23300         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23301         local before_read=$(facet_meminfo ost1 Cached)
23302         echo "Cache used before read: $before_read KiB"
23303
23304         lfs ladvise -a willread $DIR/$tfile ||
23305                 error "Ladvise willread failed"
23306         local after_read=$(facet_meminfo ost1 Cached)
23307         echo "Cache used after read: $after_read KiB"
23308
23309         lfs ladvise -a dontneed $DIR/$tfile ||
23310                 error "Ladvise dontneed again failed"
23311         local no_read=$(facet_meminfo ost1 Cached)
23312         echo "Cache used after dontneed ladvise: $no_read KiB"
23313
23314         if [ $total -lt $((before_read + kibibytes)) ]; then
23315                 echo "Memory is too small, abort checking"
23316                 return 0
23317         fi
23318
23319         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23320                 error "Ladvise willread should use more memory" \
23321                         "than $kibibytes KiB"
23322         fi
23323
23324         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23325                 error "Ladvise dontneed should release more memory" \
23326                         "than $kibibytes KiB"
23327         fi
23328 }
23329 run_test 255b "check 'lfs ladvise -a dontneed'"
23330
23331 test_255c() {
23332         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23333                 skip "lustre < 2.10.50 does not support lockahead"
23334
23335         local ost1_imp=$(get_osc_import_name client ost1)
23336         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23337                          cut -d'.' -f2)
23338         local count
23339         local new_count
23340         local difference
23341         local i
23342         local rc
23343
23344         test_mkdir -p $DIR/$tdir
23345         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23346
23347         #test 10 returns only success/failure
23348         i=10
23349         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23350         rc=$?
23351         if [ $rc -eq 255 ]; then
23352                 error "Ladvise test${i} failed, ${rc}"
23353         fi
23354
23355         #test 11 counts lock enqueue requests, all others count new locks
23356         i=11
23357         count=$(do_facet ost1 \
23358                 $LCTL get_param -n ost.OSS.ost.stats)
23359         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23360
23361         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23362         rc=$?
23363         if [ $rc -eq 255 ]; then
23364                 error "Ladvise test${i} failed, ${rc}"
23365         fi
23366
23367         new_count=$(do_facet ost1 \
23368                 $LCTL get_param -n ost.OSS.ost.stats)
23369         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23370                    awk '{ print $2 }')
23371
23372         difference="$((new_count - count))"
23373         if [ $difference -ne $rc ]; then
23374                 error "Ladvise test${i}, bad enqueue count, returned " \
23375                       "${rc}, actual ${difference}"
23376         fi
23377
23378         for i in $(seq 12 21); do
23379                 # If we do not do this, we run the risk of having too many
23380                 # locks and starting lock cancellation while we are checking
23381                 # lock counts.
23382                 cancel_lru_locks osc
23383
23384                 count=$($LCTL get_param -n \
23385                        ldlm.namespaces.$imp_name.lock_unused_count)
23386
23387                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23388                 rc=$?
23389                 if [ $rc -eq 255 ]; then
23390                         error "Ladvise test ${i} failed, ${rc}"
23391                 fi
23392
23393                 new_count=$($LCTL get_param -n \
23394                        ldlm.namespaces.$imp_name.lock_unused_count)
23395                 difference="$((new_count - count))"
23396
23397                 # Test 15 output is divided by 100 to map down to valid return
23398                 if [ $i -eq 15 ]; then
23399                         rc="$((rc * 100))"
23400                 fi
23401
23402                 if [ $difference -ne $rc ]; then
23403                         error "Ladvise test ${i}, bad lock count, returned " \
23404                               "${rc}, actual ${difference}"
23405                 fi
23406         done
23407
23408         #test 22 returns only success/failure
23409         i=22
23410         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23411         rc=$?
23412         if [ $rc -eq 255 ]; then
23413                 error "Ladvise test${i} failed, ${rc}"
23414         fi
23415 }
23416 run_test 255c "suite of ladvise lockahead tests"
23417
23418 test_256() {
23419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23420         remote_mds_nodsh && skip "remote MDS with nodsh"
23421         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23422         changelog_users $SINGLEMDS | grep "^cl" &&
23423                 skip "active changelog user"
23424
23425         local cl_user
23426         local cat_sl
23427         local mdt_dev
23428
23429         mdt_dev=$(facet_device $SINGLEMDS)
23430         echo $mdt_dev
23431
23432         changelog_register || error "changelog_register failed"
23433
23434         rm -rf $DIR/$tdir
23435         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23436
23437         changelog_clear 0 || error "changelog_clear failed"
23438
23439         # change something
23440         touch $DIR/$tdir/{1..10}
23441
23442         # stop the MDT
23443         stop $SINGLEMDS || error "Fail to stop MDT"
23444
23445         # remount the MDT
23446         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23447                 error "Fail to start MDT"
23448
23449         #after mount new plainllog is used
23450         touch $DIR/$tdir/{11..19}
23451         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23452         stack_trap "rm -f $tmpfile"
23453         cat_sl=$(do_facet $SINGLEMDS "sync; \
23454                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23455                  llog_reader $tmpfile | grep -c type=1064553b")
23456         do_facet $SINGLEMDS llog_reader $tmpfile
23457
23458         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23459
23460         changelog_clear 0 || error "changelog_clear failed"
23461
23462         cat_sl=$(do_facet $SINGLEMDS "sync; \
23463                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23464                  llog_reader $tmpfile | grep -c type=1064553b")
23465
23466         if (( cat_sl == 2 )); then
23467                 error "Empty plain llog was not deleted from changelog catalog"
23468         elif (( cat_sl != 1 )); then
23469                 error "Active plain llog shouldn't be deleted from catalog"
23470         fi
23471 }
23472 run_test 256 "Check llog delete for empty and not full state"
23473
23474 test_257() {
23475         remote_mds_nodsh && skip "remote MDS with nodsh"
23476         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23477                 skip "Need MDS version at least 2.8.55"
23478
23479         test_mkdir $DIR/$tdir
23480
23481         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23482                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23483         stat $DIR/$tdir
23484
23485 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23486         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23487         local facet=mds$((mdtidx + 1))
23488         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23489         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23490
23491         stop $facet || error "stop MDS failed"
23492         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23493                 error "start MDS fail"
23494         wait_recovery_complete $facet
23495 }
23496 run_test 257 "xattr locks are not lost"
23497
23498 # Verify we take the i_mutex when security requires it
23499 test_258a() {
23500 #define OBD_FAIL_IMUTEX_SEC 0x141c
23501         $LCTL set_param fail_loc=0x141c
23502         touch $DIR/$tfile
23503         chmod u+s $DIR/$tfile
23504         chmod a+rwx $DIR/$tfile
23505         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23506         RC=$?
23507         if [ $RC -ne 0 ]; then
23508                 error "error, failed to take i_mutex, rc=$?"
23509         fi
23510         rm -f $DIR/$tfile
23511 }
23512 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23513
23514 # Verify we do NOT take the i_mutex in the normal case
23515 test_258b() {
23516 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23517         $LCTL set_param fail_loc=0x141d
23518         touch $DIR/$tfile
23519         chmod a+rwx $DIR
23520         chmod a+rw $DIR/$tfile
23521         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23522         RC=$?
23523         if [ $RC -ne 0 ]; then
23524                 error "error, took i_mutex unnecessarily, rc=$?"
23525         fi
23526         rm -f $DIR/$tfile
23527
23528 }
23529 run_test 258b "verify i_mutex security behavior"
23530
23531 test_259() {
23532         local file=$DIR/$tfile
23533         local before
23534         local after
23535
23536         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23537
23538         stack_trap "rm -f $file" EXIT
23539
23540         wait_delete_completed
23541         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23542         echo "before: $before"
23543
23544         $LFS setstripe -i 0 -c 1 $file
23545         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23546         sync_all_data
23547         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23548         echo "after write: $after"
23549
23550 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23551         do_facet ost1 $LCTL set_param fail_loc=0x2301
23552         $TRUNCATE $file 0
23553         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23554         echo "after truncate: $after"
23555
23556         stop ost1
23557         do_facet ost1 $LCTL set_param fail_loc=0
23558         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23559         sleep 2
23560         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23561         echo "after restart: $after"
23562         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23563                 error "missing truncate?"
23564
23565         return 0
23566 }
23567 run_test 259 "crash at delayed truncate"
23568
23569 test_260() {
23570 #define OBD_FAIL_MDC_CLOSE               0x806
23571         $LCTL set_param fail_loc=0x80000806
23572         touch $DIR/$tfile
23573
23574 }
23575 run_test 260 "Check mdc_close fail"
23576
23577 ### Data-on-MDT sanity tests ###
23578 test_270a() {
23579         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23580                 skip "Need MDS version at least 2.10.55 for DoM"
23581
23582         # create DoM file
23583         local dom=$DIR/$tdir/dom_file
23584         local tmp=$DIR/$tdir/tmp_file
23585
23586         mkdir_on_mdt0 $DIR/$tdir
23587
23588         # basic checks for DoM component creation
23589         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23590                 error "Can set MDT layout to non-first entry"
23591
23592         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23593                 error "Can define multiple entries as MDT layout"
23594
23595         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23596
23597         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23598         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23599         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23600
23601         local mdtidx=$($LFS getstripe -m $dom)
23602         local mdtname=MDT$(printf %04x $mdtidx)
23603         local facet=mds$((mdtidx + 1))
23604         local space_check=1
23605
23606         # Skip free space checks with ZFS
23607         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23608
23609         # write
23610         sync
23611         local size_tmp=$((65536 * 3))
23612         local mdtfree1=$(do_facet $facet \
23613                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23614
23615         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23616         # check also direct IO along write
23617         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23618         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23619         sync
23620         cmp $tmp $dom || error "file data is different"
23621         [ $(stat -c%s $dom) == $size_tmp ] ||
23622                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23623         if [ $space_check == 1 ]; then
23624                 local mdtfree2=$(do_facet $facet \
23625                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23626
23627                 # increase in usage from by $size_tmp
23628                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23629                         error "MDT free space wrong after write: " \
23630                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23631         fi
23632
23633         # truncate
23634         local size_dom=10000
23635
23636         $TRUNCATE $dom $size_dom
23637         [ $(stat -c%s $dom) == $size_dom ] ||
23638                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23639         if [ $space_check == 1 ]; then
23640                 mdtfree1=$(do_facet $facet \
23641                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23642                 # decrease in usage from $size_tmp to new $size_dom
23643                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23644                   $(((size_tmp - size_dom) / 1024)) ] ||
23645                         error "MDT free space is wrong after truncate: " \
23646                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23647         fi
23648
23649         # append
23650         cat $tmp >> $dom
23651         sync
23652         size_dom=$((size_dom + size_tmp))
23653         [ $(stat -c%s $dom) == $size_dom ] ||
23654                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23655         if [ $space_check == 1 ]; then
23656                 mdtfree2=$(do_facet $facet \
23657                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23658                 # increase in usage by $size_tmp from previous
23659                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23660                         error "MDT free space is wrong after append: " \
23661                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23662         fi
23663
23664         # delete
23665         rm $dom
23666         if [ $space_check == 1 ]; then
23667                 mdtfree1=$(do_facet $facet \
23668                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23669                 # decrease in usage by $size_dom from previous
23670                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23671                         error "MDT free space is wrong after removal: " \
23672                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23673         fi
23674
23675         # combined striping
23676         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23677                 error "Can't create DoM + OST striping"
23678
23679         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23680         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23681         # check also direct IO along write
23682         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23683         sync
23684         cmp $tmp $dom || error "file data is different"
23685         [ $(stat -c%s $dom) == $size_tmp ] ||
23686                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23687         rm $dom $tmp
23688
23689         return 0
23690 }
23691 run_test 270a "DoM: basic functionality tests"
23692
23693 test_270b() {
23694         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23695                 skip "Need MDS version at least 2.10.55"
23696
23697         local dom=$DIR/$tdir/dom_file
23698         local max_size=1048576
23699
23700         mkdir -p $DIR/$tdir
23701         $LFS setstripe -E $max_size -L mdt $dom
23702
23703         # truncate over the limit
23704         $TRUNCATE $dom $(($max_size + 1)) &&
23705                 error "successful truncate over the maximum size"
23706         # write over the limit
23707         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23708                 error "successful write over the maximum size"
23709         # append over the limit
23710         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23711         echo "12345" >> $dom && error "successful append over the maximum size"
23712         rm $dom
23713
23714         return 0
23715 }
23716 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23717
23718 test_270c() {
23719         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23720                 skip "Need MDS version at least 2.10.55"
23721
23722         mkdir -p $DIR/$tdir
23723         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23724
23725         # check files inherit DoM EA
23726         touch $DIR/$tdir/first
23727         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23728                 error "bad pattern"
23729         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23730                 error "bad stripe count"
23731         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23732                 error "bad stripe size"
23733
23734         # check directory inherits DoM EA and uses it as default
23735         mkdir $DIR/$tdir/subdir
23736         touch $DIR/$tdir/subdir/second
23737         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23738                 error "bad pattern in sub-directory"
23739         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23740                 error "bad stripe count in sub-directory"
23741         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23742                 error "bad stripe size in sub-directory"
23743         return 0
23744 }
23745 run_test 270c "DoM: DoM EA inheritance tests"
23746
23747 test_270d() {
23748         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23749                 skip "Need MDS version at least 2.10.55"
23750
23751         mkdir -p $DIR/$tdir
23752         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23753
23754         # inherit default DoM striping
23755         mkdir $DIR/$tdir/subdir
23756         touch $DIR/$tdir/subdir/f1
23757
23758         # change default directory striping
23759         $LFS setstripe -c 1 $DIR/$tdir/subdir
23760         touch $DIR/$tdir/subdir/f2
23761         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23762                 error "wrong default striping in file 2"
23763         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23764                 error "bad pattern in file 2"
23765         return 0
23766 }
23767 run_test 270d "DoM: change striping from DoM to RAID0"
23768
23769 test_270e() {
23770         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23771                 skip "Need MDS version at least 2.10.55"
23772
23773         mkdir -p $DIR/$tdir/dom
23774         mkdir -p $DIR/$tdir/norm
23775         DOMFILES=20
23776         NORMFILES=10
23777         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23778         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23779
23780         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23781         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23782
23783         # find DoM files by layout
23784         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23785         [ $NUM -eq  $DOMFILES ] ||
23786                 error "lfs find -L: found $NUM, expected $DOMFILES"
23787         echo "Test 1: lfs find 20 DOM files by layout: OK"
23788
23789         # there should be 1 dir with default DOM striping
23790         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23791         [ $NUM -eq  1 ] ||
23792                 error "lfs find -L: found $NUM, expected 1 dir"
23793         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23794
23795         # find DoM files by stripe size
23796         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23797         [ $NUM -eq  $DOMFILES ] ||
23798                 error "lfs find -S: found $NUM, expected $DOMFILES"
23799         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23800
23801         # find files by stripe offset except DoM files
23802         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23803         [ $NUM -eq  $NORMFILES ] ||
23804                 error "lfs find -i: found $NUM, expected $NORMFILES"
23805         echo "Test 5: lfs find no DOM files by stripe index: OK"
23806         return 0
23807 }
23808 run_test 270e "DoM: lfs find with DoM files test"
23809
23810 test_270f() {
23811         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23812                 skip "Need MDS version at least 2.10.55"
23813
23814         local mdtname=${FSNAME}-MDT0000-mdtlov
23815         local dom=$DIR/$tdir/dom_file
23816         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23817                                                 lod.$mdtname.dom_stripesize)
23818         local dom_limit=131072
23819
23820         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23821         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23822                                                 lod.$mdtname.dom_stripesize)
23823         [ ${dom_limit} -eq ${dom_current} ] ||
23824                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23825
23826         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23827         $LFS setstripe -d $DIR/$tdir
23828         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23829                 error "Can't set directory default striping"
23830
23831         # exceed maximum stripe size
23832         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23833                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23834         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23835                 error "Able to create DoM component size more than LOD limit"
23836
23837         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23838         dom_current=$(do_facet mds1 $LCTL get_param -n \
23839                                                 lod.$mdtname.dom_stripesize)
23840         [ 0 -eq ${dom_current} ] ||
23841                 error "Can't set zero DoM stripe limit"
23842         rm $dom
23843
23844         # attempt to create DoM file on server with disabled DoM should
23845         # remove DoM entry from layout and be succeed
23846         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23847                 error "Can't create DoM file (DoM is disabled)"
23848         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23849                 error "File has DoM component while DoM is disabled"
23850         rm $dom
23851
23852         # attempt to create DoM file with only DoM stripe should return error
23853         $LFS setstripe -E $dom_limit -L mdt $dom &&
23854                 error "Able to create DoM-only file while DoM is disabled"
23855
23856         # too low values to be aligned with smallest stripe size 64K
23857         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23858         dom_current=$(do_facet mds1 $LCTL get_param -n \
23859                                                 lod.$mdtname.dom_stripesize)
23860         [ 30000 -eq ${dom_current} ] &&
23861                 error "Can set too small DoM stripe limit"
23862
23863         # 64K is a minimal stripe size in Lustre, expect limit of that size
23864         [ 65536 -eq ${dom_current} ] ||
23865                 error "Limit is not set to 64K but ${dom_current}"
23866
23867         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23868         dom_current=$(do_facet mds1 $LCTL get_param -n \
23869                                                 lod.$mdtname.dom_stripesize)
23870         echo $dom_current
23871         [ 2147483648 -eq ${dom_current} ] &&
23872                 error "Can set too large DoM stripe limit"
23873
23874         do_facet mds1 $LCTL set_param -n \
23875                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23876         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23877                 error "Can't create DoM component size after limit change"
23878         do_facet mds1 $LCTL set_param -n \
23879                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23880         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23881                 error "Can't create DoM file after limit decrease"
23882         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23883                 error "Can create big DoM component after limit decrease"
23884         touch ${dom}_def ||
23885                 error "Can't create file with old default layout"
23886
23887         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23888         return 0
23889 }
23890 run_test 270f "DoM: maximum DoM stripe size checks"
23891
23892 test_270g() {
23893         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23894                 skip "Need MDS version at least 2.13.52"
23895         local dom=$DIR/$tdir/$tfile
23896
23897         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23898         local lodname=${FSNAME}-MDT0000-mdtlov
23899
23900         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23901         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23902         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23903         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23904
23905         local dom_limit=1024
23906         local dom_threshold="50%"
23907
23908         $LFS setstripe -d $DIR/$tdir
23909         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23910                 error "Can't set directory default striping"
23911
23912         do_facet mds1 $LCTL set_param -n \
23913                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23914         # set 0 threshold and create DOM file to change tunable stripesize
23915         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23916         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23917                 error "Failed to create $dom file"
23918         # now tunable dom_cur_stripesize should reach maximum
23919         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23920                                         lod.${lodname}.dom_stripesize_cur_kb)
23921         [[ $dom_current == $dom_limit ]] ||
23922                 error "Current DOM stripesize is not maximum"
23923         rm $dom
23924
23925         # set threshold for further tests
23926         do_facet mds1 $LCTL set_param -n \
23927                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23928         echo "DOM threshold is $dom_threshold free space"
23929         local dom_def
23930         local dom_set
23931         # Spoof bfree to exceed threshold
23932         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23933         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23934         for spfree in 40 20 0 15 30 55; do
23935                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23936                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23937                         error "Failed to create $dom file"
23938                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23939                                         lod.${lodname}.dom_stripesize_cur_kb)
23940                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23941                 [[ $dom_def != $dom_current ]] ||
23942                         error "Default stripe size was not changed"
23943                 if (( spfree > 0 )) ; then
23944                         dom_set=$($LFS getstripe -S $dom)
23945                         (( dom_set == dom_def * 1024 )) ||
23946                                 error "DOM component size is still old"
23947                 else
23948                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23949                                 error "DoM component is set with no free space"
23950                 fi
23951                 rm $dom
23952                 dom_current=$dom_def
23953         done
23954 }
23955 run_test 270g "DoM: default DoM stripe size depends on free space"
23956
23957 test_270h() {
23958         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23959                 skip "Need MDS version at least 2.13.53"
23960
23961         local mdtname=${FSNAME}-MDT0000-mdtlov
23962         local dom=$DIR/$tdir/$tfile
23963         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23964
23965         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23966         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23967
23968         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23969         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23970                 error "can't create OST file"
23971         # mirrored file with DOM entry in the second mirror
23972         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23973                 error "can't create mirror with DoM component"
23974
23975         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23976
23977         # DOM component in the middle and has other enries in the same mirror,
23978         # should succeed but lost DoM component
23979         $LFS setstripe --copy=${dom}_1 $dom ||
23980                 error "Can't create file from OST|DOM mirror layout"
23981         # check new file has no DoM layout after all
23982         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23983                 error "File has DoM component while DoM is disabled"
23984 }
23985 run_test 270h "DoM: DoM stripe removal when disabled on server"
23986
23987 test_270i() {
23988         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23989                 skip "Need MDS version at least 2.14.54"
23990
23991         mkdir $DIR/$tdir
23992         # DoM with plain layout
23993         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23994                 error "default plain layout with DoM must fail"
23995         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23996                 error "setstripe plain file layout with DoM must fail"
23997         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23998                 error "default DoM layout with bad striping must fail"
23999         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24000                 error "setstripe to DoM layout with bad striping must fail"
24001         return 0
24002 }
24003 run_test 270i "DoM: setting invalid DoM striping should fail"
24004
24005 test_270j() {
24006         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24007                 skip "Need MDS version at least 2.15.55.203"
24008
24009         local dom=$DIR/$tdir/$tfile
24010         local odv
24011         local ndv
24012
24013         mkdir -p $DIR/$tdir
24014
24015         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24016
24017         odv=$($LFS data_version $dom)
24018         chmod 666 $dom
24019         mv $dom ${dom}_moved
24020         link ${dom}_moved $dom
24021         setfattr -n user.attrx -v "some_attr" $dom
24022         ndv=$($LFS data_version $dom)
24023         (( $ndv == $odv )) ||
24024                 error "data version was changed by metadata operations"
24025
24026         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24027                 error "failed to write data into $dom"
24028         cancel_lru_locks mdc
24029         ndv=$($LFS data_version $dom)
24030         (( $ndv != $odv )) ||
24031                 error "data version wasn't changed on write"
24032
24033         odv=$ndv
24034         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24035         ndv=$($LFS data_version $dom)
24036         (( $ndv != $odv )) ||
24037                 error "data version wasn't changed on truncate down"
24038
24039         odv=$ndv
24040         $TRUNCATE $dom 25000
24041         ndv=$($LFS data_version $dom)
24042         (( $ndv != $odv )) ||
24043                 error "data version wasn't changed on truncate up"
24044
24045         # check also fallocate for ldiskfs
24046         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24047                 odv=$ndv
24048                 fallocate -l 1048576 $dom
24049                 ndv=$($LFS data_version $dom)
24050                 (( $ndv != $odv )) ||
24051                         error "data version wasn't changed on fallocate"
24052
24053                 odv=$ndv
24054                 fallocate -p --offset 4096 -l 4096 $dom
24055                 ndv=$($LFS data_version $dom)
24056                 (( $ndv != $odv )) ||
24057                         error "data version wasn't changed on fallocate punch"
24058         fi
24059 }
24060 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24061
24062 test_271a() {
24063         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24064                 skip "Need MDS version at least 2.10.55"
24065
24066         local dom=$DIR/$tdir/dom
24067
24068         mkdir -p $DIR/$tdir
24069
24070         $LFS setstripe -E 1024K -L mdt $dom
24071
24072         lctl set_param -n mdc.*.stats=clear
24073         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24074         cat $dom > /dev/null
24075         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24076         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24077         ls $dom
24078         rm -f $dom
24079 }
24080 run_test 271a "DoM: data is cached for read after write"
24081
24082 test_271b() {
24083         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24084                 skip "Need MDS version at least 2.10.55"
24085
24086         local dom=$DIR/$tdir/dom
24087
24088         mkdir -p $DIR/$tdir
24089
24090         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24091
24092         lctl set_param -n mdc.*.stats=clear
24093         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24094         cancel_lru_locks mdc
24095         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24096         # second stat to check size is cached on client
24097         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24098         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24099         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24100         rm -f $dom
24101 }
24102 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24103
24104 test_271ba() {
24105         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24106                 skip "Need MDS version at least 2.10.55"
24107
24108         local dom=$DIR/$tdir/dom
24109
24110         mkdir -p $DIR/$tdir
24111
24112         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24113
24114         lctl set_param -n mdc.*.stats=clear
24115         lctl set_param -n osc.*.stats=clear
24116         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24117         cancel_lru_locks mdc
24118         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24119         # second stat to check size is cached on client
24120         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24121         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24122         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24123         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24124         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24125         rm -f $dom
24126 }
24127 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24128
24129
24130 get_mdc_stats() {
24131         local mdtidx=$1
24132         local param=$2
24133         local mdt=MDT$(printf %04x $mdtidx)
24134
24135         if [ -z $param ]; then
24136                 lctl get_param -n mdc.*$mdt*.stats
24137         else
24138                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24139         fi
24140 }
24141
24142 test_271c() {
24143         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24144                 skip "Need MDS version at least 2.10.55"
24145
24146         local dom=$DIR/$tdir/dom
24147
24148         mkdir -p $DIR/$tdir
24149
24150         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24151
24152         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24153         local facet=mds$((mdtidx + 1))
24154
24155         cancel_lru_locks mdc
24156         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24157         createmany -o $dom 1000
24158         lctl set_param -n mdc.*.stats=clear
24159         smalliomany -w $dom 1000 200
24160         get_mdc_stats $mdtidx
24161         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24162         # Each file has 1 open, 1 IO enqueues, total 2000
24163         # but now we have also +1 getxattr for security.capability, total 3000
24164         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24165         unlinkmany $dom 1000
24166
24167         cancel_lru_locks mdc
24168         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24169         createmany -o $dom 1000
24170         lctl set_param -n mdc.*.stats=clear
24171         smalliomany -w $dom 1000 200
24172         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24173         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24174         # for OPEN and IO lock.
24175         [ $((enq - enq_2)) -ge 1000 ] ||
24176                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24177         unlinkmany $dom 1000
24178         return 0
24179 }
24180 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24181
24182 cleanup_271def_tests() {
24183         trap 0
24184         rm -f $1
24185 }
24186
24187 test_271d() {
24188         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24189                 skip "Need MDS version at least 2.10.57"
24190
24191         local dom=$DIR/$tdir/dom
24192         local tmp=$TMP/$tfile
24193         trap "cleanup_271def_tests $tmp" EXIT
24194
24195         mkdir -p $DIR/$tdir
24196
24197         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24198
24199         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24200
24201         cancel_lru_locks mdc
24202         dd if=/dev/urandom of=$tmp bs=1000 count=1
24203         dd if=$tmp of=$dom bs=1000 count=1
24204         cancel_lru_locks mdc
24205
24206         cat /etc/hosts >> $tmp
24207         lctl set_param -n mdc.*.stats=clear
24208
24209         # append data to the same file it should update local page
24210         echo "Append to the same page"
24211         cat /etc/hosts >> $dom
24212         local num=$(get_mdc_stats $mdtidx ost_read)
24213         local ra=$(get_mdc_stats $mdtidx req_active)
24214         local rw=$(get_mdc_stats $mdtidx req_waittime)
24215
24216         [ -z $num ] || error "$num READ RPC occured"
24217         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24218         echo "... DONE"
24219
24220         # compare content
24221         cmp $tmp $dom || error "file miscompare"
24222
24223         cancel_lru_locks mdc
24224         lctl set_param -n mdc.*.stats=clear
24225
24226         echo "Open and read file"
24227         cat $dom > /dev/null
24228         local num=$(get_mdc_stats $mdtidx ost_read)
24229         local ra=$(get_mdc_stats $mdtidx req_active)
24230         local rw=$(get_mdc_stats $mdtidx req_waittime)
24231
24232         [ -z $num ] || error "$num READ RPC occured"
24233         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24234         echo "... DONE"
24235
24236         # compare content
24237         cmp $tmp $dom || error "file miscompare"
24238
24239         return 0
24240 }
24241 run_test 271d "DoM: read on open (1K file in reply buffer)"
24242
24243 test_271f() {
24244         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24245                 skip "Need MDS version at least 2.10.57"
24246
24247         local dom=$DIR/$tdir/dom
24248         local tmp=$TMP/$tfile
24249         trap "cleanup_271def_tests $tmp" EXIT
24250
24251         mkdir -p $DIR/$tdir
24252
24253         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24254
24255         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24256
24257         cancel_lru_locks mdc
24258         dd if=/dev/urandom of=$tmp bs=265000 count=1
24259         dd if=$tmp of=$dom bs=265000 count=1
24260         cancel_lru_locks mdc
24261         cat /etc/hosts >> $tmp
24262         lctl set_param -n mdc.*.stats=clear
24263
24264         echo "Append to the same page"
24265         cat /etc/hosts >> $dom
24266         local num=$(get_mdc_stats $mdtidx ost_read)
24267         local ra=$(get_mdc_stats $mdtidx req_active)
24268         local rw=$(get_mdc_stats $mdtidx req_waittime)
24269
24270         [ -z $num ] || error "$num READ RPC occured"
24271         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24272         echo "... DONE"
24273
24274         # compare content
24275         cmp $tmp $dom || error "file miscompare"
24276
24277         cancel_lru_locks mdc
24278         lctl set_param -n mdc.*.stats=clear
24279
24280         echo "Open and read file"
24281         cat $dom > /dev/null
24282         local num=$(get_mdc_stats $mdtidx ost_read)
24283         local ra=$(get_mdc_stats $mdtidx req_active)
24284         local rw=$(get_mdc_stats $mdtidx req_waittime)
24285
24286         [ -z $num ] && num=0
24287         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24288         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24289         echo "... DONE"
24290
24291         # compare content
24292         cmp $tmp $dom || error "file miscompare"
24293
24294         return 0
24295 }
24296 run_test 271f "DoM: read on open (200K file and read tail)"
24297
24298 test_271g() {
24299         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24300                 skip "Skipping due to old client or server version"
24301
24302         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24303         # to get layout
24304         $CHECKSTAT -t file $DIR1/$tfile
24305
24306         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24307         MULTIOP_PID=$!
24308         sleep 1
24309         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24310         $LCTL set_param fail_loc=0x80000314
24311         rm $DIR1/$tfile || error "Unlink fails"
24312         RC=$?
24313         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24314         [ $RC -eq 0 ] || error "Failed write to stale object"
24315 }
24316 run_test 271g "Discard DoM data vs client flush race"
24317
24318 test_272a() {
24319         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24320                 skip "Need MDS version at least 2.11.50"
24321
24322         local dom=$DIR/$tdir/dom
24323         mkdir -p $DIR/$tdir
24324
24325         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24326         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24327                 error "failed to write data into $dom"
24328         local old_md5=$(md5sum $dom)
24329
24330         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24331                 error "failed to migrate to the same DoM component"
24332
24333         local new_md5=$(md5sum $dom)
24334
24335         [ "$old_md5" == "$new_md5" ] ||
24336                 error "md5sum differ: $old_md5, $new_md5"
24337
24338         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24339                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24340 }
24341 run_test 272a "DoM migration: new layout with the same DOM component"
24342
24343 test_272b() {
24344         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24345                 skip "Need MDS version at least 2.11.50"
24346
24347         local dom=$DIR/$tdir/dom
24348         mkdir -p $DIR/$tdir
24349         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24350         stack_trap "rm -rf $DIR/$tdir"
24351
24352         local mdtidx=$($LFS getstripe -m $dom)
24353         local mdtname=MDT$(printf %04x $mdtidx)
24354         local facet=mds$((mdtidx + 1))
24355
24356         local mdtfree1=$(do_facet $facet \
24357                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24358         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24359                 error "failed to write data into $dom"
24360         local old_md5=$(md5sum $dom)
24361         cancel_lru_locks mdc
24362         local mdtfree1=$(do_facet $facet \
24363                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24364
24365         $LFS migrate -c2 $dom ||
24366                 error "failed to migrate to the new composite layout"
24367         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24368                 error "MDT stripe was not removed"
24369         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24370                 error "$dir1 shouldn't have DATAVER EA"
24371
24372         cancel_lru_locks mdc
24373         local new_md5=$(md5sum $dom)
24374         [ "$old_md5" == "$new_md5" ] ||
24375                 error "$old_md5 != $new_md5"
24376
24377         # Skip free space checks with ZFS
24378         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24379                 local mdtfree2=$(do_facet $facet \
24380                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24381                 [ $mdtfree2 -gt $mdtfree1 ] ||
24382                         error "MDT space is not freed after migration"
24383         fi
24384         return 0
24385 }
24386 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24387
24388 test_272c() {
24389         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24390                 skip "Need MDS version at least 2.11.50"
24391
24392         local dom=$DIR/$tdir/$tfile
24393         mkdir -p $DIR/$tdir
24394         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24395         stack_trap "rm -rf $DIR/$tdir"
24396
24397         local mdtidx=$($LFS getstripe -m $dom)
24398         local mdtname=MDT$(printf %04x $mdtidx)
24399         local facet=mds$((mdtidx + 1))
24400
24401         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24402                 error "failed to write data into $dom"
24403         local old_md5=$(md5sum $dom)
24404         cancel_lru_locks mdc
24405         local mdtfree1=$(do_facet $facet \
24406                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24407
24408         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24409                 error "failed to migrate to the new composite layout"
24410         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24411                 error "MDT stripe was not removed"
24412
24413         cancel_lru_locks mdc
24414         local new_md5=$(md5sum $dom)
24415         [ "$old_md5" == "$new_md5" ] ||
24416                 error "$old_md5 != $new_md5"
24417
24418         # Skip free space checks with ZFS
24419         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24420                 local mdtfree2=$(do_facet $facet \
24421                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24422                 [ $mdtfree2 -gt $mdtfree1 ] ||
24423                         error "MDS space is not freed after migration"
24424         fi
24425         return 0
24426 }
24427 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24428
24429 test_272d() {
24430         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24431                 skip "Need MDS version at least 2.12.55"
24432
24433         local dom=$DIR/$tdir/$tfile
24434         mkdir -p $DIR/$tdir
24435         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24436
24437         local mdtidx=$($LFS getstripe -m $dom)
24438         local mdtname=MDT$(printf %04x $mdtidx)
24439         local facet=mds$((mdtidx + 1))
24440
24441         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24442                 error "failed to write data into $dom"
24443         local old_md5=$(md5sum $dom)
24444         cancel_lru_locks mdc
24445         local mdtfree1=$(do_facet $facet \
24446                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24447
24448         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24449                 error "failed mirroring to the new composite layout"
24450         $LFS mirror resync $dom ||
24451                 error "failed mirror resync"
24452         $LFS mirror split --mirror-id 1 -d $dom ||
24453                 error "failed mirror split"
24454
24455         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24456                 error "MDT stripe was not removed"
24457
24458         cancel_lru_locks mdc
24459         local new_md5=$(md5sum $dom)
24460         [ "$old_md5" == "$new_md5" ] ||
24461                 error "$old_md5 != $new_md5"
24462
24463         # Skip free space checks with ZFS
24464         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24465                 local mdtfree2=$(do_facet $facet \
24466                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24467                 [ $mdtfree2 -gt $mdtfree1 ] ||
24468                         error "MDS space is not freed after DOM mirror deletion"
24469         fi
24470         return 0
24471 }
24472 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24473
24474 test_272e() {
24475         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24476                 skip "Need MDS version at least 2.12.55"
24477
24478         local dom=$DIR/$tdir/$tfile
24479         mkdir -p $DIR/$tdir
24480         $LFS setstripe -c 2 $dom
24481
24482         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24483                 error "failed to write data into $dom"
24484         local old_md5=$(md5sum $dom)
24485         cancel_lru_locks
24486
24487         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24488                 error "failed mirroring to the DOM layout"
24489         $LFS mirror resync $dom ||
24490                 error "failed mirror resync"
24491         $LFS mirror split --mirror-id 1 -d $dom ||
24492                 error "failed mirror split"
24493
24494         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24495                 error "MDT stripe wasn't set"
24496
24497         cancel_lru_locks
24498         local new_md5=$(md5sum $dom)
24499         [ "$old_md5" == "$new_md5" ] ||
24500                 error "$old_md5 != $new_md5"
24501
24502         return 0
24503 }
24504 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24505
24506 test_272f() {
24507         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24508                 skip "Need MDS version at least 2.12.55"
24509
24510         local dom=$DIR/$tdir/$tfile
24511         mkdir -p $DIR/$tdir
24512         $LFS setstripe -c 2 $dom
24513
24514         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24515                 error "failed to write data into $dom"
24516         local old_md5=$(md5sum $dom)
24517         cancel_lru_locks
24518
24519         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24520                 error "failed migrating to the DOM file"
24521
24522         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24523                 error "MDT stripe wasn't set"
24524
24525         cancel_lru_locks
24526         local new_md5=$(md5sum $dom)
24527         [ "$old_md5" != "$new_md5" ] &&
24528                 error "$old_md5 != $new_md5"
24529
24530         return 0
24531 }
24532 run_test 272f "DoM migration: OST-striped file to DOM file"
24533
24534 test_273a() {
24535         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24536                 skip "Need MDS version at least 2.11.50"
24537
24538         # Layout swap cannot be done if either file has DOM component,
24539         # this will never be supported, migration should be used instead
24540
24541         local dom=$DIR/$tdir/$tfile
24542         mkdir -p $DIR/$tdir
24543
24544         $LFS setstripe -c2 ${dom}_plain
24545         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24546         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24547                 error "can swap layout with DoM component"
24548         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24549                 error "can swap layout with DoM component"
24550
24551         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24552         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24553                 error "can swap layout with DoM component"
24554         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24555                 error "can swap layout with DoM component"
24556         return 0
24557 }
24558 run_test 273a "DoM: layout swapping should fail with DOM"
24559
24560 test_273b() {
24561         mkdir -p $DIR/$tdir
24562         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24563
24564 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24565         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24566
24567         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24568 }
24569 run_test 273b "DoM: race writeback and object destroy"
24570
24571 test_273c() {
24572         mkdir -p $DIR/$tdir
24573         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24574
24575         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24576         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24577
24578         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24579 }
24580 run_test 273c "race writeback and object destroy"
24581
24582 test_275() {
24583         remote_ost_nodsh && skip "remote OST with nodsh"
24584         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24585                 skip "Need OST version >= 2.10.57"
24586
24587         local file=$DIR/$tfile
24588         local oss
24589
24590         oss=$(comma_list $(osts_nodes))
24591
24592         dd if=/dev/urandom of=$file bs=1M count=2 ||
24593                 error "failed to create a file"
24594         stack_trap "rm -f $file"
24595         cancel_lru_locks osc
24596
24597         #lock 1
24598         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24599                 error "failed to read a file"
24600
24601 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24602         $LCTL set_param fail_loc=0x8000031f
24603
24604         cancel_lru_locks osc &
24605         sleep 1
24606
24607 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24608         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24609         #IO takes another lock, but matches the PENDING one
24610         #and places it to the IO RPC
24611         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24612                 error "failed to read a file with PENDING lock"
24613 }
24614 run_test 275 "Read on a canceled duplicate lock"
24615
24616 test_276() {
24617         remote_ost_nodsh && skip "remote OST with nodsh"
24618         local pid
24619
24620         do_facet ost1 "(while true; do \
24621                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24622                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24623         pid=$!
24624
24625         for LOOP in $(seq 20); do
24626                 stop ost1
24627                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24628         done
24629         kill -9 $pid
24630         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24631                 rm $TMP/sanity_276_pid"
24632 }
24633 run_test 276 "Race between mount and obd_statfs"
24634
24635 test_277() {
24636         $LCTL set_param ldlm.namespaces.*.lru_size=0
24637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24638         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24639                         grep ^used_mb | awk '{print $2}')
24640         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24642                 oflag=direct conv=notrunc
24643         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24644                         grep ^used_mb | awk '{print $2}')
24645         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24646 }
24647 run_test 277 "Direct IO shall drop page cache"
24648
24649 test_278() {
24650         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24651         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24652         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24653                 skip "needs the same host for mdt1 mdt2" && return
24654
24655         local pid1
24656         local pid2
24657
24658 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24659         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24660         stop mds2 &
24661         pid2=$!
24662
24663         stop mds1
24664
24665         echo "Starting MDTs"
24666         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24667         wait $pid2
24668 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24669 #will return NULL
24670         do_facet mds2 $LCTL set_param fail_loc=0
24671
24672         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24673         wait_recovery_complete mds2
24674 }
24675 run_test 278 "Race starting MDS between MDTs stop/start"
24676
24677 test_280() {
24678         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24679                 skip "Need MGS version at least 2.13.52"
24680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24681         combined_mgs_mds || skip "needs combined MGS/MDT"
24682
24683         umount_client $MOUNT
24684 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24685         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24686
24687         mount_client $MOUNT &
24688         sleep 1
24689         stop mgs || error "stop mgs failed"
24690         #for a race mgs would crash
24691         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24692         # make sure we unmount client before remounting
24693         wait
24694         umount_client $MOUNT
24695         mount_client $MOUNT || error "mount client failed"
24696 }
24697 run_test 280 "Race between MGS umount and client llog processing"
24698
24699 cleanup_test_300() {
24700         trap 0
24701         umask $SAVE_UMASK
24702 }
24703 test_striped_dir() {
24704         local mdt_index=$1
24705         local stripe_count
24706         local stripe_index
24707
24708         mkdir -p $DIR/$tdir
24709
24710         SAVE_UMASK=$(umask)
24711         trap cleanup_test_300 RETURN EXIT
24712
24713         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24714                                                 $DIR/$tdir/striped_dir ||
24715                 error "set striped dir error"
24716
24717         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24718         [ "$mode" = "755" ] || error "expect 755 got $mode"
24719
24720         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24721                 error "getdirstripe failed"
24722         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24723         if [ "$stripe_count" != "2" ]; then
24724                 error "1:stripe_count is $stripe_count, expect 2"
24725         fi
24726         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24727         if [ "$stripe_count" != "2" ]; then
24728                 error "2:stripe_count is $stripe_count, expect 2"
24729         fi
24730
24731         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24732         if [ "$stripe_index" != "$mdt_index" ]; then
24733                 error "stripe_index is $stripe_index, expect $mdt_index"
24734         fi
24735
24736         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24737                 error "nlink error after create striped dir"
24738
24739         mkdir $DIR/$tdir/striped_dir/a
24740         mkdir $DIR/$tdir/striped_dir/b
24741
24742         stat $DIR/$tdir/striped_dir/a ||
24743                 error "create dir under striped dir failed"
24744         stat $DIR/$tdir/striped_dir/b ||
24745                 error "create dir under striped dir failed"
24746
24747         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24748                 error "nlink error after mkdir"
24749
24750         rmdir $DIR/$tdir/striped_dir/a
24751         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24752                 error "nlink error after rmdir"
24753
24754         rmdir $DIR/$tdir/striped_dir/b
24755         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24756                 error "nlink error after rmdir"
24757
24758         chattr +i $DIR/$tdir/striped_dir
24759         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24760                 error "immutable flags not working under striped dir!"
24761         chattr -i $DIR/$tdir/striped_dir
24762
24763         rmdir $DIR/$tdir/striped_dir ||
24764                 error "rmdir striped dir error"
24765
24766         cleanup_test_300
24767
24768         true
24769 }
24770
24771 test_300a() {
24772         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24773                 skip "skipped for lustre < 2.7.0"
24774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24775         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24776
24777         test_striped_dir 0 || error "failed on striped dir on MDT0"
24778         test_striped_dir 1 || error "failed on striped dir on MDT0"
24779 }
24780 run_test 300a "basic striped dir sanity test"
24781
24782 test_300b() {
24783         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24784                 skip "skipped for lustre < 2.7.0"
24785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24787
24788         local i
24789         local mtime1
24790         local mtime2
24791         local mtime3
24792
24793         test_mkdir $DIR/$tdir || error "mkdir fail"
24794         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24795                 error "set striped dir error"
24796         for i in {0..9}; do
24797                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24798                 sleep 1
24799                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24800                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24801                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24802                 sleep 1
24803                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24804                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24805                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24806         done
24807         true
24808 }
24809 run_test 300b "check ctime/mtime for striped dir"
24810
24811 test_300c() {
24812         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24813                 skip "skipped for lustre < 2.7.0"
24814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24816
24817         local file_count
24818
24819         mkdir_on_mdt0 $DIR/$tdir
24820         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24821                 error "set striped dir error"
24822
24823         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24824                 error "chown striped dir failed"
24825
24826         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24827                 error "create 5k files failed"
24828
24829         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24830
24831         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24832
24833         rm -rf $DIR/$tdir
24834 }
24835 run_test 300c "chown && check ls under striped directory"
24836
24837 test_300d() {
24838         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24839                 skip "skipped for lustre < 2.7.0"
24840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24842
24843         local stripe_count
24844         local file
24845
24846         mkdir -p $DIR/$tdir
24847         $LFS setstripe -c 2 $DIR/$tdir
24848
24849         #local striped directory
24850         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24851                 error "set striped dir error"
24852         #look at the directories for debug purposes
24853         ls -l $DIR/$tdir
24854         $LFS getdirstripe $DIR/$tdir
24855         ls -l $DIR/$tdir/striped_dir
24856         $LFS getdirstripe $DIR/$tdir/striped_dir
24857         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24858                 error "create 10 files failed"
24859
24860         #remote striped directory
24861         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24862                 error "set striped dir error"
24863         #look at the directories for debug purposes
24864         ls -l $DIR/$tdir
24865         $LFS getdirstripe $DIR/$tdir
24866         ls -l $DIR/$tdir/remote_striped_dir
24867         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24868         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24869                 error "create 10 files failed"
24870
24871         for file in $(find $DIR/$tdir); do
24872                 stripe_count=$($LFS getstripe -c $file)
24873                 [ $stripe_count -eq 2 ] ||
24874                         error "wrong stripe $stripe_count for $file"
24875         done
24876
24877         rm -rf $DIR/$tdir
24878 }
24879 run_test 300d "check default stripe under striped directory"
24880
24881 test_300e() {
24882         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24883                 skip "Need MDS version at least 2.7.55"
24884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24885         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24886
24887         local stripe_count
24888         local file
24889
24890         mkdir -p $DIR/$tdir
24891
24892         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24893                 error "set striped dir error"
24894
24895         touch $DIR/$tdir/striped_dir/a
24896         touch $DIR/$tdir/striped_dir/b
24897         touch $DIR/$tdir/striped_dir/c
24898
24899         mkdir $DIR/$tdir/striped_dir/dir_a
24900         mkdir $DIR/$tdir/striped_dir/dir_b
24901         mkdir $DIR/$tdir/striped_dir/dir_c
24902
24903         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24904                 error "set striped adir under striped dir error"
24905
24906         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24907                 error "set striped bdir under striped dir error"
24908
24909         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24910                 error "set striped cdir under striped dir error"
24911
24912         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24913                 error "rename dir under striped dir fails"
24914
24915         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24916                 error "rename dir under different stripes fails"
24917
24918         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24919                 error "rename file under striped dir should succeed"
24920
24921         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24922                 error "rename dir under striped dir should succeed"
24923
24924         rm -rf $DIR/$tdir
24925 }
24926 run_test 300e "check rename under striped directory"
24927
24928 test_300f() {
24929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24931         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24932                 skip "Need MDS version at least 2.7.55"
24933
24934         local stripe_count
24935         local file
24936
24937         rm -rf $DIR/$tdir
24938         mkdir -p $DIR/$tdir
24939
24940         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24941                 error "set striped dir error"
24942
24943         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24944                 error "set striped dir error"
24945
24946         touch $DIR/$tdir/striped_dir/a
24947         mkdir $DIR/$tdir/striped_dir/dir_a
24948         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24949                 error "create striped dir under striped dir fails"
24950
24951         touch $DIR/$tdir/striped_dir1/b
24952         mkdir $DIR/$tdir/striped_dir1/dir_b
24953         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24954                 error "create striped dir under striped dir fails"
24955
24956         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24957                 error "rename dir under different striped dir should fail"
24958
24959         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24960                 error "rename striped dir under diff striped dir should fail"
24961
24962         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24963                 error "rename file under diff striped dirs fails"
24964
24965         rm -rf $DIR/$tdir
24966 }
24967 run_test 300f "check rename cross striped directory"
24968
24969 test_300_check_default_striped_dir()
24970 {
24971         local dirname=$1
24972         local default_count=$2
24973         local default_index=$3
24974         local stripe_count
24975         local stripe_index
24976         local dir_stripe_index
24977         local dir
24978
24979         echo "checking $dirname $default_count $default_index"
24980         $LFS setdirstripe -D -c $default_count -i $default_index \
24981                                 -H all_char $DIR/$tdir/$dirname ||
24982                 error "set default stripe on striped dir error"
24983         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24984         [ $stripe_count -eq $default_count ] ||
24985                 error "expect $default_count get $stripe_count for $dirname"
24986
24987         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24988         [ $stripe_index -eq $default_index ] ||
24989                 error "expect $default_index get $stripe_index for $dirname"
24990
24991         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24992                                                 error "create dirs failed"
24993
24994         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24995         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24996         for dir in $(find $DIR/$tdir/$dirname/*); do
24997                 stripe_count=$($LFS getdirstripe -c $dir)
24998                 (( $stripe_count == $default_count )) ||
24999                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25000                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25001                 error "stripe count $default_count != $stripe_count for $dir"
25002
25003                 stripe_index=$($LFS getdirstripe -i $dir)
25004                 [ $default_index -eq -1 ] ||
25005                         [ $stripe_index -eq $default_index ] ||
25006                         error "$stripe_index != $default_index for $dir"
25007
25008                 #check default stripe
25009                 stripe_count=$($LFS getdirstripe -D -c $dir)
25010                 [ $stripe_count -eq $default_count ] ||
25011                 error "default count $default_count != $stripe_count for $dir"
25012
25013                 stripe_index=$($LFS getdirstripe -D -i $dir)
25014                 [ $stripe_index -eq $default_index ] ||
25015                 error "default index $default_index != $stripe_index for $dir"
25016         done
25017         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25018 }
25019
25020 test_300g() {
25021         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25022         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25023                 skip "Need MDS version at least 2.7.55"
25024
25025         local dir
25026         local stripe_count
25027         local stripe_index
25028
25029         mkdir_on_mdt0 $DIR/$tdir
25030         mkdir $DIR/$tdir/normal_dir
25031
25032         #Checking when client cache stripe index
25033         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25034         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25035                 error "create striped_dir failed"
25036
25037         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25038                 error "create dir0 fails"
25039         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25040         [ $stripe_index -eq 0 ] ||
25041                 error "dir0 expect index 0 got $stripe_index"
25042
25043         mkdir $DIR/$tdir/striped_dir/dir1 ||
25044                 error "create dir1 fails"
25045         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25046         [ $stripe_index -eq 1 ] ||
25047                 error "dir1 expect index 1 got $stripe_index"
25048
25049         #check default stripe count/stripe index
25050         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25051         test_300_check_default_striped_dir normal_dir 1 0
25052         test_300_check_default_striped_dir normal_dir -1 1
25053         test_300_check_default_striped_dir normal_dir 2 -1
25054
25055         #delete default stripe information
25056         echo "delete default stripeEA"
25057         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25058                 error "set default stripe on striped dir error"
25059
25060         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25061         for dir in $(find $DIR/$tdir/normal_dir/*); do
25062                 stripe_count=$($LFS getdirstripe -c $dir)
25063                 [ $stripe_count -eq 0 ] ||
25064                         error "expect 1 get $stripe_count for $dir"
25065         done
25066 }
25067 run_test 300g "check default striped directory for normal directory"
25068
25069 test_300h() {
25070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25071         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25072                 skip "Need MDS version at least 2.7.55"
25073
25074         local dir
25075         local stripe_count
25076
25077         mkdir $DIR/$tdir
25078         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25079                 error "set striped dir error"
25080
25081         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25082         test_300_check_default_striped_dir striped_dir 1 0
25083         test_300_check_default_striped_dir striped_dir -1 1
25084         test_300_check_default_striped_dir striped_dir 2 -1
25085
25086         #delete default stripe information
25087         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25088                 error "set default stripe on striped dir error"
25089
25090         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25091         for dir in $(find $DIR/$tdir/striped_dir/*); do
25092                 stripe_count=$($LFS getdirstripe -c $dir)
25093                 [ $stripe_count -eq 0 ] ||
25094                         error "expect 1 get $stripe_count for $dir"
25095         done
25096 }
25097 run_test 300h "check default striped directory for striped directory"
25098
25099 test_300i() {
25100         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25101         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25102         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25103                 skip "Need MDS version at least 2.7.55"
25104
25105         local stripe_count
25106         local file
25107
25108         mkdir $DIR/$tdir
25109
25110         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25111                 error "set striped dir error"
25112
25113         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25114                 error "create files under striped dir failed"
25115
25116         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25117                 error "set striped hashdir error"
25118
25119         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25120                 error "create dir0 under hash dir failed"
25121         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25122                 error "create dir1 under hash dir failed"
25123         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25124                 error "create dir2 under hash dir failed"
25125
25126         # unfortunately, we need to umount to clear dir layout cache for now
25127         # once we fully implement dir layout, we can drop this
25128         umount_client $MOUNT || error "umount failed"
25129         mount_client $MOUNT || error "mount failed"
25130
25131         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25132         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25133         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25134
25135         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25136                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25137                         error "create crush2 dir $tdir/hashdir/d3 failed"
25138                 $LFS find -H crush2 $DIR/$tdir/hashdir
25139                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25140                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25141
25142                 # mkdir with an invalid hash type (hash=fail_val) from client
25143                 # should be replaced on MDS with a valid (default) hash type
25144                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25145                 $LCTL set_param fail_loc=0x1901 fail_val=99
25146                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25147
25148                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25149                 local expect=$(do_facet mds1 \
25150                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25151                 [[ $hash == $expect ]] ||
25152                         error "d99 hash '$hash' != expected hash '$expect'"
25153         fi
25154
25155         #set the stripe to be unknown hash type on read
25156         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25157         $LCTL set_param fail_loc=0x1901 fail_val=99
25158         for ((i = 0; i < 10; i++)); do
25159                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25160                         error "stat f-$i failed"
25161                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25162         done
25163
25164         touch $DIR/$tdir/striped_dir/f0 &&
25165                 error "create under striped dir with unknown hash should fail"
25166
25167         $LCTL set_param fail_loc=0
25168
25169         umount_client $MOUNT || error "umount failed"
25170         mount_client $MOUNT || error "mount failed"
25171
25172         return 0
25173 }
25174 run_test 300i "client handle unknown hash type striped directory"
25175
25176 test_300j() {
25177         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25179         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25180                 skip "Need MDS version at least 2.7.55"
25181
25182         local stripe_count
25183         local file
25184
25185         mkdir $DIR/$tdir
25186
25187         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25188         $LCTL set_param fail_loc=0x1702
25189         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25190                 error "set striped dir error"
25191
25192         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25193                 error "create files under striped dir failed"
25194
25195         $LCTL set_param fail_loc=0
25196
25197         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25198
25199         return 0
25200 }
25201 run_test 300j "test large update record"
25202
25203 test_300k() {
25204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25205         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25206         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25207                 skip "Need MDS version at least 2.7.55"
25208
25209         # this test needs a huge transaction
25210         local kb
25211         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25212              osd*.$FSNAME-MDT0000.kbytestotal")
25213         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25214
25215         local stripe_count
25216         local file
25217
25218         mkdir $DIR/$tdir
25219
25220         #define OBD_FAIL_LARGE_STRIPE   0x1703
25221         $LCTL set_param fail_loc=0x1703
25222         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25223                 error "set striped dir error"
25224         $LCTL set_param fail_loc=0
25225
25226         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25227                 error "getstripeddir fails"
25228         rm -rf $DIR/$tdir/striped_dir ||
25229                 error "unlink striped dir fails"
25230
25231         return 0
25232 }
25233 run_test 300k "test large striped directory"
25234
25235 test_300l() {
25236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25237         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25238         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25239                 skip "Need MDS version at least 2.7.55"
25240
25241         local stripe_index
25242
25243         test_mkdir -p $DIR/$tdir/striped_dir
25244         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25245                         error "chown $RUNAS_ID failed"
25246         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25247                 error "set default striped dir failed"
25248
25249         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25250         $LCTL set_param fail_loc=0x80000158
25251         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25252
25253         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25254         [ $stripe_index -eq 1 ] ||
25255                 error "expect 1 get $stripe_index for $dir"
25256 }
25257 run_test 300l "non-root user to create dir under striped dir with stale layout"
25258
25259 test_300m() {
25260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25261         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25262         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25263                 skip "Need MDS version at least 2.7.55"
25264
25265         mkdir -p $DIR/$tdir/striped_dir
25266         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25267                 error "set default stripes dir error"
25268
25269         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25270
25271         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25272         [ $stripe_count -eq 0 ] ||
25273                         error "expect 0 get $stripe_count for a"
25274
25275         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25276                 error "set default stripes dir error"
25277
25278         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25279
25280         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25281         [ $stripe_count -eq 0 ] ||
25282                         error "expect 0 get $stripe_count for b"
25283
25284         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25285                 error "set default stripes dir error"
25286
25287         mkdir $DIR/$tdir/striped_dir/c &&
25288                 error "default stripe_index is invalid, mkdir c should fails"
25289
25290         rm -rf $DIR/$tdir || error "rmdir fails"
25291 }
25292 run_test 300m "setstriped directory on single MDT FS"
25293
25294 cleanup_300n() {
25295         local list=$(comma_list $(mdts_nodes))
25296
25297         trap 0
25298         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25299 }
25300
25301 test_300n() {
25302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25303         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25304         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25305                 skip "Need MDS version at least 2.7.55"
25306         remote_mds_nodsh && skip "remote MDS with nodsh"
25307
25308         local stripe_index
25309         local list=$(comma_list $(mdts_nodes))
25310
25311         trap cleanup_300n RETURN EXIT
25312         mkdir -p $DIR/$tdir
25313         chmod 777 $DIR/$tdir
25314         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25315                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25316                 error "create striped dir succeeds with gid=0"
25317
25318         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25319         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25320                 error "create striped dir fails with gid=-1"
25321
25322         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25323         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25324                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25325                 error "set default striped dir succeeds with gid=0"
25326
25327
25328         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25329         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25330                 error "set default striped dir fails with gid=-1"
25331
25332
25333         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25334         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25335                                         error "create test_dir fails"
25336         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25337                                         error "create test_dir1 fails"
25338         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25339                                         error "create test_dir2 fails"
25340         cleanup_300n
25341 }
25342 run_test 300n "non-root user to create dir under striped dir with default EA"
25343
25344 test_300o() {
25345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25347         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25348                 skip "Need MDS version at least 2.7.55"
25349
25350         local numfree1
25351         local numfree2
25352
25353         mkdir -p $DIR/$tdir
25354
25355         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25356         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25357         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25358                 skip "not enough free inodes $numfree1 $numfree2"
25359         fi
25360
25361         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25362         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25363         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25364                 skip "not enough free space $numfree1 $numfree2"
25365         fi
25366
25367         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25368                 error "setdirstripe fails"
25369
25370         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25371                 error "create dirs fails"
25372
25373         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25374         ls $DIR/$tdir/striped_dir > /dev/null ||
25375                 error "ls striped dir fails"
25376         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25377                 error "unlink big striped dir fails"
25378 }
25379 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25380
25381 test_300p() {
25382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25384         remote_mds_nodsh && skip "remote MDS with nodsh"
25385
25386         mkdir_on_mdt0 $DIR/$tdir
25387
25388         #define OBD_FAIL_OUT_ENOSPC     0x1704
25389         do_facet mds2 lctl set_param fail_loc=0x80001704
25390         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25391                  && error "create striped directory should fail"
25392
25393         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25394
25395         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25396         true
25397 }
25398 run_test 300p "create striped directory without space"
25399
25400 test_300q() {
25401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25403
25404         local fd=$(free_fd)
25405         local cmd="exec $fd<$tdir"
25406         cd $DIR
25407         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25408         eval $cmd
25409         cmd="exec $fd<&-"
25410         trap "eval $cmd" EXIT
25411         cd $tdir || error "cd $tdir fails"
25412         rmdir  ../$tdir || error "rmdir $tdir fails"
25413         mkdir local_dir && error "create dir succeeds"
25414         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25415         eval $cmd
25416         return 0
25417 }
25418 run_test 300q "create remote directory under orphan directory"
25419
25420 test_300r() {
25421         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25422                 skip "Need MDS version at least 2.7.55" && return
25423         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25424
25425         mkdir $DIR/$tdir
25426
25427         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25428                 error "set striped dir error"
25429
25430         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25431                 error "getstripeddir fails"
25432
25433         local stripe_count
25434         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25435                       awk '/lmv_stripe_count:/ { print $2 }')
25436
25437         [ $MDSCOUNT -ne $stripe_count ] &&
25438                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25439
25440         rm -rf $DIR/$tdir/striped_dir ||
25441                 error "unlink striped dir fails"
25442 }
25443 run_test 300r "test -1 striped directory"
25444
25445 test_300s_helper() {
25446         local count=$1
25447
25448         local stripe_dir=$DIR/$tdir/striped_dir.$count
25449
25450         $LFS mkdir -c $count $stripe_dir ||
25451                 error "lfs mkdir -c error"
25452
25453         $LFS getdirstripe $stripe_dir ||
25454                 error "lfs getdirstripe fails"
25455
25456         local stripe_count
25457         stripe_count=$($LFS getdirstripe $stripe_dir |
25458                       awk '/lmv_stripe_count:/ { print $2 }')
25459
25460         [ $count -ne $stripe_count ] &&
25461                 error_noexit "bad stripe count $stripe_count expected $count"
25462
25463         local dupe_stripes
25464         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25465                 awk '/0x/ {count[$1] += 1}; END {
25466                         for (idx in count) {
25467                                 if (count[idx]>1) {
25468                                         print "index " idx " count " count[idx]
25469                                 }
25470                         }
25471                 }')
25472
25473         if [[ -n "$dupe_stripes" ]] ; then
25474                 lfs getdirstripe $stripe_dir
25475                 error_noexit "Dupe MDT above: $dupe_stripes "
25476         fi
25477
25478         rm -rf $stripe_dir ||
25479                 error_noexit "unlink $stripe_dir fails"
25480 }
25481
25482 test_300s() {
25483         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25484                 skip "Need MDS version at least 2.7.55" && return
25485         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25486
25487         mkdir $DIR/$tdir
25488         for count in $(seq 2 $MDSCOUNT); do
25489                 test_300s_helper $count
25490         done
25491 }
25492 run_test 300s "test lfs mkdir -c without -i"
25493
25494 test_300t() {
25495         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25496                 skip "need MDS 2.14.55 or later"
25497         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25498
25499         local testdir="$DIR/$tdir/striped_dir"
25500         local dir1=$testdir/dir1
25501         local dir2=$testdir/dir2
25502
25503         mkdir -p $testdir
25504
25505         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25506                 error "failed to set default stripe count for $testdir"
25507
25508         mkdir $dir1
25509         local stripe_count=$($LFS getdirstripe -c $dir1)
25510
25511         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25512
25513         local max_count=$((MDSCOUNT - 1))
25514         local mdts=$(comma_list $(mdts_nodes))
25515
25516         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25517         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25518
25519         mkdir $dir2
25520         stripe_count=$($LFS getdirstripe -c $dir2)
25521
25522         (( $stripe_count == $max_count )) || error "wrong stripe count"
25523 }
25524 run_test 300t "test max_mdt_stripecount"
25525
25526 prepare_remote_file() {
25527         mkdir $DIR/$tdir/src_dir ||
25528                 error "create remote source failed"
25529
25530         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25531                  error "cp to remote source failed"
25532         touch $DIR/$tdir/src_dir/a
25533
25534         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25535                 error "create remote target dir failed"
25536
25537         touch $DIR/$tdir/tgt_dir/b
25538
25539         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25540                 error "rename dir cross MDT failed!"
25541
25542         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25543                 error "src_child still exists after rename"
25544
25545         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25546                 error "missing file(a) after rename"
25547
25548         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25549                 error "diff after rename"
25550 }
25551
25552 test_310a() {
25553         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25555
25556         local remote_file=$DIR/$tdir/tgt_dir/b
25557
25558         mkdir -p $DIR/$tdir
25559
25560         prepare_remote_file || error "prepare remote file failed"
25561
25562         #open-unlink file
25563         $OPENUNLINK $remote_file $remote_file ||
25564                 error "openunlink $remote_file failed"
25565         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25566 }
25567 run_test 310a "open unlink remote file"
25568
25569 test_310b() {
25570         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25572
25573         local remote_file=$DIR/$tdir/tgt_dir/b
25574
25575         mkdir -p $DIR/$tdir
25576
25577         prepare_remote_file || error "prepare remote file failed"
25578
25579         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25580         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25581         $CHECKSTAT -t file $remote_file || error "check file failed"
25582 }
25583 run_test 310b "unlink remote file with multiple links while open"
25584
25585 test_310c() {
25586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25587         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25588
25589         local remote_file=$DIR/$tdir/tgt_dir/b
25590
25591         mkdir -p $DIR/$tdir
25592
25593         prepare_remote_file || error "prepare remote file failed"
25594
25595         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25596         multiop_bg_pause $remote_file O_uc ||
25597                         error "mulitop failed for remote file"
25598         MULTIPID=$!
25599         $MULTIOP $DIR/$tfile Ouc
25600         kill -USR1 $MULTIPID
25601         wait $MULTIPID
25602 }
25603 run_test 310c "open-unlink remote file with multiple links"
25604
25605 #LU-4825
25606 test_311() {
25607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25608         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25609         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25610                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25611         remote_mds_nodsh && skip "remote MDS with nodsh"
25612
25613         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25614         local mdts=$(comma_list $(mdts_nodes))
25615
25616         mkdir -p $DIR/$tdir
25617         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25618         createmany -o $DIR/$tdir/$tfile. 1000
25619
25620         # statfs data is not real time, let's just calculate it
25621         old_iused=$((old_iused + 1000))
25622
25623         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25624                         osp.*OST0000*MDT0000.create_count")
25625         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25626                                 osp.*OST0000*MDT0000.max_create_count")
25627         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25628
25629         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25630         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25631         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25632
25633         unlinkmany $DIR/$tdir/$tfile. 1000
25634
25635         do_nodes $mdts "$LCTL set_param -n \
25636                         osp.*OST0000*.max_create_count=$max_count"
25637         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25638                 do_nodes $mdts "$LCTL set_param -n \
25639                                 osp.*OST0000*.create_count=$count"
25640         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25641                         grep "=0" && error "create_count is zero"
25642
25643         local new_iused
25644         for i in $(seq 120); do
25645                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25646                 # system may be too busy to destroy all objs in time, use
25647                 # a somewhat small value to not fail autotest
25648                 [ $((old_iused - new_iused)) -gt 400 ] && break
25649                 sleep 1
25650         done
25651
25652         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25653         [ $((old_iused - new_iused)) -gt 400 ] ||
25654                 error "objs not destroyed after unlink"
25655 }
25656 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25657
25658 zfs_get_objid()
25659 {
25660         local ost=$1
25661         local tf=$2
25662         local fid=($($LFS getstripe $tf | grep 0x))
25663         local seq=${fid[3]#0x}
25664         local objid=${fid[1]}
25665
25666         local vdevdir=$(dirname $(facet_vdevice $ost))
25667         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25668         local zfs_zapid=$(do_facet $ost $cmd |
25669                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25670                           awk '/Object/{getline; print $1}')
25671         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25672                           awk "/$objid = /"'{printf $3}')
25673
25674         echo $zfs_objid
25675 }
25676
25677 zfs_object_blksz() {
25678         local ost=$1
25679         local objid=$2
25680
25681         local vdevdir=$(dirname $(facet_vdevice $ost))
25682         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25683         local blksz=$(do_facet $ost $cmd $objid |
25684                       awk '/dblk/{getline; printf $4}')
25685
25686         case "${blksz: -1}" in
25687                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25688                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25689                 *) ;;
25690         esac
25691
25692         echo $blksz
25693 }
25694
25695 test_312() { # LU-4856
25696         remote_ost_nodsh && skip "remote OST with nodsh"
25697         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25698
25699         local max_blksz=$(do_facet ost1 \
25700                           $ZFS get -p recordsize $(facet_device ost1) |
25701                           awk '!/VALUE/{print $3}')
25702         local tf=$DIR/$tfile
25703
25704         $LFS setstripe -c1 $tf
25705         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25706
25707         # Get ZFS object id
25708         local zfs_objid=$(zfs_get_objid $facet $tf)
25709         # block size change by sequential overwrite
25710         local bs
25711
25712         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25713                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25714
25715                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25716                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25717         done
25718         rm -f $tf
25719
25720         $LFS setstripe -c1 $tf
25721         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25722
25723         # block size change by sequential append write
25724         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25725         zfs_objid=$(zfs_get_objid $facet $tf)
25726         local count
25727
25728         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25729                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25730                         oflag=sync conv=notrunc
25731
25732                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25733                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25734                         error "blksz error, actual $blksz, " \
25735                                 "expected: 2 * $count * $PAGE_SIZE"
25736         done
25737         rm -f $tf
25738
25739         # random write
25740         $LFS setstripe -c1 $tf
25741         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25742         zfs_objid=$(zfs_get_objid $facet $tf)
25743
25744         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25745         blksz=$(zfs_object_blksz $facet $zfs_objid)
25746         (( blksz == PAGE_SIZE )) ||
25747                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25748
25749         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25750         blksz=$(zfs_object_blksz $facet $zfs_objid)
25751         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25752
25753         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25754         blksz=$(zfs_object_blksz $facet $zfs_objid)
25755         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25756 }
25757 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25758
25759 test_313() {
25760         remote_ost_nodsh && skip "remote OST with nodsh"
25761
25762         local file=$DIR/$tfile
25763
25764         rm -f $file
25765         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25766
25767         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25768         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25769         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25770                 error "write should failed"
25771         do_facet ost1 "$LCTL set_param fail_loc=0"
25772         rm -f $file
25773 }
25774 run_test 313 "io should fail after last_rcvd update fail"
25775
25776 test_314() {
25777         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25778
25779         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25780         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25781         rm -f $DIR/$tfile
25782         wait_delete_completed
25783         do_facet ost1 "$LCTL set_param fail_loc=0"
25784 }
25785 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25786
25787 test_315() { # LU-618
25788         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25789
25790         local file=$DIR/$tfile
25791         rm -f $file
25792
25793         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25794                 error "multiop file write failed"
25795         $MULTIOP $file oO_RDONLY:r4063232_c &
25796         PID=$!
25797
25798         sleep 2
25799
25800         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25801         kill -USR1 $PID
25802
25803         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25804         rm -f $file
25805 }
25806 run_test 315 "read should be accounted"
25807
25808 test_316() {
25809         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25810         large_xattr_enabled || skip "ea_inode feature disabled"
25811
25812         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25813         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25814         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25815         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25816
25817         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25818 }
25819 run_test 316 "lfs migrate of file with large_xattr enabled"
25820
25821 test_317() {
25822         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25823                 skip "Need MDS version at least 2.11.53"
25824         if [ "$ost1_FSTYPE" == "zfs" ]; then
25825                 skip "LU-10370: no implementation for ZFS"
25826         fi
25827
25828         local trunc_sz
25829         local grant_blk_size
25830
25831         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25832                         awk '/grant_block_size:/ { print $2; exit; }')
25833         #
25834         # Create File of size 5M. Truncate it to below size's and verify
25835         # blocks count.
25836         #
25837         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25838                 error "Create file $DIR/$tfile failed"
25839         stack_trap "rm -f $DIR/$tfile" EXIT
25840
25841         for trunc_sz in 2097152 4097 4000 509 0; do
25842                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25843                         error "truncate $tfile to $trunc_sz failed"
25844                 local sz=$(stat --format=%s $DIR/$tfile)
25845                 local blk=$(stat --format=%b $DIR/$tfile)
25846                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25847                                      grant_blk_size) * 8))
25848
25849                 if [[ $blk -ne $trunc_blk ]]; then
25850                         $(which stat) $DIR/$tfile
25851                         error "Expected Block $trunc_blk got $blk for $tfile"
25852                 fi
25853
25854                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25855                         error "Expected Size $trunc_sz got $sz for $tfile"
25856         done
25857
25858         #
25859         # sparse file test
25860         # Create file with a hole and write actual 65536 bytes which aligned
25861         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25862         #
25863         local bs=65536
25864         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25865                 error "Create file : $DIR/$tfile"
25866
25867         #
25868         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25869         # blocks. The block count must drop to 8.
25870         #
25871         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25872                 ((bs - grant_blk_size) + 1)))
25873         $TRUNCATE $DIR/$tfile $trunc_sz ||
25874                 error "truncate $tfile to $trunc_sz failed"
25875
25876         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25877         sz=$(stat --format=%s $DIR/$tfile)
25878         blk=$(stat --format=%b $DIR/$tfile)
25879
25880         if [[ $blk -ne $trunc_bsz ]]; then
25881                 $(which stat) $DIR/$tfile
25882                 error "Expected Block $trunc_bsz got $blk for $tfile"
25883         fi
25884
25885         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25886                 error "Expected Size $trunc_sz got $sz for $tfile"
25887 }
25888 run_test 317 "Verify blocks get correctly update after truncate"
25889
25890 test_318() {
25891         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25892         local old_max_active=$($LCTL get_param -n \
25893                             ${llite_name}.max_read_ahead_async_active \
25894                             2>/dev/null)
25895
25896         $LCTL set_param llite.*.max_read_ahead_async_active=256
25897         local max_active=$($LCTL get_param -n \
25898                            ${llite_name}.max_read_ahead_async_active \
25899                            2>/dev/null)
25900         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25901
25902         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25903                 error "set max_read_ahead_async_active should succeed"
25904
25905         $LCTL set_param llite.*.max_read_ahead_async_active=512
25906         max_active=$($LCTL get_param -n \
25907                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25908         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25909
25910         # restore @max_active
25911         [ $old_max_active -ne 0 ] && $LCTL set_param \
25912                 llite.*.max_read_ahead_async_active=$old_max_active
25913
25914         local old_threshold=$($LCTL get_param -n \
25915                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25916         local max_per_file_mb=$($LCTL get_param -n \
25917                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25918
25919         local invalid=$(($max_per_file_mb + 1))
25920         $LCTL set_param \
25921                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25922                         && error "set $invalid should fail"
25923
25924         local valid=$(($invalid - 1))
25925         $LCTL set_param \
25926                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25927                         error "set $valid should succeed"
25928         local threshold=$($LCTL get_param -n \
25929                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25930         [ $threshold -eq $valid ] || error \
25931                 "expect threshold $valid got $threshold"
25932         $LCTL set_param \
25933                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25934 }
25935 run_test 318 "Verify async readahead tunables"
25936
25937 test_319() {
25938         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25939
25940         local before=$(date +%s)
25941         local evict
25942         local mdir=$DIR/$tdir
25943         local file=$mdir/xxx
25944
25945         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25946         touch $file
25947
25948 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25949         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25950         $LFS migrate -m1 $mdir &
25951
25952         sleep 1
25953         dd if=$file of=/dev/null
25954         wait
25955         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25956           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25957
25958         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25959 }
25960 run_test 319 "lost lease lock on migrate error"
25961
25962 test_398a() { # LU-4198
25963         local ost1_imp=$(get_osc_import_name client ost1)
25964         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25965                          cut -d'.' -f2)
25966
25967         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25968         stack_trap "rm -f $DIR/$tfile"
25969         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25970
25971         # request a new lock on client
25972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25973
25974         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25975         local lock_count=$($LCTL get_param -n \
25976                            ldlm.namespaces.$imp_name.lru_size)
25977         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25978
25979         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25980
25981         # no lock cached, should use lockless DIO and not enqueue new lock
25982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25983         lock_count=$($LCTL get_param -n \
25984                      ldlm.namespaces.$imp_name.lru_size)
25985         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25986
25987         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25988
25989         # no lock cached, should use locked DIO append
25990         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25991                 conv=notrunc || error "DIO append failed"
25992         lock_count=$($LCTL get_param -n \
25993                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25994         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25995 }
25996 run_test 398a "direct IO should cancel lock otherwise lockless"
25997
25998 test_398b() { # LU-4198
25999         local before=$(date +%s)
26000         local njobs=4
26001         local size=48
26002
26003         which fio || skip_env "no fio installed"
26004         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26005         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26006
26007         # Single page, multiple pages, stripe size, 4*stripe size
26008         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26009                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26010                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26011                         --numjobs=$njobs --fallocate=none \
26012                         --iodepth=16 --allow_file_create=0 \
26013                         --size=$((size/njobs))M \
26014                         --filename=$DIR/$tfile &
26015                 bg_pid=$!
26016
26017                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26018                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26019                         --numjobs=$njobs --fallocate=none \
26020                         --iodepth=16 --allow_file_create=0 \
26021                         --size=$((size/njobs))M \
26022                         --filename=$DIR/$tfile || true
26023                 wait $bg_pid
26024         done
26025
26026         evict=$(do_facet client $LCTL get_param \
26027                 osc.$FSNAME-OST*-osc-*/state |
26028             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26029
26030         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26031                 (do_facet client $LCTL get_param \
26032                         osc.$FSNAME-OST*-osc-*/state;
26033                     error "eviction happened: $evict before:$before")
26034
26035         rm -f $DIR/$tfile
26036 }
26037 run_test 398b "DIO and buffer IO race"
26038
26039 test_398c() { # LU-4198
26040         local ost1_imp=$(get_osc_import_name client ost1)
26041         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26042                          cut -d'.' -f2)
26043
26044         which fio || skip_env "no fio installed"
26045
26046         saved_debug=$($LCTL get_param -n debug)
26047         $LCTL set_param debug=0
26048
26049         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26050         ((size /= 1024)) # by megabytes
26051         ((size /= 2)) # write half of the OST at most
26052         [ $size -gt 40 ] && size=40 #reduce test time anyway
26053
26054         $LFS setstripe -c 1 $DIR/$tfile
26055
26056         # it seems like ldiskfs reserves more space than necessary if the
26057         # writing blocks are not mapped, so it extends the file firstly
26058         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26059         cancel_lru_locks osc
26060
26061         # clear and verify rpc_stats later
26062         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26063
26064         local njobs=4
26065         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26066         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26067                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26068                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26069                 --filename=$DIR/$tfile
26070         [ $? -eq 0 ] || error "fio write error"
26071
26072         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26073                 error "Locks were requested while doing AIO"
26074
26075         # get the percentage of 1-page I/O
26076         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26077                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26078                 awk '{print $7}')
26079         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26080
26081         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26082         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26083                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26084                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26085                 --filename=$DIR/$tfile
26086         [ $? -eq 0 ] || error "fio mixed read write error"
26087
26088         echo "AIO with large block size ${size}M"
26089         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26090                 --numjobs=1 --fallocate=none --ioengine=libaio \
26091                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26092                 --filename=$DIR/$tfile
26093         [ $? -eq 0 ] || error "fio large block size failed"
26094
26095         rm -f $DIR/$tfile
26096         $LCTL set_param debug="$saved_debug"
26097 }
26098 run_test 398c "run fio to test AIO"
26099
26100 test_398d() { #  LU-13846
26101         which aiocp || skip_env "no aiocp installed"
26102         local aio_file=$DIR/$tfile.aio
26103
26104         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26105
26106         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26107         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26108         stack_trap "rm -f $DIR/$tfile $aio_file"
26109
26110         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26111
26112         # make sure we don't crash and fail properly
26113         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26114                 error "aio not aligned with PAGE SIZE should fail"
26115
26116         rm -f $DIR/$tfile $aio_file
26117 }
26118 run_test 398d "run aiocp to verify block size > stripe size"
26119
26120 test_398e() {
26121         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26122         touch $DIR/$tfile.new
26123         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26124 }
26125 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26126
26127 test_398f() { #  LU-14687
26128         which aiocp || skip_env "no aiocp installed"
26129         local aio_file=$DIR/$tfile.aio
26130
26131         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26132
26133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26134         stack_trap "rm -f $DIR/$tfile $aio_file"
26135
26136         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26137         $LCTL set_param fail_loc=0x1418
26138         # make sure we don't crash and fail properly
26139         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26140                 error "aio with page allocation failure succeeded"
26141         $LCTL set_param fail_loc=0
26142         diff $DIR/$tfile $aio_file
26143         [[ $? != 0 ]] || error "no diff after failed aiocp"
26144 }
26145 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26146
26147 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26148 # stripe and i/o size must be > stripe size
26149 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26150 # single RPC in flight.  This test shows async DIO submission is working by
26151 # showing multiple RPCs in flight.
26152 test_398g() { #  LU-13798
26153         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26154
26155         # We need to do some i/o first to acquire enough grant to put our RPCs
26156         # in flight; otherwise a new connection may not have enough grant
26157         # available
26158         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26159                 error "parallel dio failed"
26160         stack_trap "rm -f $DIR/$tfile"
26161
26162         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26163         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26164         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26165         stack_trap "$LCTL set_param -n $pages_per_rpc"
26166
26167         # Recreate file so it's empty
26168         rm -f $DIR/$tfile
26169         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26170         #Pause rpc completion to guarantee we see multiple rpcs in flight
26171         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26172         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26173         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26174
26175         # Clear rpc stats
26176         $LCTL set_param osc.*.rpc_stats=c
26177
26178         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26179                 error "parallel dio failed"
26180         stack_trap "rm -f $DIR/$tfile"
26181
26182         $LCTL get_param osc.*-OST0000-*.rpc_stats
26183         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26184                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26185                 grep "8:" | awk '{print $8}')
26186         # We look at the "8 rpcs in flight" field, and verify A) it is present
26187         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26188         # as expected for an 8M DIO to a file with 1M stripes.
26189         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26190
26191         # Verify turning off parallel dio works as expected
26192         # Clear rpc stats
26193         $LCTL set_param osc.*.rpc_stats=c
26194         $LCTL set_param llite.*.parallel_dio=0
26195         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26196
26197         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26198                 error "dio with parallel dio disabled failed"
26199
26200         # Ideally, we would see only one RPC in flight here, but there is an
26201         # unavoidable race between i/o completion and RPC in flight counting,
26202         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26203         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26204         # So instead we just verify it's always < 8.
26205         $LCTL get_param osc.*-OST0000-*.rpc_stats
26206         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26207                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26208                 grep '^$' -B1 | grep . | awk '{print $1}')
26209         [ $ret != "8:" ] ||
26210                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26211 }
26212 run_test 398g "verify parallel dio async RPC submission"
26213
26214 test_398h() { #  LU-13798
26215         local dio_file=$DIR/$tfile.dio
26216
26217         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26218
26219         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26220         stack_trap "rm -f $DIR/$tfile $dio_file"
26221
26222         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26223                 error "parallel dio failed"
26224         diff $DIR/$tfile $dio_file
26225         [[ $? == 0 ]] || error "file diff after aiocp"
26226 }
26227 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26228
26229 test_398i() { #  LU-13798
26230         local dio_file=$DIR/$tfile.dio
26231
26232         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26233
26234         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26235         stack_trap "rm -f $DIR/$tfile $dio_file"
26236
26237         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26238         $LCTL set_param fail_loc=0x1418
26239         # make sure we don't crash and fail properly
26240         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26241                 error "parallel dio page allocation failure succeeded"
26242         diff $DIR/$tfile $dio_file
26243         [[ $? != 0 ]] || error "no diff after failed aiocp"
26244 }
26245 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26246
26247 test_398j() { #  LU-13798
26248         # Stripe size > RPC size but less than i/o size tests split across
26249         # stripes and RPCs for individual i/o op
26250         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26251
26252         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26253         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26254         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26255         stack_trap "$LCTL set_param -n $pages_per_rpc"
26256
26257         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26258                 error "parallel dio write failed"
26259         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26260
26261         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26262                 error "parallel dio read failed"
26263         diff $DIR/$tfile $DIR/$tfile.2
26264         [[ $? == 0 ]] || error "file diff after parallel dio read"
26265 }
26266 run_test 398j "test parallel dio where stripe size > rpc_size"
26267
26268 test_398k() { #  LU-13798
26269         wait_delete_completed
26270         wait_mds_ost_sync
26271
26272         # 4 stripe file; we will cause out of space on OST0
26273         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26274
26275         # Fill OST0 (if it's not too large)
26276         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26277                    head -n1)
26278         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26279                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26280         fi
26281         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26282         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26283                 error "dd should fill OST0"
26284         stack_trap "rm -f $DIR/$tfile.1"
26285
26286         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26287         err=$?
26288
26289         ls -la $DIR/$tfile
26290         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26291                 error "file is not 0 bytes in size"
26292
26293         # dd above should not succeed, but don't error until here so we can
26294         # get debug info above
26295         [[ $err != 0 ]] ||
26296                 error "parallel dio write with enospc succeeded"
26297         stack_trap "rm -f $DIR/$tfile"
26298 }
26299 run_test 398k "test enospc on first stripe"
26300
26301 test_398l() { #  LU-13798
26302         wait_delete_completed
26303         wait_mds_ost_sync
26304
26305         # 4 stripe file; we will cause out of space on OST0
26306         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26307         # happens on the second i/o chunk we issue
26308         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26309
26310         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26311         stack_trap "rm -f $DIR/$tfile"
26312
26313         # Fill OST0 (if it's not too large)
26314         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26315                    head -n1)
26316         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26317                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26318         fi
26319         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26320         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26321                 error "dd should fill OST0"
26322         stack_trap "rm -f $DIR/$tfile.1"
26323
26324         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26325         err=$?
26326         stack_trap "rm -f $DIR/$tfile.2"
26327
26328         # Check that short write completed as expected
26329         ls -la $DIR/$tfile.2
26330         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26331                 error "file is not 1M in size"
26332
26333         # dd above should not succeed, but don't error until here so we can
26334         # get debug info above
26335         [[ $err != 0 ]] ||
26336                 error "parallel dio write with enospc succeeded"
26337
26338         # Truncate source file to same length as output file and diff them
26339         $TRUNCATE $DIR/$tfile 1048576
26340         diff $DIR/$tfile $DIR/$tfile.2
26341         [[ $? == 0 ]] || error "data incorrect after short write"
26342 }
26343 run_test 398l "test enospc on intermediate stripe/RPC"
26344
26345 test_398m() { #  LU-13798
26346         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26347
26348         # Set up failure on OST0, the first stripe:
26349         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26350         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26351         # OST0 is on ost1, OST1 is on ost2.
26352         # So this fail_val specifies OST0
26353         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26354         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26355
26356         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26357                 error "parallel dio write with failure on first stripe succeeded"
26358         stack_trap "rm -f $DIR/$tfile"
26359         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26360
26361         # Place data in file for read
26362         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26363                 error "parallel dio write failed"
26364
26365         # Fail read on OST0, first stripe
26366         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26367         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26368         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26369                 error "parallel dio read with error on first stripe succeeded"
26370         rm -f $DIR/$tfile.2
26371         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26372
26373         # Switch to testing on OST1, second stripe
26374         # Clear file contents, maintain striping
26375         echo > $DIR/$tfile
26376         # Set up failure on OST1, second stripe:
26377         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26378         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26379
26380         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26381                 error "parallel dio write with failure on second stripe succeeded"
26382         stack_trap "rm -f $DIR/$tfile"
26383         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26384
26385         # Place data in file for read
26386         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26387                 error "parallel dio write failed"
26388
26389         # Fail read on OST1, second stripe
26390         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26391         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26392         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26393                 error "parallel dio read with error on second stripe succeeded"
26394         rm -f $DIR/$tfile.2
26395         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26396 }
26397 run_test 398m "test RPC failures with parallel dio"
26398
26399 # Parallel submission of DIO should not cause problems for append, but it's
26400 # important to verify.
26401 test_398n() { #  LU-13798
26402         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26403
26404         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26405                 error "dd to create source file failed"
26406         stack_trap "rm -f $DIR/$tfile"
26407
26408         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26409                 error "parallel dio write with failure on second stripe succeeded"
26410         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26411         diff $DIR/$tfile $DIR/$tfile.1
26412         [[ $? == 0 ]] || error "data incorrect after append"
26413
26414 }
26415 run_test 398n "test append with parallel DIO"
26416
26417 test_398o() {
26418         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26419 }
26420 run_test 398o "right kms with DIO"
26421
26422 test_398p()
26423 {
26424         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26425         which aiocp || skip_env "no aiocp installed"
26426
26427         local stripe_size=$((1024 * 1024)) #1 MiB
26428         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26429         local file_size=$((25 * stripe_size))
26430
26431         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26432         stack_trap "rm -f $DIR/$tfile*"
26433         # Just a bit bigger than the largest size in the test set below
26434         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26435                 error "buffered i/o to create file failed"
26436
26437         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26438                 $((stripe_size * 4)); do
26439
26440                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26441
26442                 echo "bs: $bs, file_size $file_size"
26443                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26444                         $DIR/$tfile.1 $DIR/$tfile.2 &
26445                 pid_dio1=$!
26446                 # Buffered I/O with similar but not the same block size
26447                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26448                         conv=notrunc &
26449                 pid_bio2=$!
26450                 wait $pid_dio1
26451                 rc1=$?
26452                 wait $pid_bio2
26453                 rc2=$?
26454                 if (( rc1 != 0 )); then
26455                         error "aio copy 1 w/bsize $bs failed: $rc1"
26456                 fi
26457                 if (( rc2 != 0 )); then
26458                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26459                 fi
26460
26461                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26462                         error "size incorrect"
26463                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26464                         error "files differ, bsize $bs"
26465                 rm -f $DIR/$tfile.2
26466         done
26467 }
26468 run_test 398p "race aio with buffered i/o"
26469
26470 test_fake_rw() {
26471         local read_write=$1
26472         if [ "$read_write" = "write" ]; then
26473                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26474         elif [ "$read_write" = "read" ]; then
26475                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26476         else
26477                 error "argument error"
26478         fi
26479
26480         # turn off debug for performance testing
26481         local saved_debug=$($LCTL get_param -n debug)
26482         $LCTL set_param debug=0
26483
26484         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26485
26486         # get ost1 size - $FSNAME-OST0000
26487         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26488         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26489         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26490
26491         if [ "$read_write" = "read" ]; then
26492                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26493         fi
26494
26495         local start_time=$(date +%s.%N)
26496         $dd_cmd bs=1M count=$blocks oflag=sync ||
26497                 error "real dd $read_write error"
26498         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26499
26500         if [ "$read_write" = "write" ]; then
26501                 rm -f $DIR/$tfile
26502         fi
26503
26504         # define OBD_FAIL_OST_FAKE_RW           0x238
26505         do_facet ost1 $LCTL set_param fail_loc=0x238
26506
26507         local start_time=$(date +%s.%N)
26508         $dd_cmd bs=1M count=$blocks oflag=sync ||
26509                 error "fake dd $read_write error"
26510         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26511
26512         if [ "$read_write" = "write" ]; then
26513                 # verify file size
26514                 cancel_lru_locks osc
26515                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26516                         error "$tfile size not $blocks MB"
26517         fi
26518         do_facet ost1 $LCTL set_param fail_loc=0
26519
26520         echo "fake $read_write $duration_fake vs. normal $read_write" \
26521                 "$duration in seconds"
26522         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26523                 error_not_in_vm "fake write is slower"
26524
26525         $LCTL set_param -n debug="$saved_debug"
26526         rm -f $DIR/$tfile
26527 }
26528 test_399a() { # LU-7655 for OST fake write
26529         remote_ost_nodsh && skip "remote OST with nodsh"
26530
26531         test_fake_rw write
26532 }
26533 run_test 399a "fake write should not be slower than normal write"
26534
26535 test_399b() { # LU-8726 for OST fake read
26536         remote_ost_nodsh && skip "remote OST with nodsh"
26537         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26538                 skip_env "ldiskfs only test"
26539         fi
26540
26541         test_fake_rw read
26542 }
26543 run_test 399b "fake read should not be slower than normal read"
26544
26545 test_400a() { # LU-1606, was conf-sanity test_74
26546         if ! which $CC > /dev/null 2>&1; then
26547                 skip_env "$CC is not installed"
26548         fi
26549
26550         local extra_flags=''
26551         local out=$TMP/$tfile
26552         local prefix=/usr/include/lustre
26553         local prog
26554
26555         # Oleg removes .c files in his test rig so test if any c files exist
26556         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26557                 skip_env "Needed .c test files are missing"
26558
26559         if ! [[ -d $prefix ]]; then
26560                 # Assume we're running in tree and fixup the include path.
26561                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26562                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26563                 extra_flags+=" -L$LUSTRE/utils/.libs"
26564         fi
26565
26566         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26567                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26568                         error "client api broken"
26569         done
26570         rm -f $out
26571 }
26572 run_test 400a "Lustre client api program can compile and link"
26573
26574 test_400b() { # LU-1606, LU-5011
26575         local header
26576         local out=$TMP/$tfile
26577         local prefix=/usr/include/linux/lustre
26578
26579         # We use a hard coded prefix so that this test will not fail
26580         # when run in tree. There are headers in lustre/include/lustre/
26581         # that are not packaged (like lustre_idl.h) and have more
26582         # complicated include dependencies (like config.h and lnet/types.h).
26583         # Since this test about correct packaging we just skip them when
26584         # they don't exist (see below) rather than try to fixup cppflags.
26585
26586         if ! which $CC > /dev/null 2>&1; then
26587                 skip_env "$CC is not installed"
26588         fi
26589
26590         for header in $prefix/*.h; do
26591                 if ! [[ -f "$header" ]]; then
26592                         continue
26593                 fi
26594
26595                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26596                         continue # lustre_ioctl.h is internal header
26597                 fi
26598
26599                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26600                         error "cannot compile '$header'"
26601         done
26602         rm -f $out
26603 }
26604 run_test 400b "packaged headers can be compiled"
26605
26606 test_401a() { #LU-7437
26607         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26608         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26609
26610         #count the number of parameters by "list_param -R"
26611         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26612         #count the number of parameters by listing proc files
26613         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26614         echo "proc_dirs='$proc_dirs'"
26615         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26616         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26617                       sort -u | wc -l)
26618
26619         [ $params -eq $procs ] ||
26620                 error "found $params parameters vs. $procs proc files"
26621
26622         # test the list_param -D option only returns directories
26623         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26624         #count the number of parameters by listing proc directories
26625         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26626                 sort -u | wc -l)
26627
26628         [ $params -eq $procs ] ||
26629                 error "found $params parameters vs. $procs proc files"
26630 }
26631 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26632
26633 test_401b() {
26634         # jobid_var may not allow arbitrary values, so use jobid_name
26635         # if available
26636         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26637                 local testname=jobid_name tmp='testing%p'
26638         else
26639                 local testname=jobid_var tmp=testing
26640         fi
26641
26642         local save=$($LCTL get_param -n $testname)
26643
26644         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26645                 error "no error returned when setting bad parameters"
26646
26647         local jobid_new=$($LCTL get_param -n foe $testname baz)
26648         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26649
26650         $LCTL set_param -n fog=bam $testname=$save bat=fog
26651         local jobid_old=$($LCTL get_param -n foe $testname bag)
26652         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26653 }
26654 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26655
26656 test_401c() {
26657         # jobid_var may not allow arbitrary values, so use jobid_name
26658         # if available
26659         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26660                 local testname=jobid_name
26661         else
26662                 local testname=jobid_var
26663         fi
26664
26665         local jobid_var_old=$($LCTL get_param -n $testname)
26666         local jobid_var_new
26667
26668         $LCTL set_param $testname= &&
26669                 error "no error returned for 'set_param a='"
26670
26671         jobid_var_new=$($LCTL get_param -n $testname)
26672         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26673                 error "$testname was changed by setting without value"
26674
26675         $LCTL set_param $testname &&
26676                 error "no error returned for 'set_param a'"
26677
26678         jobid_var_new=$($LCTL get_param -n $testname)
26679         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26680                 error "$testname was changed by setting without value"
26681 }
26682 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26683
26684 test_401d() {
26685         # jobid_var may not allow arbitrary values, so use jobid_name
26686         # if available
26687         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26688                 local testname=jobid_name new_value='foo=bar%p'
26689         else
26690                 local testname=jobid_var new_valuie=foo=bar
26691         fi
26692
26693         local jobid_var_old=$($LCTL get_param -n $testname)
26694         local jobid_var_new
26695
26696         $LCTL set_param $testname=$new_value ||
26697                 error "'set_param a=b' did not accept a value containing '='"
26698
26699         jobid_var_new=$($LCTL get_param -n $testname)
26700         [[ "$jobid_var_new" == "$new_value" ]] ||
26701                 error "'set_param a=b' failed on a value containing '='"
26702
26703         # Reset the $testname to test the other format
26704         $LCTL set_param $testname=$jobid_var_old
26705         jobid_var_new=$($LCTL get_param -n $testname)
26706         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26707                 error "failed to reset $testname"
26708
26709         $LCTL set_param $testname $new_value ||
26710                 error "'set_param a b' did not accept a value containing '='"
26711
26712         jobid_var_new=$($LCTL get_param -n $testname)
26713         [[ "$jobid_var_new" == "$new_value" ]] ||
26714                 error "'set_param a b' failed on a value containing '='"
26715
26716         $LCTL set_param $testname $jobid_var_old
26717         jobid_var_new=$($LCTL get_param -n $testname)
26718         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26719                 error "failed to reset $testname"
26720 }
26721 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26722
26723 test_401e() { # LU-14779
26724         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26725                 error "lctl list_param MGC* failed"
26726         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26727         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26728                 error "lctl get_param lru_size failed"
26729 }
26730 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26731
26732 test_402() {
26733         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26734         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26735                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26736         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26737                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26738                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26739         remote_mds_nodsh && skip "remote MDS with nodsh"
26740
26741         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26742 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26743         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26744         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26745                 echo "Touch failed - OK"
26746 }
26747 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26748
26749 test_403() {
26750         local file1=$DIR/$tfile.1
26751         local file2=$DIR/$tfile.2
26752         local tfile=$TMP/$tfile
26753
26754         rm -f $file1 $file2 $tfile
26755
26756         touch $file1
26757         ln $file1 $file2
26758
26759         # 30 sec OBD_TIMEOUT in ll_getattr()
26760         # right before populating st_nlink
26761         $LCTL set_param fail_loc=0x80001409
26762         stat -c %h $file1 > $tfile &
26763
26764         # create an alias, drop all locks and reclaim the dentry
26765         < $file2
26766         cancel_lru_locks mdc
26767         cancel_lru_locks osc
26768         sysctl -w vm.drop_caches=2
26769
26770         wait
26771
26772         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26773
26774         rm -f $tfile $file1 $file2
26775 }
26776 run_test 403 "i_nlink should not drop to zero due to aliasing"
26777
26778 test_404() { # LU-6601
26779         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26780                 skip "Need server version newer than 2.8.52"
26781         remote_mds_nodsh && skip "remote MDS with nodsh"
26782
26783         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26784                 awk '/osp .*-osc-MDT/ { print $4}')
26785
26786         local osp
26787         for osp in $mosps; do
26788                 echo "Deactivate: " $osp
26789                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26790                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26791                         awk -vp=$osp '$4 == p { print $2 }')
26792                 [ $stat = IN ] || {
26793                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26794                         error "deactivate error"
26795                 }
26796                 echo "Activate: " $osp
26797                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26798                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26799                         awk -vp=$osp '$4 == p { print $2 }')
26800                 [ $stat = UP ] || {
26801                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26802                         error "activate error"
26803                 }
26804         done
26805 }
26806 run_test 404 "validate manual {de}activated works properly for OSPs"
26807
26808 test_405() {
26809         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26810         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26811                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26812                         skip "Layout swap lock is not supported"
26813
26814         check_swap_layouts_support
26815         check_swap_layout_no_dom $DIR
26816
26817         test_mkdir $DIR/$tdir
26818         swap_lock_test -d $DIR/$tdir ||
26819                 error "One layout swap locked test failed"
26820 }
26821 run_test 405 "Various layout swap lock tests"
26822
26823 test_406() {
26824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26825         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26826         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26828         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26829                 skip "Need MDS version at least 2.8.50"
26830
26831         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26832         local test_pool=$TESTNAME
26833
26834         pool_add $test_pool || error "pool_add failed"
26835         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26836                 error "pool_add_targets failed"
26837
26838         save_layout_restore_at_exit $MOUNT
26839
26840         # parent set default stripe count only, child will stripe from both
26841         # parent and fs default
26842         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26843                 error "setstripe $MOUNT failed"
26844         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26845         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26846         for i in $(seq 10); do
26847                 local f=$DIR/$tdir/$tfile.$i
26848                 touch $f || error "touch failed"
26849                 local count=$($LFS getstripe -c $f)
26850                 [ $count -eq $OSTCOUNT ] ||
26851                         error "$f stripe count $count != $OSTCOUNT"
26852                 local offset=$($LFS getstripe -i $f)
26853                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26854                 local size=$($LFS getstripe -S $f)
26855                 [ $size -eq $((def_stripe_size * 2)) ] ||
26856                         error "$f stripe size $size != $((def_stripe_size * 2))"
26857                 local pool=$($LFS getstripe -p $f)
26858                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26859         done
26860
26861         # change fs default striping, delete parent default striping, now child
26862         # will stripe from new fs default striping only
26863         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26864                 error "change $MOUNT default stripe failed"
26865         $LFS setstripe -c 0 $DIR/$tdir ||
26866                 error "delete $tdir default stripe failed"
26867         for i in $(seq 11 20); do
26868                 local f=$DIR/$tdir/$tfile.$i
26869                 touch $f || error "touch $f failed"
26870                 local count=$($LFS getstripe -c $f)
26871                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26872                 local offset=$($LFS getstripe -i $f)
26873                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26874                 local size=$($LFS getstripe -S $f)
26875                 [ $size -eq $def_stripe_size ] ||
26876                         error "$f stripe size $size != $def_stripe_size"
26877                 local pool=$($LFS getstripe -p $f)
26878                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26879         done
26880
26881         unlinkmany $DIR/$tdir/$tfile. 1 20
26882
26883         local f=$DIR/$tdir/$tfile
26884         pool_remove_all_targets $test_pool $f
26885         pool_remove $test_pool $f
26886 }
26887 run_test 406 "DNE support fs default striping"
26888
26889 test_407() {
26890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26891         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26892                 skip "Need MDS version at least 2.8.55"
26893         remote_mds_nodsh && skip "remote MDS with nodsh"
26894
26895         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26896                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26897         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26898                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26899         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26900
26901         #define OBD_FAIL_DT_TXN_STOP    0x2019
26902         for idx in $(seq $MDSCOUNT); do
26903                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26904         done
26905         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26906         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26907                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26908         true
26909 }
26910 run_test 407 "transaction fail should cause operation fail"
26911
26912 test_408() {
26913         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26914
26915         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26916         lctl set_param fail_loc=0x8000040a
26917         # let ll_prepare_partial_page() fail
26918         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26919
26920         rm -f $DIR/$tfile
26921
26922         # create at least 100 unused inodes so that
26923         # shrink_icache_memory(0) should not return 0
26924         touch $DIR/$tfile-{0..100}
26925         rm -f $DIR/$tfile-{0..100}
26926         sync
26927
26928         echo 2 > /proc/sys/vm/drop_caches
26929 }
26930 run_test 408 "drop_caches should not hang due to page leaks"
26931
26932 test_409()
26933 {
26934         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26935
26936         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26937         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26938         touch $DIR/$tdir/guard || error "(2) Fail to create"
26939
26940         local PREFIX=$(str_repeat 'A' 128)
26941         echo "Create 1K hard links start at $(date)"
26942         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26943                 error "(3) Fail to hard link"
26944
26945         echo "Links count should be right although linkEA overflow"
26946         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26947         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26948         [ $linkcount -eq 1001 ] ||
26949                 error "(5) Unexpected hard links count: $linkcount"
26950
26951         echo "List all links start at $(date)"
26952         ls -l $DIR/$tdir/foo > /dev/null ||
26953                 error "(6) Fail to list $DIR/$tdir/foo"
26954
26955         echo "Unlink hard links start at $(date)"
26956         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26957                 error "(7) Fail to unlink"
26958         echo "Unlink hard links finished at $(date)"
26959 }
26960 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26961
26962 test_410()
26963 {
26964         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26965                 skip "Need client version at least 2.9.59"
26966         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26967                 skip "Need MODULES build"
26968
26969         # Create a file, and stat it from the kernel
26970         local testfile=$DIR/$tfile
26971         touch $testfile
26972
26973         local run_id=$RANDOM
26974         local my_ino=$(stat --format "%i" $testfile)
26975
26976         # Try to insert the module. This will always fail as the
26977         # module is designed to not be inserted.
26978         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26979             &> /dev/null
26980
26981         # Anything but success is a test failure
26982         dmesg | grep -q \
26983             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26984             error "no inode match"
26985 }
26986 run_test 410 "Test inode number returned from kernel thread"
26987
26988 cleanup_test411_cgroup() {
26989         trap 0
26990         rmdir "$1"
26991 }
26992
26993 test_411() {
26994         local cg_basedir=/sys/fs/cgroup/memory
26995         # LU-9966
26996         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26997                 skip "no setup for cgroup"
26998
26999         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27000                 error "test file creation failed"
27001         cancel_lru_locks osc
27002
27003         # Create a very small memory cgroup to force a slab allocation error
27004         local cgdir=$cg_basedir/osc_slab_alloc
27005         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27006         trap "cleanup_test411_cgroup $cgdir" EXIT
27007         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27008         echo 1M > $cgdir/memory.limit_in_bytes
27009
27010         # Should not LBUG, just be killed by oom-killer
27011         # dd will return 0 even allocation failure in some environment.
27012         # So don't check return value
27013         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27014         cleanup_test411_cgroup $cgdir
27015
27016         return 0
27017 }
27018 run_test 411 "Slab allocation error with cgroup does not LBUG"
27019
27020 test_412() {
27021         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27022         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27023                 skip "Need server version at least 2.10.55"
27024
27025         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27026                 error "mkdir failed"
27027         $LFS getdirstripe $DIR/$tdir
27028         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27029         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27030                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27031         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27032         [ $stripe_count -eq 2 ] ||
27033                 error "expect 2 get $stripe_count"
27034
27035         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27036
27037         local index
27038         local index2
27039
27040         # subdirs should be on the same MDT as parent
27041         for i in $(seq 0 $((MDSCOUNT - 1))); do
27042                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27043                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27044                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27045                 (( index == i )) || error "mdt$i/sub on MDT$index"
27046         done
27047
27048         # stripe offset -1, ditto
27049         for i in {1..10}; do
27050                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27051                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27052                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27053                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27054                 (( index == index2 )) ||
27055                         error "qos$i on MDT$index, sub on MDT$index2"
27056         done
27057
27058         local testdir=$DIR/$tdir/inherit
27059
27060         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27061         # inherit 2 levels
27062         for i in 1 2; do
27063                 testdir=$testdir/s$i
27064                 mkdir $testdir || error "mkdir $testdir failed"
27065                 index=$($LFS getstripe -m $testdir)
27066                 (( index == 1 )) ||
27067                         error "$testdir on MDT$index"
27068         done
27069
27070         # not inherit any more
27071         testdir=$testdir/s3
27072         mkdir $testdir || error "mkdir $testdir failed"
27073         getfattr -d -m dmv $testdir | grep dmv &&
27074                 error "default LMV set on $testdir" || true
27075 }
27076 run_test 412 "mkdir on specific MDTs"
27077
27078 TEST413_COUNT=${TEST413_COUNT:-200}
27079
27080 #
27081 # set_maxage() is used by test_413 only.
27082 # This is a helper function to set maxage. Does not return any value.
27083 # Input: maxage to set
27084 #
27085 set_maxage() {
27086         local lmv_qos_maxage
27087         local lod_qos_maxage
27088         local new_maxage=$1
27089
27090         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27091         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27092         stack_trap "$LCTL set_param \
27093                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27094         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27095                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27096         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27097                 lod.*.mdt_qos_maxage=$new_maxage
27098         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27099                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27100 }
27101
27102 generate_uneven_mdts() {
27103         local threshold=$1
27104         local ffree
27105         local bavail
27106         local max
27107         local min
27108         local max_index
27109         local min_index
27110         local tmp
27111         local i
27112
27113         echo
27114         echo "Check for uneven MDTs: "
27115
27116         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27117         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27118         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27119
27120         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27121         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27122         max_index=0
27123         min_index=0
27124         for ((i = 1; i < ${#ffree[@]}; i++)); do
27125                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27126                 if [ $tmp -gt $max ]; then
27127                         max=$tmp
27128                         max_index=$i
27129                 fi
27130                 if [ $tmp -lt $min ]; then
27131                         min=$tmp
27132                         min_index=$i
27133                 fi
27134         done
27135
27136         (( min > 0 )) || skip "low space on MDT$min_index"
27137         (( ${ffree[min_index]} > 0 )) ||
27138                 skip "no free files on MDT$min_index"
27139         (( ${ffree[min_index]} < 10000000 )) ||
27140                 skip "too many free files on MDT$min_index"
27141
27142         # Check if we need to generate uneven MDTs
27143         local diff=$(((max - min) * 100 / min))
27144         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27145         local testdir # individual folder within $testdirp
27146         local start
27147         local cmd
27148
27149         # fallocate is faster to consume space on MDT, if available
27150         if check_fallocate_supported mds$((min_index + 1)); then
27151                 cmd="fallocate -l 128K "
27152         else
27153                 cmd="dd if=/dev/zero bs=128K count=1 of="
27154         fi
27155
27156         echo "using cmd $cmd"
27157         for (( i = 0; diff < threshold; i++ )); do
27158                 testdir=${testdirp}/$i
27159                 [ -d $testdir ] && continue
27160
27161                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27162
27163                 mkdir -p $testdirp
27164                 # generate uneven MDTs, create till $threshold% diff
27165                 echo -n "weight diff=$diff% must be > $threshold% ..."
27166                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27167                 $LFS mkdir -i $min_index $testdir ||
27168                         error "mkdir $testdir failed"
27169                 $LFS setstripe -E 1M -L mdt $testdir ||
27170                         error "setstripe $testdir failed"
27171                 start=$SECONDS
27172                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27173                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27174                 done
27175                 sync; sleep 1; sync
27176
27177                 # wait for QOS to update
27178                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27179
27180                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27181                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27182                 max=$(((${ffree[max_index]} >> 8) *
27183                         (${bavail[max_index]} * bsize >> 16)))
27184                 min=$(((${ffree[min_index]} >> 8) *
27185                         (${bavail[min_index]} * bsize >> 16)))
27186                 (( min > 0 )) || skip "low space on MDT$min_index"
27187                 diff=$(((max - min) * 100 / min))
27188         done
27189
27190         echo "MDT filesfree available: ${ffree[*]}"
27191         echo "MDT blocks available: ${bavail[*]}"
27192         echo "weight diff=$diff%"
27193 }
27194
27195 test_qos_mkdir() {
27196         local mkdir_cmd=$1
27197         local stripe_count=$2
27198         local mdts=$(comma_list $(mdts_nodes))
27199
27200         local testdir
27201         local lmv_qos_prio_free
27202         local lmv_qos_threshold_rr
27203         local lod_qos_prio_free
27204         local lod_qos_threshold_rr
27205         local total
27206         local count
27207         local i
27208
27209         # @total is total directories created if it's testing plain
27210         # directories, otherwise it's total stripe object count for
27211         # striped directories test.
27212         # remote/striped directory unlinking is slow on zfs and may
27213         # timeout, test with fewer directories
27214         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27215
27216         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27217         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27218         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27219                 head -n1)
27220         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27221         stack_trap "$LCTL set_param \
27222                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27223         stack_trap "$LCTL set_param \
27224                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27225
27226         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27227                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27228         lod_qos_prio_free=${lod_qos_prio_free%%%}
27229         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27230                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27231         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27232         stack_trap "do_nodes $mdts $LCTL set_param \
27233                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27234         stack_trap "do_nodes $mdts $LCTL set_param \
27235                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27236
27237         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27238         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27239
27240         testdir=$DIR/$tdir-s$stripe_count/rr
27241
27242         local stripe_index=$($LFS getstripe -m $testdir)
27243         local test_mkdir_rr=true
27244
27245         getfattr -d -m dmv -e hex $testdir | grep dmv
27246         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27247                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27248                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27249                         test_mkdir_rr=false
27250         fi
27251
27252         echo
27253         $test_mkdir_rr &&
27254                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27255                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27256
27257         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27258         for (( i = 0; i < total / stripe_count; i++ )); do
27259                 eval $mkdir_cmd $testdir/subdir$i ||
27260                         error "$mkdir_cmd subdir$i failed"
27261         done
27262
27263         for (( i = 0; i < $MDSCOUNT; i++ )); do
27264                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27265                 echo "$count directories created on MDT$i"
27266                 if $test_mkdir_rr; then
27267                         (( count == total / stripe_count / MDSCOUNT )) ||
27268                                 error "subdirs are not evenly distributed"
27269                 elif (( i == stripe_index )); then
27270                         (( count == total / stripe_count )) ||
27271                                 error "$count subdirs created on MDT$i"
27272                 else
27273                         (( count == 0 )) ||
27274                                 error "$count subdirs created on MDT$i"
27275                 fi
27276
27277                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27278                         count=$($LFS getdirstripe $testdir/* |
27279                                 grep -c -P "^\s+$i\t")
27280                         echo "$count stripes created on MDT$i"
27281                         # deviation should < 5% of average
27282                         delta=$((count - total / MDSCOUNT))
27283                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27284                                 error "stripes are not evenly distributed"
27285                 fi
27286         done
27287
27288         echo
27289         echo "Check for uneven MDTs: "
27290
27291         local ffree
27292         local bavail
27293         local max
27294         local min
27295         local max_index
27296         local min_index
27297         local tmp
27298
27299         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27300         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27301         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27302
27303         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27304         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27305         max_index=0
27306         min_index=0
27307         for ((i = 1; i < ${#ffree[@]}; i++)); do
27308                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27309                 if [ $tmp -gt $max ]; then
27310                         max=$tmp
27311                         max_index=$i
27312                 fi
27313                 if [ $tmp -lt $min ]; then
27314                         min=$tmp
27315                         min_index=$i
27316                 fi
27317         done
27318         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27319
27320         (( min > 0 )) || skip "low space on MDT$min_index"
27321         (( ${ffree[min_index]} < 10000000 )) ||
27322                 skip "too many free files on MDT$min_index"
27323
27324         generate_uneven_mdts 120
27325
27326         echo "MDT filesfree available: ${ffree[*]}"
27327         echo "MDT blocks available: ${bavail[*]}"
27328         echo "weight diff=$(((max - min) * 100 / min))%"
27329         echo
27330         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27331
27332         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27333         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27334         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27335         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27336         # decrease statfs age, so that it can be updated in time
27337         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27338         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27339
27340         sleep 1
27341
27342         testdir=$DIR/$tdir-s$stripe_count/qos
27343
27344         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27345         for (( i = 0; i < total / stripe_count; i++ )); do
27346                 eval $mkdir_cmd $testdir/subdir$i ||
27347                         error "$mkdir_cmd subdir$i failed"
27348         done
27349
27350         max=0
27351         for (( i = 0; i < $MDSCOUNT; i++ )); do
27352                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27353                 (( count > max )) && max=$count
27354                 echo "$count directories created on MDT$i : curmax=$max"
27355         done
27356
27357         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27358
27359         # D-value should > 10% of average
27360         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27361                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27362
27363         # ditto for stripes
27364         if (( stripe_count > 1 )); then
27365                 max=0
27366                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27367                         count=$($LFS getdirstripe $testdir/* |
27368                                 grep -c -P "^\s+$i\t")
27369                         (( count > max )) && max=$count
27370                         echo "$count stripes created on MDT$i"
27371                 done
27372
27373                 min=$($LFS getdirstripe $testdir/* |
27374                         grep -c -P "^\s+$min_index\t")
27375                 (( max - min > total / MDSCOUNT / 10 )) ||
27376                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27377         fi
27378 }
27379
27380 most_full_mdt() {
27381         local ffree
27382         local bavail
27383         local bsize
27384         local min
27385         local min_index
27386         local tmp
27387
27388         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27389         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27390         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27391
27392         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27393         min_index=0
27394         for ((i = 1; i < ${#ffree[@]}; i++)); do
27395                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27396                 (( tmp < min )) && min=$tmp && min_index=$i
27397         done
27398
27399         echo -n $min_index
27400 }
27401
27402 test_413a() {
27403         [ $MDSCOUNT -lt 2 ] &&
27404                 skip "We need at least 2 MDTs for this test"
27405
27406         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27407                 skip "Need server version at least 2.12.52"
27408
27409         local stripe_max=$((MDSCOUNT - 1))
27410         local stripe_count
27411
27412         # let caller set maxage for latest result
27413         set_maxage 1
27414
27415         # fill MDT unevenly
27416         generate_uneven_mdts 120
27417
27418         # test 4-stripe directory at most, otherwise it's too slow
27419         # We are being very defensive. Although Autotest uses 4 MDTs.
27420         # We make sure stripe_max does not go over 4.
27421         (( stripe_max > 4 )) && stripe_max=4
27422         # unlinking striped directory is slow on zfs, and may timeout, only test
27423         # plain directory
27424         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27425         for stripe_count in $(seq 1 $stripe_max); do
27426                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27427                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27428                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27429                         error "mkdir failed"
27430                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27431         done
27432 }
27433 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27434
27435 test_413b() {
27436         [ $MDSCOUNT -lt 2 ] &&
27437                 skip "We need at least 2 MDTs for this test"
27438
27439         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27440                 skip "Need server version at least 2.12.52"
27441
27442         local stripe_max=$((MDSCOUNT - 1))
27443         local testdir
27444         local stripe_count
27445
27446         # let caller set maxage for latest result
27447         set_maxage 1
27448
27449         # fill MDT unevenly
27450         generate_uneven_mdts 120
27451
27452         # test 4-stripe directory at most, otherwise it's too slow
27453         # We are being very defensive. Although Autotest uses 4 MDTs.
27454         # We make sure stripe_max does not go over 4.
27455         (( stripe_max > 4 )) && stripe_max=4
27456         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27457         for stripe_count in $(seq 1 $stripe_max); do
27458                 testdir=$DIR/$tdir-s$stripe_count
27459                 mkdir $testdir || error "mkdir $testdir failed"
27460                 mkdir $testdir/rr || error "mkdir rr failed"
27461                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27462                         error "mkdir qos failed"
27463                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27464                         $testdir/rr || error "setdirstripe rr failed"
27465                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27466                         error "setdirstripe failed"
27467                 test_qos_mkdir "mkdir" $stripe_count
27468         done
27469 }
27470 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27471
27472 test_413c() {
27473         (( $MDSCOUNT >= 2 )) ||
27474                 skip "We need at least 2 MDTs for this test"
27475
27476         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27477                 skip "Need server version at least 2.14.51"
27478
27479         local testdir
27480         local inherit
27481         local inherit_rr
27482         local lmv_qos_maxage
27483         local lod_qos_maxage
27484
27485         # let caller set maxage for latest result
27486         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27487         $LCTL set_param lmv.*.qos_maxage=1
27488         stack_trap "$LCTL set_param \
27489                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27490         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27491                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27492         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27493                 lod.*.mdt_qos_maxage=1
27494         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27495                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27496
27497         # fill MDT unevenly
27498         generate_uneven_mdts 120
27499
27500         testdir=$DIR/${tdir}-s1
27501         mkdir $testdir || error "mkdir $testdir failed"
27502         mkdir $testdir/rr || error "mkdir rr failed"
27503         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27504         # default max_inherit is -1, default max_inherit_rr is 0
27505         $LFS setdirstripe -D -c 1 $testdir/rr ||
27506                 error "setdirstripe rr failed"
27507         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27508                 error "setdirstripe qos failed"
27509         test_qos_mkdir "mkdir" 1
27510
27511         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27512         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27513         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27514         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27515         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27516
27517         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27518         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27519         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27520         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27521         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27522         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27523         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27524                 error "level2 shouldn't have default LMV" || true
27525 }
27526 run_test 413c "mkdir with default LMV max inherit rr"
27527
27528 test_413d() {
27529         (( MDSCOUNT >= 2 )) ||
27530                 skip "We need at least 2 MDTs for this test"
27531
27532         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27533                 skip "Need server version at least 2.14.51"
27534
27535         local lmv_qos_threshold_rr
27536
27537         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27538                 head -n1)
27539         stack_trap "$LCTL set_param \
27540                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27541
27542         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27543         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27544         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27545                 error "$tdir shouldn't have default LMV"
27546         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27547                 error "mkdir sub failed"
27548
27549         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27550
27551         (( count == 100 )) || error "$count subdirs on MDT0"
27552 }
27553 run_test 413d "inherit ROOT default LMV"
27554
27555 test_413e() {
27556         (( MDSCOUNT >= 2 )) ||
27557                 skip "We need at least 2 MDTs for this test"
27558         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27559                 skip "Need server version at least 2.14.55"
27560
27561         local testdir=$DIR/$tdir
27562         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27563         local max_inherit
27564         local sub_max_inherit
27565
27566         mkdir -p $testdir || error "failed to create $testdir"
27567
27568         # set default max-inherit to -1 if stripe count is 0 or 1
27569         $LFS setdirstripe -D -c 1 $testdir ||
27570                 error "failed to set default LMV"
27571         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27572         (( max_inherit == -1 )) ||
27573                 error "wrong max_inherit value $max_inherit"
27574
27575         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27576         $LFS setdirstripe -D -c -1 $testdir ||
27577                 error "failed to set default LMV"
27578         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27579         (( max_inherit > 0 )) ||
27580                 error "wrong max_inherit value $max_inherit"
27581
27582         # and the subdir will decrease the max_inherit by 1
27583         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27584         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27585         (( sub_max_inherit == max_inherit - 1)) ||
27586                 error "wrong max-inherit of subdir $sub_max_inherit"
27587
27588         # check specified --max-inherit and warning message
27589         stack_trap "rm -f $tmpfile"
27590         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27591                 error "failed to set default LMV"
27592         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27593         (( max_inherit == -1 )) ||
27594                 error "wrong max_inherit value $max_inherit"
27595
27596         # check the warning messages
27597         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27598                 error "failed to detect warning string"
27599         fi
27600 }
27601 run_test 413e "check default max-inherit value"
27602
27603 test_fs_dmv_inherit()
27604 {
27605         local testdir=$DIR/$tdir
27606
27607         local count
27608         local inherit
27609         local inherit_rr
27610
27611         for i in 1 2; do
27612                 mkdir $testdir || error "mkdir $testdir failed"
27613                 count=$($LFS getdirstripe -D -c $testdir)
27614                 (( count == 1 )) ||
27615                         error "$testdir default LMV count mismatch $count != 1"
27616                 inherit=$($LFS getdirstripe -D -X $testdir)
27617                 (( inherit == 3 - i )) ||
27618                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27619                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27620                 (( inherit_rr == 3 - i )) ||
27621                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27622                 testdir=$testdir/sub
27623         done
27624
27625         mkdir $testdir || error "mkdir $testdir failed"
27626         count=$($LFS getdirstripe -D -c $testdir)
27627         (( count == 0 )) ||
27628                 error "$testdir default LMV count not zero: $count"
27629 }
27630
27631 test_413f() {
27632         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27633
27634         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27635                 skip "Need server version at least 2.14.55"
27636
27637         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27638                 error "dump $DIR default LMV failed"
27639         stack_trap "setfattr --restore=$TMP/dmv.ea"
27640
27641         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27642                 error "set $DIR default LMV failed"
27643
27644         test_fs_dmv_inherit
27645 }
27646 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27647
27648 test_413g() {
27649         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27650
27651         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27652         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27653                 error "dump $DIR default LMV failed"
27654         stack_trap "setfattr --restore=$TMP/dmv.ea"
27655
27656         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27657                 error "set $DIR default LMV failed"
27658
27659         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27660                 error "mount $MOUNT2 failed"
27661         stack_trap "umount_client $MOUNT2"
27662
27663         local saved_DIR=$DIR
27664
27665         export DIR=$MOUNT2
27666
27667         stack_trap "export DIR=$saved_DIR"
27668
27669         # first check filesystem-wide default LMV inheritance
27670         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27671
27672         # then check subdirs are spread to all MDTs
27673         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27674
27675         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27676
27677         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27678 }
27679 run_test 413g "enforce ROOT default LMV on subdir mount"
27680
27681 test_413h() {
27682         (( MDSCOUNT >= 2 )) ||
27683                 skip "We need at least 2 MDTs for this test"
27684
27685         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27686                 skip "Need server version at least 2.15.50.6"
27687
27688         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27689
27690         stack_trap "$LCTL set_param \
27691                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27692         $LCTL set_param lmv.*.qos_maxage=1
27693
27694         local depth=5
27695         local rr_depth=4
27696         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27697         local count=$((MDSCOUNT * 20))
27698
27699         generate_uneven_mdts 50
27700
27701         mkdir -p $dir || error "mkdir $dir failed"
27702         stack_trap "rm -rf $dir"
27703         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27704                 --max-inherit-rr=$rr_depth $dir
27705
27706         for ((d=0; d < depth + 2; d++)); do
27707                 log "dir=$dir:"
27708                 for ((sub=0; sub < count; sub++)); do
27709                         mkdir $dir/d$sub
27710                 done
27711                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27712                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27713                 # subdirs within $rr_depth should be created round-robin
27714                 if (( d < rr_depth )); then
27715                         (( ${num[0]} != count )) ||
27716                                 error "all objects created on MDT ${num[1]}"
27717                 fi
27718
27719                 dir=$dir/d0
27720         done
27721 }
27722 run_test 413h "don't stick to parent for round-robin dirs"
27723
27724 test_413i() {
27725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27726
27727         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27728                 skip "Need server version at least 2.14.55"
27729
27730         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27731                 error "dump $DIR default LMV failed"
27732         stack_trap "setfattr --restore=$TMP/dmv.ea"
27733
27734         local testdir=$DIR/$tdir
27735         local def_max_rr=1
27736         local def_max=3
27737         local count
27738
27739         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27740                 --max-inherit-rr=$def_max_rr $DIR ||
27741                 error "set $DIR default LMV failed"
27742
27743         for i in $(seq 2 3); do
27744                 def_max=$((def_max - 1))
27745                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27746
27747                 mkdir $testdir
27748                 # RR is decremented and keeps zeroed once exhausted
27749                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27750                 (( count == def_max_rr )) ||
27751                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27752
27753                 # max-inherit is decremented
27754                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27755                 (( count == def_max )) ||
27756                         error_noexit "$testdir: max-inherit $count != $def_max"
27757
27758                 testdir=$testdir/d$i
27759         done
27760
27761         # d3 is the last inherited from ROOT, no inheritance anymore
27762         # i.e. no the default layout anymore
27763         mkdir -p $testdir/d4/d5
27764         count=$($LFS getdirstripe -D --max-inherit $testdir)
27765         (( count == -1 )) ||
27766                 error_noexit "$testdir: max-inherit $count != -1"
27767
27768         local p_count=$($LFS getdirstripe -i $testdir)
27769
27770         for i in $(seq 4 5); do
27771                 testdir=$testdir/d$i
27772
27773                 # the root default layout is not applied once exhausted
27774                 count=$($LFS getdirstripe -i $testdir)
27775                 (( count == p_count )) ||
27776                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27777         done
27778
27779         $LFS setdirstripe -i 0 $DIR/d2
27780         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27781         (( count == -1 )) ||
27782                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27783 }
27784 run_test 413i "check default layout inheritance"
27785
27786 test_413z() {
27787         local pids=""
27788         local subdir
27789         local pid
27790
27791         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27792                 unlinkmany $subdir/f. $TEST413_COUNT &
27793                 pids="$pids $!"
27794         done
27795
27796         for pid in $pids; do
27797                 wait $pid
27798         done
27799
27800         true
27801 }
27802 run_test 413z "413 test cleanup"
27803
27804 test_414() {
27805 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27806         $LCTL set_param fail_loc=0x80000521
27807         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27808         rm -f $DIR/$tfile
27809 }
27810 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27811
27812 test_415() {
27813         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27814         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27815                 skip "Need server version at least 2.11.52"
27816
27817         # LU-11102
27818         local total=500
27819         local max=120
27820
27821         # this test may be slow on ZFS
27822         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27823
27824         # though this test is designed for striped directory, let's test normal
27825         # directory too since lock is always saved as CoS lock.
27826         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27827         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27828         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27829         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27830         wait_delete_completed_mds
27831
27832         # run a loop without concurrent touch to measure rename duration.
27833         # only for test debug/robustness, NOT part of COS functional test.
27834         local start_time=$SECONDS
27835         for ((i = 0; i < total; i++)); do
27836                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27837                         > /dev/null
27838         done
27839         local baseline=$((SECONDS - start_time))
27840         echo "rename $total files without 'touch' took $baseline sec"
27841
27842         (
27843                 while true; do
27844                         touch $DIR/$tdir
27845                 done
27846         ) &
27847         local setattr_pid=$!
27848
27849         # rename files back to original name so unlinkmany works
27850         start_time=$SECONDS
27851         for ((i = 0; i < total; i++)); do
27852                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27853                         > /dev/null
27854         done
27855         local duration=$((SECONDS - start_time))
27856
27857         kill -9 $setattr_pid
27858
27859         echo "rename $total files with 'touch' took $duration sec"
27860         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27861         (( duration <= max )) ||
27862                 error_not_in_vm "rename took $duration > $max sec"
27863 }
27864 run_test 415 "lock revoke is not missing"
27865
27866 test_416() {
27867         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27868                 skip "Need server version at least 2.11.55"
27869
27870         # define OBD_FAIL_OSD_TXN_START    0x19a
27871         do_facet mds1 lctl set_param fail_loc=0x19a
27872
27873         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27874
27875         true
27876 }
27877 run_test 416 "transaction start failure won't cause system hung"
27878
27879 cleanup_417() {
27880         trap 0
27881         do_nodes $(comma_list $(mdts_nodes)) \
27882                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27883         do_nodes $(comma_list $(mdts_nodes)) \
27884                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27885         do_nodes $(comma_list $(mdts_nodes)) \
27886                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27887 }
27888
27889 test_417() {
27890         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27891         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27892                 skip "Need MDS version at least 2.11.56"
27893
27894         trap cleanup_417 RETURN EXIT
27895
27896         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27897         do_nodes $(comma_list $(mdts_nodes)) \
27898                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27899         $LFS migrate -m 0 $DIR/$tdir.1 &&
27900                 error "migrate dir $tdir.1 should fail"
27901
27902         do_nodes $(comma_list $(mdts_nodes)) \
27903                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27904         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27905                 error "create remote dir $tdir.2 should fail"
27906
27907         do_nodes $(comma_list $(mdts_nodes)) \
27908                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27909         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27910                 error "create striped dir $tdir.3 should fail"
27911         true
27912 }
27913 run_test 417 "disable remote dir, striped dir and dir migration"
27914
27915 # Checks that the outputs of df [-i] and lfs df [-i] match
27916 #
27917 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27918 check_lfs_df() {
27919         local dir=$2
27920         local inodes
27921         local df_out
27922         local lfs_df_out
27923         local count
27924         local passed=false
27925
27926         # blocks or inodes
27927         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27928
27929         for count in {1..100}; do
27930                 do_nodes "$CLIENTS" \
27931                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27932                 sync; sleep 0.2
27933
27934                 # read the lines of interest
27935                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27936                         error "df $inodes $dir | tail -n +2 failed"
27937                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27938                         error "lfs df $inodes $dir | grep summary: failed"
27939
27940                 # skip first substrings of each output as they are different
27941                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27942                 # compare the two outputs
27943                 passed=true
27944                 #  skip "available" on MDT until LU-13997 is fixed.
27945                 #for i in {1..5}; do
27946                 for i in 1 2 4 5; do
27947                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27948                 done
27949                 $passed && break
27950         done
27951
27952         if ! $passed; then
27953                 df -P $inodes $dir
27954                 echo
27955                 lfs df $inodes $dir
27956                 error "df and lfs df $1 output mismatch: "      \
27957                       "df ${inodes}: ${df_out[*]}, "            \
27958                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27959         fi
27960 }
27961
27962 test_418() {
27963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27964
27965         local dir=$DIR/$tdir
27966         local numfiles=$((RANDOM % 4096 + 2))
27967         local numblocks=$((RANDOM % 256 + 1))
27968
27969         wait_delete_completed
27970         test_mkdir $dir
27971
27972         # check block output
27973         check_lfs_df blocks $dir
27974         # check inode output
27975         check_lfs_df inodes $dir
27976
27977         # create a single file and retest
27978         echo "Creating a single file and testing"
27979         createmany -o $dir/$tfile- 1 &>/dev/null ||
27980                 error "creating 1 file in $dir failed"
27981         check_lfs_df blocks $dir
27982         check_lfs_df inodes $dir
27983
27984         # create a random number of files
27985         echo "Creating $((numfiles - 1)) files and testing"
27986         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27987                 error "creating $((numfiles - 1)) files in $dir failed"
27988
27989         # write a random number of blocks to the first test file
27990         echo "Writing $numblocks 4K blocks and testing"
27991         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27992                 count=$numblocks &>/dev/null ||
27993                 error "dd to $dir/${tfile}-0 failed"
27994
27995         # retest
27996         check_lfs_df blocks $dir
27997         check_lfs_df inodes $dir
27998
27999         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28000                 error "unlinking $numfiles files in $dir failed"
28001 }
28002 run_test 418 "df and lfs df outputs match"
28003
28004 test_419()
28005 {
28006         local dir=$DIR/$tdir
28007
28008         mkdir -p $dir
28009         touch $dir/file
28010
28011         cancel_lru_locks mdc
28012
28013         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28014         $LCTL set_param fail_loc=0x1410
28015         cat $dir/file
28016         $LCTL set_param fail_loc=0
28017         rm -rf $dir
28018 }
28019 run_test 419 "Verify open file by name doesn't crash kernel"
28020
28021 test_420()
28022 {
28023         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28024                 skip "Need MDS version at least 2.12.53"
28025
28026         local SAVE_UMASK=$(umask)
28027         local dir=$DIR/$tdir
28028         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28029
28030         mkdir -p $dir
28031         umask 0000
28032         mkdir -m03777 $dir/testdir
28033         ls -dn $dir/testdir
28034         # Need to remove trailing '.' when SELinux is enabled
28035         local dirperms=$(ls -dn $dir/testdir |
28036                          awk '{ sub(/\.$/, "", $1); print $1}')
28037         [ $dirperms == "drwxrwsrwt" ] ||
28038                 error "incorrect perms on $dir/testdir"
28039
28040         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28041                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28042         ls -n $dir/testdir/testfile
28043         local fileperms=$(ls -n $dir/testdir/testfile |
28044                           awk '{ sub(/\.$/, "", $1); print $1}')
28045         [ $fileperms == "-rwxr-xr-x" ] ||
28046                 error "incorrect perms on $dir/testdir/testfile"
28047
28048         umask $SAVE_UMASK
28049 }
28050 run_test 420 "clear SGID bit on non-directories for non-members"
28051
28052 test_421a() {
28053         local cnt
28054         local fid1
28055         local fid2
28056
28057         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28058                 skip "Need MDS version at least 2.12.54"
28059
28060         test_mkdir $DIR/$tdir
28061         createmany -o $DIR/$tdir/f 3
28062         cnt=$(ls -1 $DIR/$tdir | wc -l)
28063         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28064
28065         fid1=$(lfs path2fid $DIR/$tdir/f1)
28066         fid2=$(lfs path2fid $DIR/$tdir/f2)
28067         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28068
28069         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28070         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28071
28072         cnt=$(ls -1 $DIR/$tdir | wc -l)
28073         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28074
28075         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28076         createmany -o $DIR/$tdir/f 3
28077         cnt=$(ls -1 $DIR/$tdir | wc -l)
28078         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28079
28080         fid1=$(lfs path2fid $DIR/$tdir/f1)
28081         fid2=$(lfs path2fid $DIR/$tdir/f2)
28082         echo "remove using fsname $FSNAME"
28083         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28084
28085         cnt=$(ls -1 $DIR/$tdir | wc -l)
28086         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28087 }
28088 run_test 421a "simple rm by fid"
28089
28090 test_421b() {
28091         local cnt
28092         local FID1
28093         local FID2
28094
28095         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28096                 skip "Need MDS version at least 2.12.54"
28097
28098         test_mkdir $DIR/$tdir
28099         createmany -o $DIR/$tdir/f 3
28100         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28101         MULTIPID=$!
28102
28103         FID1=$(lfs path2fid $DIR/$tdir/f1)
28104         FID2=$(lfs path2fid $DIR/$tdir/f2)
28105         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28106
28107         kill -USR1 $MULTIPID
28108         wait
28109
28110         cnt=$(ls $DIR/$tdir | wc -l)
28111         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28112 }
28113 run_test 421b "rm by fid on open file"
28114
28115 test_421c() {
28116         local cnt
28117         local FIDS
28118
28119         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28120                 skip "Need MDS version at least 2.12.54"
28121
28122         test_mkdir $DIR/$tdir
28123         createmany -o $DIR/$tdir/f 3
28124         touch $DIR/$tdir/$tfile
28125         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28126         cnt=$(ls -1 $DIR/$tdir | wc -l)
28127         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28128
28129         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28130         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28131
28132         cnt=$(ls $DIR/$tdir | wc -l)
28133         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28134 }
28135 run_test 421c "rm by fid against hardlinked files"
28136
28137 test_421d() {
28138         local cnt
28139         local FIDS
28140
28141         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28142                 skip "Need MDS version at least 2.12.54"
28143
28144         test_mkdir $DIR/$tdir
28145         createmany -o $DIR/$tdir/f 4097
28146         cnt=$(ls -1 $DIR/$tdir | wc -l)
28147         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28148
28149         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28150         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28151
28152         cnt=$(ls $DIR/$tdir | wc -l)
28153         rm -rf $DIR/$tdir
28154         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28155 }
28156 run_test 421d "rmfid en masse"
28157
28158 test_421e() {
28159         local cnt
28160         local FID
28161
28162         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28163         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28164                 skip "Need MDS version at least 2.12.54"
28165
28166         mkdir -p $DIR/$tdir
28167         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28168         createmany -o $DIR/$tdir/striped_dir/f 512
28169         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28170         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28171
28172         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28173                 sed "s/[/][^:]*://g")
28174         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28175
28176         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28177         rm -rf $DIR/$tdir
28178         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28179 }
28180 run_test 421e "rmfid in DNE"
28181
28182 test_421f() {
28183         local cnt
28184         local FID
28185
28186         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28187                 skip "Need MDS version at least 2.12.54"
28188
28189         test_mkdir $DIR/$tdir
28190         touch $DIR/$tdir/f
28191         cnt=$(ls -1 $DIR/$tdir | wc -l)
28192         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28193
28194         FID=$(lfs path2fid $DIR/$tdir/f)
28195         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28196         # rmfid should fail
28197         cnt=$(ls -1 $DIR/$tdir | wc -l)
28198         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28199
28200         chmod a+rw $DIR/$tdir
28201         ls -la $DIR/$tdir
28202         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28203         # rmfid should fail
28204         cnt=$(ls -1 $DIR/$tdir | wc -l)
28205         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28206
28207         rm -f $DIR/$tdir/f
28208         $RUNAS touch $DIR/$tdir/f
28209         FID=$(lfs path2fid $DIR/$tdir/f)
28210         echo "rmfid as root"
28211         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28212         cnt=$(ls -1 $DIR/$tdir | wc -l)
28213         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28214
28215         rm -f $DIR/$tdir/f
28216         $RUNAS touch $DIR/$tdir/f
28217         cnt=$(ls -1 $DIR/$tdir | wc -l)
28218         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28219         FID=$(lfs path2fid $DIR/$tdir/f)
28220         # rmfid w/o user_fid2path mount option should fail
28221         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28222         cnt=$(ls -1 $DIR/$tdir | wc -l)
28223         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28224
28225         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28226         stack_trap "rmdir $tmpdir"
28227         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28228                 error "failed to mount client'"
28229         stack_trap "umount_client $tmpdir"
28230
28231         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28232         # rmfid should succeed
28233         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28234         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28235
28236         # rmfid shouldn't allow to remove files due to dir's permission
28237         chmod a+rwx $tmpdir/$tdir
28238         touch $tmpdir/$tdir/f
28239         ls -la $tmpdir/$tdir
28240         FID=$(lfs path2fid $tmpdir/$tdir/f)
28241         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28242         return 0
28243 }
28244 run_test 421f "rmfid checks permissions"
28245
28246 test_421g() {
28247         local cnt
28248         local FIDS
28249
28250         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28251         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28252                 skip "Need MDS version at least 2.12.54"
28253
28254         mkdir -p $DIR/$tdir
28255         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28256         createmany -o $DIR/$tdir/striped_dir/f 512
28257         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28258         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28259
28260         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28261                 sed "s/[/][^:]*://g")
28262
28263         rm -f $DIR/$tdir/striped_dir/f1*
28264         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28265         removed=$((512 - cnt))
28266
28267         # few files have been just removed, so we expect
28268         # rmfid to fail on their fids
28269         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28270         [ $removed != $errors ] && error "$errors != $removed"
28271
28272         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28273         rm -rf $DIR/$tdir
28274         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28275 }
28276 run_test 421g "rmfid to return errors properly"
28277
28278 test_421h() {
28279         local mount_other
28280         local mount_ret
28281         local rmfid_ret
28282         local old_fid
28283         local fidA
28284         local fidB
28285         local fidC
28286         local fidD
28287
28288         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28289                 skip "Need MDS version at least 2.15.53"
28290
28291         test_mkdir $DIR/$tdir
28292         test_mkdir $DIR/$tdir/subdir
28293         touch $DIR/$tdir/subdir/file0
28294         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28295         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28296         rm -f $DIR/$tdir/subdir/file0
28297         touch $DIR/$tdir/subdir/fileA
28298         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28299         echo File $DIR/$tdir/subdir/fileA FID $fidA
28300         touch $DIR/$tdir/subdir/fileB
28301         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28302         echo File $DIR/$tdir/subdir/fileB FID $fidB
28303         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28304         touch $DIR/$tdir/subdir/fileC
28305         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28306         echo File $DIR/$tdir/subdir/fileC FID $fidC
28307         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28308         touch $DIR/$tdir/fileD
28309         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28310         echo File $DIR/$tdir/fileD FID $fidD
28311
28312         # mount another client mount point with subdirectory mount
28313         export FILESET=/$tdir/subdir
28314         mount_other=${MOUNT}_other
28315         mount_client $mount_other ${MOUNT_OPTS}
28316         mount_ret=$?
28317         export FILESET=""
28318         (( mount_ret == 0 )) || error "mount $mount_other failed"
28319
28320         echo Removing FIDs:
28321         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28322         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28323         rmfid_ret=$?
28324
28325         umount_client $mount_other || error "umount $mount_other failed"
28326
28327         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28328
28329         # fileA should have been deleted
28330         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28331
28332         # fileB should have been deleted
28333         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28334
28335         # fileC should not have been deleted, fid also exists outside of fileset
28336         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28337
28338         # fileD should not have been deleted, it exists outside of fileset
28339         stat $DIR/$tdir/fileD || error "fileD deleted"
28340 }
28341 run_test 421h "rmfid with fileset mount"
28342
28343 test_422() {
28344         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28345         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28346         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28347         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28348         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28349
28350         local amc=$(at_max_get client)
28351         local amo=$(at_max_get mds1)
28352         local timeout=`lctl get_param -n timeout`
28353
28354         at_max_set 0 client
28355         at_max_set 0 mds1
28356
28357 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28358         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28359                         fail_val=$(((2*timeout + 10)*1000))
28360         touch $DIR/$tdir/d3/file &
28361         sleep 2
28362 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28363         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28364                         fail_val=$((2*timeout + 5))
28365         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28366         local pid=$!
28367         sleep 1
28368         kill -9 $pid
28369         sleep $((2 * timeout))
28370         echo kill $pid
28371         kill -9 $pid
28372         lctl mark touch
28373         touch $DIR/$tdir/d2/file3
28374         touch $DIR/$tdir/d2/file4
28375         touch $DIR/$tdir/d2/file5
28376
28377         wait
28378         at_max_set $amc client
28379         at_max_set $amo mds1
28380
28381         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28382         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28383                 error "Watchdog is always throttled"
28384 }
28385 run_test 422 "kill a process with RPC in progress"
28386
28387 stat_test() {
28388     df -h $MOUNT &
28389     df -h $MOUNT &
28390     df -h $MOUNT &
28391     df -h $MOUNT &
28392     df -h $MOUNT &
28393     df -h $MOUNT &
28394 }
28395
28396 test_423() {
28397     local _stats
28398     # ensure statfs cache is expired
28399     sleep 2;
28400
28401     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28402     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28403
28404     return 0
28405 }
28406 run_test 423 "statfs should return a right data"
28407
28408 test_424() {
28409 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28410         $LCTL set_param fail_loc=0x80000522
28411         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28412         rm -f $DIR/$tfile
28413 }
28414 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28415
28416 test_425() {
28417         test_mkdir -c -1 $DIR/$tdir
28418         $LFS setstripe -c -1 $DIR/$tdir
28419
28420         lru_resize_disable "" 100
28421         stack_trap "lru_resize_enable" EXIT
28422
28423         sleep 5
28424
28425         for i in $(seq $((MDSCOUNT * 125))); do
28426                 local t=$DIR/$tdir/$tfile_$i
28427
28428                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28429                         error_noexit "Create file $t"
28430         done
28431         stack_trap "rm -rf $DIR/$tdir" EXIT
28432
28433         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28434                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28435                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28436
28437                 [ $lock_count -le $lru_size ] ||
28438                         error "osc lock count $lock_count > lru size $lru_size"
28439         done
28440
28441         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28442                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28443                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28444
28445                 [ $lock_count -le $lru_size ] ||
28446                         error "mdc lock count $lock_count > lru size $lru_size"
28447         done
28448 }
28449 run_test 425 "lock count should not exceed lru size"
28450
28451 test_426() {
28452         splice-test -r $DIR/$tfile
28453         splice-test -rd $DIR/$tfile
28454         splice-test $DIR/$tfile
28455         splice-test -d $DIR/$tfile
28456 }
28457 run_test 426 "splice test on Lustre"
28458
28459 test_427() {
28460         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28461         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28462                 skip "Need MDS version at least 2.12.4"
28463         local log
28464
28465         mkdir $DIR/$tdir
28466         mkdir $DIR/$tdir/1
28467         mkdir $DIR/$tdir/2
28468         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28469         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28470
28471         $LFS getdirstripe $DIR/$tdir/1/dir
28472
28473         #first setfattr for creating updatelog
28474         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28475
28476 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28477         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28478         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28479         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28480
28481         sleep 2
28482         fail mds2
28483         wait_recovery_complete mds2 $((2*TIMEOUT))
28484
28485         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28486         echo $log | grep "get update log failed" &&
28487                 error "update log corruption is detected" || true
28488 }
28489 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28490
28491 test_428() {
28492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28493         local cache_limit=$CACHE_MAX
28494
28495         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28496         $LCTL set_param -n llite.*.max_cached_mb=64
28497
28498         mkdir $DIR/$tdir
28499         $LFS setstripe -c 1 $DIR/$tdir
28500         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28501         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28502         #test write
28503         for f in $(seq 4); do
28504                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28505         done
28506         wait
28507
28508         cancel_lru_locks osc
28509         # Test read
28510         for f in $(seq 4); do
28511                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28512         done
28513         wait
28514 }
28515 run_test 428 "large block size IO should not hang"
28516
28517 test_429() { # LU-7915 / LU-10948
28518         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28519         local testfile=$DIR/$tfile
28520         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28521         local new_flag=1
28522         local first_rpc
28523         local second_rpc
28524         local third_rpc
28525
28526         $LCTL get_param $ll_opencache_threshold_count ||
28527                 skip "client does not have opencache parameter"
28528
28529         set_opencache $new_flag
28530         stack_trap "restore_opencache"
28531         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28532                 error "enable opencache failed"
28533         touch $testfile
28534         # drop MDC DLM locks
28535         cancel_lru_locks mdc
28536         # clear MDC RPC stats counters
28537         $LCTL set_param $mdc_rpcstats=clear
28538
28539         # According to the current implementation, we need to run 3 times
28540         # open & close file to verify if opencache is enabled correctly.
28541         # 1st, RPCs are sent for lookup/open and open handle is released on
28542         #      close finally.
28543         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28544         #      so open handle won't be released thereafter.
28545         # 3rd, No RPC is sent out.
28546         $MULTIOP $testfile oc || error "multiop failed"
28547         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28548         echo "1st: $first_rpc RPCs in flight"
28549
28550         $MULTIOP $testfile oc || error "multiop failed"
28551         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28552         echo "2nd: $second_rpc RPCs in flight"
28553
28554         $MULTIOP $testfile oc || error "multiop failed"
28555         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28556         echo "3rd: $third_rpc RPCs in flight"
28557
28558         #verify no MDC RPC is sent
28559         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28560 }
28561 run_test 429 "verify if opencache flag on client side does work"
28562
28563 lseek_test_430() {
28564         local offset
28565         local file=$1
28566
28567         # data at [200K, 400K)
28568         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28569                 error "256K->512K dd fails"
28570         # data at [2M, 3M)
28571         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28572                 error "2M->3M dd fails"
28573         # data at [4M, 5M)
28574         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28575                 error "4M->5M dd fails"
28576         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28577         # start at first component hole #1
28578         printf "Seeking hole from 1000 ... "
28579         offset=$(lseek_test -l 1000 $file)
28580         echo $offset
28581         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28582         printf "Seeking data from 1000 ... "
28583         offset=$(lseek_test -d 1000 $file)
28584         echo $offset
28585         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28586
28587         # start at first component data block
28588         printf "Seeking hole from 300000 ... "
28589         offset=$(lseek_test -l 300000 $file)
28590         echo $offset
28591         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28592         printf "Seeking data from 300000 ... "
28593         offset=$(lseek_test -d 300000 $file)
28594         echo $offset
28595         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28596
28597         # start at the first component but beyond end of object size
28598         printf "Seeking hole from 1000000 ... "
28599         offset=$(lseek_test -l 1000000 $file)
28600         echo $offset
28601         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28602         printf "Seeking data from 1000000 ... "
28603         offset=$(lseek_test -d 1000000 $file)
28604         echo $offset
28605         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28606
28607         # start at second component stripe 2 (empty file)
28608         printf "Seeking hole from 1500000 ... "
28609         offset=$(lseek_test -l 1500000 $file)
28610         echo $offset
28611         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28612         printf "Seeking data from 1500000 ... "
28613         offset=$(lseek_test -d 1500000 $file)
28614         echo $offset
28615         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28616
28617         # start at second component stripe 1 (all data)
28618         printf "Seeking hole from 3000000 ... "
28619         offset=$(lseek_test -l 3000000 $file)
28620         echo $offset
28621         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28622         printf "Seeking data from 3000000 ... "
28623         offset=$(lseek_test -d 3000000 $file)
28624         echo $offset
28625         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28626
28627         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28628                 error "2nd dd fails"
28629         echo "Add data block at 640K...1280K"
28630
28631         # start at before new data block, in hole
28632         printf "Seeking hole from 600000 ... "
28633         offset=$(lseek_test -l 600000 $file)
28634         echo $offset
28635         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28636         printf "Seeking data from 600000 ... "
28637         offset=$(lseek_test -d 600000 $file)
28638         echo $offset
28639         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28640
28641         # start at the first component new data block
28642         printf "Seeking hole from 1000000 ... "
28643         offset=$(lseek_test -l 1000000 $file)
28644         echo $offset
28645         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28646         printf "Seeking data from 1000000 ... "
28647         offset=$(lseek_test -d 1000000 $file)
28648         echo $offset
28649         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28650
28651         # start at second component stripe 2, new data
28652         printf "Seeking hole from 1200000 ... "
28653         offset=$(lseek_test -l 1200000 $file)
28654         echo $offset
28655         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28656         printf "Seeking data from 1200000 ... "
28657         offset=$(lseek_test -d 1200000 $file)
28658         echo $offset
28659         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28660
28661         # start beyond file end
28662         printf "Using offset > filesize ... "
28663         lseek_test -l 4000000 $file && error "lseek should fail"
28664         printf "Using offset > filesize ... "
28665         lseek_test -d 4000000 $file && error "lseek should fail"
28666
28667         printf "Done\n\n"
28668 }
28669
28670 test_430a() {
28671         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28672                 skip "MDT does not support SEEK_HOLE"
28673
28674         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28675                 skip "OST does not support SEEK_HOLE"
28676
28677         local file=$DIR/$tdir/$tfile
28678
28679         mkdir -p $DIR/$tdir
28680
28681         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28682         # OST stripe #1 will have continuous data at [1M, 3M)
28683         # OST stripe #2 is empty
28684         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28685         lseek_test_430 $file
28686         rm $file
28687         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28688         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28689         lseek_test_430 $file
28690         rm $file
28691         $LFS setstripe -c2 -S 512K $file
28692         echo "Two stripes, stripe size 512K"
28693         lseek_test_430 $file
28694         rm $file
28695         # FLR with stale mirror
28696         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28697                        -N -c2 -S 1M $file
28698         echo "Mirrored file:"
28699         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28700         echo "Plain 2 stripes 1M"
28701         lseek_test_430 $file
28702         rm $file
28703 }
28704 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28705
28706 test_430b() {
28707         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28708                 skip "OST does not support SEEK_HOLE"
28709
28710         local offset
28711         local file=$DIR/$tdir/$tfile
28712
28713         mkdir -p $DIR/$tdir
28714         # Empty layout lseek should fail
28715         $MCREATE $file
28716         # seek from 0
28717         printf "Seeking hole from 0 ... "
28718         lseek_test -l 0 $file && error "lseek should fail"
28719         printf "Seeking data from 0 ... "
28720         lseek_test -d 0 $file && error "lseek should fail"
28721         rm $file
28722
28723         # 1M-hole file
28724         $LFS setstripe -E 1M -c2 -E eof $file
28725         $TRUNCATE $file 1048576
28726         printf "Seeking hole from 1000000 ... "
28727         offset=$(lseek_test -l 1000000 $file)
28728         echo $offset
28729         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28730         printf "Seeking data from 1000000 ... "
28731         lseek_test -d 1000000 $file && error "lseek should fail"
28732         rm $file
28733
28734         # full component followed by non-inited one
28735         $LFS setstripe -E 1M -c2 -E eof $file
28736         dd if=/dev/urandom of=$file bs=1M count=1
28737         printf "Seeking hole from 1000000 ... "
28738         offset=$(lseek_test -l 1000000 $file)
28739         echo $offset
28740         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28741         printf "Seeking hole from 1048576 ... "
28742         lseek_test -l 1048576 $file && error "lseek should fail"
28743         # init second component and truncate back
28744         echo "123" >> $file
28745         $TRUNCATE $file 1048576
28746         printf "Seeking hole from 1000000 ... "
28747         offset=$(lseek_test -l 1000000 $file)
28748         echo $offset
28749         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28750         printf "Seeking hole from 1048576 ... "
28751         lseek_test -l 1048576 $file && error "lseek should fail"
28752         # boundary checks for big values
28753         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28754         offset=$(lseek_test -d 0 $file.10g)
28755         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28756         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28757         offset=$(lseek_test -d 0 $file.100g)
28758         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28759         return 0
28760 }
28761 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28762
28763 test_430c() {
28764         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28765                 skip "OST does not support SEEK_HOLE"
28766
28767         local file=$DIR/$tdir/$tfile
28768         local start
28769
28770         mkdir -p $DIR/$tdir
28771         stack_trap "rm -f $file $file.tmp"
28772         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28773
28774         # cp version 8.33+ prefers lseek over fiemap
28775         local ver=$(cp --version | awk '{ print $4; exit; }')
28776
28777         echo "cp $ver installed"
28778         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28779                 start=$SECONDS
28780                 time cp -v $file $file.tmp || error "cp $file failed"
28781                 (( SECONDS - start < 5 )) || {
28782                         strace cp $file $file.tmp |&
28783                                 grep -E "open|read|seek|FIEMAP" |
28784                                 grep -A 100 $file
28785                         error "cp: too long runtime $((SECONDS - start))"
28786                 }
28787         else
28788                 echo "cp test skipped due to $ver < 8.33"
28789         fi
28790
28791         # tar version 1.29+ supports SEEK_HOLE/DATA
28792         ver=$(tar --version | awk '{ print $4; exit; }')
28793         echo "tar $ver installed"
28794         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28795                 start=$SECONDS
28796                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28797                 (( SECONDS - start < 5 )) || {
28798                         strace tar cf $file.tmp --sparse $file |&
28799                                 grep -E "open|read|seek|FIEMAP" |
28800                                 grep -A 100 $file
28801                         error "tar: too long runtime $((SECONDS - start))"
28802                 }
28803         else
28804                 echo "tar test skipped due to $ver < 1.29"
28805         fi
28806 }
28807 run_test 430c "lseek: external tools check"
28808
28809 test_431() { # LU-14187
28810         local file=$DIR/$tdir/$tfile
28811
28812         mkdir -p $DIR/$tdir
28813         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28814         dd if=/dev/urandom of=$file bs=4k count=1
28815         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28816         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28817         #define OBD_FAIL_OST_RESTART_IO 0x251
28818         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28819         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28820         cp $file $file.0
28821         cancel_lru_locks
28822         sync_all_data
28823         echo 3 > /proc/sys/vm/drop_caches
28824         diff  $file $file.0 || error "data diff"
28825 }
28826 run_test 431 "Restart transaction for IO"
28827
28828 cleanup_test_432() {
28829         do_facet mgs $LCTL nodemap_activate 0
28830         wait_nm_sync active
28831 }
28832
28833 test_432() {
28834         local tmpdir=$TMP/dir432
28835
28836         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28837                 skip "Need MDS version at least 2.14.52"
28838
28839         stack_trap cleanup_test_432 EXIT
28840         mkdir $DIR/$tdir
28841         mkdir $tmpdir
28842
28843         do_facet mgs $LCTL nodemap_activate 1
28844         wait_nm_sync active
28845         do_facet mgs $LCTL nodemap_modify --name default \
28846                 --property admin --value 1
28847         do_facet mgs $LCTL nodemap_modify --name default \
28848                 --property trusted --value 1
28849         cancel_lru_locks mdc
28850         wait_nm_sync default admin_nodemap
28851         wait_nm_sync default trusted_nodemap
28852
28853         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28854                grep -ci "Operation not permitted") -ne 0 ]; then
28855                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28856         fi
28857 }
28858 run_test 432 "mv dir from outside Lustre"
28859
28860 test_433() {
28861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28862
28863         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28864                 skip "inode cache not supported"
28865
28866         $LCTL set_param llite.*.inode_cache=0
28867         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28868
28869         local count=256
28870         local before
28871         local after
28872
28873         cancel_lru_locks mdc
28874         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28875         createmany -m $DIR/$tdir/f $count
28876         createmany -d $DIR/$tdir/d $count
28877         ls -l $DIR/$tdir > /dev/null
28878         stack_trap "rm -rf $DIR/$tdir"
28879
28880         before=$(num_objects)
28881         cancel_lru_locks mdc
28882         after=$(num_objects)
28883
28884         # sometimes even @before is less than 2 * count
28885         while (( before - after < count )); do
28886                 sleep 1
28887                 after=$(num_objects)
28888                 wait=$((wait + 1))
28889                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28890                 if (( wait > 60 )); then
28891                         error "inode slab grew from $before to $after"
28892                 fi
28893         done
28894
28895         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28896 }
28897 run_test 433 "ldlm lock cancel releases dentries and inodes"
28898
28899 test_434() {
28900         local file
28901         local getxattr_count
28902         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28903         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28904
28905         [[ $(getenforce) == "Disabled" ]] ||
28906                 skip "lsm selinux module have to be disabled for this test"
28907
28908         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28909                 error "fail to create $DIR/$tdir/ on MDT0000"
28910
28911         touch $DIR/$tdir/$tfile-{001..100}
28912
28913         # disable the xattr cache
28914         save_lustre_params client "llite.*.xattr_cache" > $p
28915         lctl set_param llite.*.xattr_cache=0
28916         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28917
28918         # clear clients mdc stats
28919         clear_stats $mdc_stat_param ||
28920                 error "fail to clear stats on mdc MDT0000"
28921
28922         for file in $DIR/$tdir/$tfile-{001..100}; do
28923                 getfattr -n security.selinux $file |&
28924                         grep -q "Operation not supported" ||
28925                         error "getxattr on security.selinux should return EOPNOTSUPP"
28926         done
28927
28928         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28929         (( getxattr_count < 100 )) ||
28930                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28931 }
28932 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28933
28934 test_440() {
28935         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28936                 source $LUSTRE/scripts/bash-completion/lustre
28937         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28938                 source /usr/share/bash-completion/completions/lustre
28939         else
28940                 skip "bash completion scripts not found"
28941         fi
28942
28943         local lctl_completions
28944         local lfs_completions
28945
28946         lctl_completions=$(_lustre_cmds lctl)
28947         if [[ ! $lctl_completions =~ "get_param" ]]; then
28948                 error "lctl bash completion failed"
28949         fi
28950
28951         lfs_completions=$(_lustre_cmds lfs)
28952         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28953                 error "lfs bash completion failed"
28954         fi
28955 }
28956 run_test 440 "bash completion for lfs, lctl"
28957
28958 prep_801() {
28959         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28960         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28961                 skip "Need server version at least 2.9.55"
28962
28963         start_full_debug_logging
28964 }
28965
28966 post_801() {
28967         stop_full_debug_logging
28968 }
28969
28970 barrier_stat() {
28971         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28972                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28973                            awk '/The barrier for/ { print $7 }')
28974                 echo $st
28975         else
28976                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28977                 echo \'$st\'
28978         fi
28979 }
28980
28981 barrier_expired() {
28982         local expired
28983
28984         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28985                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28986                           awk '/will be expired/ { print $7 }')
28987         else
28988                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28989         fi
28990
28991         echo $expired
28992 }
28993
28994 test_801a() {
28995         prep_801
28996
28997         echo "Start barrier_freeze at: $(date)"
28998         #define OBD_FAIL_BARRIER_DELAY          0x2202
28999         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29000         # Do not reduce barrier time - See LU-11873
29001         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29002
29003         sleep 2
29004         local b_status=$(barrier_stat)
29005         echo "Got barrier status at: $(date)"
29006         [ "$b_status" = "'freezing_p1'" ] ||
29007                 error "(1) unexpected barrier status $b_status"
29008
29009         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29010         wait
29011         b_status=$(barrier_stat)
29012         [ "$b_status" = "'frozen'" ] ||
29013                 error "(2) unexpected barrier status $b_status"
29014
29015         local expired=$(barrier_expired)
29016         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29017         sleep $((expired + 3))
29018
29019         b_status=$(barrier_stat)
29020         [ "$b_status" = "'expired'" ] ||
29021                 error "(3) unexpected barrier status $b_status"
29022
29023         # Do not reduce barrier time - See LU-11873
29024         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29025                 error "(4) fail to freeze barrier"
29026
29027         b_status=$(barrier_stat)
29028         [ "$b_status" = "'frozen'" ] ||
29029                 error "(5) unexpected barrier status $b_status"
29030
29031         echo "Start barrier_thaw at: $(date)"
29032         #define OBD_FAIL_BARRIER_DELAY          0x2202
29033         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29034         do_facet mgs $LCTL barrier_thaw $FSNAME &
29035
29036         sleep 2
29037         b_status=$(barrier_stat)
29038         echo "Got barrier status at: $(date)"
29039         [ "$b_status" = "'thawing'" ] ||
29040                 error "(6) unexpected barrier status $b_status"
29041
29042         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29043         wait
29044         b_status=$(barrier_stat)
29045         [ "$b_status" = "'thawed'" ] ||
29046                 error "(7) unexpected barrier status $b_status"
29047
29048         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29049         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29050         do_facet mgs $LCTL barrier_freeze $FSNAME
29051
29052         b_status=$(barrier_stat)
29053         [ "$b_status" = "'failed'" ] ||
29054                 error "(8) unexpected barrier status $b_status"
29055
29056         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29057         do_facet mgs $LCTL barrier_thaw $FSNAME
29058
29059         post_801
29060 }
29061 run_test 801a "write barrier user interfaces and stat machine"
29062
29063 test_801b() {
29064         prep_801
29065
29066         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29067         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29068         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29069         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29070         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29071
29072         cancel_lru_locks mdc
29073
29074         # 180 seconds should be long enough
29075         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29076
29077         local b_status=$(barrier_stat)
29078         [ "$b_status" = "'frozen'" ] ||
29079                 error "(6) unexpected barrier status $b_status"
29080
29081         mkdir $DIR/$tdir/d0/d10 &
29082         mkdir_pid=$!
29083
29084         touch $DIR/$tdir/d1/f13 &
29085         touch_pid=$!
29086
29087         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29088         ln_pid=$!
29089
29090         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29091         mv_pid=$!
29092
29093         rm -f $DIR/$tdir/d4/f12 &
29094         rm_pid=$!
29095
29096         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29097
29098         # To guarantee taht the 'stat' is not blocked
29099         b_status=$(barrier_stat)
29100         [ "$b_status" = "'frozen'" ] ||
29101                 error "(8) unexpected barrier status $b_status"
29102
29103         # let above commands to run at background
29104         sleep 5
29105
29106         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29107         ps -p $touch_pid || error "(10) touch should be blocked"
29108         ps -p $ln_pid || error "(11) link should be blocked"
29109         ps -p $mv_pid || error "(12) rename should be blocked"
29110         ps -p $rm_pid || error "(13) unlink should be blocked"
29111
29112         b_status=$(barrier_stat)
29113         [ "$b_status" = "'frozen'" ] ||
29114                 error "(14) unexpected barrier status $b_status"
29115
29116         do_facet mgs $LCTL barrier_thaw $FSNAME
29117         b_status=$(barrier_stat)
29118         [ "$b_status" = "'thawed'" ] ||
29119                 error "(15) unexpected barrier status $b_status"
29120
29121         wait $mkdir_pid || error "(16) mkdir should succeed"
29122         wait $touch_pid || error "(17) touch should succeed"
29123         wait $ln_pid || error "(18) link should succeed"
29124         wait $mv_pid || error "(19) rename should succeed"
29125         wait $rm_pid || error "(20) unlink should succeed"
29126
29127         post_801
29128 }
29129 run_test 801b "modification will be blocked by write barrier"
29130
29131 test_801c() {
29132         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29133
29134         prep_801
29135
29136         stop mds2 || error "(1) Fail to stop mds2"
29137
29138         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29139
29140         local b_status=$(barrier_stat)
29141         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29142                 do_facet mgs $LCTL barrier_thaw $FSNAME
29143                 error "(2) unexpected barrier status $b_status"
29144         }
29145
29146         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29147                 error "(3) Fail to rescan barrier bitmap"
29148
29149         # Do not reduce barrier time - See LU-11873
29150         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29151
29152         b_status=$(barrier_stat)
29153         [ "$b_status" = "'frozen'" ] ||
29154                 error "(4) unexpected barrier status $b_status"
29155
29156         do_facet mgs $LCTL barrier_thaw $FSNAME
29157         b_status=$(barrier_stat)
29158         [ "$b_status" = "'thawed'" ] ||
29159                 error "(5) unexpected barrier status $b_status"
29160
29161         local devname=$(mdsdevname 2)
29162
29163         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29164
29165         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29166                 error "(7) Fail to rescan barrier bitmap"
29167
29168         post_801
29169 }
29170 run_test 801c "rescan barrier bitmap"
29171
29172 test_802b() {
29173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29174         remote_mds_nodsh && skip "remote MDS with nodsh"
29175
29176         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29177                 skip "readonly option not available"
29178
29179         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29180
29181         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29182                 error "(2) Fail to copy"
29183
29184         # write back all cached data before setting MDT to readonly
29185         cancel_lru_locks
29186         sync_all_data
29187
29188         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29189         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29190
29191         echo "Modify should be refused"
29192         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29193
29194         echo "Read should be allowed"
29195         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29196                 error "(7) Read should succeed under ro mode"
29197
29198         # disable readonly
29199         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29200 }
29201 run_test 802b "be able to set MDTs to readonly"
29202
29203 test_803a() {
29204         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29205         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29206                 skip "MDS needs to be newer than 2.10.54"
29207
29208         mkdir_on_mdt0 $DIR/$tdir
29209         # Create some objects on all MDTs to trigger related logs objects
29210         for idx in $(seq $MDSCOUNT); do
29211                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29212                         $DIR/$tdir/dir${idx} ||
29213                         error "Fail to create $DIR/$tdir/dir${idx}"
29214         done
29215
29216         wait_delete_completed # ensure old test cleanups are finished
29217         sleep 3
29218         echo "before create:"
29219         $LFS df -i $MOUNT
29220         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29221
29222         for i in {1..10}; do
29223                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29224                         error "Fail to create $DIR/$tdir/foo$i"
29225         done
29226
29227         # sync ZFS-on-MDS to refresh statfs data
29228         wait_zfs_commit mds1
29229         sleep 3
29230         echo "after create:"
29231         $LFS df -i $MOUNT
29232         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29233
29234         # allow for an llog to be cleaned up during the test
29235         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29236                 error "before ($before_used) + 10 > after ($after_used)"
29237
29238         for i in {1..10}; do
29239                 rm -rf $DIR/$tdir/foo$i ||
29240                         error "Fail to remove $DIR/$tdir/foo$i"
29241         done
29242
29243         # sync ZFS-on-MDS to refresh statfs data
29244         wait_zfs_commit mds1
29245         wait_delete_completed
29246         sleep 3 # avoid MDT return cached statfs
29247         echo "after unlink:"
29248         $LFS df -i $MOUNT
29249         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29250
29251         # allow for an llog to be created during the test
29252         [ $after_used -le $((before_used + 1)) ] ||
29253                 error "after ($after_used) > before ($before_used) + 1"
29254 }
29255 run_test 803a "verify agent object for remote object"
29256
29257 test_803b() {
29258         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29259         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29260                 skip "MDS needs to be newer than 2.13.56"
29261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29262
29263         for i in $(seq 0 $((MDSCOUNT - 1))); do
29264                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29265         done
29266
29267         local before=0
29268         local after=0
29269
29270         local tmp
29271
29272         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29273         for i in $(seq 0 $((MDSCOUNT - 1))); do
29274                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29275                         awk '/getattr/ { print $2 }')
29276                 before=$((before + tmp))
29277         done
29278         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29279         for i in $(seq 0 $((MDSCOUNT - 1))); do
29280                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29281                         awk '/getattr/ { print $2 }')
29282                 after=$((after + tmp))
29283         done
29284
29285         [ $before -eq $after ] || error "getattr count $before != $after"
29286 }
29287 run_test 803b "remote object can getattr from cache"
29288
29289 test_804() {
29290         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29291         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29292                 skip "MDS needs to be newer than 2.10.54"
29293         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29294
29295         mkdir -p $DIR/$tdir
29296         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29297                 error "Fail to create $DIR/$tdir/dir0"
29298
29299         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29300         local dev=$(mdsdevname 2)
29301
29302         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29303                 grep ${fid} || error "NOT found agent entry for dir0"
29304
29305         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29306                 error "Fail to create $DIR/$tdir/dir1"
29307
29308         touch $DIR/$tdir/dir1/foo0 ||
29309                 error "Fail to create $DIR/$tdir/dir1/foo0"
29310         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29311         local rc=0
29312
29313         for idx in $(seq $MDSCOUNT); do
29314                 dev=$(mdsdevname $idx)
29315                 do_facet mds${idx} \
29316                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29317                         grep ${fid} && rc=$idx
29318         done
29319
29320         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29321                 error "Fail to rename foo0 to foo1"
29322         if [ $rc -eq 0 ]; then
29323                 for idx in $(seq $MDSCOUNT); do
29324                         dev=$(mdsdevname $idx)
29325                         do_facet mds${idx} \
29326                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29327                         grep ${fid} && rc=$idx
29328                 done
29329         fi
29330
29331         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29332                 error "Fail to rename foo1 to foo2"
29333         if [ $rc -eq 0 ]; then
29334                 for idx in $(seq $MDSCOUNT); do
29335                         dev=$(mdsdevname $idx)
29336                         do_facet mds${idx} \
29337                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29338                         grep ${fid} && rc=$idx
29339                 done
29340         fi
29341
29342         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29343
29344         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29345                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29346         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29347                 error "Fail to rename foo2 to foo0"
29348         unlink $DIR/$tdir/dir1/foo0 ||
29349                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29350         rm -rf $DIR/$tdir/dir0 ||
29351                 error "Fail to rm $DIR/$tdir/dir0"
29352
29353         for idx in $(seq $MDSCOUNT); do
29354                 rc=0
29355
29356                 stop mds${idx}
29357                 dev=$(mdsdevname $idx)
29358                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29359                         rc=$?
29360                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29361                         error "mount mds$idx failed"
29362                 df $MOUNT > /dev/null 2>&1
29363
29364                 # e2fsck should not return error
29365                 [ $rc -eq 0 ] ||
29366                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29367         done
29368 }
29369 run_test 804 "verify agent entry for remote entry"
29370
29371 cleanup_805() {
29372         do_facet $SINGLEMDS zfs set quota=$old $fsset
29373         unlinkmany $DIR/$tdir/f- 1000000
29374         trap 0
29375 }
29376
29377 test_805() {
29378         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29379         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29380         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29381                 skip "netfree not implemented before 0.7"
29382         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29383                 skip "Need MDS version at least 2.10.57"
29384
29385         local fsset
29386         local freekb
29387         local usedkb
29388         local old
29389         local quota
29390         local pref="osd-zfs.$FSNAME-MDT0000."
29391
29392         # limit available space on MDS dataset to meet nospace issue
29393         # quickly. then ZFS 0.7.2 can use reserved space if asked
29394         # properly (using netfree flag in osd_declare_destroy()
29395         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29396         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29397                 gawk '{print $3}')
29398         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29399         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29400         let "usedkb=usedkb-freekb"
29401         let "freekb=freekb/2"
29402         if let "freekb > 5000"; then
29403                 let "freekb=5000"
29404         fi
29405         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29406         trap cleanup_805 EXIT
29407         mkdir_on_mdt0 $DIR/$tdir
29408         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29409                 error "Can't set PFL layout"
29410         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29411         rm -rf $DIR/$tdir || error "not able to remove"
29412         do_facet $SINGLEMDS zfs set quota=$old $fsset
29413         trap 0
29414 }
29415 run_test 805 "ZFS can remove from full fs"
29416
29417 # Size-on-MDS test
29418 check_lsom_data()
29419 {
29420         local file=$1
29421         local expect=$(stat -c %s $file)
29422
29423         check_lsom_size $1 $expect
29424
29425         local blocks=$($LFS getsom -b $file)
29426         expect=$(stat -c %b $file)
29427         [[ $blocks == $expect ]] ||
29428                 error "$file expected blocks: $expect, got: $blocks"
29429 }
29430
29431 check_lsom_size()
29432 {
29433         local size
29434         local expect=$2
29435
29436         cancel_lru_locks mdc
29437
29438         size=$($LFS getsom -s $1)
29439         [[ $size == $expect ]] ||
29440                 error "$file expected size: $expect, got: $size"
29441 }
29442
29443 test_806() {
29444         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29445                 skip "Need MDS version at least 2.11.52"
29446
29447         local bs=1048576
29448
29449         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29450
29451         disable_opencache
29452         stack_trap "restore_opencache"
29453
29454         # single-threaded write
29455         echo "Test SOM for single-threaded write"
29456         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29457                 error "write $tfile failed"
29458         check_lsom_size $DIR/$tfile $bs
29459
29460         local num=32
29461         local size=$(($num * $bs))
29462         local offset=0
29463         local i
29464
29465         echo "Test SOM for single client multi-threaded($num) write"
29466         $TRUNCATE $DIR/$tfile 0
29467         for ((i = 0; i < $num; i++)); do
29468                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29469                 local pids[$i]=$!
29470                 offset=$((offset + $bs))
29471         done
29472         for (( i=0; i < $num; i++ )); do
29473                 wait ${pids[$i]}
29474         done
29475         check_lsom_size $DIR/$tfile $size
29476
29477         $TRUNCATE $DIR/$tfile 0
29478         for ((i = 0; i < $num; i++)); do
29479                 offset=$((offset - $bs))
29480                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29481                 local pids[$i]=$!
29482         done
29483         for (( i=0; i < $num; i++ )); do
29484                 wait ${pids[$i]}
29485         done
29486         check_lsom_size $DIR/$tfile $size
29487
29488         # multi-client writes
29489         num=$(get_node_count ${CLIENTS//,/ })
29490         size=$(($num * $bs))
29491         offset=0
29492         i=0
29493
29494         echo "Test SOM for multi-client ($num) writes"
29495         $TRUNCATE $DIR/$tfile 0
29496         for client in ${CLIENTS//,/ }; do
29497                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29498                 local pids[$i]=$!
29499                 i=$((i + 1))
29500                 offset=$((offset + $bs))
29501         done
29502         for (( i=0; i < $num; i++ )); do
29503                 wait ${pids[$i]}
29504         done
29505         check_lsom_size $DIR/$tfile $offset
29506
29507         i=0
29508         $TRUNCATE $DIR/$tfile 0
29509         for client in ${CLIENTS//,/ }; do
29510                 offset=$((offset - $bs))
29511                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29512                 local pids[$i]=$!
29513                 i=$((i + 1))
29514         done
29515         for (( i=0; i < $num; i++ )); do
29516                 wait ${pids[$i]}
29517         done
29518         check_lsom_size $DIR/$tfile $size
29519
29520         # verify SOM blocks count
29521         echo "Verify SOM block count"
29522         $TRUNCATE $DIR/$tfile 0
29523         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29524                 error "failed to write file $tfile with fdatasync and fstat"
29525         check_lsom_data $DIR/$tfile
29526
29527         $TRUNCATE $DIR/$tfile 0
29528         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29529                 error "failed to write file $tfile with fdatasync"
29530         check_lsom_data $DIR/$tfile
29531
29532         $TRUNCATE $DIR/$tfile 0
29533         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29534                 error "failed to write file $tfile with sync IO"
29535         check_lsom_data $DIR/$tfile
29536
29537         # verify truncate
29538         echo "Test SOM for truncate"
29539         # use ftruncate to sync blocks on close request
29540         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29541         check_lsom_size $DIR/$tfile 16384
29542         check_lsom_data $DIR/$tfile
29543
29544         $TRUNCATE $DIR/$tfile 1234
29545         check_lsom_size $DIR/$tfile 1234
29546         # sync blocks on the MDT
29547         $MULTIOP $DIR/$tfile oc
29548         check_lsom_data $DIR/$tfile
29549 }
29550 run_test 806 "Verify Lazy Size on MDS"
29551
29552 test_807() {
29553         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29555                 skip "Need MDS version at least 2.11.52"
29556
29557         # Registration step
29558         changelog_register || error "changelog_register failed"
29559         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29560         changelog_users $SINGLEMDS | grep -q $cl_user ||
29561                 error "User $cl_user not found in changelog_users"
29562
29563         rm -rf $DIR/$tdir || error "rm $tdir failed"
29564         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29565         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29566         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29567         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29568                 error "truncate $tdir/trunc failed"
29569
29570         local bs=1048576
29571         echo "Test SOM for single-threaded write with fsync"
29572         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29573                 error "write $tfile failed"
29574         sync;sync;sync
29575
29576         # multi-client wirtes
29577         local num=$(get_node_count ${CLIENTS//,/ })
29578         local offset=0
29579         local i=0
29580
29581         echo "Test SOM for multi-client ($num) writes"
29582         touch $DIR/$tfile || error "touch $tfile failed"
29583         $TRUNCATE $DIR/$tfile 0
29584         for client in ${CLIENTS//,/ }; do
29585                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29586                 local pids[$i]=$!
29587                 i=$((i + 1))
29588                 offset=$((offset + $bs))
29589         done
29590         for (( i=0; i < $num; i++ )); do
29591                 wait ${pids[$i]}
29592         done
29593
29594         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29595         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29596         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29597         check_lsom_data $DIR/$tdir/trunc
29598         check_lsom_data $DIR/$tdir/single_dd
29599         check_lsom_data $DIR/$tfile
29600
29601         rm -rf $DIR/$tdir
29602         # Deregistration step
29603         changelog_deregister || error "changelog_deregister failed"
29604 }
29605 run_test 807 "verify LSOM syncing tool"
29606
29607 check_som_nologged()
29608 {
29609         local lines=$($LFS changelog $FSNAME-MDT0000 |
29610                 grep 'x=trusted.som' | wc -l)
29611         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29612 }
29613
29614 test_808() {
29615         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29616                 skip "Need MDS version at least 2.11.55"
29617
29618         # Registration step
29619         changelog_register || error "changelog_register failed"
29620
29621         touch $DIR/$tfile || error "touch $tfile failed"
29622         check_som_nologged
29623
29624         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29625                 error "write $tfile failed"
29626         check_som_nologged
29627
29628         $TRUNCATE $DIR/$tfile 1234
29629         check_som_nologged
29630
29631         $TRUNCATE $DIR/$tfile 1048576
29632         check_som_nologged
29633
29634         # Deregistration step
29635         changelog_deregister || error "changelog_deregister failed"
29636 }
29637 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29638
29639 check_som_nodata()
29640 {
29641         $LFS getsom $1
29642         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29643 }
29644
29645 test_809() {
29646         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29647                 skip "Need MDS version at least 2.11.56"
29648
29649         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29650                 error "failed to create DoM-only file $DIR/$tfile"
29651         touch $DIR/$tfile || error "touch $tfile failed"
29652         check_som_nodata $DIR/$tfile
29653
29654         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29655                 error "write $tfile failed"
29656         check_som_nodata $DIR/$tfile
29657
29658         $TRUNCATE $DIR/$tfile 1234
29659         check_som_nodata $DIR/$tfile
29660
29661         $TRUNCATE $DIR/$tfile 4097
29662         check_som_nodata $DIR/$file
29663 }
29664 run_test 809 "Verify no SOM xattr store for DoM-only files"
29665
29666 test_810() {
29667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29668         $GSS && skip_env "could not run with gss"
29669         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29670                 skip "OST < 2.12.58 doesn't align checksum"
29671
29672         set_checksums 1
29673         stack_trap "set_checksums $ORIG_CSUM" EXIT
29674         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29675
29676         local csum
29677         local before
29678         local after
29679         for csum in $CKSUM_TYPES; do
29680                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29681                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29682                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29683                         eval set -- $i
29684                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29685                         before=$(md5sum $DIR/$tfile)
29686                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29687                         after=$(md5sum $DIR/$tfile)
29688                         [ "$before" == "$after" ] ||
29689                                 error "$csum: $before != $after bs=$1 seek=$2"
29690                 done
29691         done
29692 }
29693 run_test 810 "partial page writes on ZFS (LU-11663)"
29694
29695 test_812a() {
29696         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29697                 skip "OST < 2.12.51 doesn't support this fail_loc"
29698
29699         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29700         # ensure ost1 is connected
29701         stat $DIR/$tfile >/dev/null || error "can't stat"
29702         wait_osc_import_state client ost1 FULL
29703         # no locks, no reqs to let the connection idle
29704         cancel_lru_locks osc
29705
29706         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29707 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29708         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29709         wait_osc_import_state client ost1 CONNECTING
29710         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29711
29712         stat $DIR/$tfile >/dev/null || error "can't stat file"
29713 }
29714 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29715
29716 test_812b() { # LU-12378
29717         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29718                 skip "OST < 2.12.51 doesn't support this fail_loc"
29719
29720         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29721         # ensure ost1 is connected
29722         stat $DIR/$tfile >/dev/null || error "can't stat"
29723         wait_osc_import_state client ost1 FULL
29724         # no locks, no reqs to let the connection idle
29725         cancel_lru_locks osc
29726
29727         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29728 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29729         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29730         wait_osc_import_state client ost1 CONNECTING
29731         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29732
29733         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29734         wait_osc_import_state client ost1 IDLE
29735 }
29736 run_test 812b "do not drop no resend request for idle connect"
29737
29738 test_812c() {
29739         local old
29740
29741         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29742
29743         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29744         $LFS getstripe $DIR/$tfile
29745         $LCTL set_param osc.*.idle_timeout=10
29746         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29747         # ensure ost1 is connected
29748         stat $DIR/$tfile >/dev/null || error "can't stat"
29749         wait_osc_import_state client ost1 FULL
29750         # no locks, no reqs to let the connection idle
29751         cancel_lru_locks osc
29752
29753 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29754         $LCTL set_param fail_loc=0x80000533
29755         sleep 15
29756         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29757 }
29758 run_test 812c "idle import vs lock enqueue race"
29759
29760 test_813() {
29761         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29762         [ -z "$file_heat_sav" ] && skip "no file heat support"
29763
29764         local readsample
29765         local writesample
29766         local readbyte
29767         local writebyte
29768         local readsample1
29769         local writesample1
29770         local readbyte1
29771         local writebyte1
29772
29773         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29774         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29775
29776         $LCTL set_param -n llite.*.file_heat=1
29777         echo "Turn on file heat"
29778         echo "Period second: $period_second, Decay percentage: $decay_pct"
29779
29780         echo "QQQQ" > $DIR/$tfile
29781         echo "QQQQ" > $DIR/$tfile
29782         echo "QQQQ" > $DIR/$tfile
29783         cat $DIR/$tfile > /dev/null
29784         cat $DIR/$tfile > /dev/null
29785         cat $DIR/$tfile > /dev/null
29786         cat $DIR/$tfile > /dev/null
29787
29788         local out=$($LFS heat_get $DIR/$tfile)
29789
29790         $LFS heat_get $DIR/$tfile
29791         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29792         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29793         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29794         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29795
29796         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29797         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29798         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29799         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29800
29801         sleep $((period_second + 3))
29802         echo "Sleep $((period_second + 3)) seconds..."
29803         # The recursion formula to calculate the heat of the file f is as
29804         # follow:
29805         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29806         # Where Hi is the heat value in the period between time points i*I and
29807         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29808         # to the weight of Ci.
29809         out=$($LFS heat_get $DIR/$tfile)
29810         $LFS heat_get $DIR/$tfile
29811         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29812         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29813         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29814         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29815
29816         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29817                 error "read sample ($readsample) is wrong"
29818         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29819                 error "write sample ($writesample) is wrong"
29820         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29821                 error "read bytes ($readbyte) is wrong"
29822         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29823                 error "write bytes ($writebyte) is wrong"
29824
29825         echo "QQQQ" > $DIR/$tfile
29826         echo "QQQQ" > $DIR/$tfile
29827         echo "QQQQ" > $DIR/$tfile
29828         cat $DIR/$tfile > /dev/null
29829         cat $DIR/$tfile > /dev/null
29830         cat $DIR/$tfile > /dev/null
29831         cat $DIR/$tfile > /dev/null
29832
29833         sleep $((period_second + 3))
29834         echo "Sleep $((period_second + 3)) seconds..."
29835
29836         out=$($LFS heat_get $DIR/$tfile)
29837         $LFS heat_get $DIR/$tfile
29838         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29839         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29840         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29841         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29842
29843         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29844                 4 * $decay_pct) / 100") -eq 1 ] ||
29845                 error "read sample ($readsample1) is wrong"
29846         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29847                 3 * $decay_pct) / 100") -eq 1 ] ||
29848                 error "write sample ($writesample1) is wrong"
29849         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29850                 20 * $decay_pct) / 100") -eq 1 ] ||
29851                 error "read bytes ($readbyte1) is wrong"
29852         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29853                 15 * $decay_pct) / 100") -eq 1 ] ||
29854                 error "write bytes ($writebyte1) is wrong"
29855
29856         echo "Turn off file heat for the file $DIR/$tfile"
29857         $LFS heat_set -o $DIR/$tfile
29858
29859         echo "QQQQ" > $DIR/$tfile
29860         echo "QQQQ" > $DIR/$tfile
29861         echo "QQQQ" > $DIR/$tfile
29862         cat $DIR/$tfile > /dev/null
29863         cat $DIR/$tfile > /dev/null
29864         cat $DIR/$tfile > /dev/null
29865         cat $DIR/$tfile > /dev/null
29866
29867         out=$($LFS heat_get $DIR/$tfile)
29868         $LFS heat_get $DIR/$tfile
29869         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29870         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29871         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29872         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29873
29874         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29875         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29876         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29877         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29878
29879         echo "Trun on file heat for the file $DIR/$tfile"
29880         $LFS heat_set -O $DIR/$tfile
29881
29882         echo "QQQQ" > $DIR/$tfile
29883         echo "QQQQ" > $DIR/$tfile
29884         echo "QQQQ" > $DIR/$tfile
29885         cat $DIR/$tfile > /dev/null
29886         cat $DIR/$tfile > /dev/null
29887         cat $DIR/$tfile > /dev/null
29888         cat $DIR/$tfile > /dev/null
29889
29890         out=$($LFS heat_get $DIR/$tfile)
29891         $LFS heat_get $DIR/$tfile
29892         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29893         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29894         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29895         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29896
29897         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29898         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29899         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29900         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29901
29902         $LFS heat_set -c $DIR/$tfile
29903         $LCTL set_param -n llite.*.file_heat=0
29904         echo "Turn off file heat support for the Lustre filesystem"
29905
29906         echo "QQQQ" > $DIR/$tfile
29907         echo "QQQQ" > $DIR/$tfile
29908         echo "QQQQ" > $DIR/$tfile
29909         cat $DIR/$tfile > /dev/null
29910         cat $DIR/$tfile > /dev/null
29911         cat $DIR/$tfile > /dev/null
29912         cat $DIR/$tfile > /dev/null
29913
29914         out=$($LFS heat_get $DIR/$tfile)
29915         $LFS heat_get $DIR/$tfile
29916         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29917         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29918         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29919         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29920
29921         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29922         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29923         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29924         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29925
29926         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29927         rm -f $DIR/$tfile
29928 }
29929 run_test 813 "File heat verfication"
29930
29931 test_814()
29932 {
29933         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29934         echo -n y >> $DIR/$tfile
29935         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29936         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29937 }
29938 run_test 814 "sparse cp works as expected (LU-12361)"
29939
29940 test_815()
29941 {
29942         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29943         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29944 }
29945 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29946
29947 test_816() {
29948         local ost1_imp=$(get_osc_import_name client ost1)
29949         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29950                          cut -d'.' -f2)
29951
29952         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29953         # ensure ost1 is connected
29954
29955         stat $DIR/$tfile >/dev/null || error "can't stat"
29956         wait_osc_import_state client ost1 FULL
29957         # no locks, no reqs to let the connection idle
29958         cancel_lru_locks osc
29959         lru_resize_disable osc
29960         local before
29961         local now
29962         before=$($LCTL get_param -n \
29963                  ldlm.namespaces.$imp_name.lru_size)
29964
29965         wait_osc_import_state client ost1 IDLE
29966         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29967         now=$($LCTL get_param -n \
29968               ldlm.namespaces.$imp_name.lru_size)
29969         [ $before == $now ] || error "lru_size changed $before != $now"
29970 }
29971 run_test 816 "do not reset lru_resize on idle reconnect"
29972
29973 cleanup_817() {
29974         umount $tmpdir
29975         exportfs -u localhost:$DIR/nfsexp
29976         rm -rf $DIR/nfsexp
29977 }
29978
29979 test_817() {
29980         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29981
29982         mkdir -p $DIR/nfsexp
29983         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29984                 error "failed to export nfs"
29985
29986         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29987         stack_trap cleanup_817 EXIT
29988
29989         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29990                 error "failed to mount nfs to $tmpdir"
29991
29992         cp /bin/true $tmpdir
29993         $DIR/nfsexp/true || error "failed to execute 'true' command"
29994 }
29995 run_test 817 "nfsd won't cache write lock for exec file"
29996
29997 test_818() {
29998         test_mkdir -i0 -c1 $DIR/$tdir
29999         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30000         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30001         stop $SINGLEMDS
30002
30003         # restore osp-syn threads
30004         stack_trap "fail $SINGLEMDS"
30005
30006         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30007         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30008         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30009                 error "start $SINGLEMDS failed"
30010         rm -rf $DIR/$tdir
30011
30012         local testid=$(echo $TESTNAME | tr '_' ' ')
30013
30014         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30015                 grep "run LFSCK" || error "run LFSCK is not suggested"
30016 }
30017 run_test 818 "unlink with failed llog"
30018
30019 test_819a() {
30020         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30021         cancel_lru_locks osc
30022         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30023         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30024         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30025         rm -f $TDIR/$tfile
30026 }
30027 run_test 819a "too big niobuf in read"
30028
30029 test_819b() {
30030         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30031         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30032         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30033         cancel_lru_locks osc
30034         sleep 1
30035         rm -f $TDIR/$tfile
30036 }
30037 run_test 819b "too big niobuf in write"
30038
30039
30040 function test_820_start_ost() {
30041         sleep 5
30042
30043         for num in $(seq $OSTCOUNT); do
30044                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30045         done
30046 }
30047
30048 test_820() {
30049         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30050
30051         mkdir $DIR/$tdir
30052         umount_client $MOUNT || error "umount failed"
30053         for num in $(seq $OSTCOUNT); do
30054                 stop ost$num
30055         done
30056
30057         # mount client with no active OSTs
30058         # so that the client can't initialize max LOV EA size
30059         # from OSC notifications
30060         mount_client $MOUNT || error "mount failed"
30061         # delay OST starting to keep this 0 max EA size for a while
30062         test_820_start_ost &
30063
30064         # create a directory on MDS2
30065         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30066                 error "Failed to create directory"
30067         # open intent should update default EA size
30068         # see mdc_update_max_ea_from_body()
30069         # notice this is the very first RPC to MDS2
30070         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30071         ret=$?
30072         echo $out
30073         # With SSK, this situation can lead to -EPERM being returned.
30074         # In that case, simply retry.
30075         if [ $ret -ne 0 ] && $SHARED_KEY; then
30076                 if echo "$out" | grep -q "not permitted"; then
30077                         cp /etc/services $DIR/$tdir/mds2
30078                         ret=$?
30079                 fi
30080         fi
30081         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30082 }
30083 run_test 820 "update max EA from open intent"
30084
30085 test_823() {
30086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30087         local OST_MAX_PRECREATE=20000
30088
30089         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30090                 skip "Need MDS version at least 2.14.56"
30091
30092         save_lustre_params mds1 \
30093                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30094         do_facet $SINGLEMDS "$LCTL set_param -n \
30095                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30096         do_facet $SINGLEMDS "$LCTL set_param -n \
30097                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30098
30099         stack_trap "restore_lustre_params < $p; rm $p"
30100
30101         do_facet $SINGLEMDS "$LCTL set_param -n \
30102                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30103
30104         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30105                       osp.$FSNAME-OST0000*MDT0000.create_count")
30106         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30107                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30108         local expect_count=$(((($max/2)/256) * 256))
30109
30110         log "setting create_count to 100200:"
30111         log " -result- count: $count with max: $max, expecting: $expect_count"
30112
30113         [[ $count -eq expect_count ]] ||
30114                 error "Create count not set to max precreate."
30115 }
30116 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30117
30118 test_831() {
30119         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30120                 skip "Need MDS version 2.14.56"
30121
30122         local sync_changes=$(do_facet $SINGLEMDS \
30123                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30124
30125         [ "$sync_changes" -gt 100 ] &&
30126                 skip "Sync changes $sync_changes > 100 already"
30127
30128         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30129
30130         $LFS mkdir -i 0 $DIR/$tdir
30131         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30132
30133         save_lustre_params mds1 \
30134                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30135         save_lustre_params mds1 \
30136                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30137
30138         do_facet mds1 "$LCTL set_param -n \
30139                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30140                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30141         stack_trap "restore_lustre_params < $p" EXIT
30142
30143         createmany -o $DIR/$tdir/f- 1000
30144         unlinkmany $DIR/$tdir/f- 1000 &
30145         local UNLINK_PID=$!
30146
30147         while sleep 1; do
30148                 sync_changes=$(do_facet mds1 \
30149                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30150                 # the check in the code is racy, fail the test
30151                 # if the value above the limit by 10.
30152                 [ $sync_changes -gt 110 ] && {
30153                         kill -2 $UNLINK_PID
30154                         wait
30155                         error "osp changes throttling failed, $sync_changes>110"
30156                 }
30157                 kill -0 $UNLINK_PID 2> /dev/null || break
30158         done
30159         wait
30160 }
30161 run_test 831 "throttling unlink/setattr queuing on OSP"
30162
30163 test_832() {
30164         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30165         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30166                 skip "Need MDS version 2.15.52+"
30167         is_rmentry_supported || skip "rm_entry not supported"
30168
30169         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30170         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30171         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30172                 error "mkdir remote_dir failed"
30173         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30174                 error "mkdir striped_dir failed"
30175         touch $DIR/$tdir/file || error "touch file failed"
30176         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30177         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30178 }
30179 run_test 832 "lfs rm_entry"
30180
30181 test_833() {
30182         local file=$DIR/$tfile
30183
30184         stack_trap "rm -f $file" EXIT
30185         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30186
30187         local wpid
30188         local rpid
30189         local rpid2
30190
30191         # Buffered I/O write
30192         (
30193                 while [ ! -e $DIR/sanity.833.lck ]; do
30194                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30195                                 error "failed to write $file"
30196                         sleep 0.$((RANDOM % 4 + 1))
30197                 done
30198         )&
30199         wpid=$!
30200
30201         # Buffered I/O read
30202         (
30203                 while [ ! -e $DIR/sanity.833.lck ]; do
30204                         dd if=$file of=/dev/null bs=1M count=50 ||
30205                                 error "failed to read $file"
30206                         sleep 0.$((RANDOM % 4 + 1))
30207                 done
30208         )&
30209         rpid=$!
30210
30211         # Direct I/O read
30212         (
30213                 while [ ! -e $DIR/sanity.833.lck ]; do
30214                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30215                                 error "failed to read $file in direct I/O mode"
30216                         sleep 0.$((RANDOM % 4 + 1))
30217                 done
30218         )&
30219         rpid2=$!
30220
30221         sleep 30
30222         touch $DIR/sanity.833.lck
30223         wait $wpid || error "$?: buffered write failed"
30224         wait $rpid || error "$?: buffered read failed"
30225         wait $rpid2 || error "$?: direct read failed"
30226 }
30227 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30228
30229 #
30230 # tests that do cleanup/setup should be run at the end
30231 #
30232
30233 test_900() {
30234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30235         local ls
30236
30237         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30238         $LCTL set_param fail_loc=0x903
30239
30240         cancel_lru_locks MGC
30241
30242         FAIL_ON_ERROR=true cleanup
30243         FAIL_ON_ERROR=true setup
30244 }
30245 run_test 900 "umount should not race with any mgc requeue thread"
30246
30247 # LUS-6253/LU-11185
30248 test_901() {
30249         local old
30250         local count
30251         local oldc
30252         local newc
30253         local olds
30254         local news
30255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30256
30257         # some get_param have a bug to handle dot in param name
30258         cancel_lru_locks MGC
30259         old=$(mount -t lustre | wc -l)
30260         # 1 config+sptlrpc
30261         # 2 params
30262         # 3 nodemap
30263         # 4 IR
30264         old=$((old * 4))
30265         oldc=0
30266         count=0
30267         while [ $old -ne $oldc ]; do
30268                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30269                 sleep 1
30270                 ((count++))
30271                 if [ $count -ge $TIMEOUT ]; then
30272                         error "too large timeout"
30273                 fi
30274         done
30275         umount_client $MOUNT || error "umount failed"
30276         mount_client $MOUNT || error "mount failed"
30277         cancel_lru_locks MGC
30278         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30279
30280         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30281
30282         return 0
30283 }
30284 run_test 901 "don't leak a mgc lock on client umount"
30285
30286 # LU-13377
30287 test_902() {
30288         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30289                 skip "client does not have LU-13377 fix"
30290         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30291         $LCTL set_param fail_loc=0x1415
30292         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30293         cancel_lru_locks osc
30294         rm -f $DIR/$tfile
30295 }
30296 run_test 902 "test short write doesn't hang lustre"
30297
30298 # LU-14711
30299 test_903() {
30300         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30301         echo "blah" > $DIR/${tfile}-2
30302         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30303         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30304         $LCTL set_param fail_loc=0x417 fail_val=20
30305
30306         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30307         sleep 1 # To start the destroy
30308         wait_destroy_complete 150 || error "Destroy taking too long"
30309         cat $DIR/$tfile > /dev/null || error "Evicted"
30310 }
30311 run_test 903 "Test long page discard does not cause evictions"
30312
30313 test_904() {
30314         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30315         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30316                 grep -q project || skip "skip project quota not supported"
30317
30318         local testfile="$DIR/$tdir/$tfile"
30319         local xattr="trusted.projid"
30320         local projid
30321         local mdts=$(comma_list $(mdts_nodes))
30322         local saved=$(do_facet mds1 $LCTL get_param -n \
30323                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30324
30325         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30326         stack_trap "do_nodes $mdts $LCTL set_param \
30327                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30328
30329         mkdir -p $DIR/$tdir
30330         touch $testfile
30331         #hide projid xattr on server
30332         $LFS project -p 1 $testfile ||
30333                 error "set $testfile project id failed"
30334         getfattr -m - $testfile | grep $xattr &&
30335                 error "do not show trusted.projid when disabled on server"
30336         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30337         #should be hidden when projid is 0
30338         $LFS project -p 0 $testfile ||
30339                 error "set $testfile project id failed"
30340         getfattr -m - $testfile | grep $xattr &&
30341                 error "do not show trusted.projid with project ID 0"
30342
30343         #still can getxattr explicitly
30344         projid=$(getfattr -n $xattr $testfile |
30345                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30346         [ $projid == "0" ] ||
30347                 error "projid expected 0 not $projid"
30348
30349         #set the projid via setxattr
30350         setfattr -n $xattr -v "1000" $testfile ||
30351                 error "setattr failed with $?"
30352         projid=($($LFS project $testfile))
30353         [ ${projid[0]} == "1000" ] ||
30354                 error "projid expected 1000 not $projid"
30355
30356         #check the new projid via getxattr
30357         $LFS project -p 1001 $testfile ||
30358                 error "set $testfile project id failed"
30359         getfattr -m - $testfile | grep $xattr ||
30360                 error "should show trusted.projid when project ID != 0"
30361         projid=$(getfattr -n $xattr $testfile |
30362                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30363         [ $projid == "1001" ] ||
30364                 error "projid expected 1001 not $projid"
30365
30366         #try to set invalid projid
30367         setfattr -n $xattr -v "4294967295" $testfile &&
30368                 error "set invalid projid should fail"
30369
30370         #remove the xattr means setting projid to 0
30371         setfattr -x $xattr $testfile ||
30372                 error "setfattr failed with $?"
30373         projid=($($LFS project $testfile))
30374         [ ${projid[0]} == "0" ] ||
30375                 error "projid expected 0 not $projid"
30376
30377         #should be hidden when parent has inherit flag and same projid
30378         $LFS project -srp 1002 $DIR/$tdir ||
30379                 error "set $tdir project id failed"
30380         getfattr -m - $testfile | grep $xattr &&
30381                 error "do not show trusted.projid with inherit flag"
30382
30383         #still can getxattr explicitly
30384         projid=$(getfattr -n $xattr $testfile |
30385                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30386         [ $projid == "1002" ] ||
30387                 error "projid expected 1002 not $projid"
30388 }
30389 run_test 904 "virtual project ID xattr"
30390
30391 # LU-8582
30392 test_905() {
30393         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30394                 skip "need OST version >= 2.15.50.220 for fail_loc"
30395
30396         remote_ost_nodsh && skip "remote OST with nodsh"
30397         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30398
30399         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30400
30401         #define OBD_FAIL_OST_OPCODE 0x253
30402         # OST_LADVISE = 21
30403         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30404         $LFS ladvise -a willread $DIR/$tfile &&
30405                 error "unexpected success of ladvise with fault injection"
30406         $LFS ladvise -a willread $DIR/$tfile |&
30407                 grep -q "Operation not supported"
30408         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30409 }
30410 run_test 905 "bad or new opcode should not stuck client"
30411
30412 test_906() {
30413         grep -q io_uring_setup /proc/kallsyms ||
30414                 skip "Client OS does not support io_uring I/O engine"
30415         io_uring_probe || skip "kernel does not support io_uring fully"
30416         which fio || skip_env "no fio installed"
30417         fio --enghelp | grep -q io_uring ||
30418                 skip_env "fio does not support io_uring I/O engine"
30419
30420         local file=$DIR/$tfile
30421         local ioengine="io_uring"
30422         local numjobs=2
30423         local size=50M
30424
30425         fio --name=seqwrite --ioengine=$ioengine        \
30426                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30427                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30428                 error "fio seqwrite $file failed"
30429
30430         fio --name=seqread --ioengine=$ioengine \
30431                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30432                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30433                 error "fio seqread $file failed"
30434
30435         rm -f $file || error "rm -f $file failed"
30436 }
30437 run_test 906 "Simple test for io_uring I/O engine via fio"
30438
30439 complete_test $SECONDS
30440 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30441 check_and_cleanup_lustre
30442 if [ "$I_MOUNTED" != "yes" ]; then
30443         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30444 fi
30445 exit_status