Whamcloud - gitweb
LU-16374 enc: rename O_FILE_ENC to O_CIPHERTEXT
[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
14246         test_mkdir $DIR/$tdir
14247         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14248         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14249                 error "setfacl $DIR/$tdir failed"
14250         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14251 }
14252 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14253
14254 test_126() { # bug 12829/13455
14255         $GSS && skip_env "must run as gss disabled"
14256         $LCTL get_param -n llite.*.client_type | grep -q local ||
14257                 skip "must run as local client"
14258         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14259
14260         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14261         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14262         rm -f $DIR/$tfile
14263         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14264 }
14265 run_test 126 "check that the fsgid provided by the client is taken into account"
14266
14267 test_127a() { # bug 15521
14268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14269         local name count samp unit min max sum sumsq
14270         local tmpfile=$TMP/$tfile.tmp
14271
14272         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14273         echo "stats before reset"
14274         stack_trap "rm -f $tmpfile"
14275         local now=$(date +%s)
14276
14277         $LCTL get_param osc.*.stats | tee $tmpfile
14278
14279         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14280         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14281         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14282         local uptime=$(awk '{ print $1 }' /proc/uptime)
14283
14284         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14285         (( ${snapshot_time%\.*} >= $now - 5 &&
14286            ${snapshot_time%\.*} <= $now + 5 )) ||
14287                 error "snapshot_time=$snapshot_time != now=$now"
14288         # elapsed _should_ be from mount, but at least less than uptime
14289         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14290                 error "elapsed=$elapsed > uptime=$uptime"
14291         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14292            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14293                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14294
14295         $LCTL set_param osc.*.stats=0
14296         local reset=$(date +%s)
14297         local fsize=$((2048 * 1024))
14298
14299         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14300         cancel_lru_locks osc
14301         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14302
14303         now=$(date +%s)
14304         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14305         while read name count samp unit min max sum sumsq; do
14306                 [[ "$samp" == "samples" ]] || continue
14307
14308                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14309                 [ ! $min ] && error "Missing min value for $name proc entry"
14310                 eval $name=$count || error "Wrong proc format"
14311
14312                 case $name in
14313                 read_bytes|write_bytes)
14314                         [[ "$unit" =~ "bytes" ]] ||
14315                                 error "unit is not 'bytes': $unit"
14316                         (( $min >= 4096 )) || error "min is too small: $min"
14317                         (( $min <= $fsize )) || error "min is too big: $min"
14318                         (( $max >= 4096 )) || error "max is too small: $max"
14319                         (( $max <= $fsize )) || error "max is too big: $max"
14320                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14321                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14322                                 error "sumsquare is too small: $sumsq"
14323                         (( $sumsq <= $fsize * $fsize )) ||
14324                                 error "sumsquare is too big: $sumsq"
14325                         ;;
14326                 ost_read|ost_write)
14327                         [[ "$unit" =~ "usec" ]] ||
14328                                 error "unit is not 'usec': $unit"
14329                         ;;
14330                 *)      ;;
14331                 esac
14332         done < $tmpfile
14333
14334         #check that we actually got some stats
14335         [ "$read_bytes" ] || error "Missing read_bytes stats"
14336         [ "$write_bytes" ] || error "Missing write_bytes stats"
14337         [ "$read_bytes" != 0 ] || error "no read done"
14338         [ "$write_bytes" != 0 ] || error "no write done"
14339
14340         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14341         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14342         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14343
14344         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14345         (( ${snapshot_time%\.*} >= $now - 5 &&
14346            ${snapshot_time%\.*} <= $now + 5 )) ||
14347                 error "reset snapshot_time=$snapshot_time != now=$now"
14348         # elapsed should be from time of stats reset
14349         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14350            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14351                 error "reset elapsed=$elapsed > $now - $reset"
14352         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14353            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14354                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14355 }
14356 run_test 127a "verify the client stats are sane"
14357
14358 test_127b() { # bug LU-333
14359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14360         local name count samp unit min max sum sumsq
14361
14362         echo "stats before reset"
14363         $LCTL get_param llite.*.stats
14364         $LCTL set_param llite.*.stats=0
14365
14366         # perform 2 reads and writes so MAX is different from SUM.
14367         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14368         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14369         cancel_lru_locks osc
14370         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14371         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14372
14373         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14374         stack_trap "rm -f $TMP/$tfile.tmp"
14375         while read name count samp unit min max sum sumsq; do
14376                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14377                 eval $name=$count || error "Wrong proc format"
14378
14379                 case $name in
14380                 read_bytes|write_bytes)
14381                         [[ "$unit" =~ "bytes" ]] ||
14382                                 error "unit is not 'bytes': $unit"
14383                         (( $count == 2 )) || error "count is not 2: $count"
14384                         (( $min == $PAGE_SIZE )) ||
14385                                 error "min is not $PAGE_SIZE: $min"
14386                         (( $max == $PAGE_SIZE )) ||
14387                                 error "max is not $PAGE_SIZE: $max"
14388                         (( $sum == $PAGE_SIZE * 2 )) ||
14389                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14390                         ;;
14391                 read|write)
14392                         [[ "$unit" =~ "usec" ]] ||
14393                                 error "unit is not 'usec': $unit"
14394                         ;;
14395                 *)      ;;
14396                 esac
14397         done < $TMP/$tfile.tmp
14398
14399         #check that we actually got some stats
14400         [ "$read_bytes" ] || error "Missing read_bytes stats"
14401         [ "$write_bytes" ] || error "Missing write_bytes stats"
14402         [ "$read_bytes" != 0 ] || error "no read done"
14403         [ "$write_bytes" != 0 ] || error "no write done"
14404 }
14405 run_test 127b "verify the llite client stats are sane"
14406
14407 test_127c() { # LU-12394
14408         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14409         local size
14410         local bsize
14411         local reads
14412         local writes
14413         local count
14414
14415         $LCTL set_param llite.*.extents_stats=1
14416         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14417
14418         # Use two stripes so there is enough space in default config
14419         $LFS setstripe -c 2 $DIR/$tfile
14420
14421         # Extent stats start at 0-4K and go in power of two buckets
14422         # LL_HIST_START = 12 --> 2^12 = 4K
14423         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14424         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14425         # small configs
14426         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14427                 do
14428                 # Write and read, 2x each, second time at a non-zero offset
14429                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14430                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14431                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14432                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14433                 rm -f $DIR/$tfile
14434         done
14435
14436         $LCTL get_param llite.*.extents_stats
14437
14438         count=2
14439         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14440                 do
14441                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14442                                 grep -m 1 $bsize)
14443                 reads=$(echo $bucket | awk '{print $5}')
14444                 writes=$(echo $bucket | awk '{print $9}')
14445                 [ "$reads" -eq $count ] ||
14446                         error "$reads reads in < $bsize bucket, expect $count"
14447                 [ "$writes" -eq $count ] ||
14448                         error "$writes writes in < $bsize bucket, expect $count"
14449         done
14450
14451         # Test mmap write and read
14452         $LCTL set_param llite.*.extents_stats=c
14453         size=512
14454         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14455         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14456         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14457
14458         $LCTL get_param llite.*.extents_stats
14459
14460         count=$(((size*1024) / PAGE_SIZE))
14461
14462         bsize=$((2 * PAGE_SIZE / 1024))K
14463
14464         bucket=$($LCTL get_param -n llite.*.extents_stats |
14465                         grep -m 1 $bsize)
14466         reads=$(echo $bucket | awk '{print $5}')
14467         writes=$(echo $bucket | awk '{print $9}')
14468         # mmap writes fault in the page first, creating an additonal read
14469         [ "$reads" -eq $((2 * count)) ] ||
14470                 error "$reads reads in < $bsize bucket, expect $count"
14471         [ "$writes" -eq $count ] ||
14472                 error "$writes writes in < $bsize bucket, expect $count"
14473 }
14474 run_test 127c "test llite extent stats with regular & mmap i/o"
14475
14476 test_128() { # bug 15212
14477         touch $DIR/$tfile
14478         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14479                 find $DIR/$tfile
14480                 find $DIR/$tfile
14481         EOF
14482
14483         result=$(grep error $TMP/$tfile.log)
14484         rm -f $DIR/$tfile $TMP/$tfile.log
14485         [ -z "$result" ] ||
14486                 error "consecutive find's under interactive lfs failed"
14487 }
14488 run_test 128 "interactive lfs for 2 consecutive find's"
14489
14490 set_dir_limits () {
14491         local mntdev
14492         local canondev
14493         local node
14494
14495         local ldproc=/proc/fs/ldiskfs
14496         local facets=$(get_facets MDS)
14497
14498         for facet in ${facets//,/ }; do
14499                 canondev=$(ldiskfs_canon \
14500                            *.$(convert_facet2label $facet).mntdev $facet)
14501                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14502                         ldproc=/sys/fs/ldiskfs
14503                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14504                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14505         done
14506 }
14507
14508 check_mds_dmesg() {
14509         local facets=$(get_facets MDS)
14510         for facet in ${facets//,/ }; do
14511                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14512         done
14513         return 1
14514 }
14515
14516 test_129() {
14517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14518         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14519                 skip "Need MDS version with at least 2.5.56"
14520         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14521                 skip_env "ldiskfs only test"
14522         fi
14523         remote_mds_nodsh && skip "remote MDS with nodsh"
14524
14525         local ENOSPC=28
14526         local has_warning=false
14527
14528         rm -rf $DIR/$tdir
14529         mkdir -p $DIR/$tdir
14530
14531         # block size of mds1
14532         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14533         set_dir_limits $maxsize $((maxsize * 6 / 8))
14534         stack_trap "set_dir_limits 0 0"
14535         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14536         local dirsize=$(stat -c%s "$DIR/$tdir")
14537         local nfiles=0
14538         while (( $dirsize <= $maxsize )); do
14539                 $MCREATE $DIR/$tdir/file_base_$nfiles
14540                 rc=$?
14541                 # check two errors:
14542                 # ENOSPC for ext4 max_dir_size, which has been used since
14543                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14544                 if (( rc == ENOSPC )); then
14545                         set_dir_limits 0 0
14546                         echo "rc=$rc returned as expected after $nfiles files"
14547
14548                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14549                                 error "create failed w/o dir size limit"
14550
14551                         # messages may be rate limited if test is run repeatedly
14552                         check_mds_dmesg '"is approaching max"' ||
14553                                 echo "warning message should be output"
14554                         check_mds_dmesg '"has reached max"' ||
14555                                 echo "reached message should be output"
14556
14557                         dirsize=$(stat -c%s "$DIR/$tdir")
14558
14559                         [[ $dirsize -ge $maxsize ]] && return 0
14560                         error "dirsize $dirsize < $maxsize after $nfiles files"
14561                 elif (( rc != 0 )); then
14562                         break
14563                 fi
14564                 nfiles=$((nfiles + 1))
14565                 dirsize=$(stat -c%s "$DIR/$tdir")
14566         done
14567
14568         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14569 }
14570 run_test 129 "test directory size limit ========================"
14571
14572 OLDIFS="$IFS"
14573 cleanup_130() {
14574         trap 0
14575         IFS="$OLDIFS"
14576         rm -f $DIR/$tfile
14577 }
14578
14579 test_130a() {
14580         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14581         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14582
14583         trap cleanup_130 EXIT RETURN
14584
14585         local fm_file=$DIR/$tfile
14586         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14587         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14588                 error "dd failed for $fm_file"
14589
14590         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14591         filefrag -ves $fm_file
14592         local rc=$?
14593         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14594                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14595         (( $rc == 0 )) || error "filefrag $fm_file failed"
14596
14597         filefrag_op=$(filefrag -ve -k $fm_file |
14598                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14599         local lun=$($LFS getstripe -i $fm_file)
14600
14601         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14602         IFS=$'\n'
14603         local tot_len=0
14604         for line in $filefrag_op; do
14605                 local frag_lun=$(echo $line | cut -d: -f5)
14606                 local ext_len=$(echo $line | cut -d: -f4)
14607
14608                 if (( $frag_lun != $lun )); then
14609                         error "FIEMAP on 1-stripe file($fm_file) failed"
14610                         return
14611                 fi
14612                 (( tot_len += ext_len ))
14613         done
14614
14615         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14616                 error "FIEMAP on 1-stripe file($fm_file) failed"
14617                 return
14618         fi
14619
14620         echo "FIEMAP on single striped file succeeded"
14621 }
14622 run_test 130a "FIEMAP (1-stripe file)"
14623
14624 test_130b() {
14625         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14626
14627         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14628         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14629         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14630                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14631
14632         trap cleanup_130 EXIT RETURN
14633
14634         local fm_file=$DIR/$tfile
14635         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14636                 error "setstripe on $fm_file"
14637
14638         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14639                 error "dd failed on $fm_file"
14640
14641         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14642         filefrag_op=$(filefrag -ve -k $fm_file |
14643                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14644
14645         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14646                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14647
14648         IFS=$'\n'
14649         local tot_len=0
14650         local num_luns=1
14651
14652         for line in $filefrag_op; do
14653                 local frag_lun=$(echo $line | cut -d: -f5 |
14654                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14655                 local ext_len=$(echo $line | cut -d: -f4)
14656                 if (( $frag_lun != $last_lun )); then
14657                         if (( tot_len != 1024 )); then
14658                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14659                                 return
14660                         else
14661                                 (( num_luns += 1 ))
14662                                 tot_len=0
14663                         fi
14664                 fi
14665                 (( tot_len += ext_len ))
14666                 last_lun=$frag_lun
14667         done
14668         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14669                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14670                 return
14671         fi
14672
14673         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14674 }
14675 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14676
14677 test_130c() {
14678         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14679
14680         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14681         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14682         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14683                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14684
14685         trap cleanup_130 EXIT RETURN
14686
14687         local fm_file=$DIR/$tfile
14688         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14689
14690         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14691                 error "dd failed on $fm_file"
14692
14693         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14694         filefrag_op=$(filefrag -ve -k $fm_file |
14695                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14696
14697         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14698                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14699
14700         IFS=$'\n'
14701         local tot_len=0
14702         local num_luns=1
14703         for line in $filefrag_op; do
14704                 local frag_lun=$(echo $line | cut -d: -f5 |
14705                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14706                 local ext_len=$(echo $line | cut -d: -f4)
14707                 if (( $frag_lun != $last_lun )); then
14708                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14709                         if (( logical != 512 )); then
14710                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14711                                 return
14712                         fi
14713                         if (( tot_len != 512 )); then
14714                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14715                                 return
14716                         else
14717                                 (( num_luns += 1 ))
14718                                 tot_len=0
14719                         fi
14720                 fi
14721                 (( tot_len += ext_len ))
14722                 last_lun=$frag_lun
14723         done
14724         if (( num_luns != 2 || tot_len != 512 )); then
14725                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14726                 return
14727         fi
14728
14729         echo "FIEMAP on 2-stripe file with hole succeeded"
14730 }
14731 run_test 130c "FIEMAP (2-stripe file with hole)"
14732
14733 test_130d() {
14734         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14735
14736         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14737         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14738         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14739                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14740
14741         trap cleanup_130 EXIT RETURN
14742
14743         local fm_file=$DIR/$tfile
14744         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14745                         error "setstripe on $fm_file"
14746
14747         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14748         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14749                 error "dd failed on $fm_file"
14750
14751         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14752         filefrag_op=$(filefrag -ve -k $fm_file |
14753                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14754
14755         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14756                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14757
14758         IFS=$'\n'
14759         local tot_len=0
14760         local num_luns=1
14761         for line in $filefrag_op; do
14762                 local frag_lun=$(echo $line | cut -d: -f5 |
14763                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14764                 local ext_len=$(echo $line | cut -d: -f4)
14765                 if (( $frag_lun != $last_lun )); then
14766                         if (( tot_len != 1024 )); then
14767                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14768                                 return
14769                         else
14770                                 (( num_luns += 1 ))
14771                                 local tot_len=0
14772                         fi
14773                 fi
14774                 (( tot_len += ext_len ))
14775                 last_lun=$frag_lun
14776         done
14777         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14778                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14779                 return
14780         fi
14781
14782         echo "FIEMAP on N-stripe file succeeded"
14783 }
14784 run_test 130d "FIEMAP (N-stripe file)"
14785
14786 test_130e() {
14787         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14788
14789         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14790         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14791         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14792                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14793
14794         trap cleanup_130 EXIT RETURN
14795
14796         local fm_file=$DIR/$tfile
14797         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14798         stack_trap "rm -f $fm_file"
14799
14800         local num_blks=512
14801         local expected_len=$(( (num_blks / 2) * 64 ))
14802         for ((i = 0; i < $num_blks; i++)); do
14803                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14804                         conv=notrunc > /dev/null 2>&1
14805         done
14806
14807         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14808         filefrag_op=$(filefrag -ve -k $fm_file |
14809                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14810
14811         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14812
14813         IFS=$'\n'
14814         local tot_len=0
14815         local num_luns=1
14816         for line in $filefrag_op; do
14817                 local frag_lun=$(echo $line | cut -d: -f5)
14818                 local ext_len=$(echo $line | cut -d: -f4)
14819                 if (( $frag_lun != $last_lun )); then
14820                         if (( tot_len != $expected_len )); then
14821                                 error "OST$last_lun $tot_len != $expected_len"
14822                         else
14823                                 (( num_luns += 1 ))
14824                                 tot_len=0
14825                         fi
14826                 fi
14827                 (( tot_len += ext_len ))
14828                 last_lun=$frag_lun
14829         done
14830         if (( num_luns != 2 || tot_len != $expected_len )); then
14831                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14832         fi
14833
14834         echo "FIEMAP with continuation calls succeeded"
14835 }
14836 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14837
14838 test_130f() {
14839         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14840         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14841         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14842                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14843
14844         local fm_file=$DIR/$tfile
14845         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14846                 error "multiop create with lov_delay_create on $fm_file"
14847
14848         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14849         filefrag_extents=$(filefrag -vek $fm_file |
14850                            awk '/extents? found/ { print $2 }')
14851         if (( $filefrag_extents != 0 )); then
14852                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14853         fi
14854
14855         rm -f $fm_file
14856 }
14857 run_test 130f "FIEMAP (unstriped file)"
14858
14859 test_130g() {
14860         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14861                 skip "Need MDS version with at least 2.12.53 for overstriping"
14862         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14863         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14864         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14865                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14866
14867         local file=$DIR/$tfile
14868         local nr=$((OSTCOUNT * 100))
14869
14870         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14871
14872         stack_trap "rm -f $file"
14873         dd if=/dev/zero of=$file count=$nr bs=1M
14874         sync
14875         nr=$($LFS getstripe -c $file)
14876
14877         local extents=$(filefrag -v $file |
14878                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14879
14880         echo "filefrag list $extents extents in file with stripecount $nr"
14881         if (( extents < nr )); then
14882                 $LFS getstripe $file
14883                 filefrag -v $file
14884                 error "filefrag printed $extents < $nr extents"
14885         fi
14886 }
14887 run_test 130g "FIEMAP (overstripe file)"
14888
14889 # Test for writev/readv
14890 test_131a() {
14891         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14892                 error "writev test failed"
14893         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14894                 error "readv failed"
14895         rm -f $DIR/$tfile
14896 }
14897 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14898
14899 test_131b() {
14900         local fsize=$((524288 + 1048576 + 1572864))
14901         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14902                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14903                         error "append writev test failed"
14904
14905         ((fsize += 1572864 + 1048576))
14906         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14907                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14908                         error "append writev test failed"
14909         rm -f $DIR/$tfile
14910 }
14911 run_test 131b "test append writev"
14912
14913 test_131c() {
14914         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14915         error "NOT PASS"
14916 }
14917 run_test 131c "test read/write on file w/o objects"
14918
14919 test_131d() {
14920         rwv -f $DIR/$tfile -w -n 1 1572864
14921         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14922         if [ "$NOB" != 1572864 ]; then
14923                 error "Short read filed: read $NOB bytes instead of 1572864"
14924         fi
14925         rm -f $DIR/$tfile
14926 }
14927 run_test 131d "test short read"
14928
14929 test_131e() {
14930         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14931         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14932         error "read hitting hole failed"
14933         rm -f $DIR/$tfile
14934 }
14935 run_test 131e "test read hitting hole"
14936
14937 check_stats() {
14938         local facet=$1
14939         local op=$2
14940         local want=${3:-0}
14941         local res
14942
14943         # open             11 samples [usecs] 468 4793 13658 35791898
14944         case $facet in
14945         mds*) res=($(do_facet $facet \
14946                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14947                  ;;
14948         ost*) res=($(do_facet $facet \
14949                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14950                  ;;
14951         *) error "Wrong facet '$facet'" ;;
14952         esac
14953         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14954         # if $want is zero, it means any stat increment is ok.
14955         if (( $want > 0 )); then
14956                 local count=${res[1]}
14957
14958                 if (( $count != $want )); then
14959                         if [[ $facet =~ "mds" ]]; then
14960                                 do_nodes $(comma_list $(mdts_nodes)) \
14961                                         $LCTL get_param mdt.*.md_stats
14962                         else
14963                                 do_nodes $(comma_list $(osts-nodes)) \
14964                                         $LCTL get_param obdfilter.*.stats
14965                         fi
14966                         error "The $op counter on $facet is $count, not $want"
14967                 fi
14968         fi
14969 }
14970
14971 test_133a() {
14972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14973         remote_ost_nodsh && skip "remote OST with nodsh"
14974         remote_mds_nodsh && skip "remote MDS with nodsh"
14975         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14976                 skip_env "MDS doesn't support rename stats"
14977
14978         local testdir=$DIR/${tdir}/stats_testdir
14979
14980         mkdir -p $DIR/${tdir}
14981
14982         # clear stats.
14983         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14984         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14985
14986         # verify mdt stats first.
14987         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14988         check_stats $SINGLEMDS "mkdir" 1
14989
14990         # clear "open" from "lfs mkdir" above
14991         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14992         touch ${testdir}/${tfile} || error "touch failed"
14993         check_stats $SINGLEMDS "open" 1
14994         check_stats $SINGLEMDS "close" 1
14995         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14996                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14997                 check_stats $SINGLEMDS "mknod" 2
14998         }
14999         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15000         check_stats $SINGLEMDS "unlink" 1
15001         rm -f ${testdir}/${tfile} || error "file remove failed"
15002         check_stats $SINGLEMDS "unlink" 2
15003
15004         # remove working dir and check mdt stats again.
15005         rmdir ${testdir} || error "rmdir failed"
15006         check_stats $SINGLEMDS "rmdir" 1
15007
15008         local testdir1=$DIR/${tdir}/stats_testdir1
15009         mkdir_on_mdt0 -p ${testdir}
15010         mkdir_on_mdt0 -p ${testdir1}
15011         touch ${testdir1}/test1
15012         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15013         check_stats $SINGLEMDS "crossdir_rename" 1
15014
15015         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15016         check_stats $SINGLEMDS "samedir_rename" 1
15017
15018         rm -rf $DIR/${tdir}
15019 }
15020 run_test 133a "Verifying MDT stats ========================================"
15021
15022 test_133b() {
15023         local res
15024
15025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15026         remote_ost_nodsh && skip "remote OST with nodsh"
15027         remote_mds_nodsh && skip "remote MDS with nodsh"
15028
15029         local testdir=$DIR/${tdir}/stats_testdir
15030
15031         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15032         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15033         touch ${testdir}/${tfile} || error "touch failed"
15034         cancel_lru_locks mdc
15035
15036         # clear stats.
15037         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15038         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15039
15040         # extra mdt stats verification.
15041         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15042         check_stats $SINGLEMDS "setattr" 1
15043         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15044         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15045         then            # LU-1740
15046                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15047                 check_stats $SINGLEMDS "getattr" 1
15048         fi
15049         rm -rf $DIR/${tdir}
15050
15051         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15052         # so the check below is not reliable
15053         [ $MDSCOUNT -eq 1 ] || return 0
15054
15055         # Sleep to avoid a cached response.
15056         #define OBD_STATFS_CACHE_SECONDS 1
15057         sleep 2
15058         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15059         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15060         $LFS df || error "lfs failed"
15061         check_stats $SINGLEMDS "statfs" 1
15062
15063         # check aggregated statfs (LU-10018)
15064         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15065                 return 0
15066         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15067                 return 0
15068         sleep 2
15069         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15070         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15071         df $DIR
15072         check_stats $SINGLEMDS "statfs" 1
15073
15074         # We want to check that the client didn't send OST_STATFS to
15075         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15076         # extra care is needed here.
15077         if remote_mds; then
15078                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15079                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15080
15081                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15082                 [ "$res" ] && error "OST got STATFS"
15083         fi
15084
15085         return 0
15086 }
15087 run_test 133b "Verifying extra MDT stats =================================="
15088
15089 test_133c() {
15090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15091         remote_ost_nodsh && skip "remote OST with nodsh"
15092         remote_mds_nodsh && skip "remote MDS with nodsh"
15093
15094         local testdir=$DIR/$tdir/stats_testdir
15095
15096         test_mkdir -p $testdir
15097
15098         # verify obdfilter stats.
15099         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15100         sync
15101         cancel_lru_locks osc
15102         wait_delete_completed
15103
15104         # clear stats.
15105         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15106         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15107
15108         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15109                 error "dd failed"
15110         sync
15111         cancel_lru_locks osc
15112         check_stats ost1 "write" 1
15113
15114         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15115         check_stats ost1 "read" 1
15116
15117         > $testdir/$tfile || error "truncate failed"
15118         check_stats ost1 "punch" 1
15119
15120         rm -f $testdir/$tfile || error "file remove failed"
15121         wait_delete_completed
15122         check_stats ost1 "destroy" 1
15123
15124         rm -rf $DIR/$tdir
15125 }
15126 run_test 133c "Verifying OST stats ========================================"
15127
15128 order_2() {
15129         local value=$1
15130         local orig=$value
15131         local order=1
15132
15133         while [ $value -ge 2 ]; do
15134                 order=$((order*2))
15135                 value=$((value/2))
15136         done
15137
15138         if [ $orig -gt $order ]; then
15139                 order=$((order*2))
15140         fi
15141         echo $order
15142 }
15143
15144 size_in_KMGT() {
15145     local value=$1
15146     local size=('K' 'M' 'G' 'T');
15147     local i=0
15148     local size_string=$value
15149
15150     while [ $value -ge 1024 ]; do
15151         if [ $i -gt 3 ]; then
15152             #T is the biggest unit we get here, if that is bigger,
15153             #just return XXXT
15154             size_string=${value}T
15155             break
15156         fi
15157         value=$((value >> 10))
15158         if [ $value -lt 1024 ]; then
15159             size_string=${value}${size[$i]}
15160             break
15161         fi
15162         i=$((i + 1))
15163     done
15164
15165     echo $size_string
15166 }
15167
15168 get_rename_size() {
15169         local size=$1
15170         local context=${2:-.}
15171         local sample=$(do_facet $SINGLEMDS $LCTL \
15172                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15173                 grep -A1 $context |
15174                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15175         echo $sample
15176 }
15177
15178 test_133d() {
15179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15180         remote_ost_nodsh && skip "remote OST with nodsh"
15181         remote_mds_nodsh && skip "remote MDS with nodsh"
15182         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15183                 skip_env "MDS doesn't support rename stats"
15184
15185         local testdir1=$DIR/${tdir}/stats_testdir1
15186         local testdir2=$DIR/${tdir}/stats_testdir2
15187         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15188
15189         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15190
15191         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15192         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15193
15194         createmany -o $testdir1/test 512 || error "createmany failed"
15195
15196         # check samedir rename size
15197         mv ${testdir1}/test0 ${testdir1}/test_0
15198
15199         local testdir1_size=$(ls -l $DIR/${tdir} |
15200                 awk '/stats_testdir1/ {print $5}')
15201         local testdir2_size=$(ls -l $DIR/${tdir} |
15202                 awk '/stats_testdir2/ {print $5}')
15203
15204         testdir1_size=$(order_2 $testdir1_size)
15205         testdir2_size=$(order_2 $testdir2_size)
15206
15207         testdir1_size=$(size_in_KMGT $testdir1_size)
15208         testdir2_size=$(size_in_KMGT $testdir2_size)
15209
15210         echo "source rename dir size: ${testdir1_size}"
15211         echo "target rename dir size: ${testdir2_size}"
15212
15213         local cmd="do_facet $SINGLEMDS $LCTL "
15214         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15215
15216         eval $cmd || error "$cmd failed"
15217         local samedir=$($cmd | grep 'same_dir')
15218         local same_sample=$(get_rename_size $testdir1_size)
15219         [ -z "$samedir" ] && error "samedir_rename_size count error"
15220         [[ $same_sample -eq 1 ]] ||
15221                 error "samedir_rename_size error $same_sample"
15222         echo "Check same dir rename stats success"
15223
15224         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15225
15226         # check crossdir rename size
15227         mv ${testdir1}/test_0 ${testdir2}/test_0
15228
15229         testdir1_size=$(ls -l $DIR/${tdir} |
15230                 awk '/stats_testdir1/ {print $5}')
15231         testdir2_size=$(ls -l $DIR/${tdir} |
15232                 awk '/stats_testdir2/ {print $5}')
15233
15234         testdir1_size=$(order_2 $testdir1_size)
15235         testdir2_size=$(order_2 $testdir2_size)
15236
15237         testdir1_size=$(size_in_KMGT $testdir1_size)
15238         testdir2_size=$(size_in_KMGT $testdir2_size)
15239
15240         echo "source rename dir size: ${testdir1_size}"
15241         echo "target rename dir size: ${testdir2_size}"
15242
15243         eval $cmd || error "$cmd failed"
15244         local crossdir=$($cmd | grep 'crossdir')
15245         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15246         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15247         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15248         [[ $src_sample -eq 1 ]] ||
15249                 error "crossdir_rename_size error $src_sample"
15250         [[ $tgt_sample -eq 1 ]] ||
15251                 error "crossdir_rename_size error $tgt_sample"
15252         echo "Check cross dir rename stats success"
15253         rm -rf $DIR/${tdir}
15254 }
15255 run_test 133d "Verifying rename_stats ========================================"
15256
15257 test_133e() {
15258         remote_mds_nodsh && skip "remote MDS with nodsh"
15259         remote_ost_nodsh && skip "remote OST with nodsh"
15260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15261
15262         local testdir=$DIR/${tdir}/stats_testdir
15263         local ctr f0 f1 bs=32768 count=42 sum
15264
15265         mkdir -p ${testdir} || error "mkdir failed"
15266
15267         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15268
15269         for ctr in {write,read}_bytes; do
15270                 sync
15271                 cancel_lru_locks osc
15272
15273                 do_facet ost1 $LCTL set_param -n \
15274                         "obdfilter.*.exports.clear=clear"
15275
15276                 if [ $ctr = write_bytes ]; then
15277                         f0=/dev/zero
15278                         f1=${testdir}/${tfile}
15279                 else
15280                         f0=${testdir}/${tfile}
15281                         f1=/dev/null
15282                 fi
15283
15284                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15285                         error "dd failed"
15286                 sync
15287                 cancel_lru_locks osc
15288
15289                 sum=$(do_facet ost1 $LCTL get_param \
15290                         "obdfilter.*.exports.*.stats" |
15291                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15292                                 $1 == ctr { sum += $7 }
15293                                 END { printf("%0.0f", sum) }')
15294
15295                 if ((sum != bs * count)); then
15296                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15297                 fi
15298         done
15299
15300         rm -rf $DIR/${tdir}
15301 }
15302 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15303
15304 test_133f() {
15305         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15306                 skip "too old lustre for get_param -R ($facet_ver)"
15307
15308         # verifying readability.
15309         $LCTL get_param -R '*' &> /dev/null
15310
15311         # Verifing writability with badarea_io.
15312         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15313         local skipped_params='force_lbug|changelog_mask|daemon_file'
15314         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15315                 egrep -v "$skipped_params" |
15316                 xargs -n 1 find $proc_dirs -name |
15317                 xargs -n 1 badarea_io ||
15318                 error "client badarea_io failed"
15319
15320         # remount the FS in case writes/reads /proc break the FS
15321         cleanup || error "failed to unmount"
15322         setup || error "failed to setup"
15323 }
15324 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15325
15326 test_133g() {
15327         remote_mds_nodsh && skip "remote MDS with nodsh"
15328         remote_ost_nodsh && skip "remote OST with nodsh"
15329
15330         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15331         local proc_dirs_str=$(eval echo $proc_dirs)
15332         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15333         local facet
15334         for facet in mds1 ost1; do
15335                 local facet_ver=$(lustre_version_code $facet)
15336                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15337                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15338                 else
15339                         log "$facet: too old lustre for get_param -R"
15340                 fi
15341                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15342                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15343                                 tr -d = | egrep -v $skipped_params |
15344                                 xargs -n 1 find $proc_dirs_str -name |
15345                                 xargs -n 1 badarea_io" ||
15346                                         error "$facet badarea_io failed"
15347                 else
15348                         skip_noexit "$facet: too old lustre for get_param -R"
15349                 fi
15350         done
15351
15352         # remount the FS in case writes/reads /proc break the FS
15353         cleanup || error "failed to unmount"
15354         setup || error "failed to setup"
15355 }
15356 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15357
15358 test_133h() {
15359         remote_mds_nodsh && skip "remote MDS with nodsh"
15360         remote_ost_nodsh && skip "remote OST with nodsh"
15361         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15362                 skip "Need MDS version at least 2.9.54"
15363
15364         local facet
15365         for facet in client mds1 ost1; do
15366                 # Get the list of files that are missing the terminating newline
15367                 local plist=$(do_facet $facet
15368                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15369                 local ent
15370                 for ent in $plist; do
15371                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15372                                 awk -v FS='\v' -v RS='\v\v' \
15373                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15374                                         print FILENAME}'" 2>/dev/null)
15375                         [ -z $missing ] || {
15376                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15377                                 error "file does not end with newline: $facet-$ent"
15378                         }
15379                 done
15380         done
15381 }
15382 run_test 133h "Proc files should end with newlines"
15383
15384 test_134a() {
15385         remote_mds_nodsh && skip "remote MDS with nodsh"
15386         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15387                 skip "Need MDS version at least 2.7.54"
15388
15389         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15390         cancel_lru_locks mdc
15391
15392         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15393         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15394         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15395
15396         local nr=1000
15397         createmany -o $DIR/$tdir/f $nr ||
15398                 error "failed to create $nr files in $DIR/$tdir"
15399         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15400
15401         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15402         do_facet mds1 $LCTL set_param fail_loc=0x327
15403         do_facet mds1 $LCTL set_param fail_val=500
15404         touch $DIR/$tdir/m
15405
15406         echo "sleep 10 seconds ..."
15407         sleep 10
15408         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15409
15410         do_facet mds1 $LCTL set_param fail_loc=0
15411         do_facet mds1 $LCTL set_param fail_val=0
15412         [ $lck_cnt -lt $unused ] ||
15413                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15414
15415         rm $DIR/$tdir/m
15416         unlinkmany $DIR/$tdir/f $nr
15417 }
15418 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15419
15420 test_134b() {
15421         remote_mds_nodsh && skip "remote MDS with nodsh"
15422         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15423                 skip "Need MDS version at least 2.7.54"
15424
15425         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15426         cancel_lru_locks mdc
15427
15428         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15429                         ldlm.lock_reclaim_threshold_mb)
15430         # disable reclaim temporarily
15431         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15432
15433         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15434         do_facet mds1 $LCTL set_param fail_loc=0x328
15435         do_facet mds1 $LCTL set_param fail_val=500
15436
15437         $LCTL set_param debug=+trace
15438
15439         local nr=600
15440         createmany -o $DIR/$tdir/f $nr &
15441         local create_pid=$!
15442
15443         echo "Sleep $TIMEOUT seconds ..."
15444         sleep $TIMEOUT
15445         if ! ps -p $create_pid  > /dev/null 2>&1; then
15446                 do_facet mds1 $LCTL set_param fail_loc=0
15447                 do_facet mds1 $LCTL set_param fail_val=0
15448                 do_facet mds1 $LCTL set_param \
15449                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15450                 error "createmany finished incorrectly!"
15451         fi
15452         do_facet mds1 $LCTL set_param fail_loc=0
15453         do_facet mds1 $LCTL set_param fail_val=0
15454         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15455         wait $create_pid || return 1
15456
15457         unlinkmany $DIR/$tdir/f $nr
15458 }
15459 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15460
15461 test_135() {
15462         remote_mds_nodsh && skip "remote MDS with nodsh"
15463         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15464                 skip "Need MDS version at least 2.13.50"
15465         local fname
15466
15467         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15468
15469 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15470         #set only one record at plain llog
15471         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15472
15473         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15474
15475         #fill already existed plain llog each 64767
15476         #wrapping whole catalog
15477         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15478
15479         createmany -o $DIR/$tdir/$tfile_ 64700
15480         for (( i = 0; i < 64700; i = i + 2 ))
15481         do
15482                 rm $DIR/$tdir/$tfile_$i &
15483                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15484                 local pid=$!
15485                 wait $pid
15486         done
15487
15488         #waiting osp synchronization
15489         wait_delete_completed
15490 }
15491 run_test 135 "Race catalog processing"
15492
15493 test_136() {
15494         remote_mds_nodsh && skip "remote MDS with nodsh"
15495         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15496                 skip "Need MDS version at least 2.13.50"
15497         local fname
15498
15499         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15500         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15501         #set only one record at plain llog
15502 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15503         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15504
15505         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15506
15507         #fill already existed 2 plain llogs each 64767
15508         #wrapping whole catalog
15509         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15510         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15511         wait_delete_completed
15512
15513         createmany -o $DIR/$tdir/$tfile_ 10
15514         sleep 25
15515
15516         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15517         for (( i = 0; i < 10; i = i + 3 ))
15518         do
15519                 rm $DIR/$tdir/$tfile_$i &
15520                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15521                 local pid=$!
15522                 wait $pid
15523                 sleep 7
15524                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15525         done
15526
15527         #waiting osp synchronization
15528         wait_delete_completed
15529 }
15530 run_test 136 "Race catalog processing 2"
15531
15532 test_140() { #bug-17379
15533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15534
15535         test_mkdir $DIR/$tdir
15536         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15537         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15538
15539         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15540         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15541         local i=0
15542         while i=$((i + 1)); do
15543                 test_mkdir $i
15544                 cd $i || error "Changing to $i"
15545                 ln -s ../stat stat || error "Creating stat symlink"
15546                 # Read the symlink until ELOOP present,
15547                 # not LBUGing the system is considered success,
15548                 # we didn't overrun the stack.
15549                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15550                 if [ $ret -ne 0 ]; then
15551                         if [ $ret -eq 40 ]; then
15552                                 break  # -ELOOP
15553                         else
15554                                 error "Open stat symlink"
15555                                         return
15556                         fi
15557                 fi
15558         done
15559         i=$((i - 1))
15560         echo "The symlink depth = $i"
15561         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15562                 error "Invalid symlink depth"
15563
15564         # Test recursive symlink
15565         ln -s symlink_self symlink_self
15566         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15567         echo "open symlink_self returns $ret"
15568         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15569 }
15570 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15571
15572 test_150a() {
15573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15574
15575         local TF="$TMP/$tfile"
15576
15577         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15578         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15579         cp $TF $DIR/$tfile
15580         cancel_lru_locks $OSC
15581         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15582         remount_client $MOUNT
15583         df -P $MOUNT
15584         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15585
15586         $TRUNCATE $TF 6000
15587         $TRUNCATE $DIR/$tfile 6000
15588         cancel_lru_locks $OSC
15589         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15590
15591         echo "12345" >>$TF
15592         echo "12345" >>$DIR/$tfile
15593         cancel_lru_locks $OSC
15594         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15595
15596         echo "12345" >>$TF
15597         echo "12345" >>$DIR/$tfile
15598         cancel_lru_locks $OSC
15599         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15600 }
15601 run_test 150a "truncate/append tests"
15602
15603 test_150b() {
15604         check_set_fallocate_or_skip
15605         local out
15606
15607         touch $DIR/$tfile
15608         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15609         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15610                 skip_eopnotsupp "$out|check_fallocate failed"
15611 }
15612 run_test 150b "Verify fallocate (prealloc) functionality"
15613
15614 test_150bb() {
15615         check_set_fallocate_or_skip
15616
15617         touch $DIR/$tfile
15618         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15619         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15620         > $DIR/$tfile
15621         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15622         # precomputed md5sum for 20MB of zeroes
15623         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15624         local sum=($(md5sum $DIR/$tfile))
15625
15626         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15627
15628         check_set_fallocate 1
15629
15630         > $DIR/$tfile
15631         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15632         sum=($(md5sum $DIR/$tfile))
15633
15634         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15635 }
15636 run_test 150bb "Verify fallocate modes both zero space"
15637
15638 test_150c() {
15639         check_set_fallocate_or_skip
15640         local striping="-c2"
15641
15642         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15643         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15644         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15645         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15646         local want=$((OSTCOUNT * 1048576))
15647
15648         # Must allocate all requested space, not more than 5% extra
15649         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15650                 error "bytes $bytes is not $want"
15651
15652         rm -f $DIR/$tfile
15653
15654         echo "verify fallocate on PFL file"
15655
15656         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15657
15658         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15659                 error "Create $DIR/$tfile failed"
15660         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15661         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15662         want=$((512 * 1048576))
15663
15664         # Must allocate all requested space, not more than 5% extra
15665         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15666                 error "bytes $bytes is not $want"
15667 }
15668 run_test 150c "Verify fallocate Size and Blocks"
15669
15670 test_150d() {
15671         check_set_fallocate_or_skip
15672         local striping="-c2"
15673
15674         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15675
15676         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15677         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15678                 error "setstripe failed"
15679         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15680         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15681         local want=$((OSTCOUNT * 1048576))
15682
15683         # Must allocate all requested space, not more than 5% extra
15684         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15685                 error "bytes $bytes is not $want"
15686 }
15687 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15688
15689 test_150e() {
15690         check_set_fallocate_or_skip
15691
15692         echo "df before:"
15693         $LFS df
15694         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15695         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15696                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15697
15698         # Find OST with Minimum Size
15699         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15700                        sort -un | head -1)
15701
15702         # Get 100MB per OST of the available space to reduce run time
15703         # else 60% of the available space if we are running SLOW tests
15704         if [ $SLOW == "no" ]; then
15705                 local space=$((1024 * 100 * OSTCOUNT))
15706         else
15707                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15708         fi
15709
15710         fallocate -l${space}k $DIR/$tfile ||
15711                 error "fallocate ${space}k $DIR/$tfile failed"
15712         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15713
15714         # get size immediately after fallocate. This should be correctly
15715         # updated
15716         local size=$(stat -c '%s' $DIR/$tfile)
15717         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15718
15719         # Sleep for a while for statfs to get updated. And not pull from cache.
15720         sleep 2
15721
15722         echo "df after fallocate:"
15723         $LFS df
15724
15725         (( size / 1024 == space )) || error "size $size != requested $space"
15726         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15727                 error "used $used < space $space"
15728
15729         rm $DIR/$tfile || error "rm failed"
15730         sync
15731         wait_delete_completed
15732
15733         echo "df after unlink:"
15734         $LFS df
15735 }
15736 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15737
15738 test_150f() {
15739         local size
15740         local blocks
15741         local want_size_before=20480 # in bytes
15742         local want_blocks_before=40 # 512 sized blocks
15743         local want_blocks_after=24  # 512 sized blocks
15744         local length=$(((want_blocks_before - want_blocks_after) * 512))
15745
15746         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15747                 skip "need at least 2.14.0 for fallocate punch"
15748
15749         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15750                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15751         fi
15752
15753         check_set_fallocate_or_skip
15754         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15755
15756         [[ "x$DOM" == "xyes" ]] &&
15757                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15758
15759         echo "Verify fallocate punch: Range within the file range"
15760         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15761                 error "dd failed for bs 4096 and count 5"
15762
15763         # Call fallocate with punch range which is within the file range
15764         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15765                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15766         # client must see changes immediately after fallocate
15767         size=$(stat -c '%s' $DIR/$tfile)
15768         blocks=$(stat -c '%b' $DIR/$tfile)
15769
15770         # Verify punch worked.
15771         (( blocks == want_blocks_after )) ||
15772                 error "punch failed: blocks $blocks != $want_blocks_after"
15773
15774         (( size == want_size_before )) ||
15775                 error "punch failed: size $size != $want_size_before"
15776
15777         # Verify there is hole in file
15778         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15779         # precomputed md5sum
15780         local expect="4a9a834a2db02452929c0a348273b4aa"
15781
15782         cksum=($(md5sum $DIR/$tfile))
15783         [[ "${cksum[0]}" == "$expect" ]] ||
15784                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15785
15786         # Start second sub-case for fallocate punch.
15787         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15788         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15789                 error "dd failed for bs 4096 and count 5"
15790
15791         # Punch range less than block size will have no change in block count
15792         want_blocks_after=40  # 512 sized blocks
15793
15794         # Punch overlaps two blocks and less than blocksize
15795         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15796                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15797         size=$(stat -c '%s' $DIR/$tfile)
15798         blocks=$(stat -c '%b' $DIR/$tfile)
15799
15800         # Verify punch worked.
15801         (( blocks == want_blocks_after )) ||
15802                 error "punch failed: blocks $blocks != $want_blocks_after"
15803
15804         (( size == want_size_before )) ||
15805                 error "punch failed: size $size != $want_size_before"
15806
15807         # Verify if range is really zero'ed out. We expect Zeros.
15808         # precomputed md5sum
15809         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15810         cksum=($(md5sum $DIR/$tfile))
15811         [[ "${cksum[0]}" == "$expect" ]] ||
15812                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15813 }
15814 run_test 150f "Verify fallocate punch functionality"
15815
15816 test_150g() {
15817         local space
15818         local size
15819         local blocks
15820         local blocks_after
15821         local size_after
15822         local BS=4096 # Block size in bytes
15823
15824         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15825                 skip "need at least 2.14.0 for fallocate punch"
15826
15827         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15828                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15829         fi
15830
15831         check_set_fallocate_or_skip
15832         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15833
15834         if [[ "x$DOM" == "xyes" ]]; then
15835                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15836                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15837         else
15838                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15839                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15840         fi
15841
15842         # Get 100MB per OST of the available space to reduce run time
15843         # else 60% of the available space if we are running SLOW tests
15844         if [ $SLOW == "no" ]; then
15845                 space=$((1024 * 100 * OSTCOUNT))
15846         else
15847                 # Find OST with Minimum Size
15848                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15849                         sort -un | head -1)
15850                 echo "min size OST: $space"
15851                 space=$(((space * 60)/100 * OSTCOUNT))
15852         fi
15853         # space in 1k units, round to 4k blocks
15854         local blkcount=$((space * 1024 / $BS))
15855
15856         echo "Verify fallocate punch: Very large Range"
15857         fallocate -l${space}k $DIR/$tfile ||
15858                 error "fallocate ${space}k $DIR/$tfile failed"
15859         # write 1M at the end, start and in the middle
15860         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15861                 error "dd failed: bs $BS count 256"
15862         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15863                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15864         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15865                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15866
15867         # Gather stats.
15868         size=$(stat -c '%s' $DIR/$tfile)
15869
15870         # gather punch length.
15871         local punch_size=$((size - (BS * 2)))
15872
15873         echo "punch_size = $punch_size"
15874         echo "size - punch_size: $((size - punch_size))"
15875         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15876
15877         # Call fallocate to punch all except 2 blocks. We leave the
15878         # first and the last block
15879         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15880         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15881                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15882
15883         size_after=$(stat -c '%s' $DIR/$tfile)
15884         blocks_after=$(stat -c '%b' $DIR/$tfile)
15885
15886         # Verify punch worked.
15887         # Size should be kept
15888         (( size == size_after )) ||
15889                 error "punch failed: size $size != $size_after"
15890
15891         # two 4k data blocks to remain plus possible 1 extra extent block
15892         (( blocks_after <= ((BS / 512) * 3) )) ||
15893                 error "too many blocks remains: $blocks_after"
15894
15895         # Verify that file has hole between the first and the last blocks
15896         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15897         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15898
15899         echo "Hole at [$hole_start, $hole_end)"
15900         (( hole_start == BS )) ||
15901                 error "no hole at offset $BS after punch"
15902
15903         (( hole_end == BS + punch_size )) ||
15904                 error "data at offset $hole_end < $((BS + punch_size))"
15905 }
15906 run_test 150g "Verify fallocate punch on large range"
15907
15908 test_150h() {
15909         local file=$DIR/$tfile
15910         local size
15911
15912         check_set_fallocate_or_skip
15913         statx_supported || skip_env "Test must be statx() syscall supported"
15914
15915         # fallocate() does not update the size information on the MDT
15916         fallocate -l 16K $file || error "failed to fallocate $file"
15917         cancel_lru_locks $OSC
15918         # STATX with cached-always mode will not send glimpse RPCs to OST,
15919         # it uses the caching attrs on the client side as much as possible.
15920         size=$($STATX --cached=always -c %s $file)
15921         [ $size == 16384 ] ||
15922                 error "size after fallocate() is $size, expected 16384"
15923 }
15924 run_test 150h "Verify extend fallocate updates the file size"
15925
15926 #LU-2902 roc_hit was not able to read all values from lproc
15927 function roc_hit_init() {
15928         local list=$(comma_list $(osts_nodes))
15929         local dir=$DIR/$tdir-check
15930         local file=$dir/$tfile
15931         local BEFORE
15932         local AFTER
15933         local idx
15934
15935         test_mkdir $dir
15936         #use setstripe to do a write to every ost
15937         for i in $(seq 0 $((OSTCOUNT-1))); do
15938                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15939                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15940                 idx=$(printf %04x $i)
15941                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15942                         awk '$1 == "cache_access" {sum += $7}
15943                                 END { printf("%0.0f", sum) }')
15944
15945                 cancel_lru_locks osc
15946                 cat $file >/dev/null
15947
15948                 AFTER=$(get_osd_param $list *OST*$idx stats |
15949                         awk '$1 == "cache_access" {sum += $7}
15950                                 END { printf("%0.0f", sum) }')
15951
15952                 echo BEFORE:$BEFORE AFTER:$AFTER
15953                 if ! let "AFTER - BEFORE == 4"; then
15954                         rm -rf $dir
15955                         error "roc_hit is not safe to use"
15956                 fi
15957                 rm $file
15958         done
15959
15960         rm -rf $dir
15961 }
15962
15963 function roc_hit() {
15964         local list=$(comma_list $(osts_nodes))
15965         echo $(get_osd_param $list '' stats |
15966                 awk '$1 == "cache_hit" {sum += $7}
15967                         END { printf("%0.0f", sum) }')
15968 }
15969
15970 function set_cache() {
15971         local on=1
15972
15973         if [ "$2" == "off" ]; then
15974                 on=0;
15975         fi
15976         local list=$(comma_list $(osts_nodes))
15977         set_osd_param $list '' $1_cache_enable $on
15978
15979         cancel_lru_locks osc
15980 }
15981
15982 test_151() {
15983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15984         remote_ost_nodsh && skip "remote OST with nodsh"
15985         (( CLIENT_VERSION == OST1_VERSION )) ||
15986                 skip "LU-13081: no interop testing for OSS cache"
15987
15988         local CPAGES=3
15989         local list=$(comma_list $(osts_nodes))
15990
15991         # check whether obdfilter is cache capable at all
15992         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15993                 skip "not cache-capable obdfilter"
15994         fi
15995
15996         # check cache is enabled on all obdfilters
15997         if get_osd_param $list '' read_cache_enable | grep 0; then
15998                 skip "oss cache is disabled"
15999         fi
16000
16001         set_osd_param $list '' writethrough_cache_enable 1
16002
16003         # check write cache is enabled on all obdfilters
16004         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16005                 skip "oss write cache is NOT enabled"
16006         fi
16007
16008         roc_hit_init
16009
16010         #define OBD_FAIL_OBD_NO_LRU  0x609
16011         do_nodes $list $LCTL set_param fail_loc=0x609
16012
16013         # pages should be in the case right after write
16014         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16015                 error "dd failed"
16016
16017         local BEFORE=$(roc_hit)
16018         cancel_lru_locks osc
16019         cat $DIR/$tfile >/dev/null
16020         local AFTER=$(roc_hit)
16021
16022         do_nodes $list $LCTL set_param fail_loc=0
16023
16024         if ! let "AFTER - BEFORE == CPAGES"; then
16025                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16026         fi
16027
16028         cancel_lru_locks osc
16029         # invalidates OST cache
16030         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16031         set_osd_param $list '' read_cache_enable 0
16032         cat $DIR/$tfile >/dev/null
16033
16034         # now data shouldn't be found in the cache
16035         BEFORE=$(roc_hit)
16036         cancel_lru_locks osc
16037         cat $DIR/$tfile >/dev/null
16038         AFTER=$(roc_hit)
16039         if let "AFTER - BEFORE != 0"; then
16040                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16041         fi
16042
16043         set_osd_param $list '' read_cache_enable 1
16044         rm -f $DIR/$tfile
16045 }
16046 run_test 151 "test cache on oss and controls ==============================="
16047
16048 test_152() {
16049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16050
16051         local TF="$TMP/$tfile"
16052
16053         # simulate ENOMEM during write
16054 #define OBD_FAIL_OST_NOMEM      0x226
16055         lctl set_param fail_loc=0x80000226
16056         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16057         cp $TF $DIR/$tfile
16058         sync || error "sync failed"
16059         lctl set_param fail_loc=0
16060
16061         # discard client's cache
16062         cancel_lru_locks osc
16063
16064         # simulate ENOMEM during read
16065         lctl set_param fail_loc=0x80000226
16066         cmp $TF $DIR/$tfile || error "cmp failed"
16067         lctl set_param fail_loc=0
16068
16069         rm -f $TF
16070 }
16071 run_test 152 "test read/write with enomem ============================"
16072
16073 test_153() {
16074         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16075 }
16076 run_test 153 "test if fdatasync does not crash ======================="
16077
16078 dot_lustre_fid_permission_check() {
16079         local fid=$1
16080         local ffid=$MOUNT/.lustre/fid/$fid
16081         local test_dir=$2
16082
16083         echo "stat fid $fid"
16084         stat $ffid || error "stat $ffid failed."
16085         echo "touch fid $fid"
16086         touch $ffid || error "touch $ffid failed."
16087         echo "write to fid $fid"
16088         cat /etc/hosts > $ffid || error "write $ffid failed."
16089         echo "read fid $fid"
16090         diff /etc/hosts $ffid || error "read $ffid failed."
16091         echo "append write to fid $fid"
16092         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16093         echo "rename fid $fid"
16094         mv $ffid $test_dir/$tfile.1 &&
16095                 error "rename $ffid to $tfile.1 should fail."
16096         touch $test_dir/$tfile.1
16097         mv $test_dir/$tfile.1 $ffid &&
16098                 error "rename $tfile.1 to $ffid should fail."
16099         rm -f $test_dir/$tfile.1
16100         echo "truncate fid $fid"
16101         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16102         echo "link fid $fid"
16103         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16104         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16105                 echo "setfacl fid $fid"
16106                 setfacl -R -m u:$USER0:rwx $ffid ||
16107                         error "setfacl $ffid failed"
16108                 echo "getfacl fid $fid"
16109                 getfacl $ffid || error "getfacl $ffid failed."
16110         fi
16111         echo "unlink fid $fid"
16112         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16113         echo "mknod fid $fid"
16114         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16115
16116         fid=[0xf00000400:0x1:0x0]
16117         ffid=$MOUNT/.lustre/fid/$fid
16118
16119         echo "stat non-exist fid $fid"
16120         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16121         echo "write to non-exist fid $fid"
16122         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16123         echo "link new fid $fid"
16124         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16125
16126         mkdir -p $test_dir/$tdir
16127         touch $test_dir/$tdir/$tfile
16128         fid=$($LFS path2fid $test_dir/$tdir)
16129         rc=$?
16130         [ $rc -ne 0 ] &&
16131                 error "error: could not get fid for $test_dir/$dir/$tfile."
16132
16133         ffid=$MOUNT/.lustre/fid/$fid
16134
16135         echo "ls $fid"
16136         ls $ffid || error "ls $ffid failed."
16137         echo "touch $fid/$tfile.1"
16138         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16139
16140         echo "touch $MOUNT/.lustre/fid/$tfile"
16141         touch $MOUNT/.lustre/fid/$tfile && \
16142                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16143
16144         echo "setxattr to $MOUNT/.lustre/fid"
16145         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16146
16147         echo "listxattr for $MOUNT/.lustre/fid"
16148         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16149
16150         echo "delxattr from $MOUNT/.lustre/fid"
16151         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16152
16153         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16154         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16155                 error "touch invalid fid should fail."
16156
16157         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16158         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16159                 error "touch non-normal fid should fail."
16160
16161         echo "rename $tdir to $MOUNT/.lustre/fid"
16162         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16163                 error "rename to $MOUNT/.lustre/fid should fail."
16164
16165         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16166         then            # LU-3547
16167                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16168                 local new_obf_mode=777
16169
16170                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16171                 chmod $new_obf_mode $DIR/.lustre/fid ||
16172                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16173
16174                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16175                 [ $obf_mode -eq $new_obf_mode ] ||
16176                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16177
16178                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16179                 chmod $old_obf_mode $DIR/.lustre/fid ||
16180                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16181         fi
16182
16183         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16184         fid=$($LFS path2fid $test_dir/$tfile-2)
16185
16186         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16187         then # LU-5424
16188                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16189                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16190                         error "create lov data thru .lustre failed"
16191         fi
16192         echo "cp /etc/passwd $test_dir/$tfile-2"
16193         cp /etc/passwd $test_dir/$tfile-2 ||
16194                 error "copy to $test_dir/$tfile-2 failed."
16195         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16196         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16197                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16198
16199         rm -rf $test_dir/tfile.lnk
16200         rm -rf $test_dir/$tfile-2
16201 }
16202
16203 test_154A() {
16204         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16205                 skip "Need MDS version at least 2.4.1"
16206
16207         local tf=$DIR/$tfile
16208         touch $tf
16209
16210         local fid=$($LFS path2fid $tf)
16211         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16212
16213         # check that we get the same pathname back
16214         local rootpath
16215         local found
16216         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16217                 echo "$rootpath $fid"
16218                 found=$($LFS fid2path $rootpath "$fid")
16219                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16220                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16221         done
16222
16223         # check wrong root path format
16224         rootpath=$MOUNT"_wrong"
16225         found=$($LFS fid2path $rootpath "$fid")
16226         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16227 }
16228 run_test 154A "lfs path2fid and fid2path basic checks"
16229
16230 test_154B() {
16231         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16232                 skip "Need MDS version at least 2.4.1"
16233
16234         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16235         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16236         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16237         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16238
16239         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16240         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16241
16242         # check that we get the same pathname
16243         echo "PFID: $PFID, name: $name"
16244         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16245         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16246         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16247                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16248
16249         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16250 }
16251 run_test 154B "verify the ll_decode_linkea tool"
16252
16253 test_154a() {
16254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16255         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16256         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16257                 skip "Need MDS version at least 2.2.51"
16258         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16259
16260         cp /etc/hosts $DIR/$tfile
16261
16262         fid=$($LFS path2fid $DIR/$tfile)
16263         rc=$?
16264         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16265
16266         dot_lustre_fid_permission_check "$fid" $DIR ||
16267                 error "dot lustre permission check $fid failed"
16268
16269         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16270
16271         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16272
16273         touch $MOUNT/.lustre/file &&
16274                 error "creation is not allowed under .lustre"
16275
16276         mkdir $MOUNT/.lustre/dir &&
16277                 error "mkdir is not allowed under .lustre"
16278
16279         rm -rf $DIR/$tfile
16280 }
16281 run_test 154a "Open-by-FID"
16282
16283 test_154b() {
16284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16285         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16286         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16287         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16288                 skip "Need MDS version at least 2.2.51"
16289
16290         local remote_dir=$DIR/$tdir/remote_dir
16291         local MDTIDX=1
16292         local rc=0
16293
16294         mkdir -p $DIR/$tdir
16295         $LFS mkdir -i $MDTIDX $remote_dir ||
16296                 error "create remote directory failed"
16297
16298         cp /etc/hosts $remote_dir/$tfile
16299
16300         fid=$($LFS path2fid $remote_dir/$tfile)
16301         rc=$?
16302         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16303
16304         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16305                 error "dot lustre permission check $fid failed"
16306         rm -rf $DIR/$tdir
16307 }
16308 run_test 154b "Open-by-FID for remote directory"
16309
16310 test_154c() {
16311         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16312                 skip "Need MDS version at least 2.4.1"
16313
16314         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16315         local FID1=$($LFS path2fid $DIR/$tfile.1)
16316         local FID2=$($LFS path2fid $DIR/$tfile.2)
16317         local FID3=$($LFS path2fid $DIR/$tfile.3)
16318
16319         local N=1
16320         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16321                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16322                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16323                 local want=FID$N
16324                 [ "$FID" = "${!want}" ] ||
16325                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16326                 N=$((N + 1))
16327         done
16328
16329         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16330         do
16331                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16332                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16333                 N=$((N + 1))
16334         done
16335 }
16336 run_test 154c "lfs path2fid and fid2path multiple arguments"
16337
16338 test_154d() {
16339         remote_mds_nodsh && skip "remote MDS with nodsh"
16340         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16341                 skip "Need MDS version at least 2.5.53"
16342
16343         if remote_mds; then
16344                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16345         else
16346                 nid="0@lo"
16347         fi
16348         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16349         local fd
16350         local cmd
16351
16352         rm -f $DIR/$tfile
16353         touch $DIR/$tfile
16354
16355         local fid=$($LFS path2fid $DIR/$tfile)
16356         # Open the file
16357         fd=$(free_fd)
16358         cmd="exec $fd<$DIR/$tfile"
16359         eval $cmd
16360         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16361         echo "$fid_list" | grep "$fid"
16362         rc=$?
16363
16364         cmd="exec $fd>/dev/null"
16365         eval $cmd
16366         if [ $rc -ne 0 ]; then
16367                 error "FID $fid not found in open files list $fid_list"
16368         fi
16369 }
16370 run_test 154d "Verify open file fid"
16371
16372 test_154e()
16373 {
16374         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16375                 skip "Need MDS version at least 2.6.50"
16376
16377         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16378                 error ".lustre returned by readdir"
16379         fi
16380 }
16381 run_test 154e ".lustre is not returned by readdir"
16382
16383 test_154f() {
16384         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16385
16386         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16387         mkdir_on_mdt0 $DIR/$tdir
16388         # test dirs inherit from its stripe
16389         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16390         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16391         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16392         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16393         touch $DIR/f
16394
16395         # get fid of parents
16396         local FID0=$($LFS path2fid $DIR/$tdir)
16397         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16398         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16399         local FID3=$($LFS path2fid $DIR)
16400
16401         # check that path2fid --parents returns expected <parent_fid>/name
16402         # 1) test for a directory (single parent)
16403         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16404         [ "$parent" == "$FID0/foo1" ] ||
16405                 error "expected parent: $FID0/foo1, got: $parent"
16406
16407         # 2) test for a file with nlink > 1 (multiple parents)
16408         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16409         echo "$parent" | grep -F "$FID1/$tfile" ||
16410                 error "$FID1/$tfile not returned in parent list"
16411         echo "$parent" | grep -F "$FID2/link" ||
16412                 error "$FID2/link not returned in parent list"
16413
16414         # 3) get parent by fid
16415         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16416         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16417         echo "$parent" | grep -F "$FID1/$tfile" ||
16418                 error "$FID1/$tfile not returned in parent list (by fid)"
16419         echo "$parent" | grep -F "$FID2/link" ||
16420                 error "$FID2/link not returned in parent list (by fid)"
16421
16422         # 4) test for entry in root directory
16423         parent=$($LFS path2fid --parents $DIR/f)
16424         echo "$parent" | grep -F "$FID3/f" ||
16425                 error "$FID3/f not returned in parent list"
16426
16427         # 5) test it on root directory
16428         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16429                 error "$MOUNT should not have parents"
16430
16431         # enable xattr caching and check that linkea is correctly updated
16432         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16433         save_lustre_params client "llite.*.xattr_cache" > $save
16434         lctl set_param llite.*.xattr_cache 1
16435
16436         # 6.1) linkea update on rename
16437         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16438
16439         # get parents by fid
16440         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16441         # foo1 should no longer be returned in parent list
16442         echo "$parent" | grep -F "$FID1" &&
16443                 error "$FID1 should no longer be in parent list"
16444         # the new path should appear
16445         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16446                 error "$FID2/$tfile.moved is not in parent list"
16447
16448         # 6.2) linkea update on unlink
16449         rm -f $DIR/$tdir/foo2/link
16450         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16451         # foo2/link should no longer be returned in parent list
16452         echo "$parent" | grep -F "$FID2/link" &&
16453                 error "$FID2/link should no longer be in parent list"
16454         true
16455
16456         rm -f $DIR/f
16457         restore_lustre_params < $save
16458         rm -f $save
16459 }
16460 run_test 154f "get parent fids by reading link ea"
16461
16462 test_154g()
16463 {
16464         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16465            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16466                 skip "Need MDS version at least 2.6.92"
16467
16468         mkdir_on_mdt0 $DIR/$tdir
16469         llapi_fid_test -d $DIR/$tdir
16470 }
16471 run_test 154g "various llapi FID tests"
16472
16473 test_154h()
16474 {
16475         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16476                 skip "Need client at least version 2.15.55.1"
16477
16478         # Create an empty file
16479         touch $DIR/$tfile
16480
16481         # Get FID (interactive mode) and save under $TMP/$tfile.log
16482         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16483                 path2fid $DIR/$tfile
16484         EOF
16485
16486         fid=$(cat $TMP/$tfile.log)
16487         # $fid should not be empty
16488         [[ ! -z $fid ]] || error "FID is empty"
16489         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16490 }
16491 run_test 154h "Verify interactive path2fid"
16492
16493 test_155_small_load() {
16494     local temp=$TMP/$tfile
16495     local file=$DIR/$tfile
16496
16497     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16498         error "dd of=$temp bs=6096 count=1 failed"
16499     cp $temp $file
16500     cancel_lru_locks $OSC
16501     cmp $temp $file || error "$temp $file differ"
16502
16503     $TRUNCATE $temp 6000
16504     $TRUNCATE $file 6000
16505     cmp $temp $file || error "$temp $file differ (truncate1)"
16506
16507     echo "12345" >>$temp
16508     echo "12345" >>$file
16509     cmp $temp $file || error "$temp $file differ (append1)"
16510
16511     echo "12345" >>$temp
16512     echo "12345" >>$file
16513     cmp $temp $file || error "$temp $file differ (append2)"
16514
16515     rm -f $temp $file
16516     true
16517 }
16518
16519 test_155_big_load() {
16520         remote_ost_nodsh && skip "remote OST with nodsh"
16521
16522         local temp=$TMP/$tfile
16523         local file=$DIR/$tfile
16524
16525         free_min_max
16526         local cache_size=$(do_facet ost$((MAXI+1)) \
16527                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16528
16529         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16530         # pre-set value
16531         if [ -z "$cache_size" ]; then
16532                 cache_size=256
16533         fi
16534         local large_file_size=$((cache_size * 2))
16535
16536         echo "OSS cache size: $cache_size KB"
16537         echo "Large file size: $large_file_size KB"
16538
16539         [ $MAXV -le $large_file_size ] &&
16540                 skip_env "max available OST size needs > $large_file_size KB"
16541
16542         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16543
16544         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16545                 error "dd of=$temp bs=$large_file_size count=1k failed"
16546         cp $temp $file
16547         ls -lh $temp $file
16548         cancel_lru_locks osc
16549         cmp $temp $file || error "$temp $file differ"
16550
16551         rm -f $temp $file
16552         true
16553 }
16554
16555 save_writethrough() {
16556         local facets=$(get_facets OST)
16557
16558         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16559 }
16560
16561 test_155a() {
16562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16563
16564         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16565
16566         save_writethrough $p
16567
16568         set_cache read on
16569         set_cache writethrough on
16570         test_155_small_load
16571         restore_lustre_params < $p
16572         rm -f $p
16573 }
16574 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16575
16576 test_155b() {
16577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16578
16579         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16580
16581         save_writethrough $p
16582
16583         set_cache read on
16584         set_cache writethrough off
16585         test_155_small_load
16586         restore_lustre_params < $p
16587         rm -f $p
16588 }
16589 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16590
16591 test_155c() {
16592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16593
16594         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16595
16596         save_writethrough $p
16597
16598         set_cache read off
16599         set_cache writethrough on
16600         test_155_small_load
16601         restore_lustre_params < $p
16602         rm -f $p
16603 }
16604 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16605
16606 test_155d() {
16607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16608
16609         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16610
16611         save_writethrough $p
16612
16613         set_cache read off
16614         set_cache writethrough off
16615         test_155_small_load
16616         restore_lustre_params < $p
16617         rm -f $p
16618 }
16619 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16620
16621 test_155e() {
16622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16623
16624         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16625
16626         save_writethrough $p
16627
16628         set_cache read on
16629         set_cache writethrough on
16630         test_155_big_load
16631         restore_lustre_params < $p
16632         rm -f $p
16633 }
16634 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16635
16636 test_155f() {
16637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16638
16639         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16640
16641         save_writethrough $p
16642
16643         set_cache read on
16644         set_cache writethrough off
16645         test_155_big_load
16646         restore_lustre_params < $p
16647         rm -f $p
16648 }
16649 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16650
16651 test_155g() {
16652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16653
16654         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16655
16656         save_writethrough $p
16657
16658         set_cache read off
16659         set_cache writethrough on
16660         test_155_big_load
16661         restore_lustre_params < $p
16662         rm -f $p
16663 }
16664 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16665
16666 test_155h() {
16667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16668
16669         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16670
16671         save_writethrough $p
16672
16673         set_cache read off
16674         set_cache writethrough off
16675         test_155_big_load
16676         restore_lustre_params < $p
16677         rm -f $p
16678 }
16679 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16680
16681 test_156() {
16682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16683         remote_ost_nodsh && skip "remote OST with nodsh"
16684         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16685                 skip "stats not implemented on old servers"
16686         [ "$ost1_FSTYPE" = "zfs" ] &&
16687                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16688         (( CLIENT_VERSION == OST1_VERSION )) ||
16689                 skip "LU-13081: no interop testing for OSS cache"
16690
16691         local CPAGES=3
16692         local BEFORE
16693         local AFTER
16694         local file="$DIR/$tfile"
16695         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16696
16697         save_writethrough $p
16698         roc_hit_init
16699
16700         log "Turn on read and write cache"
16701         set_cache read on
16702         set_cache writethrough on
16703
16704         log "Write data and read it back."
16705         log "Read should be satisfied from the cache."
16706         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16707         BEFORE=$(roc_hit)
16708         cancel_lru_locks osc
16709         cat $file >/dev/null
16710         AFTER=$(roc_hit)
16711         if ! let "AFTER - BEFORE == CPAGES"; then
16712                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16713         else
16714                 log "cache hits: before: $BEFORE, after: $AFTER"
16715         fi
16716
16717         log "Read again; it should be satisfied from the cache."
16718         BEFORE=$AFTER
16719         cancel_lru_locks osc
16720         cat $file >/dev/null
16721         AFTER=$(roc_hit)
16722         if ! let "AFTER - BEFORE == CPAGES"; then
16723                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16724         else
16725                 log "cache hits:: before: $BEFORE, after: $AFTER"
16726         fi
16727
16728         log "Turn off the read cache and turn on the write cache"
16729         set_cache read off
16730         set_cache writethrough on
16731
16732         log "Read again; it should be satisfied from the cache."
16733         BEFORE=$(roc_hit)
16734         cancel_lru_locks osc
16735         cat $file >/dev/null
16736         AFTER=$(roc_hit)
16737         if ! let "AFTER - BEFORE == CPAGES"; then
16738                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16739         else
16740                 log "cache hits:: before: $BEFORE, after: $AFTER"
16741         fi
16742
16743         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16744                 # > 2.12.56 uses pagecache if cached
16745                 log "Read again; it should not be satisfied from the cache."
16746                 BEFORE=$AFTER
16747                 cancel_lru_locks osc
16748                 cat $file >/dev/null
16749                 AFTER=$(roc_hit)
16750                 if ! let "AFTER - BEFORE == 0"; then
16751                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16752                 else
16753                         log "cache hits:: before: $BEFORE, after: $AFTER"
16754                 fi
16755         fi
16756
16757         log "Write data and read it back."
16758         log "Read should be satisfied from the cache."
16759         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16760         BEFORE=$(roc_hit)
16761         cancel_lru_locks osc
16762         cat $file >/dev/null
16763         AFTER=$(roc_hit)
16764         if ! let "AFTER - BEFORE == CPAGES"; then
16765                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16766         else
16767                 log "cache hits:: before: $BEFORE, after: $AFTER"
16768         fi
16769
16770         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16771                 # > 2.12.56 uses pagecache if cached
16772                 log "Read again; it should not be satisfied from the cache."
16773                 BEFORE=$AFTER
16774                 cancel_lru_locks osc
16775                 cat $file >/dev/null
16776                 AFTER=$(roc_hit)
16777                 if ! let "AFTER - BEFORE == 0"; then
16778                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16779                 else
16780                         log "cache hits:: before: $BEFORE, after: $AFTER"
16781                 fi
16782         fi
16783
16784         log "Turn off read and write cache"
16785         set_cache read off
16786         set_cache writethrough off
16787
16788         log "Write data and read it back"
16789         log "It should not be satisfied from the cache."
16790         rm -f $file
16791         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16792         cancel_lru_locks osc
16793         BEFORE=$(roc_hit)
16794         cat $file >/dev/null
16795         AFTER=$(roc_hit)
16796         if ! let "AFTER - BEFORE == 0"; then
16797                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16798         else
16799                 log "cache hits:: before: $BEFORE, after: $AFTER"
16800         fi
16801
16802         log "Turn on the read cache and turn off the write cache"
16803         set_cache read on
16804         set_cache writethrough off
16805
16806         log "Write data and read it back"
16807         log "It should not be satisfied from the cache."
16808         rm -f $file
16809         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16810         BEFORE=$(roc_hit)
16811         cancel_lru_locks osc
16812         cat $file >/dev/null
16813         AFTER=$(roc_hit)
16814         if ! let "AFTER - BEFORE == 0"; then
16815                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16816         else
16817                 log "cache hits:: before: $BEFORE, after: $AFTER"
16818         fi
16819
16820         log "Read again; it should be satisfied from the cache."
16821         BEFORE=$(roc_hit)
16822         cancel_lru_locks osc
16823         cat $file >/dev/null
16824         AFTER=$(roc_hit)
16825         if ! let "AFTER - BEFORE == CPAGES"; then
16826                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16827         else
16828                 log "cache hits:: before: $BEFORE, after: $AFTER"
16829         fi
16830
16831         restore_lustre_params < $p
16832         rm -f $p $file
16833 }
16834 run_test 156 "Verification of tunables"
16835
16836 test_160a() {
16837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16838         remote_mds_nodsh && skip "remote MDS with nodsh"
16839         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16840                 skip "Need MDS version at least 2.2.0"
16841
16842         changelog_register || error "changelog_register failed"
16843         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16844         changelog_users $SINGLEMDS | grep -q $cl_user ||
16845                 error "User $cl_user not found in changelog_users"
16846
16847         mkdir_on_mdt0 $DIR/$tdir
16848
16849         # change something
16850         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16851         changelog_clear 0 || error "changelog_clear failed"
16852         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16853         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16854         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16855         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16856         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16857         rm $DIR/$tdir/pics/desktop.jpg
16858
16859         echo "verifying changelog mask"
16860         changelog_chmask "-MKDIR"
16861         changelog_chmask "-CLOSE"
16862
16863         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16864         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16865
16866         changelog_chmask "+MKDIR"
16867         changelog_chmask "+CLOSE"
16868
16869         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16870         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16871
16872         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16873         CLOSES=$(changelog_dump | grep -c "CLOSE")
16874         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16875         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16876
16877         # verify contents
16878         echo "verifying target fid"
16879         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16880         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16881         [ "$fidc" == "$fidf" ] ||
16882                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16883         echo "verifying parent fid"
16884         # The FID returned from the Changelog may be the directory shard on
16885         # a different MDT, and not the FID returned by path2fid on the parent.
16886         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16887         # since this is what will matter when recreating this file in the tree.
16888         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16889         local pathp=$($LFS fid2path $MOUNT "$fidp")
16890         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16891                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16892
16893         echo "getting records for $cl_user"
16894         changelog_users $SINGLEMDS
16895         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16896         local nclr=3
16897         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16898                 error "changelog_clear failed"
16899         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16900         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16901         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16902                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16903
16904         local min0_rec=$(changelog_users $SINGLEMDS |
16905                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16906         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16907                           awk '{ print $1; exit; }')
16908
16909         changelog_dump | tail -n 5
16910         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16911         [ $first_rec == $((min0_rec + 1)) ] ||
16912                 error "first index should be $min0_rec + 1 not $first_rec"
16913
16914         # LU-3446 changelog index reset on MDT restart
16915         local cur_rec1=$(changelog_users $SINGLEMDS |
16916                          awk '/^current.index:/ { print $NF }')
16917         changelog_clear 0 ||
16918                 error "clear all changelog records for $cl_user failed"
16919         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16920         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16921                 error "Fail to start $SINGLEMDS"
16922         local cur_rec2=$(changelog_users $SINGLEMDS |
16923                          awk '/^current.index:/ { print $NF }')
16924         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16925         [ $cur_rec1 == $cur_rec2 ] ||
16926                 error "current index should be $cur_rec1 not $cur_rec2"
16927
16928         echo "verifying users from this test are deregistered"
16929         changelog_deregister || error "changelog_deregister failed"
16930         changelog_users $SINGLEMDS | grep -q $cl_user &&
16931                 error "User '$cl_user' still in changelog_users"
16932
16933         # lctl get_param -n mdd.*.changelog_users
16934         # current_index: 144
16935         # ID    index (idle seconds)
16936         # cl3   144   (2) mask=<list>
16937         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16938                 # this is the normal case where all users were deregistered
16939                 # make sure no new records are added when no users are present
16940                 local last_rec1=$(changelog_users $SINGLEMDS |
16941                                   awk '/^current.index:/ { print $NF }')
16942                 touch $DIR/$tdir/chloe
16943                 local last_rec2=$(changelog_users $SINGLEMDS |
16944                                   awk '/^current.index:/ { print $NF }')
16945                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16946                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16947         else
16948                 # any changelog users must be leftovers from a previous test
16949                 changelog_users $SINGLEMDS
16950                 echo "other changelog users; can't verify off"
16951         fi
16952 }
16953 run_test 160a "changelog sanity"
16954
16955 test_160b() { # LU-3587
16956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16957         remote_mds_nodsh && skip "remote MDS with nodsh"
16958         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16959                 skip "Need MDS version at least 2.2.0"
16960
16961         changelog_register || error "changelog_register failed"
16962         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16963         changelog_users $SINGLEMDS | grep -q $cl_user ||
16964                 error "User '$cl_user' not found in changelog_users"
16965
16966         local longname1=$(str_repeat a 255)
16967         local longname2=$(str_repeat b 255)
16968
16969         cd $DIR
16970         echo "creating very long named file"
16971         touch $longname1 || error "create of '$longname1' failed"
16972         echo "renaming very long named file"
16973         mv $longname1 $longname2
16974
16975         changelog_dump | grep RENME | tail -n 5
16976         rm -f $longname2
16977 }
16978 run_test 160b "Verify that very long rename doesn't crash in changelog"
16979
16980 test_160c() {
16981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16982         remote_mds_nodsh && skip "remote MDS with nodsh"
16983
16984         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16985                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16986                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16987                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16988
16989         local rc=0
16990
16991         # Registration step
16992         changelog_register || error "changelog_register failed"
16993
16994         rm -rf $DIR/$tdir
16995         mkdir -p $DIR/$tdir
16996         $MCREATE $DIR/$tdir/foo_160c
16997         changelog_chmask "-TRUNC"
16998         $TRUNCATE $DIR/$tdir/foo_160c 200
16999         changelog_chmask "+TRUNC"
17000         $TRUNCATE $DIR/$tdir/foo_160c 199
17001         changelog_dump | tail -n 5
17002         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17003         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17004 }
17005 run_test 160c "verify that changelog log catch the truncate event"
17006
17007 test_160d() {
17008         remote_mds_nodsh && skip "remote MDS with nodsh"
17009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17011         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17012                 skip "Need MDS version at least 2.7.60"
17013
17014         # Registration step
17015         changelog_register || error "changelog_register failed"
17016
17017         mkdir -p $DIR/$tdir/migrate_dir
17018         changelog_clear 0 || error "changelog_clear failed"
17019
17020         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17021         changelog_dump | tail -n 5
17022         local migrates=$(changelog_dump | grep -c "MIGRT")
17023         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17024 }
17025 run_test 160d "verify that changelog log catch the migrate event"
17026
17027 test_160e() {
17028         remote_mds_nodsh && skip "remote MDS with nodsh"
17029
17030         # Create a user
17031         changelog_register || error "changelog_register failed"
17032
17033         local MDT0=$(facet_svc $SINGLEMDS)
17034         local rc
17035
17036         # No user (expect fail)
17037         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17038         rc=$?
17039         if [ $rc -eq 0 ]; then
17040                 error "Should fail without user"
17041         elif [ $rc -ne 4 ]; then
17042                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17043         fi
17044
17045         # Delete a future user (expect fail)
17046         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17047         rc=$?
17048         if [ $rc -eq 0 ]; then
17049                 error "Deleted non-existant user cl77"
17050         elif [ $rc -ne 2 ]; then
17051                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17052         fi
17053
17054         # Clear to a bad index (1 billion should be safe)
17055         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17056         rc=$?
17057
17058         if [ $rc -eq 0 ]; then
17059                 error "Successfully cleared to invalid CL index"
17060         elif [ $rc -ne 22 ]; then
17061                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17062         fi
17063 }
17064 run_test 160e "changelog negative testing (should return errors)"
17065
17066 test_160f() {
17067         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17068         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17069                 skip "Need MDS version at least 2.10.56"
17070
17071         local mdts=$(comma_list $(mdts_nodes))
17072
17073         # Create a user
17074         changelog_register || error "first changelog_register failed"
17075         changelog_register || error "second changelog_register failed"
17076         local cl_users
17077         declare -A cl_user1
17078         declare -A cl_user2
17079         local user_rec1
17080         local user_rec2
17081         local i
17082
17083         # generate some changelog records to accumulate on each MDT
17084         # use all_char because created files should be evenly distributed
17085         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17086                 error "test_mkdir $tdir failed"
17087         log "$(date +%s): creating first files"
17088         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17089                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17090                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17091         done
17092
17093         # check changelogs have been generated
17094         local start=$SECONDS
17095         local idle_time=$((MDSCOUNT * 5 + 5))
17096         local nbcl=$(changelog_dump | wc -l)
17097         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17098
17099         for param in "changelog_max_idle_time=$idle_time" \
17100                      "changelog_gc=1" \
17101                      "changelog_min_gc_interval=2" \
17102                      "changelog_min_free_cat_entries=3"; do
17103                 local MDT0=$(facet_svc $SINGLEMDS)
17104                 local var="${param%=*}"
17105                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17106
17107                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17108                 do_nodes $mdts $LCTL set_param mdd.*.$param
17109         done
17110
17111         # force cl_user2 to be idle (1st part), but also cancel the
17112         # cl_user1 records so that it is not evicted later in the test.
17113         local sleep1=$((idle_time / 2))
17114         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17115         sleep $sleep1
17116
17117         # simulate changelog catalog almost full
17118         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17119         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17120
17121         for i in $(seq $MDSCOUNT); do
17122                 cl_users=(${CL_USERS[mds$i]})
17123                 cl_user1[mds$i]="${cl_users[0]}"
17124                 cl_user2[mds$i]="${cl_users[1]}"
17125
17126                 [ -n "${cl_user1[mds$i]}" ] ||
17127                         error "mds$i: no user registered"
17128                 [ -n "${cl_user2[mds$i]}" ] ||
17129                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17130
17131                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17132                 [ -n "$user_rec1" ] ||
17133                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17134                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17135                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17136                 [ -n "$user_rec2" ] ||
17137                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17138                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17139                      "$user_rec1 + 2 == $user_rec2"
17140                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17141                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17142                               "$user_rec1 + 2, but is $user_rec2"
17143                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17144                 [ -n "$user_rec2" ] ||
17145                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17146                 [ $user_rec1 == $user_rec2 ] ||
17147                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17148                               "$user_rec1, but is $user_rec2"
17149         done
17150
17151         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17152         local sleep2=$((idle_time - (SECONDS - start) + 1))
17153         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17154         sleep $sleep2
17155
17156         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17157         # cl_user1 should be OK because it recently processed records.
17158         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17159         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17160                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17161                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17162         done
17163
17164         # ensure gc thread is done
17165         for i in $(mdts_nodes); do
17166                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17167                         error "$i: GC-thread not done"
17168         done
17169
17170         local first_rec
17171         for (( i = 1; i <= MDSCOUNT; i++ )); do
17172                 # check cl_user1 still registered
17173                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17174                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17175                 # check cl_user2 unregistered
17176                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17177                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17178
17179                 # check changelogs are present and starting at $user_rec1 + 1
17180                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17181                 [ -n "$user_rec1" ] ||
17182                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17183                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17184                             awk '{ print $1; exit; }')
17185
17186                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17187                 [ $((user_rec1 + 1)) == $first_rec ] ||
17188                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17189         done
17190 }
17191 run_test 160f "changelog garbage collect (timestamped users)"
17192
17193 test_160g() {
17194         remote_mds_nodsh && skip "remote MDS with nodsh"
17195         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17196                 skip "Need MDS version at least 2.14.55"
17197
17198         local mdts=$(comma_list $(mdts_nodes))
17199
17200         # Create a user
17201         changelog_register || error "first changelog_register failed"
17202         changelog_register || error "second changelog_register failed"
17203         local cl_users
17204         declare -A cl_user1
17205         declare -A cl_user2
17206         local user_rec1
17207         local user_rec2
17208         local i
17209
17210         # generate some changelog records to accumulate on each MDT
17211         # use all_char because created files should be evenly distributed
17212         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17213                 error "test_mkdir $tdir failed"
17214         for ((i = 0; i < MDSCOUNT; i++)); do
17215                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17216                         error "create $DIR/$tdir/d$i.1 failed"
17217         done
17218
17219         # check changelogs have been generated
17220         local nbcl=$(changelog_dump | wc -l)
17221         (( $nbcl > 0 )) || error "no changelogs found"
17222
17223         # reduce the max_idle_indexes value to make sure we exceed it
17224         for param in "changelog_max_idle_indexes=2" \
17225                      "changelog_gc=1" \
17226                      "changelog_min_gc_interval=2"; do
17227                 local MDT0=$(facet_svc $SINGLEMDS)
17228                 local var="${param%=*}"
17229                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17230
17231                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17232                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17233                         error "unable to set mdd.*.$param"
17234         done
17235
17236         local start=$SECONDS
17237         for i in $(seq $MDSCOUNT); do
17238                 cl_users=(${CL_USERS[mds$i]})
17239                 cl_user1[mds$i]="${cl_users[0]}"
17240                 cl_user2[mds$i]="${cl_users[1]}"
17241
17242                 [ -n "${cl_user1[mds$i]}" ] ||
17243                         error "mds$i: user1 is not registered"
17244                 [ -n "${cl_user2[mds$i]}" ] ||
17245                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17246
17247                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17248                 [ -n "$user_rec1" ] ||
17249                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17250                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17251                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17252                 [ -n "$user_rec2" ] ||
17253                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17254                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17255                      "$user_rec1 + 2 == $user_rec2"
17256                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17257                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17258                               "expected $user_rec1 + 2, but is $user_rec2"
17259                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17260                 [ -n "$user_rec2" ] ||
17261                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17262                 [ $user_rec1 == $user_rec2 ] ||
17263                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17264                               "expected $user_rec1, but is $user_rec2"
17265         done
17266
17267         # ensure we are past the previous changelog_min_gc_interval set above
17268         local sleep2=$((start + 2 - SECONDS))
17269         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17270         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17271         # cl_user1 should be OK because it recently processed records.
17272         for ((i = 0; i < MDSCOUNT; i++)); do
17273                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17274                         error "create $DIR/$tdir/d$i.3 failed"
17275         done
17276
17277         # ensure gc thread is done
17278         for i in $(mdts_nodes); do
17279                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17280                         error "$i: GC-thread not done"
17281         done
17282
17283         local first_rec
17284         for (( i = 1; i <= MDSCOUNT; i++ )); do
17285                 # check cl_user1 still registered
17286                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17287                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17288                 # check cl_user2 unregistered
17289                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17290                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17291
17292                 # check changelogs are present and starting at $user_rec1 + 1
17293                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17294                 [ -n "$user_rec1" ] ||
17295                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17296                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17297                             awk '{ print $1; exit; }')
17298
17299                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17300                 [ $((user_rec1 + 1)) == $first_rec ] ||
17301                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17302         done
17303 }
17304 run_test 160g "changelog garbage collect on idle records"
17305
17306 test_160h() {
17307         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17308         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17309                 skip "Need MDS version at least 2.10.56"
17310
17311         local mdts=$(comma_list $(mdts_nodes))
17312
17313         # Create a user
17314         changelog_register || error "first changelog_register failed"
17315         changelog_register || error "second changelog_register failed"
17316         local cl_users
17317         declare -A cl_user1
17318         declare -A cl_user2
17319         local user_rec1
17320         local user_rec2
17321         local i
17322
17323         # generate some changelog records to accumulate on each MDT
17324         # use all_char because created files should be evenly distributed
17325         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17326                 error "test_mkdir $tdir failed"
17327         for ((i = 0; i < MDSCOUNT; i++)); do
17328                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17329                         error "create $DIR/$tdir/d$i.1 failed"
17330         done
17331
17332         # check changelogs have been generated
17333         local nbcl=$(changelog_dump | wc -l)
17334         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17335
17336         for param in "changelog_max_idle_time=10" \
17337                      "changelog_gc=1" \
17338                      "changelog_min_gc_interval=2"; do
17339                 local MDT0=$(facet_svc $SINGLEMDS)
17340                 local var="${param%=*}"
17341                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17342
17343                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17344                 do_nodes $mdts $LCTL set_param mdd.*.$param
17345         done
17346
17347         # force cl_user2 to be idle (1st part)
17348         sleep 9
17349
17350         for i in $(seq $MDSCOUNT); do
17351                 cl_users=(${CL_USERS[mds$i]})
17352                 cl_user1[mds$i]="${cl_users[0]}"
17353                 cl_user2[mds$i]="${cl_users[1]}"
17354
17355                 [ -n "${cl_user1[mds$i]}" ] ||
17356                         error "mds$i: no user registered"
17357                 [ -n "${cl_user2[mds$i]}" ] ||
17358                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17359
17360                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17361                 [ -n "$user_rec1" ] ||
17362                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17363                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17364                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17365                 [ -n "$user_rec2" ] ||
17366                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17367                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17368                      "$user_rec1 + 2 == $user_rec2"
17369                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17370                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17371                               "$user_rec1 + 2, but is $user_rec2"
17372                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17373                 [ -n "$user_rec2" ] ||
17374                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17375                 [ $user_rec1 == $user_rec2 ] ||
17376                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17377                               "$user_rec1, but is $user_rec2"
17378         done
17379
17380         # force cl_user2 to be idle (2nd part) and to reach
17381         # changelog_max_idle_time
17382         sleep 2
17383
17384         # force each GC-thread start and block then
17385         # one per MDT/MDD, set fail_val accordingly
17386         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17387         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17388
17389         # generate more changelogs to trigger fail_loc
17390         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17391                 error "create $DIR/$tdir/${tfile}bis failed"
17392
17393         # stop MDT to stop GC-thread, should be done in back-ground as it will
17394         # block waiting for the thread to be released and exit
17395         declare -A stop_pids
17396         for i in $(seq $MDSCOUNT); do
17397                 stop mds$i &
17398                 stop_pids[mds$i]=$!
17399         done
17400
17401         for i in $(mdts_nodes); do
17402                 local facet
17403                 local nb=0
17404                 local facets=$(facets_up_on_host $i)
17405
17406                 for facet in ${facets//,/ }; do
17407                         if [[ $facet == mds* ]]; then
17408                                 nb=$((nb + 1))
17409                         fi
17410                 done
17411                 # ensure each MDS's gc threads are still present and all in "R"
17412                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17413                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17414                         error "$i: expected $nb GC-thread"
17415                 wait_update $i \
17416                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17417                         "R" 20 ||
17418                         error "$i: GC-thread not found in R-state"
17419                 # check umounts of each MDT on MDS have reached kthread_stop()
17420                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17421                         error "$i: expected $nb umount"
17422                 wait_update $i \
17423                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17424                         error "$i: umount not found in D-state"
17425         done
17426
17427         # release all GC-threads
17428         do_nodes $mdts $LCTL set_param fail_loc=0
17429
17430         # wait for MDT stop to complete
17431         for i in $(seq $MDSCOUNT); do
17432                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17433         done
17434
17435         # XXX
17436         # may try to check if any orphan changelog records are present
17437         # via ldiskfs/zfs and llog_reader...
17438
17439         # re-start/mount MDTs
17440         for i in $(seq $MDSCOUNT); do
17441                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17442                         error "Fail to start mds$i"
17443         done
17444
17445         local first_rec
17446         for i in $(seq $MDSCOUNT); do
17447                 # check cl_user1 still registered
17448                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17449                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17450                 # check cl_user2 unregistered
17451                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17452                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17453
17454                 # check changelogs are present and starting at $user_rec1 + 1
17455                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17456                 [ -n "$user_rec1" ] ||
17457                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17458                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17459                             awk '{ print $1; exit; }')
17460
17461                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17462                 [ $((user_rec1 + 1)) == $first_rec ] ||
17463                         error "mds$i: first index should be $user_rec1 + 1, " \
17464                               "but is $first_rec"
17465         done
17466 }
17467 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17468               "during mount"
17469
17470 test_160i() {
17471
17472         local mdts=$(comma_list $(mdts_nodes))
17473
17474         changelog_register || error "first changelog_register failed"
17475
17476         # generate some changelog records to accumulate on each MDT
17477         # use all_char because created files should be evenly distributed
17478         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17479                 error "test_mkdir $tdir failed"
17480         for ((i = 0; i < MDSCOUNT; i++)); do
17481                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17482                         error "create $DIR/$tdir/d$i.1 failed"
17483         done
17484
17485         # check changelogs have been generated
17486         local nbcl=$(changelog_dump | wc -l)
17487         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17488
17489         # simulate race between register and unregister
17490         # XXX as fail_loc is set per-MDS, with DNE configs the race
17491         # simulation will only occur for one MDT per MDS and for the
17492         # others the normal race scenario will take place
17493         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17494         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17495         do_nodes $mdts $LCTL set_param fail_val=1
17496
17497         # unregister 1st user
17498         changelog_deregister &
17499         local pid1=$!
17500         # wait some time for deregister work to reach race rdv
17501         sleep 2
17502         # register 2nd user
17503         changelog_register || error "2nd user register failed"
17504
17505         wait $pid1 || error "1st user deregister failed"
17506
17507         local i
17508         local last_rec
17509         declare -A LAST_REC
17510         for i in $(seq $MDSCOUNT); do
17511                 if changelog_users mds$i | grep "^cl"; then
17512                         # make sure new records are added with one user present
17513                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17514                                           awk '/^current.index:/ { print $NF }')
17515                 else
17516                         error "mds$i has no user registered"
17517                 fi
17518         done
17519
17520         # generate more changelog records to accumulate on each MDT
17521         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17522                 error "create $DIR/$tdir/${tfile}bis failed"
17523
17524         for i in $(seq $MDSCOUNT); do
17525                 last_rec=$(changelog_users $SINGLEMDS |
17526                            awk '/^current.index:/ { print $NF }')
17527                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17528                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17529                         error "changelogs are off on mds$i"
17530         done
17531 }
17532 run_test 160i "changelog user register/unregister race"
17533
17534 test_160j() {
17535         remote_mds_nodsh && skip "remote MDS with nodsh"
17536         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17537                 skip "Need MDS version at least 2.12.56"
17538
17539         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17540         stack_trap "umount $MOUNT2" EXIT
17541
17542         changelog_register || error "first changelog_register failed"
17543         stack_trap "changelog_deregister" EXIT
17544
17545         # generate some changelog
17546         # use all_char because created files should be evenly distributed
17547         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17548                 error "mkdir $tdir failed"
17549         for ((i = 0; i < MDSCOUNT; i++)); do
17550                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17551                         error "create $DIR/$tdir/d$i.1 failed"
17552         done
17553
17554         # open the changelog device
17555         exec 3>/dev/changelog-$FSNAME-MDT0000
17556         stack_trap "exec 3>&-" EXIT
17557         exec 4</dev/changelog-$FSNAME-MDT0000
17558         stack_trap "exec 4<&-" EXIT
17559
17560         # umount the first lustre mount
17561         umount $MOUNT
17562         stack_trap "mount_client $MOUNT" EXIT
17563
17564         # read changelog, which may or may not fail, but should not crash
17565         cat <&4 >/dev/null
17566
17567         # clear changelog
17568         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17569         changelog_users $SINGLEMDS | grep -q $cl_user ||
17570                 error "User $cl_user not found in changelog_users"
17571
17572         printf 'clear:'$cl_user':0' >&3
17573 }
17574 run_test 160j "client can be umounted while its chanangelog is being used"
17575
17576 test_160k() {
17577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17578         remote_mds_nodsh && skip "remote MDS with nodsh"
17579
17580         mkdir -p $DIR/$tdir/1/1
17581
17582         changelog_register || error "changelog_register failed"
17583         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17584
17585         changelog_users $SINGLEMDS | grep -q $cl_user ||
17586                 error "User '$cl_user' not found in changelog_users"
17587 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17588         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17589         rmdir $DIR/$tdir/1/1 & sleep 1
17590         mkdir $DIR/$tdir/2
17591         touch $DIR/$tdir/2/2
17592         rm -rf $DIR/$tdir/2
17593
17594         wait
17595         sleep 4
17596
17597         changelog_dump | grep rmdir || error "rmdir not recorded"
17598 }
17599 run_test 160k "Verify that changelog records are not lost"
17600
17601 # Verifies that a file passed as a parameter has recently had an operation
17602 # performed on it that has generated an MTIME changelog which contains the
17603 # correct parent FID. As files might reside on a different MDT from the
17604 # parent directory in DNE configurations, the FIDs are translated to paths
17605 # before being compared, which should be identical
17606 compare_mtime_changelog() {
17607         local file="${1}"
17608         local mdtidx
17609         local mtime
17610         local cl_fid
17611         local pdir
17612         local dir
17613
17614         mdtidx=$($LFS getstripe --mdt-index $file)
17615         mdtidx=$(printf "%04x" $mdtidx)
17616
17617         # Obtain the parent FID from the MTIME changelog
17618         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17619         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17620
17621         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17622         [ -z "$cl_fid" ] && error "parent FID not present"
17623
17624         # Verify that the path for the parent FID is the same as the path for
17625         # the test directory
17626         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17627
17628         dir=$(dirname $1)
17629
17630         [[ "${pdir%/}" == "$dir" ]] ||
17631                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17632 }
17633
17634 test_160l() {
17635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17636
17637         remote_mds_nodsh && skip "remote MDS with nodsh"
17638         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17639                 skip "Need MDS version at least 2.13.55"
17640
17641         local cl_user
17642
17643         changelog_register || error "changelog_register failed"
17644         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17645
17646         changelog_users $SINGLEMDS | grep -q $cl_user ||
17647                 error "User '$cl_user' not found in changelog_users"
17648
17649         # Clear some types so that MTIME changelogs are generated
17650         changelog_chmask "-CREAT"
17651         changelog_chmask "-CLOSE"
17652
17653         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17654
17655         # Test CL_MTIME during setattr
17656         touch $DIR/$tdir/$tfile
17657         compare_mtime_changelog $DIR/$tdir/$tfile
17658
17659         # Test CL_MTIME during close
17660         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17661         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17662 }
17663 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17664
17665 test_160m() {
17666         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17667         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17668                 skip "Need MDS version at least 2.14.51"
17669         local cl_users
17670         local cl_user1
17671         local cl_user2
17672         local pid1
17673
17674         # Create a user
17675         changelog_register || error "first changelog_register failed"
17676         changelog_register || error "second changelog_register failed"
17677
17678         cl_users=(${CL_USERS[mds1]})
17679         cl_user1="${cl_users[0]}"
17680         cl_user2="${cl_users[1]}"
17681         # generate some changelog records to accumulate on MDT0
17682         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17683         createmany -m $DIR/$tdir/$tfile 50 ||
17684                 error "create $DIR/$tdir/$tfile failed"
17685         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17686         rm -f $DIR/$tdir
17687
17688         # check changelogs have been generated
17689         local nbcl=$(changelog_dump | wc -l)
17690         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17691
17692 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17693         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17694
17695         __changelog_clear mds1 $cl_user1 +10
17696         __changelog_clear mds1 $cl_user2 0 &
17697         pid1=$!
17698         sleep 2
17699         __changelog_clear mds1 $cl_user1 0 ||
17700                 error "fail to cancel record for $cl_user1"
17701         wait $pid1
17702         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17703 }
17704 run_test 160m "Changelog clear race"
17705
17706 test_160n() {
17707         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17708         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17709                 skip "Need MDS version at least 2.14.51"
17710         local cl_users
17711         local cl_user1
17712         local cl_user2
17713         local pid1
17714         local first_rec
17715         local last_rec=0
17716
17717         # Create a user
17718         changelog_register || error "first changelog_register failed"
17719
17720         cl_users=(${CL_USERS[mds1]})
17721         cl_user1="${cl_users[0]}"
17722
17723         # generate some changelog records to accumulate on MDT0
17724         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17725         first_rec=$(changelog_users $SINGLEMDS |
17726                         awk '/^current.index:/ { print $NF }')
17727         while (( last_rec < (( first_rec + 65000)) )); do
17728                 createmany -m $DIR/$tdir/$tfile 10000 ||
17729                         error "create $DIR/$tdir/$tfile failed"
17730
17731                 for i in $(seq 0 10000); do
17732                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17733                                 > /dev/null
17734                 done
17735
17736                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17737                         error "unlinkmany failed unlink"
17738                 last_rec=$(changelog_users $SINGLEMDS |
17739                         awk '/^current.index:/ { print $NF }')
17740                 echo last record $last_rec
17741                 (( last_rec == 0 )) && error "no changelog found"
17742         done
17743
17744 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17745         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17746
17747         __changelog_clear mds1 $cl_user1 0 &
17748         pid1=$!
17749         sleep 2
17750         __changelog_clear mds1 $cl_user1 0 ||
17751                 error "fail to cancel record for $cl_user1"
17752         wait $pid1
17753         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17754 }
17755 run_test 160n "Changelog destroy race"
17756
17757 test_160o() {
17758         local mdt="$(facet_svc $SINGLEMDS)"
17759
17760         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17761         remote_mds_nodsh && skip "remote MDS with nodsh"
17762         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17763                 skip "Need MDS version at least 2.14.52"
17764
17765         changelog_register --user test_160o -m unlnk+close+open ||
17766                 error "changelog_register failed"
17767
17768         do_facet $SINGLEMDS $LCTL --device $mdt \
17769                                 changelog_register -u "Tt3_-#" &&
17770                 error "bad symbols in name should fail"
17771
17772         do_facet $SINGLEMDS $LCTL --device $mdt \
17773                                 changelog_register -u test_160o &&
17774                 error "the same name registration should fail"
17775
17776         do_facet $SINGLEMDS $LCTL --device $mdt \
17777                         changelog_register -u test_160toolongname &&
17778                 error "too long name registration should fail"
17779
17780         changelog_chmask "MARK+HSM"
17781         lctl get_param mdd.*.changelog*mask
17782         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17783         changelog_users $SINGLEMDS | grep -q $cl_user ||
17784                 error "User $cl_user not found in changelog_users"
17785         #verify username
17786         echo $cl_user | grep -q test_160o ||
17787                 error "User $cl_user has no specific name 'test160o'"
17788
17789         # change something
17790         changelog_clear 0 || error "changelog_clear failed"
17791         # generate some changelog records to accumulate on MDT0
17792         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17793         touch $DIR/$tdir/$tfile                 # open 1
17794
17795         OPENS=$(changelog_dump | grep -c "OPEN")
17796         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17797
17798         # must be no MKDIR it wasn't set as user mask
17799         MKDIR=$(changelog_dump | grep -c "MKDIR")
17800         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17801
17802         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17803                                 mdd.$mdt.changelog_current_mask -n)
17804         # register maskless user
17805         changelog_register || error "changelog_register failed"
17806         # effective mask should be not changed because it is not minimal
17807         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17808                                 mdd.$mdt.changelog_current_mask -n)
17809         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17810         # set server mask to minimal value
17811         changelog_chmask "MARK"
17812         # check effective mask again, should be treated as DEFMASK now
17813         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17814                                 mdd.$mdt.changelog_current_mask -n)
17815         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17816
17817         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17818                 # set server mask back to some value
17819                 changelog_chmask "CLOSE,UNLNK"
17820                 # check effective mask again, should not remain as DEFMASK
17821                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17822                                 mdd.$mdt.changelog_current_mask -n)
17823                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17824         fi
17825
17826         do_facet $SINGLEMDS $LCTL --device $mdt \
17827                                 changelog_deregister -u test_160o ||
17828                 error "cannot deregister by name"
17829 }
17830 run_test 160o "changelog user name and mask"
17831
17832 test_160p() {
17833         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17834         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17835                 skip "Need MDS version at least 2.14.51"
17836         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17837         local cl_users
17838         local cl_user1
17839         local entry_count
17840
17841         # Create a user
17842         changelog_register || error "first changelog_register failed"
17843
17844         cl_users=(${CL_USERS[mds1]})
17845         cl_user1="${cl_users[0]}"
17846
17847         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17848         createmany -m $DIR/$tdir/$tfile 50 ||
17849                 error "create $DIR/$tdir/$tfile failed"
17850         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17851         rm -rf $DIR/$tdir
17852
17853         # check changelogs have been generated
17854         entry_count=$(changelog_dump | wc -l)
17855         ((entry_count != 0)) || error "no changelog entries found"
17856
17857         # remove changelog_users and check that orphan entries are removed
17858         stop mds1
17859         local dev=$(mdsdevname 1)
17860         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17861         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17862         entry_count=$(changelog_dump | wc -l)
17863         ((entry_count == 0)) ||
17864                 error "found $entry_count changelog entries, expected none"
17865 }
17866 run_test 160p "Changelog orphan cleanup with no users"
17867
17868 test_160q() {
17869         local mdt="$(facet_svc $SINGLEMDS)"
17870         local clu
17871
17872         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17873         remote_mds_nodsh && skip "remote MDS with nodsh"
17874         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17875                 skip "Need MDS version at least 2.14.54"
17876
17877         # set server mask to minimal value like server init does
17878         changelog_chmask "MARK"
17879         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17880                 error "changelog_register failed"
17881         # check effective mask again, should be treated as DEFMASK now
17882         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17883                                 mdd.$mdt.changelog_current_mask -n)
17884         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17885                 error "changelog_deregister failed"
17886         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17887 }
17888 run_test 160q "changelog effective mask is DEFMASK if not set"
17889
17890 test_160s() {
17891         remote_mds_nodsh && skip "remote MDS with nodsh"
17892         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17893                 skip "Need MDS version at least 2.14.55"
17894
17895         local mdts=$(comma_list $(mdts_nodes))
17896
17897         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17898         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17899                                        fail_val=$((24 * 3600 * 10))
17900
17901         # Create a user which is 10 days old
17902         changelog_register || error "first changelog_register failed"
17903         local cl_users
17904         declare -A cl_user1
17905         local i
17906
17907         # generate some changelog records to accumulate on each MDT
17908         # use all_char because created files should be evenly distributed
17909         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17910                 error "test_mkdir $tdir failed"
17911         for ((i = 0; i < MDSCOUNT; i++)); do
17912                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17913                         error "create $DIR/$tdir/d$i.1 failed"
17914         done
17915
17916         # check changelogs have been generated
17917         local nbcl=$(changelog_dump | wc -l)
17918         (( nbcl > 0 )) || error "no changelogs found"
17919
17920         # reduce the max_idle_indexes value to make sure we exceed it
17921         for param in "changelog_max_idle_indexes=2097446912" \
17922                      "changelog_max_idle_time=2592000" \
17923                      "changelog_gc=1" \
17924                      "changelog_min_gc_interval=2"; do
17925                 local MDT0=$(facet_svc $SINGLEMDS)
17926                 local var="${param%=*}"
17927                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17928
17929                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17930                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17931                         error "unable to set mdd.*.$param"
17932         done
17933
17934         local start=$SECONDS
17935         for i in $(seq $MDSCOUNT); do
17936                 cl_users=(${CL_USERS[mds$i]})
17937                 cl_user1[mds$i]="${cl_users[0]}"
17938
17939                 [[ -n "${cl_user1[mds$i]}" ]] ||
17940                         error "mds$i: no user registered"
17941         done
17942
17943         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17944         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17945
17946         # ensure we are past the previous changelog_min_gc_interval set above
17947         local sleep2=$((start + 2 - SECONDS))
17948         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17949
17950         # Generate one more changelog to trigger GC
17951         for ((i = 0; i < MDSCOUNT; i++)); do
17952                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17953                         error "create $DIR/$tdir/d$i.3 failed"
17954         done
17955
17956         # ensure gc thread is done
17957         for node in $(mdts_nodes); do
17958                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17959                         error "$node: GC-thread not done"
17960         done
17961
17962         do_nodes $mdts $LCTL set_param fail_loc=0
17963
17964         for (( i = 1; i <= MDSCOUNT; i++ )); do
17965                 # check cl_user1 is purged
17966                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17967                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17968         done
17969         return 0
17970 }
17971 run_test 160s "changelog garbage collect on idle records * time"
17972
17973 test_160t() {
17974         remote_mds_nodsh && skip "remote MDS with nodsh"
17975         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17976                 skip "Need MDS version at least 2.15.50"
17977
17978         local MDT0=$(facet_svc $SINGLEMDS)
17979         local cl_users
17980         local cl_user1
17981         local cl_user2
17982         local start
17983
17984         changelog_register --user user1 -m all ||
17985                 error "user1 failed to register"
17986
17987         mkdir_on_mdt0 $DIR/$tdir
17988         # create default overstripe to maximize changelog size
17989         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17990         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17991         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17992
17993         # user2 consumes less records so less space
17994         changelog_register --user user2 || error "user2 failed to register"
17995         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17996         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17997
17998         # check changelogs have been generated
17999         local nbcl=$(changelog_dump | wc -l)
18000         (( nbcl > 0 )) || error "no changelogs found"
18001
18002         # reduce the changelog_min_gc_interval to force check
18003         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18004                 local var="${param%=*}"
18005                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18006
18007                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18008                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18009                         error "unable to set mdd.*.$param"
18010         done
18011
18012         start=$SECONDS
18013         cl_users=(${CL_USERS[mds1]})
18014         cl_user1="${cl_users[0]}"
18015         cl_user2="${cl_users[1]}"
18016
18017         [[ -n $cl_user1 ]] ||
18018                 error "mds1: user #1 isn't registered"
18019         [[ -n $cl_user2 ]] ||
18020                 error "mds1: user #2 isn't registered"
18021
18022         # ensure we are past the previous changelog_min_gc_interval set above
18023         local sleep2=$((start + 2 - SECONDS))
18024         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18025
18026         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18027         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18028                         fail_val=$(((llog_size1 + llog_size2) / 2))
18029
18030         # Generate more changelog to trigger GC
18031         createmany -o $DIR/$tdir/u3_ 4 ||
18032                 error "create failed for more files"
18033
18034         # ensure gc thread is done
18035         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18036                 error "mds1: GC-thread not done"
18037
18038         do_facet mds1 $LCTL set_param fail_loc=0
18039
18040         # check cl_user1 is purged
18041         changelog_users mds1 | grep -q "$cl_user1" &&
18042                 error "User $cl_user1 is registered"
18043         # check cl_user2 is not purged
18044         changelog_users mds1 | grep -q "$cl_user2" ||
18045                 error "User $cl_user2 is not registered"
18046 }
18047 run_test 160t "changelog garbage collect on lack of space"
18048
18049 test_161a() {
18050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18051
18052         test_mkdir -c1 $DIR/$tdir
18053         cp /etc/hosts $DIR/$tdir/$tfile
18054         test_mkdir -c1 $DIR/$tdir/foo1
18055         test_mkdir -c1 $DIR/$tdir/foo2
18056         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18057         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18058         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18059         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18060         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18061         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18062                 $LFS fid2path $DIR $FID
18063                 error "bad link ea"
18064         fi
18065         # middle
18066         rm $DIR/$tdir/foo2/zachary
18067         # last
18068         rm $DIR/$tdir/foo2/thor
18069         # first
18070         rm $DIR/$tdir/$tfile
18071         # rename
18072         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18073         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18074                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18075         rm $DIR/$tdir/foo2/maggie
18076
18077         # overflow the EA
18078         local longname=$tfile.avg_len_is_thirty_two_
18079         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18080                 error_noexit 'failed to unlink many hardlinks'" EXIT
18081         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18082                 error "failed to hardlink many files"
18083         links=$($LFS fid2path $DIR $FID | wc -l)
18084         echo -n "${links}/1000 links in link EA"
18085         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18086 }
18087 run_test 161a "link ea sanity"
18088
18089 test_161b() {
18090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18091         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18092
18093         local MDTIDX=1
18094         local remote_dir=$DIR/$tdir/remote_dir
18095
18096         mkdir -p $DIR/$tdir
18097         $LFS mkdir -i $MDTIDX $remote_dir ||
18098                 error "create remote directory failed"
18099
18100         cp /etc/hosts $remote_dir/$tfile
18101         mkdir -p $remote_dir/foo1
18102         mkdir -p $remote_dir/foo2
18103         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18104         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18105         ln $remote_dir/$tfile $remote_dir/foo1/luna
18106         ln $remote_dir/$tfile $remote_dir/foo2/thor
18107
18108         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18109                      tr -d ']')
18110         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18111                 $LFS fid2path $DIR $FID
18112                 error "bad link ea"
18113         fi
18114         # middle
18115         rm $remote_dir/foo2/zachary
18116         # last
18117         rm $remote_dir/foo2/thor
18118         # first
18119         rm $remote_dir/$tfile
18120         # rename
18121         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18122         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18123         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18124                 $LFS fid2path $DIR $FID
18125                 error "bad link rename"
18126         fi
18127         rm $remote_dir/foo2/maggie
18128
18129         # overflow the EA
18130         local longname=filename_avg_len_is_thirty_two_
18131         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18132                 error "failed to hardlink many files"
18133         links=$($LFS fid2path $DIR $FID | wc -l)
18134         echo -n "${links}/1000 links in link EA"
18135         [[ ${links} -gt 60 ]] ||
18136                 error "expected at least 60 links in link EA"
18137         unlinkmany $remote_dir/foo2/$longname 1000 ||
18138         error "failed to unlink many hardlinks"
18139 }
18140 run_test 161b "link ea sanity under remote directory"
18141
18142 test_161c() {
18143         remote_mds_nodsh && skip "remote MDS with nodsh"
18144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18145         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18146                 skip "Need MDS version at least 2.1.5"
18147
18148         # define CLF_RENAME_LAST 0x0001
18149         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18150         changelog_register || error "changelog_register failed"
18151
18152         rm -rf $DIR/$tdir
18153         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18154         touch $DIR/$tdir/foo_161c
18155         touch $DIR/$tdir/bar_161c
18156         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18157         changelog_dump | grep RENME | tail -n 5
18158         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18159         changelog_clear 0 || error "changelog_clear failed"
18160         if [ x$flags != "x0x1" ]; then
18161                 error "flag $flags is not 0x1"
18162         fi
18163
18164         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18165         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18166         touch $DIR/$tdir/foo_161c
18167         touch $DIR/$tdir/bar_161c
18168         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18169         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18170         changelog_dump | grep RENME | tail -n 5
18171         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18172         changelog_clear 0 || error "changelog_clear failed"
18173         if [ x$flags != "x0x0" ]; then
18174                 error "flag $flags is not 0x0"
18175         fi
18176         echo "rename overwrite a target having nlink > 1," \
18177                 "changelog record has flags of $flags"
18178
18179         # rename doesn't overwrite a target (changelog flag 0x0)
18180         touch $DIR/$tdir/foo_161c
18181         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18182         changelog_dump | grep RENME | tail -n 5
18183         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18184         changelog_clear 0 || error "changelog_clear failed"
18185         if [ x$flags != "x0x0" ]; then
18186                 error "flag $flags is not 0x0"
18187         fi
18188         echo "rename doesn't overwrite a target," \
18189                 "changelog record has flags of $flags"
18190
18191         # define CLF_UNLINK_LAST 0x0001
18192         # unlink a file having nlink = 1 (changelog flag 0x1)
18193         rm -f $DIR/$tdir/foo2_161c
18194         changelog_dump | grep UNLNK | tail -n 5
18195         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18196         changelog_clear 0 || error "changelog_clear failed"
18197         if [ x$flags != "x0x1" ]; then
18198                 error "flag $flags is not 0x1"
18199         fi
18200         echo "unlink a file having nlink = 1," \
18201                 "changelog record has flags of $flags"
18202
18203         # unlink a file having nlink > 1 (changelog flag 0x0)
18204         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18205         rm -f $DIR/$tdir/foobar_161c
18206         changelog_dump | grep UNLNK | tail -n 5
18207         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18208         changelog_clear 0 || error "changelog_clear failed"
18209         if [ x$flags != "x0x0" ]; then
18210                 error "flag $flags is not 0x0"
18211         fi
18212         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18213 }
18214 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18215
18216 test_161d() {
18217         remote_mds_nodsh && skip "remote MDS with nodsh"
18218         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18219
18220         local pid
18221         local fid
18222
18223         changelog_register || error "changelog_register failed"
18224
18225         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18226         # interfer with $MOUNT/.lustre/fid/ access
18227         mkdir $DIR/$tdir
18228         [[ $? -eq 0 ]] || error "mkdir failed"
18229
18230         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18231         $LCTL set_param fail_loc=0x8000140c
18232         # 5s pause
18233         $LCTL set_param fail_val=5
18234
18235         # create file
18236         echo foofoo > $DIR/$tdir/$tfile &
18237         pid=$!
18238
18239         # wait for create to be delayed
18240         sleep 2
18241
18242         ps -p $pid
18243         [[ $? -eq 0 ]] || error "create should be blocked"
18244
18245         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18246         stack_trap "rm -f $tempfile"
18247         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18248         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18249         # some delay may occur during ChangeLog publishing and file read just
18250         # above, that could allow file write to happen finally
18251         [[ -s $tempfile ]] && echo "file should be empty"
18252
18253         $LCTL set_param fail_loc=0
18254
18255         wait $pid
18256         [[ $? -eq 0 ]] || error "create failed"
18257 }
18258 run_test 161d "create with concurrent .lustre/fid access"
18259
18260 check_path() {
18261         local expected="$1"
18262         shift
18263         local fid="$2"
18264
18265         local path
18266         path=$($LFS fid2path "$@")
18267         local rc=$?
18268
18269         if [ $rc -ne 0 ]; then
18270                 error "path looked up of '$expected' failed: rc=$rc"
18271         elif [ "$path" != "$expected" ]; then
18272                 error "path looked up '$path' instead of '$expected'"
18273         else
18274                 echo "FID '$fid' resolves to path '$path' as expected"
18275         fi
18276 }
18277
18278 test_162a() { # was test_162
18279         test_mkdir -p -c1 $DIR/$tdir/d2
18280         touch $DIR/$tdir/d2/$tfile
18281         touch $DIR/$tdir/d2/x1
18282         touch $DIR/$tdir/d2/x2
18283         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18284         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18285         # regular file
18286         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18287         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18288
18289         # softlink
18290         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18291         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18292         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18293
18294         # softlink to wrong file
18295         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18296         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18297         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18298
18299         # hardlink
18300         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18301         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18302         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18303         # fid2path dir/fsname should both work
18304         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18305         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18306
18307         # hardlink count: check that there are 2 links
18308         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18309         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18310
18311         # hardlink indexing: remove the first link
18312         rm $DIR/$tdir/d2/p/q/r/hlink
18313         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18314 }
18315 run_test 162a "path lookup sanity"
18316
18317 test_162b() {
18318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18319         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18320
18321         mkdir $DIR/$tdir
18322         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18323                                 error "create striped dir failed"
18324
18325         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18326                                         tail -n 1 | awk '{print $2}')
18327         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18328
18329         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18330         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18331
18332         # regular file
18333         for ((i=0;i<5;i++)); do
18334                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18335                         error "get fid for f$i failed"
18336                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18337
18338                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18339                         error "get fid for d$i failed"
18340                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18341         done
18342
18343         return 0
18344 }
18345 run_test 162b "striped directory path lookup sanity"
18346
18347 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18348 test_162c() {
18349         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18350                 skip "Need MDS version at least 2.7.51"
18351
18352         local lpath=$tdir.local
18353         local rpath=$tdir.remote
18354
18355         test_mkdir $DIR/$lpath
18356         test_mkdir $DIR/$rpath
18357
18358         for ((i = 0; i <= 101; i++)); do
18359                 lpath="$lpath/$i"
18360                 mkdir $DIR/$lpath
18361                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18362                         error "get fid for local directory $DIR/$lpath failed"
18363                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18364
18365                 rpath="$rpath/$i"
18366                 test_mkdir $DIR/$rpath
18367                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18368                         error "get fid for remote directory $DIR/$rpath failed"
18369                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18370         done
18371
18372         return 0
18373 }
18374 run_test 162c "fid2path works with paths 100 or more directories deep"
18375
18376 oalr_event_count() {
18377         local event="${1}"
18378         local trace="${2}"
18379
18380         awk -v name="${FSNAME}-OST0000" \
18381             -v event="${event}" \
18382             '$1 == "TRACE" && $2 == event && $3 == name' \
18383             "${trace}" |
18384         wc -l
18385 }
18386
18387 oalr_expect_event_count() {
18388         local event="${1}"
18389         local trace="${2}"
18390         local expect="${3}"
18391         local count
18392
18393         count=$(oalr_event_count "${event}" "${trace}")
18394         if ((count == expect)); then
18395                 return 0
18396         fi
18397
18398         error_noexit "${event} event count was '${count}', expected ${expect}"
18399         cat "${trace}" >&2
18400         exit 1
18401 }
18402
18403 cleanup_165() {
18404         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18405         stop ost1
18406         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18407 }
18408
18409 setup_165() {
18410         sync # Flush previous IOs so we can count log entries.
18411         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18412         stack_trap cleanup_165 EXIT
18413 }
18414
18415 test_165a() {
18416         local trace="/tmp/${tfile}.trace"
18417         local rc
18418         local count
18419
18420         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18421                 skip "OFD access log unsupported"
18422
18423         setup_165
18424         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18425         sleep 5
18426
18427         do_facet ost1 ofd_access_log_reader --list
18428         stop ost1
18429
18430         do_facet ost1 killall -TERM ofd_access_log_reader
18431         wait
18432         rc=$?
18433
18434         if ((rc != 0)); then
18435                 error "ofd_access_log_reader exited with rc = '${rc}'"
18436         fi
18437
18438         # Parse trace file for discovery events:
18439         oalr_expect_event_count alr_log_add "${trace}" 1
18440         oalr_expect_event_count alr_log_eof "${trace}" 1
18441         oalr_expect_event_count alr_log_free "${trace}" 1
18442 }
18443 run_test 165a "ofd access log discovery"
18444
18445 test_165b() {
18446         local trace="/tmp/${tfile}.trace"
18447         local file="${DIR}/${tfile}"
18448         local pfid1
18449         local pfid2
18450         local -a entry
18451         local rc
18452         local count
18453         local size
18454         local flags
18455
18456         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18457                 skip "OFD access log unsupported"
18458
18459         setup_165
18460         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18461         sleep 5
18462
18463         do_facet ost1 ofd_access_log_reader --list
18464
18465         lfs setstripe -c 1 -i 0 "${file}"
18466         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18467                 error "cannot create '${file}'"
18468
18469         sleep 5
18470         do_facet ost1 killall -TERM ofd_access_log_reader
18471         wait
18472         rc=$?
18473
18474         if ((rc != 0)); then
18475                 error "ofd_access_log_reader exited with rc = '${rc}'"
18476         fi
18477
18478         oalr_expect_event_count alr_log_entry "${trace}" 1
18479
18480         pfid1=$($LFS path2fid "${file}")
18481
18482         # 1     2             3   4    5     6   7    8    9     10
18483         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18484         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18485
18486         echo "entry = '${entry[*]}'" >&2
18487
18488         pfid2=${entry[4]}
18489         if [[ "${pfid1}" != "${pfid2}" ]]; then
18490                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18491         fi
18492
18493         size=${entry[8]}
18494         if ((size != 1048576)); then
18495                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18496         fi
18497
18498         flags=${entry[10]}
18499         if [[ "${flags}" != "w" ]]; then
18500                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18501         fi
18502
18503         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18504         sleep 5
18505
18506         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18507                 error "cannot read '${file}'"
18508         sleep 5
18509
18510         do_facet ost1 killall -TERM ofd_access_log_reader
18511         wait
18512         rc=$?
18513
18514         if ((rc != 0)); then
18515                 error "ofd_access_log_reader exited with rc = '${rc}'"
18516         fi
18517
18518         oalr_expect_event_count alr_log_entry "${trace}" 1
18519
18520         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18521         echo "entry = '${entry[*]}'" >&2
18522
18523         pfid2=${entry[4]}
18524         if [[ "${pfid1}" != "${pfid2}" ]]; then
18525                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18526         fi
18527
18528         size=${entry[8]}
18529         if ((size != 524288)); then
18530                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18531         fi
18532
18533         flags=${entry[10]}
18534         if [[ "${flags}" != "r" ]]; then
18535                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18536         fi
18537 }
18538 run_test 165b "ofd access log entries are produced and consumed"
18539
18540 test_165c() {
18541         local trace="/tmp/${tfile}.trace"
18542         local file="${DIR}/${tdir}/${tfile}"
18543
18544         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18545                 skip "OFD access log unsupported"
18546
18547         test_mkdir "${DIR}/${tdir}"
18548
18549         setup_165
18550         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18551         sleep 5
18552
18553         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18554
18555         # 4096 / 64 = 64. Create twice as many entries.
18556         for ((i = 0; i < 128; i++)); do
18557                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18558                         error "cannot create file"
18559         done
18560
18561         sync
18562
18563         do_facet ost1 killall -TERM ofd_access_log_reader
18564         wait
18565         rc=$?
18566         if ((rc != 0)); then
18567                 error "ofd_access_log_reader exited with rc = '${rc}'"
18568         fi
18569
18570         unlinkmany  "${file}-%d" 128
18571 }
18572 run_test 165c "full ofd access logs do not block IOs"
18573
18574 oal_get_read_count() {
18575         local stats="$1"
18576
18577         # STATS lustre-OST0001 alr_read_count 1
18578
18579         do_facet ost1 cat "${stats}" |
18580         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18581              END { print count; }'
18582 }
18583
18584 oal_expect_read_count() {
18585         local stats="$1"
18586         local count
18587         local expect="$2"
18588
18589         # Ask ofd_access_log_reader to write stats.
18590         do_facet ost1 killall -USR1 ofd_access_log_reader
18591
18592         # Allow some time for things to happen.
18593         sleep 1
18594
18595         count=$(oal_get_read_count "${stats}")
18596         if ((count == expect)); then
18597                 return 0
18598         fi
18599
18600         error_noexit "bad read count, got ${count}, expected ${expect}"
18601         do_facet ost1 cat "${stats}" >&2
18602         exit 1
18603 }
18604
18605 test_165d() {
18606         local stats="/tmp/${tfile}.stats"
18607         local file="${DIR}/${tdir}/${tfile}"
18608         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18609
18610         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18611                 skip "OFD access log unsupported"
18612
18613         test_mkdir "${DIR}/${tdir}"
18614
18615         setup_165
18616         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18617         sleep 5
18618
18619         lfs setstripe -c 1 -i 0 "${file}"
18620
18621         do_facet ost1 lctl set_param "${param}=rw"
18622         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18623                 error "cannot create '${file}'"
18624         oal_expect_read_count "${stats}" 1
18625
18626         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18627                 error "cannot read '${file}'"
18628         oal_expect_read_count "${stats}" 2
18629
18630         do_facet ost1 lctl set_param "${param}=r"
18631         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18632                 error "cannot create '${file}'"
18633         oal_expect_read_count "${stats}" 2
18634
18635         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18636                 error "cannot read '${file}'"
18637         oal_expect_read_count "${stats}" 3
18638
18639         do_facet ost1 lctl set_param "${param}=w"
18640         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18641                 error "cannot create '${file}'"
18642         oal_expect_read_count "${stats}" 4
18643
18644         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18645                 error "cannot read '${file}'"
18646         oal_expect_read_count "${stats}" 4
18647
18648         do_facet ost1 lctl set_param "${param}=0"
18649         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18650                 error "cannot create '${file}'"
18651         oal_expect_read_count "${stats}" 4
18652
18653         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18654                 error "cannot read '${file}'"
18655         oal_expect_read_count "${stats}" 4
18656
18657         do_facet ost1 killall -TERM ofd_access_log_reader
18658         wait
18659         rc=$?
18660         if ((rc != 0)); then
18661                 error "ofd_access_log_reader exited with rc = '${rc}'"
18662         fi
18663 }
18664 run_test 165d "ofd_access_log mask works"
18665
18666 test_165e() {
18667         local stats="/tmp/${tfile}.stats"
18668         local file0="${DIR}/${tdir}-0/${tfile}"
18669         local file1="${DIR}/${tdir}-1/${tfile}"
18670
18671         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18672                 skip "OFD access log unsupported"
18673
18674         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18675
18676         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18677         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18678
18679         lfs setstripe -c 1 -i 0 "${file0}"
18680         lfs setstripe -c 1 -i 0 "${file1}"
18681
18682         setup_165
18683         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18684         sleep 5
18685
18686         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18687                 error "cannot create '${file0}'"
18688         sync
18689         oal_expect_read_count "${stats}" 0
18690
18691         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18692                 error "cannot create '${file1}'"
18693         sync
18694         oal_expect_read_count "${stats}" 1
18695
18696         do_facet ost1 killall -TERM ofd_access_log_reader
18697         wait
18698         rc=$?
18699         if ((rc != 0)); then
18700                 error "ofd_access_log_reader exited with rc = '${rc}'"
18701         fi
18702 }
18703 run_test 165e "ofd_access_log MDT index filter works"
18704
18705 test_165f() {
18706         local trace="/tmp/${tfile}.trace"
18707         local rc
18708         local count
18709
18710         setup_165
18711         do_facet ost1 timeout 60 ofd_access_log_reader \
18712                 --exit-on-close --debug=- --trace=- > "${trace}" &
18713         sleep 5
18714         stop ost1
18715
18716         wait
18717         rc=$?
18718
18719         if ((rc != 0)); then
18720                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18721                 cat "${trace}"
18722                 exit 1
18723         fi
18724 }
18725 run_test 165f "ofd_access_log_reader --exit-on-close works"
18726
18727 test_169() {
18728         # do directio so as not to populate the page cache
18729         log "creating a 10 Mb file"
18730         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18731                 error "multiop failed while creating a file"
18732         log "starting reads"
18733         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18734         log "truncating the file"
18735         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18736                 error "multiop failed while truncating the file"
18737         log "killing dd"
18738         kill %+ || true # reads might have finished
18739         echo "wait until dd is finished"
18740         wait
18741         log "removing the temporary file"
18742         rm -rf $DIR/$tfile || error "tmp file removal failed"
18743 }
18744 run_test 169 "parallel read and truncate should not deadlock"
18745
18746 test_170() {
18747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18748
18749         $LCTL clear     # bug 18514
18750         $LCTL debug_daemon start $TMP/${tfile}_log_good
18751         touch $DIR/$tfile
18752         $LCTL debug_daemon stop
18753         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18754                 error "sed failed to read log_good"
18755
18756         $LCTL debug_daemon start $TMP/${tfile}_log_good
18757         rm -rf $DIR/$tfile
18758         $LCTL debug_daemon stop
18759
18760         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18761                error "lctl df log_bad failed"
18762
18763         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18764         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18765
18766         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18767         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18768
18769         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18770                 error "bad_line good_line1 good_line2 are empty"
18771
18772         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18773         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18774         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18775
18776         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18777         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18778         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18779
18780         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18781                 error "bad_line_new good_line_new are empty"
18782
18783         local expected_good=$((good_line1 + good_line2*2))
18784
18785         rm -f $TMP/${tfile}*
18786         # LU-231, short malformed line may not be counted into bad lines
18787         if [ $bad_line -ne $bad_line_new ] &&
18788                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18789                 error "expected $bad_line bad lines, but got $bad_line_new"
18790                 return 1
18791         fi
18792
18793         if [ $expected_good -ne $good_line_new ]; then
18794                 error "expected $expected_good good lines, but got $good_line_new"
18795                 return 2
18796         fi
18797         true
18798 }
18799 run_test 170 "test lctl df to handle corrupted log ====================="
18800
18801 test_171() { # bug20592
18802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18803
18804         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18805         $LCTL set_param fail_loc=0x50e
18806         $LCTL set_param fail_val=3000
18807         multiop_bg_pause $DIR/$tfile O_s || true
18808         local MULTIPID=$!
18809         kill -USR1 $MULTIPID
18810         # cause log dump
18811         sleep 3
18812         wait $MULTIPID
18813         if dmesg | grep "recursive fault"; then
18814                 error "caught a recursive fault"
18815         fi
18816         $LCTL set_param fail_loc=0
18817         true
18818 }
18819 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18820
18821 test_172() {
18822
18823         #define OBD_FAIL_OBD_CLEANUP  0x60e
18824         $LCTL set_param fail_loc=0x60e
18825         umount $MOUNT || error "umount $MOUNT failed"
18826         stack_trap "mount_client $MOUNT"
18827
18828         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18829                 error "no client OBDs are remained"
18830
18831         $LCTL dl | while read devno state type name foo; do
18832                 case $type in
18833                 lov|osc|lmv|mdc)
18834                         $LCTL --device $name cleanup
18835                         $LCTL --device $name detach
18836                         ;;
18837                 *)
18838                         # skip server devices
18839                         ;;
18840                 esac
18841         done
18842
18843         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18844                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18845                 error "some client OBDs are still remained"
18846         fi
18847
18848 }
18849 run_test 172 "manual device removal with lctl cleanup/detach ======"
18850
18851 # it would be good to share it with obdfilter-survey/iokit-libecho code
18852 setup_obdecho_osc () {
18853         local rc=0
18854         local ost_nid=$1
18855         local obdfilter_name=$2
18856         echo "Creating new osc for $obdfilter_name on $ost_nid"
18857         # make sure we can find loopback nid
18858         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18859
18860         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18861                            ${obdfilter_name}_osc_UUID || rc=2; }
18862         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18863                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18864         return $rc
18865 }
18866
18867 cleanup_obdecho_osc () {
18868         local obdfilter_name=$1
18869         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18870         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18871         return 0
18872 }
18873
18874 obdecho_test() {
18875         local OBD=$1
18876         local node=$2
18877         local pages=${3:-64}
18878         local rc=0
18879         local id
18880
18881         local count=10
18882         local obd_size=$(get_obd_size $node $OBD)
18883         local page_size=$(get_page_size $node)
18884         if [[ -n "$obd_size" ]]; then
18885                 local new_count=$((obd_size / (pages * page_size / 1024)))
18886                 [[ $new_count -ge $count ]] || count=$new_count
18887         fi
18888
18889         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18890         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18891                            rc=2; }
18892         if [ $rc -eq 0 ]; then
18893             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18894             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18895         fi
18896         echo "New object id is $id"
18897         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18898                            rc=4; }
18899         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18900                            "test_brw $count w v $pages $id" || rc=4; }
18901         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18902                            rc=4; }
18903         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18904                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18905         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18906                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18907         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18908         return $rc
18909 }
18910
18911 test_180a() {
18912         skip "obdecho on osc is no longer supported"
18913 }
18914 run_test 180a "test obdecho on osc"
18915
18916 test_180b() {
18917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18918         remote_ost_nodsh && skip "remote OST with nodsh"
18919
18920         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18921                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18922                 error "failed to load module obdecho"
18923
18924         local target=$(do_facet ost1 $LCTL dl |
18925                        awk '/obdfilter/ { print $4; exit; }')
18926
18927         if [ -n "$target" ]; then
18928                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18929         else
18930                 do_facet ost1 $LCTL dl
18931                 error "there is no obdfilter target on ost1"
18932         fi
18933 }
18934 run_test 180b "test obdecho directly on obdfilter"
18935
18936 test_180c() { # LU-2598
18937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18938         remote_ost_nodsh && skip "remote OST with nodsh"
18939         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18940                 skip "Need MDS version at least 2.4.0"
18941
18942         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18943                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18944                 error "failed to load module obdecho"
18945
18946         local target=$(do_facet ost1 $LCTL dl |
18947                        awk '/obdfilter/ { print $4; exit; }')
18948
18949         if [ -n "$target" ]; then
18950                 local pages=16384 # 64MB bulk I/O RPC size
18951
18952                 obdecho_test "$target" ost1 "$pages" ||
18953                         error "obdecho_test with pages=$pages failed with $?"
18954         else
18955                 do_facet ost1 $LCTL dl
18956                 error "there is no obdfilter target on ost1"
18957         fi
18958 }
18959 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18960
18961 test_181() { # bug 22177
18962         test_mkdir $DIR/$tdir
18963         # create enough files to index the directory
18964         createmany -o $DIR/$tdir/foobar 4000
18965         # print attributes for debug purpose
18966         lsattr -d .
18967         # open dir
18968         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18969         MULTIPID=$!
18970         # remove the files & current working dir
18971         unlinkmany $DIR/$tdir/foobar 4000
18972         rmdir $DIR/$tdir
18973         kill -USR1 $MULTIPID
18974         wait $MULTIPID
18975         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18976         return 0
18977 }
18978 run_test 181 "Test open-unlinked dir ========================"
18979
18980 test_182a() {
18981         local fcount=1000
18982         local tcount=10
18983
18984         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18985
18986         $LCTL set_param mdc.*.rpc_stats=clear
18987
18988         for (( i = 0; i < $tcount; i++ )) ; do
18989                 mkdir $DIR/$tdir/$i
18990         done
18991
18992         for (( i = 0; i < $tcount; i++ )) ; do
18993                 createmany -o $DIR/$tdir/$i/f- $fcount &
18994         done
18995         wait
18996
18997         for (( i = 0; i < $tcount; i++ )) ; do
18998                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18999         done
19000         wait
19001
19002         $LCTL get_param mdc.*.rpc_stats
19003
19004         rm -rf $DIR/$tdir
19005 }
19006 run_test 182a "Test parallel modify metadata operations from mdc"
19007
19008 test_182b() {
19009         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19010         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19011         local dcount=1000
19012         local tcount=10
19013         local stime
19014         local etime
19015         local delta
19016
19017         do_facet mds1 $LCTL list_param \
19018                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19019                 skip "MDS lacks parallel RPC handling"
19020
19021         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19022
19023         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19024                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19025
19026         stime=$(date +%s)
19027         createmany -i 0 -d $DIR/$tdir/t- $tcount
19028
19029         for (( i = 0; i < $tcount; i++ )) ; do
19030                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19031         done
19032         wait
19033         etime=$(date +%s)
19034         delta=$((etime - stime))
19035         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19036
19037         stime=$(date +%s)
19038         for (( i = 0; i < $tcount; i++ )) ; do
19039                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19040         done
19041         wait
19042         etime=$(date +%s)
19043         delta=$((etime - stime))
19044         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19045
19046         rm -rf $DIR/$tdir
19047
19048         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19049
19050         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19051
19052         stime=$(date +%s)
19053         createmany -i 0 -d $DIR/$tdir/t- $tcount
19054
19055         for (( i = 0; i < $tcount; i++ )) ; do
19056                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19057         done
19058         wait
19059         etime=$(date +%s)
19060         delta=$((etime - stime))
19061         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19062
19063         stime=$(date +%s)
19064         for (( i = 0; i < $tcount; i++ )) ; do
19065                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19066         done
19067         wait
19068         etime=$(date +%s)
19069         delta=$((etime - stime))
19070         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19071
19072         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19073 }
19074 run_test 182b "Test parallel modify metadata operations from osp"
19075
19076 test_183() { # LU-2275
19077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19078         remote_mds_nodsh && skip "remote MDS with nodsh"
19079         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19080                 skip "Need MDS version at least 2.3.56"
19081
19082         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19083         echo aaa > $DIR/$tdir/$tfile
19084
19085 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19086         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19087
19088         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19089         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19090
19091         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19092
19093         # Flush negative dentry cache
19094         touch $DIR/$tdir/$tfile
19095
19096         # We are not checking for any leaked references here, they'll
19097         # become evident next time we do cleanup with module unload.
19098         rm -rf $DIR/$tdir
19099 }
19100 run_test 183 "No crash or request leak in case of strange dispositions ========"
19101
19102 # test suite 184 is for LU-2016, LU-2017
19103 test_184a() {
19104         check_swap_layouts_support
19105
19106         dir0=$DIR/$tdir/$testnum
19107         test_mkdir -p -c1 $dir0
19108         ref1=/etc/passwd
19109         ref2=/etc/group
19110         file1=$dir0/f1
19111         file2=$dir0/f2
19112         $LFS setstripe -c1 $file1
19113         cp $ref1 $file1
19114         $LFS setstripe -c2 $file2
19115         cp $ref2 $file2
19116         gen1=$($LFS getstripe -g $file1)
19117         gen2=$($LFS getstripe -g $file2)
19118
19119         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19120         gen=$($LFS getstripe -g $file1)
19121         [[ $gen1 != $gen ]] ||
19122                 error "Layout generation on $file1 does not change"
19123         gen=$($LFS getstripe -g $file2)
19124         [[ $gen2 != $gen ]] ||
19125                 error "Layout generation on $file2 does not change"
19126
19127         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19128         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19129
19130         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19131 }
19132 run_test 184a "Basic layout swap"
19133
19134 test_184b() {
19135         check_swap_layouts_support
19136
19137         dir0=$DIR/$tdir/$testnum
19138         mkdir -p $dir0 || error "creating dir $dir0"
19139         file1=$dir0/f1
19140         file2=$dir0/f2
19141         file3=$dir0/f3
19142         dir1=$dir0/d1
19143         dir2=$dir0/d2
19144         mkdir $dir1 $dir2
19145         $LFS setstripe -c1 $file1
19146         $LFS setstripe -c2 $file2
19147         $LFS setstripe -c1 $file3
19148         chown $RUNAS_ID $file3
19149         gen1=$($LFS getstripe -g $file1)
19150         gen2=$($LFS getstripe -g $file2)
19151
19152         $LFS swap_layouts $dir1 $dir2 &&
19153                 error "swap of directories layouts should fail"
19154         $LFS swap_layouts $dir1 $file1 &&
19155                 error "swap of directory and file layouts should fail"
19156         $RUNAS $LFS swap_layouts $file1 $file2 &&
19157                 error "swap of file we cannot write should fail"
19158         $LFS swap_layouts $file1 $file3 &&
19159                 error "swap of file with different owner should fail"
19160         /bin/true # to clear error code
19161 }
19162 run_test 184b "Forbidden layout swap (will generate errors)"
19163
19164 test_184c() {
19165         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19166         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19167         check_swap_layouts_support
19168         check_swap_layout_no_dom $DIR
19169
19170         local dir0=$DIR/$tdir/$testnum
19171         mkdir -p $dir0 || error "creating dir $dir0"
19172
19173         local ref1=$dir0/ref1
19174         local ref2=$dir0/ref2
19175         local file1=$dir0/file1
19176         local file2=$dir0/file2
19177         # create a file large enough for the concurrent test
19178         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19179         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19180         echo "ref file size: ref1($(stat -c %s $ref1))," \
19181              "ref2($(stat -c %s $ref2))"
19182
19183         cp $ref2 $file2
19184         dd if=$ref1 of=$file1 bs=16k &
19185         local DD_PID=$!
19186
19187         # Make sure dd starts to copy file, but wait at most 5 seconds
19188         local loops=0
19189         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19190
19191         $LFS swap_layouts $file1 $file2
19192         local rc=$?
19193         wait $DD_PID
19194         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19195         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19196
19197         # how many bytes copied before swapping layout
19198         local copied=$(stat -c %s $file2)
19199         local remaining=$(stat -c %s $ref1)
19200         remaining=$((remaining - copied))
19201         echo "Copied $copied bytes before swapping layout..."
19202
19203         cmp -n $copied $file1 $ref2 | grep differ &&
19204                 error "Content mismatch [0, $copied) of ref2 and file1"
19205         cmp -n $copied $file2 $ref1 ||
19206                 error "Content mismatch [0, $copied) of ref1 and file2"
19207         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19208                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19209
19210         # clean up
19211         rm -f $ref1 $ref2 $file1 $file2
19212 }
19213 run_test 184c "Concurrent write and layout swap"
19214
19215 test_184d() {
19216         check_swap_layouts_support
19217         check_swap_layout_no_dom $DIR
19218         [ -z "$(which getfattr 2>/dev/null)" ] &&
19219                 skip_env "no getfattr command"
19220
19221         local file1=$DIR/$tdir/$tfile-1
19222         local file2=$DIR/$tdir/$tfile-2
19223         local file3=$DIR/$tdir/$tfile-3
19224         local lovea1
19225         local lovea2
19226
19227         mkdir -p $DIR/$tdir
19228         touch $file1 || error "create $file1 failed"
19229         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19230                 error "create $file2 failed"
19231         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19232                 error "create $file3 failed"
19233         lovea1=$(get_layout_param $file1)
19234
19235         $LFS swap_layouts $file2 $file3 ||
19236                 error "swap $file2 $file3 layouts failed"
19237         $LFS swap_layouts $file1 $file2 ||
19238                 error "swap $file1 $file2 layouts failed"
19239
19240         lovea2=$(get_layout_param $file2)
19241         echo "$lovea1"
19242         echo "$lovea2"
19243         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19244
19245         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19246         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19247 }
19248 run_test 184d "allow stripeless layouts swap"
19249
19250 test_184e() {
19251         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19252                 skip "Need MDS version at least 2.6.94"
19253         check_swap_layouts_support
19254         check_swap_layout_no_dom $DIR
19255         [ -z "$(which getfattr 2>/dev/null)" ] &&
19256                 skip_env "no getfattr command"
19257
19258         local file1=$DIR/$tdir/$tfile-1
19259         local file2=$DIR/$tdir/$tfile-2
19260         local file3=$DIR/$tdir/$tfile-3
19261         local lovea
19262
19263         mkdir -p $DIR/$tdir
19264         touch $file1 || error "create $file1 failed"
19265         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19266                 error "create $file2 failed"
19267         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19268                 error "create $file3 failed"
19269
19270         $LFS swap_layouts $file1 $file2 ||
19271                 error "swap $file1 $file2 layouts failed"
19272
19273         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19274         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19275
19276         echo 123 > $file1 || error "Should be able to write into $file1"
19277
19278         $LFS swap_layouts $file1 $file3 ||
19279                 error "swap $file1 $file3 layouts failed"
19280
19281         echo 123 > $file1 || error "Should be able to write into $file1"
19282
19283         rm -rf $file1 $file2 $file3
19284 }
19285 run_test 184e "Recreate layout after stripeless layout swaps"
19286
19287 test_184f() {
19288         # Create a file with name longer than sizeof(struct stat) ==
19289         # 144 to see if we can get chars from the file name to appear
19290         # in the returned striping. Note that 'f' == 0x66.
19291         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19292
19293         mkdir -p $DIR/$tdir
19294         mcreate $DIR/$tdir/$file
19295         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19296                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19297         fi
19298 }
19299 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19300
19301 test_185() { # LU-2441
19302         # LU-3553 - no volatile file support in old servers
19303         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19304                 skip "Need MDS version at least 2.3.60"
19305
19306         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19307         touch $DIR/$tdir/spoo
19308         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19309         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19310                 error "cannot create/write a volatile file"
19311         [ "$FILESET" == "" ] &&
19312         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19313                 error "FID is still valid after close"
19314
19315         multiop_bg_pause $DIR/$tdir Vw4096_c
19316         local multi_pid=$!
19317
19318         local OLD_IFS=$IFS
19319         IFS=":"
19320         local fidv=($fid)
19321         IFS=$OLD_IFS
19322         # assume that the next FID for this client is sequential, since stdout
19323         # is unfortunately eaten by multiop_bg_pause
19324         local n=$((${fidv[1]} + 1))
19325         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19326         if [ "$FILESET" == "" ]; then
19327                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19328                         error "FID is missing before close"
19329         fi
19330         kill -USR1 $multi_pid
19331         # 1 second delay, so if mtime change we will see it
19332         sleep 1
19333         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19334         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19335 }
19336 run_test 185 "Volatile file support"
19337
19338 function create_check_volatile() {
19339         local idx=$1
19340         local tgt
19341
19342         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19343         local PID=$!
19344         sleep 1
19345         local FID=$(cat /tmp/${tfile}.fid)
19346         [ "$FID" == "" ] && error "can't get FID for volatile"
19347         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19348         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19349         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19350         kill -USR1 $PID
19351         wait
19352         sleep 1
19353         cancel_lru_locks mdc # flush opencache
19354         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19355         return 0
19356 }
19357
19358 test_185a(){
19359         # LU-12516 - volatile creation via .lustre
19360         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19361                 skip "Need MDS version at least 2.3.55"
19362
19363         create_check_volatile 0
19364         [ $MDSCOUNT -lt 2 ] && return 0
19365
19366         # DNE case
19367         create_check_volatile 1
19368
19369         return 0
19370 }
19371 run_test 185a "Volatile file creation in .lustre/fid/"
19372
19373 test_187a() {
19374         remote_mds_nodsh && skip "remote MDS with nodsh"
19375         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19376                 skip "Need MDS version at least 2.3.0"
19377
19378         local dir0=$DIR/$tdir/$testnum
19379         mkdir -p $dir0 || error "creating dir $dir0"
19380
19381         local file=$dir0/file1
19382         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19383         stack_trap "rm -f $file"
19384         local dv1=$($LFS data_version $file)
19385         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19386         local dv2=$($LFS data_version $file)
19387         [[ $dv1 != $dv2 ]] ||
19388                 error "data version did not change on write $dv1 == $dv2"
19389 }
19390 run_test 187a "Test data version change"
19391
19392 test_187b() {
19393         remote_mds_nodsh && skip "remote MDS with nodsh"
19394         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19395                 skip "Need MDS version at least 2.3.0"
19396
19397         local dir0=$DIR/$tdir/$testnum
19398         mkdir -p $dir0 || error "creating dir $dir0"
19399
19400         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19401         [[ ${DV[0]} != ${DV[1]} ]] ||
19402                 error "data version did not change on write"\
19403                       " ${DV[0]} == ${DV[1]}"
19404
19405         # clean up
19406         rm -f $file1
19407 }
19408 run_test 187b "Test data version change on volatile file"
19409
19410 test_200() {
19411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19412         remote_mgs_nodsh && skip "remote MGS with nodsh"
19413         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19414
19415         local POOL=${POOL:-cea1}
19416         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19417         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19418         # Pool OST targets
19419         local first_ost=0
19420         local last_ost=$(($OSTCOUNT - 1))
19421         local ost_step=2
19422         local ost_list=$(seq $first_ost $ost_step $last_ost)
19423         local ost_range="$first_ost $last_ost $ost_step"
19424         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19425         local file_dir=$POOL_ROOT/file_tst
19426         local subdir=$test_path/subdir
19427         local rc=0
19428
19429         while : ; do
19430                 # former test_200a test_200b
19431                 pool_add $POOL                          || { rc=$? ; break; }
19432                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19433                 # former test_200c test_200d
19434                 mkdir -p $test_path
19435                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19436                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19437                 mkdir -p $subdir
19438                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19439                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19440                                                         || { rc=$? ; break; }
19441                 # former test_200e test_200f
19442                 local files=$((OSTCOUNT*3))
19443                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19444                                                         || { rc=$? ; break; }
19445                 pool_create_files $POOL $file_dir $files "$ost_list" \
19446                                                         || { rc=$? ; break; }
19447                 # former test_200g test_200h
19448                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19449                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19450
19451                 # former test_201a test_201b test_201c
19452                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19453
19454                 local f=$test_path/$tfile
19455                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19456                 pool_remove $POOL $f                    || { rc=$? ; break; }
19457                 break
19458         done
19459
19460         destroy_test_pools
19461
19462         return $rc
19463 }
19464 run_test 200 "OST pools"
19465
19466 # usage: default_attr <count | size | offset>
19467 default_attr() {
19468         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19469 }
19470
19471 # usage: check_default_stripe_attr
19472 check_default_stripe_attr() {
19473         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19474         case $1 in
19475         --stripe-count|-c)
19476                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19477         --stripe-size|-S)
19478                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19479         --stripe-index|-i)
19480                 EXPECTED=-1;;
19481         *)
19482                 error "unknown getstripe attr '$1'"
19483         esac
19484
19485         [ $ACTUAL == $EXPECTED ] ||
19486                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19487 }
19488
19489 test_204a() {
19490         test_mkdir $DIR/$tdir
19491         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19492
19493         check_default_stripe_attr --stripe-count
19494         check_default_stripe_attr --stripe-size
19495         check_default_stripe_attr --stripe-index
19496 }
19497 run_test 204a "Print default stripe attributes"
19498
19499 test_204b() {
19500         test_mkdir $DIR/$tdir
19501         $LFS setstripe --stripe-count 1 $DIR/$tdir
19502
19503         check_default_stripe_attr --stripe-size
19504         check_default_stripe_attr --stripe-index
19505 }
19506 run_test 204b "Print default stripe size and offset"
19507
19508 test_204c() {
19509         test_mkdir $DIR/$tdir
19510         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19511
19512         check_default_stripe_attr --stripe-count
19513         check_default_stripe_attr --stripe-index
19514 }
19515 run_test 204c "Print default stripe count and offset"
19516
19517 test_204d() {
19518         test_mkdir $DIR/$tdir
19519         $LFS setstripe --stripe-index 0 $DIR/$tdir
19520
19521         check_default_stripe_attr --stripe-count
19522         check_default_stripe_attr --stripe-size
19523 }
19524 run_test 204d "Print default stripe count and size"
19525
19526 test_204e() {
19527         test_mkdir $DIR/$tdir
19528         $LFS setstripe -d $DIR/$tdir
19529
19530         # LU-16904 check if root is set as PFL layout
19531         local numcomp=$($LFS getstripe --component-count $MOUNT)
19532
19533         if [[ $numcomp -gt 0 ]]; then
19534                 check_default_stripe_attr --stripe-count
19535         else
19536                 check_default_stripe_attr --stripe-count --raw
19537         fi
19538         check_default_stripe_attr --stripe-size --raw
19539         check_default_stripe_attr --stripe-index --raw
19540 }
19541 run_test 204e "Print raw stripe attributes"
19542
19543 test_204f() {
19544         test_mkdir $DIR/$tdir
19545         $LFS setstripe --stripe-count 1 $DIR/$tdir
19546
19547         check_default_stripe_attr --stripe-size --raw
19548         check_default_stripe_attr --stripe-index --raw
19549 }
19550 run_test 204f "Print raw stripe size and offset"
19551
19552 test_204g() {
19553         test_mkdir $DIR/$tdir
19554         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19555
19556         check_default_stripe_attr --stripe-count --raw
19557         check_default_stripe_attr --stripe-index --raw
19558 }
19559 run_test 204g "Print raw stripe count and offset"
19560
19561 test_204h() {
19562         test_mkdir $DIR/$tdir
19563         $LFS setstripe --stripe-index 0 $DIR/$tdir
19564
19565         check_default_stripe_attr --stripe-count --raw
19566         check_default_stripe_attr --stripe-size --raw
19567 }
19568 run_test 204h "Print raw stripe count and size"
19569
19570 # Figure out which job scheduler is being used, if any,
19571 # or use a fake one
19572 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19573         JOBENV=SLURM_JOB_ID
19574 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19575         JOBENV=LSB_JOBID
19576 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19577         JOBENV=PBS_JOBID
19578 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19579         JOBENV=LOADL_STEP_ID
19580 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19581         JOBENV=JOB_ID
19582 else
19583         $LCTL list_param jobid_name > /dev/null 2>&1
19584         if [ $? -eq 0 ]; then
19585                 JOBENV=nodelocal
19586         else
19587                 JOBENV=FAKE_JOBID
19588         fi
19589 fi
19590 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19591
19592 verify_jobstats() {
19593         local cmd=($1)
19594         shift
19595         local facets="$@"
19596
19597 # we don't really need to clear the stats for this test to work, since each
19598 # command has a unique jobid, but it makes debugging easier if needed.
19599 #       for facet in $facets; do
19600 #               local dev=$(convert_facet2label $facet)
19601 #               # clear old jobstats
19602 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19603 #       done
19604
19605         # use a new JobID for each test, or we might see an old one
19606         [ "$JOBENV" = "FAKE_JOBID" ] &&
19607                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19608
19609         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19610
19611         [ "$JOBENV" = "nodelocal" ] && {
19612                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19613                 $LCTL set_param jobid_name=$FAKE_JOBID
19614                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19615         }
19616
19617         log "Test: ${cmd[*]}"
19618         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19619
19620         if [ $JOBENV = "FAKE_JOBID" ]; then
19621                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19622         else
19623                 ${cmd[*]}
19624         fi
19625
19626         # all files are created on OST0000
19627         for facet in $facets; do
19628                 local stats="*.$(convert_facet2label $facet).job_stats"
19629
19630                 # strip out libtool wrappers for in-tree executables
19631                 if (( $(do_facet $facet lctl get_param $stats |
19632                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19633                         do_facet $facet lctl get_param $stats
19634                         error "No jobstats for $JOBVAL found on $facet::$stats"
19635                 fi
19636         done
19637 }
19638
19639 jobstats_set() {
19640         local new_jobenv=$1
19641
19642         set_persistent_param_and_check client "jobid_var" \
19643                 "$FSNAME.sys.jobid_var" $new_jobenv
19644 }
19645
19646 test_205a() { # Job stats
19647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19648         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19649                 skip "Need MDS version with at least 2.7.1"
19650         remote_mgs_nodsh && skip "remote MGS with nodsh"
19651         remote_mds_nodsh && skip "remote MDS with nodsh"
19652         remote_ost_nodsh && skip "remote OST with nodsh"
19653         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19654                 skip "Server doesn't support jobstats"
19655         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19656
19657         local old_jobenv=$($LCTL get_param -n jobid_var)
19658         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19659         stack_trap "jobstats_set $old_jobenv" EXIT
19660
19661         changelog_register
19662
19663         local old_jobid_name=$($LCTL get_param jobid_name)
19664         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19665
19666         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19667                                 mdt.*.job_cleanup_interval | head -n 1)
19668         local new_interval=5
19669         do_facet $SINGLEMDS \
19670                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19671         stack_trap "do_facet $SINGLEMDS \
19672                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19673         local start=$SECONDS
19674
19675         local cmd
19676         # mkdir
19677         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19678         verify_jobstats "$cmd" "$SINGLEMDS"
19679         # rmdir
19680         cmd="rmdir $DIR/$tdir"
19681         verify_jobstats "$cmd" "$SINGLEMDS"
19682         # mkdir on secondary MDT
19683         if [ $MDSCOUNT -gt 1 ]; then
19684                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19685                 verify_jobstats "$cmd" "mds2"
19686         fi
19687         # mknod
19688         cmd="mknod $DIR/$tfile c 1 3"
19689         verify_jobstats "$cmd" "$SINGLEMDS"
19690         # unlink
19691         cmd="rm -f $DIR/$tfile"
19692         verify_jobstats "$cmd" "$SINGLEMDS"
19693         # create all files on OST0000 so verify_jobstats can find OST stats
19694         # open & close
19695         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19696         verify_jobstats "$cmd" "$SINGLEMDS"
19697         # setattr
19698         cmd="touch $DIR/$tfile"
19699         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19700         # write
19701         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19702         verify_jobstats "$cmd" "ost1"
19703         # read
19704         cancel_lru_locks osc
19705         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19706         verify_jobstats "$cmd" "ost1"
19707         # truncate
19708         cmd="$TRUNCATE $DIR/$tfile 0"
19709         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19710         # rename
19711         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19712         verify_jobstats "$cmd" "$SINGLEMDS"
19713         # jobstats expiry - sleep until old stats should be expired
19714         local left=$((new_interval + 5 - (SECONDS - start)))
19715         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19716                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19717                         "0" $left
19718         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19719         verify_jobstats "$cmd" "$SINGLEMDS"
19720         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19721             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19722
19723         # Ensure that jobid are present in changelog (if supported by MDS)
19724         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19725                 changelog_dump | tail -10
19726                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19727                 [ $jobids -eq 9 ] ||
19728                         error "Wrong changelog jobid count $jobids != 9"
19729
19730                 # LU-5862
19731                 JOBENV="disable"
19732                 jobstats_set $JOBENV
19733                 touch $DIR/$tfile
19734                 changelog_dump | grep $tfile
19735                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19736                 [ $jobids -eq 0 ] ||
19737                         error "Unexpected jobids when jobid_var=$JOBENV"
19738         fi
19739
19740         # test '%j' access to environment variable - if supported
19741         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19742                 JOBENV="JOBCOMPLEX"
19743                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19744
19745                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19746         fi
19747
19748         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19749                 JOBENV="JOBCOMPLEX"
19750                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19751
19752                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19753         fi
19754
19755         # test '%j' access to per-session jobid - if supported
19756         if lctl list_param jobid_this_session > /dev/null 2>&1
19757         then
19758                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19759                 lctl set_param jobid_this_session=$USER
19760
19761                 JOBENV="JOBCOMPLEX"
19762                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19763
19764                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19765         fi
19766 }
19767 run_test 205a "Verify job stats"
19768
19769 # LU-13117, LU-13597, LU-16599
19770 test_205b() {
19771         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19772                 skip "Need MDS version at least 2.13.54.91"
19773
19774         local job_stats="mdt.*.job_stats"
19775         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19776
19777         do_facet mds1 $LCTL set_param $job_stats=clear
19778
19779         # Setting jobid_var to USER might not be supported
19780         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19781         $LCTL set_param jobid_var=USER || true
19782         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19783         $LCTL set_param jobid_name="%j.%e.%u"
19784
19785         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19786         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19787                 { do_facet mds1 $LCTL get_param $job_stats;
19788                   error "Unexpected jobid found"; }
19789         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19790                 { do_facet mds1 $LCTL get_param $job_stats;
19791                   error "wrong job_stats format found"; }
19792
19793         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19794                 echo "MDS does not yet escape jobid" && return 0
19795
19796         mkdir_on_mdt0 $DIR/$tdir
19797         $LCTL set_param jobid_var=TEST205b
19798         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19799         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19800                       awk '/has\\x20sp/ {print $3}')
19801         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19802                   error "jobid not escaped"; }
19803
19804         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19805                 # need to run such a command on mds1:
19806                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19807                 #
19808                 # there might be multiple MDTs on single mds server, so need to
19809                 # specifiy MDT0000. Or the command will fail due to other MDTs
19810                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19811                         error "cannot clear escaped jobid in job_stats";
19812         else
19813                 echo "MDS does not support clearing escaped jobid"
19814         fi
19815 }
19816 run_test 205b "Verify job stats jobid and output format"
19817
19818 # LU-13733
19819 test_205c() {
19820         $LCTL set_param llite.*.stats=0
19821         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19822         $LCTL get_param llite.*.stats
19823         $LCTL get_param llite.*.stats | grep \
19824                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19825                         error "wrong client stats format found"
19826 }
19827 run_test 205c "Verify client stats format"
19828
19829 test_205d() {
19830         local file=$DIR/$tdir/$tfile
19831
19832         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19833                 skip "need lustre >= 2.15.53 for lljobstat"
19834         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19835                 skip "need lustre >= 2.15.53 for lljobstat"
19836         verify_yaml_available || skip_env "YAML verification not installed"
19837
19838         test_mkdir -i 0 $DIR/$tdir
19839         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19840         stack_trap "rm -rf $DIR/$tdir"
19841
19842         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19843                 error "failed to write data to $file"
19844         mv $file $file.2
19845
19846         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19847         echo -n 'verify rename_stats...'
19848         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19849                 verify_yaml || error "rename_stats is not valid YAML"
19850         echo " OK"
19851
19852         echo -n 'verify mdt job_stats...'
19853         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19854                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19855         echo " OK"
19856
19857         echo -n 'verify ost job_stats...'
19858         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19859                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19860         echo " OK"
19861 }
19862 run_test 205d "verify the format of some stats files"
19863
19864 test_205e() {
19865         local ops_comma
19866         local file=$DIR/$tdir/$tfile
19867         local -a cli_params
19868
19869         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19870                 skip "need lustre >= 2.15.53 for lljobstat"
19871         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19872                 skip "need lustre >= 2.15.53 for lljobstat"
19873         verify_yaml_available || skip_env "YAML verification not installed"
19874
19875         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19876         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19877         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19878
19879         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19880         stack_trap "rm -rf $DIR/$tdir"
19881
19882         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19883                 error "failed to create $file on ost1"
19884         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19885                 error "failed to write data to $file"
19886
19887         do_facet mds1 "$LCTL get_param *.*.job_stats"
19888         do_facet ost1 "$LCTL get_param *.*.job_stats"
19889
19890         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19891         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19892                 error "The output of lljobstat is not an valid YAML"
19893
19894         # verify that job dd.0 does exist and has some ops on ost1
19895         # typically this line is like:
19896         # - 205e.dd.0:            {ops: 20, ...}
19897         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19898                     awk '$2=="205e.dd.0:" {print $4}')
19899
19900         (( ${ops_comma%,} >= 10 )) ||
19901                 error "cannot find job 205e.dd.0 with ops >= 10"
19902 }
19903 run_test 205e "verify the output of lljobstat"
19904
19905 test_205f() {
19906         verify_yaml_available || skip_env "YAML verification not installed"
19907
19908         # check both qos_ost_weights and qos_mdt_weights
19909         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19910         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19911                 error "qos_ost_weights is not valid YAML"
19912 }
19913 run_test 205f "verify qos_ost_weights YAML format "
19914
19915 __test_205_jobstats_dump() {
19916         local -a pids
19917         local nbr_instance=$1
19918
19919         while true; do
19920                 if (( ${#pids[@]} >= nbr_instance )); then
19921                         wait ${pids[@]}
19922                         pids=()
19923                 fi
19924
19925                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19926                 pids+=( $! )
19927         done
19928 }
19929
19930 __test_205_cleanup() {
19931         kill $@
19932         # Clear all job entries
19933         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19934 }
19935
19936 test_205g() {
19937         local -a mds1_params
19938         local -a cli_params
19939         local pids
19940         local interval=5
19941
19942         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19943         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19944         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19945
19946         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19947         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19948         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19949
19950         # start jobs loop
19951         export TEST205G_ID=205g
19952         stack_trap "unset TEST205G_ID" EXIT
19953         while true; do
19954                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19955         done & pids="$! "
19956
19957         __test_205_jobstats_dump 4 & pids+="$! "
19958         stack_trap "__test_205_cleanup $pids" EXIT INT
19959
19960         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19961 }
19962 run_test 205g "stress test for job_stats procfile"
19963
19964 test_205h() {
19965         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
19966
19967         local dir=$DIR/$tdir
19968         local f=$dir/$tfile
19969         local f2=$dir/$tfile-2
19970         local f3=$dir/$tfile-3
19971         local subdir=$DIR/dir
19972         local val
19973
19974         local mdts=$(comma_list $(mdts_nodes))
19975         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
19976         local client_saved=$($LCTL get_param -n jobid_var)
19977
19978         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
19979         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
19980
19981         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
19982                 error "failed to set job_xattr parameter to user.job"
19983         $LCTL set_param jobid_var=procname.uid ||
19984                 error "failed to set jobid_var parameter"
19985
19986         test_mkdir $dir
19987
19988         touch $f
19989         val=$(getfattr -n user.job $f | grep user.job)
19990         [[ $val = user.job=\"touch.0\" ]] ||
19991                 error "expected user.job=\"touch.0\", got '$val'"
19992
19993         mkdir $subdir
19994         val=$(getfattr -n user.job $subdir | grep user.job)
19995         [[ $val = user.job=\"mkdir.0\" ]] ||
19996                 error "expected user.job=\"mkdir.0\", got '$val'"
19997
19998         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
19999                 error "failed to set job_xattr parameter to NONE"
20000
20001         touch $f2
20002         val=$(getfattr -d $f2)
20003         [[ -z $val ]] ||
20004                 error "expected no user xattr, got '$val'"
20005
20006         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20007                 error "failed to set job_xattr parameter to trusted.job"
20008
20009         touch $f3
20010         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20011         [[ $val = trusted.job=\"touch.0\" ]] ||
20012                 error "expected trusted.job=\"touch.0\", got '$val'"
20013 }
20014 run_test 205h "check jobid xattr is stored correctly"
20015
20016 test_205i() {
20017         local mdts=$(comma_list $(mdts_nodes))
20018         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20019
20020         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20021
20022         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20023                 error "failed to set mdt.*.job_xattr to user.1234567"
20024
20025         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20026                 error "failed to reject too long job_xattr name"
20027
20028         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20029                 error "failed to reject job_xattr name in bad format"
20030
20031         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20032                 error "failed to reject job_xattr name with invalid character"
20033
20034         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20035                         xargs $LCTL set_param" &&
20036                 error "failed to reject job_xattr name with non-ascii character"
20037
20038         return 0
20039 }
20040 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20041
20042 # LU-1480, LU-1773 and LU-1657
20043 test_206() {
20044         mkdir -p $DIR/$tdir
20045         $LFS setstripe -c -1 $DIR/$tdir
20046 #define OBD_FAIL_LOV_INIT 0x1403
20047         $LCTL set_param fail_loc=0xa0001403
20048         $LCTL set_param fail_val=1
20049         touch $DIR/$tdir/$tfile || true
20050 }
20051 run_test 206 "fail lov_init_raid0() doesn't lbug"
20052
20053 test_207a() {
20054         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20055         local fsz=`stat -c %s $DIR/$tfile`
20056         cancel_lru_locks mdc
20057
20058         # do not return layout in getattr intent
20059 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20060         $LCTL set_param fail_loc=0x170
20061         local sz=`stat -c %s $DIR/$tfile`
20062
20063         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20064
20065         rm -rf $DIR/$tfile
20066 }
20067 run_test 207a "can refresh layout at glimpse"
20068
20069 test_207b() {
20070         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20071         local cksum=`md5sum $DIR/$tfile`
20072         local fsz=`stat -c %s $DIR/$tfile`
20073         cancel_lru_locks mdc
20074         cancel_lru_locks osc
20075
20076         # do not return layout in getattr intent
20077 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20078         $LCTL set_param fail_loc=0x171
20079
20080         # it will refresh layout after the file is opened but before read issues
20081         echo checksum is "$cksum"
20082         echo "$cksum" |md5sum -c --quiet || error "file differs"
20083
20084         rm -rf $DIR/$tfile
20085 }
20086 run_test 207b "can refresh layout at open"
20087
20088 test_208() {
20089         # FIXME: in this test suite, only RD lease is used. This is okay
20090         # for now as only exclusive open is supported. After generic lease
20091         # is done, this test suite should be revised. - Jinshan
20092
20093         remote_mds_nodsh && skip "remote MDS with nodsh"
20094         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20095                 skip "Need MDS version at least 2.4.52"
20096
20097         echo "==== test 1: verify get lease work"
20098         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20099
20100         echo "==== test 2: verify lease can be broken by upcoming open"
20101         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20102         local PID=$!
20103         sleep 2
20104
20105         $MULTIOP $DIR/$tfile oO_RDWR:c
20106         kill -USR1 $PID && wait $PID || error "break lease error"
20107
20108         echo "==== test 3: verify lease can't be granted if an open already exists"
20109         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20110         local PID=$!
20111         sleep 2
20112
20113         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20114         kill -USR1 $PID && wait $PID || error "open file error"
20115
20116         echo "==== test 4: lease can sustain over recovery"
20117         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20118         PID=$!
20119         sleep 2
20120
20121         fail mds1
20122
20123         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20124
20125         echo "==== test 5: lease broken can't be regained by replay"
20126         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20127         PID=$!
20128         sleep 2
20129
20130         # open file to break lease and then recovery
20131         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20132         fail mds1
20133
20134         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20135
20136         rm -f $DIR/$tfile
20137 }
20138 run_test 208 "Exclusive open"
20139
20140 test_209() {
20141         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20142                 skip_env "must have disp_stripe"
20143
20144         touch $DIR/$tfile
20145         sync; sleep 5; sync;
20146
20147         echo 3 > /proc/sys/vm/drop_caches
20148         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20149                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20150         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20151
20152         # open/close 500 times
20153         for i in $(seq 500); do
20154                 cat $DIR/$tfile
20155         done
20156
20157         echo 3 > /proc/sys/vm/drop_caches
20158         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20159                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20160         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20161
20162         echo "before: $req_before, after: $req_after"
20163         [ $((req_after - req_before)) -ge 300 ] &&
20164                 error "open/close requests are not freed"
20165         return 0
20166 }
20167 run_test 209 "read-only open/close requests should be freed promptly"
20168
20169 test_210() {
20170         local pid
20171
20172         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20173         pid=$!
20174         sleep 1
20175
20176         $LFS getstripe $DIR/$tfile
20177         kill -USR1 $pid
20178         wait $pid || error "multiop failed"
20179
20180         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20181         pid=$!
20182         sleep 1
20183
20184         $LFS getstripe $DIR/$tfile
20185         kill -USR1 $pid
20186         wait $pid || error "multiop failed"
20187 }
20188 run_test 210 "lfs getstripe does not break leases"
20189
20190 test_212() {
20191         size=`date +%s`
20192         size=$((size % 8192 + 1))
20193         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20194         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20195         rm -f $DIR/f212 $DIR/f212.xyz
20196 }
20197 run_test 212 "Sendfile test ============================================"
20198
20199 test_213() {
20200         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20201         cancel_lru_locks osc
20202         lctl set_param fail_loc=0x8000040f
20203         # generate a read lock
20204         cat $DIR/$tfile > /dev/null
20205         # write to the file, it will try to cancel the above read lock.
20206         cat /etc/hosts >> $DIR/$tfile
20207 }
20208 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20209
20210 test_214() { # for bug 20133
20211         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20212         for (( i=0; i < 340; i++ )) ; do
20213                 touch $DIR/$tdir/d214c/a$i
20214         done
20215
20216         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20217         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20218         ls $DIR/d214c || error "ls $DIR/d214c failed"
20219         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20220         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20221 }
20222 run_test 214 "hash-indexed directory test - bug 20133"
20223
20224 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20225 create_lnet_proc_files() {
20226         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20227 }
20228
20229 # counterpart of create_lnet_proc_files
20230 remove_lnet_proc_files() {
20231         rm -f $TMP/lnet_$1.sys
20232 }
20233
20234 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20235 # 3rd arg as regexp for body
20236 check_lnet_proc_stats() {
20237         local l=$(cat "$TMP/lnet_$1" |wc -l)
20238         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20239
20240         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20241 }
20242
20243 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20244 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20245 # optional and can be regexp for 2nd line (lnet.routes case)
20246 check_lnet_proc_entry() {
20247         local blp=2          # blp stands for 'position of 1st line of body'
20248         [ -z "$5" ] || blp=3 # lnet.routes case
20249
20250         local l=$(cat "$TMP/lnet_$1" |wc -l)
20251         # subtracting one from $blp because the body can be empty
20252         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20253
20254         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20255                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20256
20257         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20258                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20259
20260         # bail out if any unexpected line happened
20261         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20262         [ "$?" != 0 ] || error "$2 misformatted"
20263 }
20264
20265 test_215() { # for bugs 18102, 21079, 21517
20266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20267
20268         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20269         local P='[1-9][0-9]*'           # positive numeric
20270         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20271         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20272         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20273         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20274
20275         local L1 # regexp for 1st line
20276         local L2 # regexp for 2nd line (optional)
20277         local BR # regexp for the rest (body)
20278
20279         # lnet.stats should look as 11 space-separated non-negative numerics
20280         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20281         create_lnet_proc_files "stats"
20282         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20283         remove_lnet_proc_files "stats"
20284
20285         # lnet.routes should look like this:
20286         # Routing disabled/enabled
20287         # net hops priority state router
20288         # where net is a string like tcp0, hops > 0, priority >= 0,
20289         # state is up/down,
20290         # router is a string like 192.168.1.1@tcp2
20291         L1="^Routing (disabled|enabled)$"
20292         L2="^net +hops +priority +state +router$"
20293         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20294         create_lnet_proc_files "routes"
20295         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20296         remove_lnet_proc_files "routes"
20297
20298         # lnet.routers should look like this:
20299         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20300         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20301         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20302         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20303         L1="^ref +rtr_ref +alive +router$"
20304         BR="^$P +$P +(up|down) +$NID$"
20305         create_lnet_proc_files "routers"
20306         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20307         remove_lnet_proc_files "routers"
20308
20309         # lnet.peers should look like this:
20310         # nid refs state last max rtr min tx min queue
20311         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20312         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20313         # numeric (0 or >0 or <0), queue >= 0.
20314         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20315         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20316         create_lnet_proc_files "peers"
20317         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20318         remove_lnet_proc_files "peers"
20319
20320         # lnet.buffers  should look like this:
20321         # pages count credits min
20322         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20323         L1="^pages +count +credits +min$"
20324         BR="^ +$N +$N +$I +$I$"
20325         create_lnet_proc_files "buffers"
20326         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20327         remove_lnet_proc_files "buffers"
20328
20329         # lnet.nis should look like this:
20330         # nid status alive refs peer rtr max tx min
20331         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20332         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20333         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20334         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20335         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20336         create_lnet_proc_files "nis"
20337         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20338         remove_lnet_proc_files "nis"
20339
20340         # can we successfully write to lnet.stats?
20341         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20342 }
20343 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20344
20345 test_216() { # bug 20317
20346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20347         remote_ost_nodsh && skip "remote OST with nodsh"
20348
20349         local node
20350         local facets=$(get_facets OST)
20351         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20352
20353         save_lustre_params client "osc.*.contention_seconds" > $p
20354         save_lustre_params $facets \
20355                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20356         save_lustre_params $facets \
20357                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20358         save_lustre_params $facets \
20359                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20360         clear_stats osc.*.osc_stats
20361
20362         # agressive lockless i/o settings
20363         do_nodes $(comma_list $(osts_nodes)) \
20364                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20365                         ldlm.namespaces.filter-*.contended_locks=0 \
20366                         ldlm.namespaces.filter-*.contention_seconds=60"
20367         lctl set_param -n osc.*.contention_seconds=60
20368
20369         $DIRECTIO write $DIR/$tfile 0 10 4096
20370         $CHECKSTAT -s 40960 $DIR/$tfile
20371
20372         # disable lockless i/o
20373         do_nodes $(comma_list $(osts_nodes)) \
20374                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20375                         ldlm.namespaces.filter-*.contended_locks=32 \
20376                         ldlm.namespaces.filter-*.contention_seconds=0"
20377         lctl set_param -n osc.*.contention_seconds=0
20378         clear_stats osc.*.osc_stats
20379
20380         dd if=/dev/zero of=$DIR/$tfile count=0
20381         $CHECKSTAT -s 0 $DIR/$tfile
20382
20383         restore_lustre_params <$p
20384         rm -f $p
20385         rm $DIR/$tfile
20386 }
20387 run_test 216 "check lockless direct write updates file size and kms correctly"
20388
20389 test_217() { # bug 22430
20390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20391
20392         local node
20393
20394         for node in $(nodes_list); do
20395                 local nid=$(host_nids_address $node $NETTYPE)
20396                 local node_ip=$(do_node $node getent ahostsv4 $node |
20397                                 awk '{ print $1; exit; }')
20398
20399                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20400                 # if hostname matches any NID, use hostname for better testing
20401                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20402                         echo "lctl ping node $node@$NETTYPE"
20403                         lctl ping $node@$NETTYPE
20404                 else # otherwise, at least test 'lctl ping' is working
20405                         echo "lctl ping nid $(h2nettype $nid)"
20406                         lctl ping $(h2nettype $nid)
20407                         echo "skipping $node (no hyphen detected)"
20408                 fi
20409         done
20410 }
20411 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20412
20413 test_218() {
20414         # do directio so as not to populate the page cache
20415         log "creating a 10 Mb file"
20416         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20417                 error "multiop failed while creating a file"
20418         log "starting reads"
20419         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20420         log "truncating the file"
20421         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20422                 error "multiop failed while truncating the file"
20423         log "killing dd"
20424         kill %+ || true # reads might have finished
20425         echo "wait until dd is finished"
20426         wait
20427         log "removing the temporary file"
20428         rm -rf $DIR/$tfile || error "tmp file removal failed"
20429 }
20430 run_test 218 "parallel read and truncate should not deadlock"
20431
20432 test_219() {
20433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20434
20435         # write one partial page
20436         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20437         # set no grant so vvp_io_commit_write will do sync write
20438         $LCTL set_param fail_loc=0x411
20439         # write a full page at the end of file
20440         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20441
20442         $LCTL set_param fail_loc=0
20443         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20444         $LCTL set_param fail_loc=0x411
20445         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20446
20447         # LU-4201
20448         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20449         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20450 }
20451 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20452
20453 test_220() { #LU-325
20454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20455         remote_ost_nodsh && skip "remote OST with nodsh"
20456         remote_mds_nodsh && skip "remote MDS with nodsh"
20457         remote_mgs_nodsh && skip "remote MGS with nodsh"
20458
20459         local OSTIDX=0
20460
20461         # create on MDT0000 so the last_id and next_id are correct
20462         mkdir_on_mdt0 $DIR/$tdir
20463         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20464         OST=${OST%_UUID}
20465
20466         # on the mdt's osc
20467         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20468         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20469                         osp.$mdtosc_proc1.prealloc_last_id)
20470         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20471                         osp.$mdtosc_proc1.prealloc_next_id)
20472
20473         $LFS df -i
20474
20475         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20476         #define OBD_FAIL_OST_ENOINO              0x229
20477         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20478         create_pool $FSNAME.$TESTNAME || return 1
20479         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20480
20481         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20482
20483         MDSOBJS=$((last_id - next_id))
20484         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20485
20486         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20487         echo "OST still has $count kbytes free"
20488
20489         echo "create $MDSOBJS files @next_id..."
20490         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20491
20492         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20493                         osp.$mdtosc_proc1.prealloc_last_id)
20494         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20495                         osp.$mdtosc_proc1.prealloc_next_id)
20496
20497         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20498         $LFS df -i
20499
20500         echo "cleanup..."
20501
20502         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20503         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20504
20505         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20506                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20507         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20508                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20509         echo "unlink $MDSOBJS files @$next_id..."
20510         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20511 }
20512 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20513
20514 test_221() {
20515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20516
20517         dd if=`which date` of=$MOUNT/date oflag=sync
20518         chmod +x $MOUNT/date
20519
20520         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20521         $LCTL set_param fail_loc=0x80001401
20522
20523         $MOUNT/date > /dev/null
20524         rm -f $MOUNT/date
20525 }
20526 run_test 221 "make sure fault and truncate race to not cause OOM"
20527
20528 test_222a () {
20529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20530
20531         rm -rf $DIR/$tdir
20532         test_mkdir $DIR/$tdir
20533         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20534         createmany -o $DIR/$tdir/$tfile 10
20535         cancel_lru_locks mdc
20536         cancel_lru_locks osc
20537         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20538         $LCTL set_param fail_loc=0x31a
20539         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20540         $LCTL set_param fail_loc=0
20541         rm -r $DIR/$tdir
20542 }
20543 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20544
20545 test_222b () {
20546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20547
20548         rm -rf $DIR/$tdir
20549         test_mkdir $DIR/$tdir
20550         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20551         createmany -o $DIR/$tdir/$tfile 10
20552         cancel_lru_locks mdc
20553         cancel_lru_locks osc
20554         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20555         $LCTL set_param fail_loc=0x31a
20556         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20557         $LCTL set_param fail_loc=0
20558 }
20559 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20560
20561 test_223 () {
20562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20563
20564         rm -rf $DIR/$tdir
20565         test_mkdir $DIR/$tdir
20566         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20567         createmany -o $DIR/$tdir/$tfile 10
20568         cancel_lru_locks mdc
20569         cancel_lru_locks osc
20570         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20571         $LCTL set_param fail_loc=0x31b
20572         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20573         $LCTL set_param fail_loc=0
20574         rm -r $DIR/$tdir
20575 }
20576 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20577
20578 test_224a() { # LU-1039, MRP-303
20579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20580         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20581         $LCTL set_param fail_loc=0x508
20582         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20583         $LCTL set_param fail_loc=0
20584         df $DIR
20585 }
20586 run_test 224a "Don't panic on bulk IO failure"
20587
20588 test_224bd_sub() { # LU-1039, MRP-303
20589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20590         local timeout=$1
20591
20592         shift
20593         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20594
20595         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20596
20597         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20598         cancel_lru_locks osc
20599         set_checksums 0
20600         stack_trap "set_checksums $ORIG_CSUM" EXIT
20601         local at_max_saved=0
20602
20603         # adaptive timeouts may prevent seeing the issue
20604         if at_is_enabled; then
20605                 at_max_saved=$(at_max_get mds)
20606                 at_max_set 0 mds client
20607                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20608         fi
20609
20610         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20611         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20612         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20613
20614         do_facet ost1 $LCTL set_param fail_loc=0
20615         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20616         df $DIR
20617 }
20618
20619 test_224b() {
20620         test_224bd_sub 3 error "dd failed"
20621 }
20622 run_test 224b "Don't panic on bulk IO failure"
20623
20624 test_224c() { # LU-6441
20625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20626         remote_mds_nodsh && skip "remote MDS with nodsh"
20627
20628         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20629         save_writethrough $p
20630         set_cache writethrough on
20631
20632         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20633         local at_max=$($LCTL get_param -n at_max)
20634         local timeout=$($LCTL get_param -n timeout)
20635         local test_at="at_max"
20636         local param_at="$FSNAME.sys.at_max"
20637         local test_timeout="timeout"
20638         local param_timeout="$FSNAME.sys.timeout"
20639
20640         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20641
20642         set_persistent_param_and_check client "$test_at" "$param_at" 0
20643         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20644
20645         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20646         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20647         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20648         stack_trap "rm -f $DIR/$tfile"
20649         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20650         sync
20651         do_facet ost1 "$LCTL set_param fail_loc=0"
20652
20653         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20654         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20655                 $timeout
20656
20657         $LCTL set_param -n $pages_per_rpc
20658         restore_lustre_params < $p
20659         rm -f $p
20660 }
20661 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20662
20663 test_224d() { # LU-11169
20664         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20665 }
20666 run_test 224d "Don't corrupt data on bulk IO timeout"
20667
20668 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20669 test_225a () {
20670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20671         if [ -z ${MDSSURVEY} ]; then
20672                 skip_env "mds-survey not found"
20673         fi
20674         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20675                 skip "Need MDS version at least 2.2.51"
20676
20677         local mds=$(facet_host $SINGLEMDS)
20678         local target=$(do_nodes $mds 'lctl dl' |
20679                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20680
20681         local cmd1="file_count=1000 thrhi=4"
20682         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20683         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20684         local cmd="$cmd1 $cmd2 $cmd3"
20685
20686         rm -f ${TMP}/mds_survey*
20687         echo + $cmd
20688         eval $cmd || error "mds-survey with zero-stripe failed"
20689         cat ${TMP}/mds_survey*
20690         rm -f ${TMP}/mds_survey*
20691 }
20692 run_test 225a "Metadata survey sanity with zero-stripe"
20693
20694 test_225b () {
20695         if [ -z ${MDSSURVEY} ]; then
20696                 skip_env "mds-survey not found"
20697         fi
20698         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20699                 skip "Need MDS version at least 2.2.51"
20700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20701         remote_mds_nodsh && skip "remote MDS with nodsh"
20702         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20703                 skip_env "Need to mount OST to test"
20704         fi
20705
20706         local mds=$(facet_host $SINGLEMDS)
20707         local target=$(do_nodes $mds 'lctl dl' |
20708                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20709
20710         local cmd1="file_count=1000 thrhi=4"
20711         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20712         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20713         local cmd="$cmd1 $cmd2 $cmd3"
20714
20715         rm -f ${TMP}/mds_survey*
20716         echo + $cmd
20717         eval $cmd || error "mds-survey with stripe_count failed"
20718         cat ${TMP}/mds_survey*
20719         rm -f ${TMP}/mds_survey*
20720 }
20721 run_test 225b "Metadata survey sanity with stripe_count = 1"
20722
20723 mcreate_path2fid () {
20724         local mode=$1
20725         local major=$2
20726         local minor=$3
20727         local name=$4
20728         local desc=$5
20729         local path=$DIR/$tdir/$name
20730         local fid
20731         local rc
20732         local fid_path
20733
20734         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20735                 error "cannot create $desc"
20736
20737         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20738         rc=$?
20739         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20740
20741         fid_path=$($LFS fid2path $MOUNT $fid)
20742         rc=$?
20743         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20744
20745         [ "$path" == "$fid_path" ] ||
20746                 error "fid2path returned $fid_path, expected $path"
20747
20748         echo "pass with $path and $fid"
20749 }
20750
20751 test_226a () {
20752         rm -rf $DIR/$tdir
20753         mkdir -p $DIR/$tdir
20754
20755         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20756         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20757         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20758         mcreate_path2fid 0040666 0 0 dir "directory"
20759         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20760         mcreate_path2fid 0100666 0 0 file "regular file"
20761         mcreate_path2fid 0120666 0 0 link "symbolic link"
20762         mcreate_path2fid 0140666 0 0 sock "socket"
20763 }
20764 run_test 226a "call path2fid and fid2path on files of all type"
20765
20766 test_226b () {
20767         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20768
20769         local MDTIDX=1
20770
20771         rm -rf $DIR/$tdir
20772         mkdir -p $DIR/$tdir
20773         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20774                 error "create remote directory failed"
20775         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20776         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20777                                 "character special file (null)"
20778         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20779                                 "character special file (no device)"
20780         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20781         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20782                                 "block special file (loop)"
20783         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20784         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20785         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20786 }
20787 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20788
20789 test_226c () {
20790         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20791         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20792                 skip "Need MDS version at least 2.13.55"
20793
20794         local submnt=/mnt/submnt
20795         local srcfile=/etc/passwd
20796         local dstfile=$submnt/passwd
20797         local path
20798         local fid
20799
20800         rm -rf $DIR/$tdir
20801         rm -rf $submnt
20802         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20803                 error "create remote directory failed"
20804         mkdir -p $submnt || error "create $submnt failed"
20805         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20806                 error "mount $submnt failed"
20807         stack_trap "umount $submnt" EXIT
20808
20809         cp $srcfile $dstfile
20810         fid=$($LFS path2fid $dstfile)
20811         path=$($LFS fid2path $submnt "$fid")
20812         [ "$path" = "$dstfile" ] ||
20813                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20814 }
20815 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20816
20817 test_226e () {
20818         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
20819                 skip "Need client at least version 2.15.56"
20820
20821         # Define filename with 'newline' and a space
20822         local testfile="Test"$'\n'"file 01"
20823         # Define link name with multiple 'newline' and a space
20824         local linkfile="Link"$'\n'"file "$'\n'"01"
20825         # Remove prior hard link
20826         rm -f $DIR/"$linkfile"
20827
20828         # Create file
20829         touch $DIR/"$testfile"
20830         # Create link
20831         ln $DIR/"$testfile" $DIR/"$linkfile"
20832
20833         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
20834                 error "getstripe failed on $DIR/$testfile"
20835
20836         # Call with -0 option
20837         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
20838                 echo "FILE:" | grep -c "FILE:")
20839
20840         # With -0 option the output should be exactly 2 lines.
20841         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
20842 }
20843 run_test 226e "Verify path2fid -0 option with newline and space"
20844
20845 # LU-1299 Executing or running ldd on a truncated executable does not
20846 # cause an out-of-memory condition.
20847 test_227() {
20848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20849         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20850
20851         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20852         chmod +x $MOUNT/date
20853
20854         $MOUNT/date > /dev/null
20855         ldd $MOUNT/date > /dev/null
20856         rm -f $MOUNT/date
20857 }
20858 run_test 227 "running truncated executable does not cause OOM"
20859
20860 # LU-1512 try to reuse idle OI blocks
20861 test_228a() {
20862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20863         remote_mds_nodsh && skip "remote MDS with nodsh"
20864         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20865
20866         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20867         local myDIR=$DIR/$tdir
20868
20869         mkdir -p $myDIR
20870         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20871         $LCTL set_param fail_loc=0x80001002
20872         createmany -o $myDIR/t- 10000
20873         $LCTL set_param fail_loc=0
20874         # The guard is current the largest FID holder
20875         touch $myDIR/guard
20876         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20877                     tr -d '[')
20878         local IDX=$(($SEQ % 64))
20879
20880         do_facet $SINGLEMDS sync
20881         # Make sure journal flushed.
20882         sleep 6
20883         local blk1=$(do_facet $SINGLEMDS \
20884                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20885                      grep Blockcount | awk '{print $4}')
20886
20887         # Remove old files, some OI blocks will become idle.
20888         unlinkmany $myDIR/t- 10000
20889         # Create new files, idle OI blocks should be reused.
20890         createmany -o $myDIR/t- 2000
20891         do_facet $SINGLEMDS sync
20892         # Make sure journal flushed.
20893         sleep 6
20894         local blk2=$(do_facet $SINGLEMDS \
20895                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20896                      grep Blockcount | awk '{print $4}')
20897
20898         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20899 }
20900 run_test 228a "try to reuse idle OI blocks"
20901
20902 test_228b() {
20903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20904         remote_mds_nodsh && skip "remote MDS with nodsh"
20905         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20906
20907         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20908         local myDIR=$DIR/$tdir
20909
20910         mkdir -p $myDIR
20911         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20912         $LCTL set_param fail_loc=0x80001002
20913         createmany -o $myDIR/t- 10000
20914         $LCTL set_param fail_loc=0
20915         # The guard is current the largest FID holder
20916         touch $myDIR/guard
20917         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20918                     tr -d '[')
20919         local IDX=$(($SEQ % 64))
20920
20921         do_facet $SINGLEMDS sync
20922         # Make sure journal flushed.
20923         sleep 6
20924         local blk1=$(do_facet $SINGLEMDS \
20925                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20926                      grep Blockcount | awk '{print $4}')
20927
20928         # Remove old files, some OI blocks will become idle.
20929         unlinkmany $myDIR/t- 10000
20930
20931         # stop the MDT
20932         stop $SINGLEMDS || error "Fail to stop MDT."
20933         # remount the MDT
20934         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20935                 error "Fail to start MDT."
20936
20937         client_up || error "Fail to df."
20938         # Create new files, idle OI blocks should be reused.
20939         createmany -o $myDIR/t- 2000
20940         do_facet $SINGLEMDS sync
20941         # Make sure journal flushed.
20942         sleep 6
20943         local blk2=$(do_facet $SINGLEMDS \
20944                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20945                      grep Blockcount | awk '{print $4}')
20946
20947         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20948 }
20949 run_test 228b "idle OI blocks can be reused after MDT restart"
20950
20951 #LU-1881
20952 test_228c() {
20953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20954         remote_mds_nodsh && skip "remote MDS with nodsh"
20955         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20956
20957         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20958         local myDIR=$DIR/$tdir
20959
20960         mkdir -p $myDIR
20961         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20962         $LCTL set_param fail_loc=0x80001002
20963         # 20000 files can guarantee there are index nodes in the OI file
20964         createmany -o $myDIR/t- 20000
20965         $LCTL set_param fail_loc=0
20966         # The guard is current the largest FID holder
20967         touch $myDIR/guard
20968         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20969                     tr -d '[')
20970         local IDX=$(($SEQ % 64))
20971
20972         do_facet $SINGLEMDS sync
20973         # Make sure journal flushed.
20974         sleep 6
20975         local blk1=$(do_facet $SINGLEMDS \
20976                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20977                      grep Blockcount | awk '{print $4}')
20978
20979         # Remove old files, some OI blocks will become idle.
20980         unlinkmany $myDIR/t- 20000
20981         rm -f $myDIR/guard
20982         # The OI file should become empty now
20983
20984         # Create new files, idle OI blocks should be reused.
20985         createmany -o $myDIR/t- 2000
20986         do_facet $SINGLEMDS sync
20987         # Make sure journal flushed.
20988         sleep 6
20989         local blk2=$(do_facet $SINGLEMDS \
20990                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20991                      grep Blockcount | awk '{print $4}')
20992
20993         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20994 }
20995 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20996
20997 test_229() { # LU-2482, LU-3448
20998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20999         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21000         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21001                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21002
21003         rm -f $DIR/$tfile
21004
21005         # Create a file with a released layout and stripe count 2.
21006         $MULTIOP $DIR/$tfile H2c ||
21007                 error "failed to create file with released layout"
21008
21009         $LFS getstripe -v $DIR/$tfile
21010
21011         local pattern=$($LFS getstripe -L $DIR/$tfile)
21012         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21013
21014         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21015                 error "getstripe"
21016         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21017         stat $DIR/$tfile || error "failed to stat released file"
21018
21019         chown $RUNAS_ID $DIR/$tfile ||
21020                 error "chown $RUNAS_ID $DIR/$tfile failed"
21021
21022         chgrp $RUNAS_ID $DIR/$tfile ||
21023                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21024
21025         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21026         rm $DIR/$tfile || error "failed to remove released file"
21027 }
21028 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21029
21030 test_230a() {
21031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21033         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21034                 skip "Need MDS version at least 2.11.52"
21035
21036         local MDTIDX=1
21037
21038         test_mkdir $DIR/$tdir
21039         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21040         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21041         [ $mdt_idx -ne 0 ] &&
21042                 error "create local directory on wrong MDT $mdt_idx"
21043
21044         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21045                         error "create remote directory failed"
21046         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21047         [ $mdt_idx -ne $MDTIDX ] &&
21048                 error "create remote directory on wrong MDT $mdt_idx"
21049
21050         createmany -o $DIR/$tdir/test_230/t- 10 ||
21051                 error "create files on remote directory failed"
21052         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21053         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21054         rm -r $DIR/$tdir || error "unlink remote directory failed"
21055 }
21056 run_test 230a "Create remote directory and files under the remote directory"
21057
21058 test_230b() {
21059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21061         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21062                 skip "Need MDS version at least 2.11.52"
21063
21064         local MDTIDX=1
21065         local mdt_index
21066         local i
21067         local file
21068         local pid
21069         local stripe_count
21070         local migrate_dir=$DIR/$tdir/migrate_dir
21071         local other_dir=$DIR/$tdir/other_dir
21072
21073         test_mkdir $DIR/$tdir
21074         test_mkdir -i0 -c1 $migrate_dir
21075         test_mkdir -i0 -c1 $other_dir
21076         for ((i=0; i<10; i++)); do
21077                 mkdir -p $migrate_dir/dir_${i}
21078                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21079                         error "create files under remote dir failed $i"
21080         done
21081
21082         cp /etc/passwd $migrate_dir/$tfile
21083         cp /etc/passwd $other_dir/$tfile
21084         chattr +SAD $migrate_dir
21085         chattr +SAD $migrate_dir/$tfile
21086
21087         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21088         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21089         local old_dir_mode=$(stat -c%f $migrate_dir)
21090         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21091
21092         mkdir -p $migrate_dir/dir_default_stripe2
21093         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21094         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21095
21096         mkdir -p $other_dir
21097         ln $migrate_dir/$tfile $other_dir/luna
21098         ln $migrate_dir/$tfile $migrate_dir/sofia
21099         ln $other_dir/$tfile $migrate_dir/david
21100         ln -s $migrate_dir/$tfile $other_dir/zachary
21101         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21102         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21103
21104         local len
21105         local lnktgt
21106
21107         # inline symlink
21108         for len in 58 59 60; do
21109                 lnktgt=$(str_repeat 'l' $len)
21110                 touch $migrate_dir/$lnktgt
21111                 ln -s $lnktgt $migrate_dir/${len}char_ln
21112         done
21113
21114         # PATH_MAX
21115         for len in 4094 4095; do
21116                 lnktgt=$(str_repeat 'l' $len)
21117                 ln -s $lnktgt $migrate_dir/${len}char_ln
21118         done
21119
21120         # NAME_MAX
21121         for len in 254 255; do
21122                 touch $migrate_dir/$(str_repeat 'l' $len)
21123         done
21124
21125         $LFS migrate -m $MDTIDX $migrate_dir ||
21126                 error "fails on migrating remote dir to MDT1"
21127
21128         echo "migratate to MDT1, then checking.."
21129         for ((i = 0; i < 10; i++)); do
21130                 for file in $(find $migrate_dir/dir_${i}); do
21131                         mdt_index=$($LFS getstripe -m $file)
21132                         # broken symlink getstripe will fail
21133                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21134                                 error "$file is not on MDT${MDTIDX}"
21135                 done
21136         done
21137
21138         # the multiple link file should still in MDT0
21139         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21140         [ $mdt_index == 0 ] ||
21141                 error "$file is not on MDT${MDTIDX}"
21142
21143         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21144         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21145                 error " expect $old_dir_flag get $new_dir_flag"
21146
21147         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21148         [ "$old_file_flag" = "$new_file_flag" ] ||
21149                 error " expect $old_file_flag get $new_file_flag"
21150
21151         local new_dir_mode=$(stat -c%f $migrate_dir)
21152         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21153                 error "expect mode $old_dir_mode get $new_dir_mode"
21154
21155         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21156         [ "$old_file_mode" = "$new_file_mode" ] ||
21157                 error "expect mode $old_file_mode get $new_file_mode"
21158
21159         diff /etc/passwd $migrate_dir/$tfile ||
21160                 error "$tfile different after migration"
21161
21162         diff /etc/passwd $other_dir/luna ||
21163                 error "luna different after migration"
21164
21165         diff /etc/passwd $migrate_dir/sofia ||
21166                 error "sofia different after migration"
21167
21168         diff /etc/passwd $migrate_dir/david ||
21169                 error "david different after migration"
21170
21171         diff /etc/passwd $other_dir/zachary ||
21172                 error "zachary different after migration"
21173
21174         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21175                 error "${tfile}_ln different after migration"
21176
21177         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21178                 error "${tfile}_ln_other different after migration"
21179
21180         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21181         [ $stripe_count = 2 ] ||
21182                 error "dir strpe_count $d != 2 after migration."
21183
21184         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21185         [ $stripe_count = 2 ] ||
21186                 error "file strpe_count $d != 2 after migration."
21187
21188         #migrate back to MDT0
21189         MDTIDX=0
21190
21191         $LFS migrate -m $MDTIDX $migrate_dir ||
21192                 error "fails on migrating remote dir to MDT0"
21193
21194         echo "migrate back to MDT0, checking.."
21195         for file in $(find $migrate_dir); do
21196                 mdt_index=$($LFS getstripe -m $file)
21197                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21198                         error "$file is not on MDT${MDTIDX}"
21199         done
21200
21201         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21202         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21203                 error " expect $old_dir_flag get $new_dir_flag"
21204
21205         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21206         [ "$old_file_flag" = "$new_file_flag" ] ||
21207                 error " expect $old_file_flag get $new_file_flag"
21208
21209         local new_dir_mode=$(stat -c%f $migrate_dir)
21210         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21211                 error "expect mode $old_dir_mode get $new_dir_mode"
21212
21213         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21214         [ "$old_file_mode" = "$new_file_mode" ] ||
21215                 error "expect mode $old_file_mode get $new_file_mode"
21216
21217         diff /etc/passwd ${migrate_dir}/$tfile ||
21218                 error "$tfile different after migration"
21219
21220         diff /etc/passwd ${other_dir}/luna ||
21221                 error "luna different after migration"
21222
21223         diff /etc/passwd ${migrate_dir}/sofia ||
21224                 error "sofia different after migration"
21225
21226         diff /etc/passwd ${other_dir}/zachary ||
21227                 error "zachary different after migration"
21228
21229         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21230                 error "${tfile}_ln different after migration"
21231
21232         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21233                 error "${tfile}_ln_other different after migration"
21234
21235         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21236         [ $stripe_count = 2 ] ||
21237                 error "dir strpe_count $d != 2 after migration."
21238
21239         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21240         [ $stripe_count = 2 ] ||
21241                 error "file strpe_count $d != 2 after migration."
21242
21243         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21244 }
21245 run_test 230b "migrate directory"
21246
21247 test_230c() {
21248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21250         remote_mds_nodsh && skip "remote MDS with nodsh"
21251         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21252                 skip "Need MDS version at least 2.11.52"
21253
21254         local MDTIDX=1
21255         local total=3
21256         local mdt_index
21257         local file
21258         local migrate_dir=$DIR/$tdir/migrate_dir
21259
21260         #If migrating directory fails in the middle, all entries of
21261         #the directory is still accessiable.
21262         test_mkdir $DIR/$tdir
21263         test_mkdir -i0 -c1 $migrate_dir
21264         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21265         stat $migrate_dir
21266         createmany -o $migrate_dir/f $total ||
21267                 error "create files under ${migrate_dir} failed"
21268
21269         # fail after migrating top dir, and this will fail only once, so the
21270         # first sub file migration will fail (currently f3), others succeed.
21271         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21272         do_facet mds1 lctl set_param fail_loc=0x1801
21273         local t=$(ls $migrate_dir | wc -l)
21274         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21275                 error "migrate should fail"
21276         local u=$(ls $migrate_dir | wc -l)
21277         [ "$u" == "$t" ] || error "$u != $t during migration"
21278
21279         # add new dir/file should succeed
21280         mkdir $migrate_dir/dir ||
21281                 error "mkdir failed under migrating directory"
21282         touch $migrate_dir/file ||
21283                 error "create file failed under migrating directory"
21284
21285         # add file with existing name should fail
21286         for file in $migrate_dir/f*; do
21287                 stat $file > /dev/null || error "stat $file failed"
21288                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21289                         error "open(O_CREAT|O_EXCL) $file should fail"
21290                 $MULTIOP $file m && error "create $file should fail"
21291                 touch $DIR/$tdir/remote_dir/$tfile ||
21292                         error "touch $tfile failed"
21293                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21294                         error "link $file should fail"
21295                 mdt_index=$($LFS getstripe -m $file)
21296                 if [ $mdt_index == 0 ]; then
21297                         # file failed to migrate is not allowed to rename to
21298                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21299                                 error "rename to $file should fail"
21300                 else
21301                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21302                                 error "rename to $file failed"
21303                 fi
21304                 echo hello >> $file || error "write $file failed"
21305         done
21306
21307         # resume migration with different options should fail
21308         $LFS migrate -m 0 $migrate_dir &&
21309                 error "migrate -m 0 $migrate_dir should fail"
21310
21311         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21312                 error "migrate -c 2 $migrate_dir should fail"
21313
21314         # resume migration should succeed
21315         $LFS migrate -m $MDTIDX $migrate_dir ||
21316                 error "migrate $migrate_dir failed"
21317
21318         echo "Finish migration, then checking.."
21319         for file in $(find $migrate_dir); do
21320                 mdt_index=$($LFS getstripe -m $file)
21321                 [ $mdt_index == $MDTIDX ] ||
21322                         error "$file is not on MDT${MDTIDX}"
21323         done
21324
21325         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21326 }
21327 run_test 230c "check directory accessiblity if migration failed"
21328
21329 test_230d() {
21330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21331         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21332         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21333                 skip "Need MDS version at least 2.11.52"
21334         # LU-11235
21335         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21336
21337         local migrate_dir=$DIR/$tdir/migrate_dir
21338         local old_index
21339         local new_index
21340         local old_count
21341         local new_count
21342         local new_hash
21343         local mdt_index
21344         local i
21345         local j
21346
21347         old_index=$((RANDOM % MDSCOUNT))
21348         old_count=$((MDSCOUNT - old_index))
21349         new_index=$((RANDOM % MDSCOUNT))
21350         new_count=$((MDSCOUNT - new_index))
21351         new_hash=1 # for all_char
21352
21353         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21354         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21355
21356         test_mkdir $DIR/$tdir
21357         test_mkdir -i $old_index -c $old_count $migrate_dir
21358
21359         for ((i=0; i<100; i++)); do
21360                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21361                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21362                         error "create files under remote dir failed $i"
21363         done
21364
21365         echo -n "Migrate from MDT$old_index "
21366         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21367         echo -n "to MDT$new_index"
21368         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21369         echo
21370
21371         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21372         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21373                 error "migrate remote dir error"
21374
21375         echo "Finish migration, then checking.."
21376         for file in $(find $migrate_dir -maxdepth 1); do
21377                 mdt_index=$($LFS getstripe -m $file)
21378                 if [ $mdt_index -lt $new_index ] ||
21379                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21380                         error "$file is on MDT$mdt_index"
21381                 fi
21382         done
21383
21384         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21385 }
21386 run_test 230d "check migrate big directory"
21387
21388 test_230e() {
21389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21390         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21391         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21392                 skip "Need MDS version at least 2.11.52"
21393
21394         local i
21395         local j
21396         local a_fid
21397         local b_fid
21398
21399         mkdir_on_mdt0 $DIR/$tdir
21400         mkdir $DIR/$tdir/migrate_dir
21401         mkdir $DIR/$tdir/other_dir
21402         touch $DIR/$tdir/migrate_dir/a
21403         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21404         ls $DIR/$tdir/other_dir
21405
21406         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21407                 error "migrate dir fails"
21408
21409         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21410         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21411
21412         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21413         [ $mdt_index == 0 ] || error "a is not on MDT0"
21414
21415         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21416                 error "migrate dir fails"
21417
21418         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21419         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21420
21421         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21422         [ $mdt_index == 1 ] || error "a is not on MDT1"
21423
21424         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21425         [ $mdt_index == 1 ] || error "b is not on MDT1"
21426
21427         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21428         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21429
21430         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21431
21432         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21433 }
21434 run_test 230e "migrate mulitple local link files"
21435
21436 test_230f() {
21437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21439         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21440                 skip "Need MDS version at least 2.11.52"
21441
21442         local a_fid
21443         local ln_fid
21444
21445         mkdir -p $DIR/$tdir
21446         mkdir $DIR/$tdir/migrate_dir
21447         $LFS mkdir -i1 $DIR/$tdir/other_dir
21448         touch $DIR/$tdir/migrate_dir/a
21449         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21450         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21451         ls $DIR/$tdir/other_dir
21452
21453         # a should be migrated to MDT1, since no other links on MDT0
21454         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21455                 error "#1 migrate dir fails"
21456         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21457         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21458         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21459         [ $mdt_index == 1 ] || error "a is not on MDT1"
21460
21461         # a should stay on MDT1, because it is a mulitple link file
21462         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21463                 error "#2 migrate dir fails"
21464         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21465         [ $mdt_index == 1 ] || error "a is not on MDT1"
21466
21467         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21468                 error "#3 migrate dir fails"
21469
21470         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21471         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21472         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21473
21474         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21475         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21476
21477         # a should be migrated to MDT0, since no other links on MDT1
21478         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21479                 error "#4 migrate dir fails"
21480         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21481         [ $mdt_index == 0 ] || error "a is not on MDT0"
21482
21483         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21484 }
21485 run_test 230f "migrate mulitple remote link files"
21486
21487 test_230g() {
21488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21489         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21490         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21491                 skip "Need MDS version at least 2.11.52"
21492
21493         mkdir -p $DIR/$tdir/migrate_dir
21494
21495         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21496                 error "migrating dir to non-exist MDT succeeds"
21497         true
21498 }
21499 run_test 230g "migrate dir to non-exist MDT"
21500
21501 test_230h() {
21502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21504         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21505                 skip "Need MDS version at least 2.11.52"
21506
21507         local mdt_index
21508
21509         mkdir -p $DIR/$tdir/migrate_dir
21510
21511         $LFS migrate -m1 $DIR &&
21512                 error "migrating mountpoint1 should fail"
21513
21514         $LFS migrate -m1 $DIR/$tdir/.. &&
21515                 error "migrating mountpoint2 should fail"
21516
21517         # same as mv
21518         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21519                 error "migrating $tdir/migrate_dir/.. should fail"
21520
21521         true
21522 }
21523 run_test 230h "migrate .. and root"
21524
21525 test_230i() {
21526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21527         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21528         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21529                 skip "Need MDS version at least 2.11.52"
21530
21531         mkdir -p $DIR/$tdir/migrate_dir
21532
21533         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21534                 error "migration fails with a tailing slash"
21535
21536         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21537                 error "migration fails with two tailing slashes"
21538 }
21539 run_test 230i "lfs migrate -m tolerates trailing slashes"
21540
21541 test_230j() {
21542         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21543         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21544                 skip "Need MDS version at least 2.11.52"
21545
21546         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21547         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21548                 error "create $tfile failed"
21549         cat /etc/passwd > $DIR/$tdir/$tfile
21550
21551         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21552
21553         cmp /etc/passwd $DIR/$tdir/$tfile ||
21554                 error "DoM file mismatch after migration"
21555 }
21556 run_test 230j "DoM file data not changed after dir migration"
21557
21558 test_230k() {
21559         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21560         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21561                 skip "Need MDS version at least 2.11.56"
21562
21563         local total=20
21564         local files_on_starting_mdt=0
21565
21566         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21567         $LFS getdirstripe $DIR/$tdir
21568         for i in $(seq $total); do
21569                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21570                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21571                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21572         done
21573
21574         echo "$files_on_starting_mdt files on MDT0"
21575
21576         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21577         $LFS getdirstripe $DIR/$tdir
21578
21579         files_on_starting_mdt=0
21580         for i in $(seq $total); do
21581                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21582                         error "file $tfile.$i mismatch after migration"
21583                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21584                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21585         done
21586
21587         echo "$files_on_starting_mdt files on MDT1 after migration"
21588         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21589
21590         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21591         $LFS getdirstripe $DIR/$tdir
21592
21593         files_on_starting_mdt=0
21594         for i in $(seq $total); do
21595                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21596                         error "file $tfile.$i mismatch after 2nd migration"
21597                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21598                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21599         done
21600
21601         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21602         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21603
21604         true
21605 }
21606 run_test 230k "file data not changed after dir migration"
21607
21608 test_230l() {
21609         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21610         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21611                 skip "Need MDS version at least 2.11.56"
21612
21613         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21614         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21615                 error "create files under remote dir failed $i"
21616         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21617 }
21618 run_test 230l "readdir between MDTs won't crash"
21619
21620 test_230m() {
21621         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21622         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21623                 skip "Need MDS version at least 2.11.56"
21624
21625         local MDTIDX=1
21626         local mig_dir=$DIR/$tdir/migrate_dir
21627         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21628         local shortstr="b"
21629         local val
21630
21631         echo "Creating files and dirs with xattrs"
21632         test_mkdir $DIR/$tdir
21633         test_mkdir -i0 -c1 $mig_dir
21634         mkdir $mig_dir/dir
21635         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21636                 error "cannot set xattr attr1 on dir"
21637         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21638                 error "cannot set xattr attr2 on dir"
21639         touch $mig_dir/dir/f0
21640         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21641                 error "cannot set xattr attr1 on file"
21642         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21643                 error "cannot set xattr attr2 on file"
21644         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21645         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21646         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21647         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21648         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21649         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21650         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21651         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21652         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21653
21654         echo "Migrating to MDT1"
21655         $LFS migrate -m $MDTIDX $mig_dir ||
21656                 error "fails on migrating dir to MDT1"
21657
21658         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21659         echo "Checking xattrs"
21660         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21661         [ "$val" = $longstr ] ||
21662                 error "expecting xattr1 $longstr on dir, found $val"
21663         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21664         [ "$val" = $shortstr ] ||
21665                 error "expecting xattr2 $shortstr on dir, found $val"
21666         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21667         [ "$val" = $longstr ] ||
21668                 error "expecting xattr1 $longstr on file, found $val"
21669         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21670         [ "$val" = $shortstr ] ||
21671                 error "expecting xattr2 $shortstr on file, found $val"
21672 }
21673 run_test 230m "xattrs not changed after dir migration"
21674
21675 test_230n() {
21676         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21677         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21678                 skip "Need MDS version at least 2.13.53"
21679
21680         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21681         cat /etc/hosts > $DIR/$tdir/$tfile
21682         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21683         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21684
21685         cmp /etc/hosts $DIR/$tdir/$tfile ||
21686                 error "File data mismatch after migration"
21687 }
21688 run_test 230n "Dir migration with mirrored file"
21689
21690 test_230o() {
21691         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21692         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21693                 skip "Need MDS version at least 2.13.52"
21694
21695         local mdts=$(comma_list $(mdts_nodes))
21696         local timeout=100
21697         local restripe_status
21698         local delta
21699         local i
21700
21701         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21702
21703         # in case "crush" hash type is not set
21704         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21705
21706         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21707                            mdt.*MDT0000.enable_dir_restripe)
21708         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21709         stack_trap "do_nodes $mdts $LCTL set_param \
21710                     mdt.*.enable_dir_restripe=$restripe_status"
21711
21712         mkdir $DIR/$tdir
21713         createmany -m $DIR/$tdir/f 100 ||
21714                 error "create files under remote dir failed $i"
21715         createmany -d $DIR/$tdir/d 100 ||
21716                 error "create dirs under remote dir failed $i"
21717
21718         for i in $(seq 2 $MDSCOUNT); do
21719                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21720                 $LFS setdirstripe -c $i $DIR/$tdir ||
21721                         error "split -c $i $tdir failed"
21722                 wait_update $HOSTNAME \
21723                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21724                         error "dir split not finished"
21725                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21726                         awk '/migrate/ {sum += $2} END { print sum }')
21727                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21728                 # delta is around total_files/stripe_count
21729                 (( $delta < 200 / (i - 1) + 4 )) ||
21730                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21731         done
21732 }
21733 run_test 230o "dir split"
21734
21735 test_230p() {
21736         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21737         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21738                 skip "Need MDS version at least 2.13.52"
21739
21740         local mdts=$(comma_list $(mdts_nodes))
21741         local timeout=100
21742         local restripe_status
21743         local delta
21744         local c
21745
21746         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21747
21748         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21749
21750         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21751                            mdt.*MDT0000.enable_dir_restripe)
21752         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21753         stack_trap "do_nodes $mdts $LCTL set_param \
21754                     mdt.*.enable_dir_restripe=$restripe_status"
21755
21756         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21757         createmany -m $DIR/$tdir/f 100 ||
21758                 error "create files under remote dir failed"
21759         createmany -d $DIR/$tdir/d 100 ||
21760                 error "create dirs under remote dir failed"
21761
21762         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21763                 local mdt_hash="crush"
21764
21765                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21766                 $LFS setdirstripe -c $c $DIR/$tdir ||
21767                         error "split -c $c $tdir failed"
21768                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21769                         mdt_hash="$mdt_hash,fixed"
21770                 elif [ $c -eq 1 ]; then
21771                         mdt_hash="none"
21772                 fi
21773                 wait_update $HOSTNAME \
21774                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21775                         error "dir merge not finished"
21776                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21777                         awk '/migrate/ {sum += $2} END { print sum }')
21778                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21779                 # delta is around total_files/stripe_count
21780                 (( delta < 200 / c + 4 )) ||
21781                         error "$delta files migrated >= $((200 / c + 4))"
21782         done
21783 }
21784 run_test 230p "dir merge"
21785
21786 test_230q() {
21787         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21788         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21789                 skip "Need MDS version at least 2.13.52"
21790
21791         local mdts=$(comma_list $(mdts_nodes))
21792         local saved_threshold=$(do_facet mds1 \
21793                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21794         local saved_delta=$(do_facet mds1 \
21795                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21796         local threshold=100
21797         local delta=2
21798         local total=0
21799         local stripe_count=0
21800         local stripe_index
21801         local nr_files
21802         local create
21803
21804         # test with fewer files on ZFS
21805         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21806
21807         stack_trap "do_nodes $mdts $LCTL set_param \
21808                     mdt.*.dir_split_count=$saved_threshold"
21809         stack_trap "do_nodes $mdts $LCTL set_param \
21810                     mdt.*.dir_split_delta=$saved_delta"
21811         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21812         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21813         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21814         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21815         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21816         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21817
21818         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21819         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21820
21821         create=$((threshold * 3 / 2))
21822         while [ $stripe_count -lt $MDSCOUNT ]; do
21823                 createmany -m $DIR/$tdir/f $total $create ||
21824                         error "create sub files failed"
21825                 stat $DIR/$tdir > /dev/null
21826                 total=$((total + create))
21827                 stripe_count=$((stripe_count + delta))
21828                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21829
21830                 wait_update $HOSTNAME \
21831                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21832                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21833
21834                 wait_update $HOSTNAME \
21835                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21836                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21837
21838                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21839                 echo "$nr_files/$total files on MDT$stripe_index after split"
21840                 # allow 10% margin of imbalance with crush hash
21841                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21842                         error "$nr_files files on MDT$stripe_index after split"
21843
21844                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21845                 [ $nr_files -eq $total ] ||
21846                         error "total sub files $nr_files != $total"
21847         done
21848
21849         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21850
21851         echo "fixed layout directory won't auto split"
21852         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21853         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21854                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21855         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21856                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21857 }
21858 run_test 230q "dir auto split"
21859
21860 test_230r() {
21861         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21862         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21863         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21864                 skip "Need MDS version at least 2.13.54"
21865
21866         # maximum amount of local locks:
21867         # parent striped dir - 2 locks
21868         # new stripe in parent to migrate to - 1 lock
21869         # source and target - 2 locks
21870         # Total 5 locks for regular file
21871         mkdir -p $DIR/$tdir
21872         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21873         touch $DIR/$tdir/dir1/eee
21874
21875         # create 4 hardlink for 4 more locks
21876         # Total: 9 locks > RS_MAX_LOCKS (8)
21877         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21878         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21879         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21880         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21881         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21882         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21883         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21884         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21885
21886         cancel_lru_locks mdc
21887
21888         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21889                 error "migrate dir fails"
21890
21891         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21892 }
21893 run_test 230r "migrate with too many local locks"
21894
21895 test_230s() {
21896         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21897                 skip "Need MDS version at least 2.14.52"
21898
21899         local mdts=$(comma_list $(mdts_nodes))
21900         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21901                                 mdt.*MDT0000.enable_dir_restripe)
21902
21903         stack_trap "do_nodes $mdts $LCTL set_param \
21904                     mdt.*.enable_dir_restripe=$restripe_status"
21905
21906         local st
21907         for st in 0 1; do
21908                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21909                 test_mkdir $DIR/$tdir
21910                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21911                         error "$LFS mkdir should return EEXIST if target exists"
21912                 rmdir $DIR/$tdir
21913         done
21914 }
21915 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21916
21917 test_230t()
21918 {
21919         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21920         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21921                 skip "Need MDS version at least 2.14.50"
21922
21923         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21924         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21925         $LFS project -p 1 -s $DIR/$tdir ||
21926                 error "set $tdir project id failed"
21927         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21928                 error "set subdir project id failed"
21929         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21930 }
21931 run_test 230t "migrate directory with project ID set"
21932
21933 test_230u()
21934 {
21935         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21936         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21937                 skip "Need MDS version at least 2.14.53"
21938
21939         local count
21940
21941         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21942         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21943         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21944         for i in $(seq 0 $((MDSCOUNT - 1))); do
21945                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21946                 echo "$count dirs migrated to MDT$i"
21947         done
21948         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21949         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21950 }
21951 run_test 230u "migrate directory by QOS"
21952
21953 test_230v()
21954 {
21955         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21956         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21957                 skip "Need MDS version at least 2.14.53"
21958
21959         local count
21960
21961         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21962         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21963         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21964         for i in $(seq 0 $((MDSCOUNT - 1))); do
21965                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21966                 echo "$count subdirs migrated to MDT$i"
21967                 (( i == 3 )) && (( count > 0 )) &&
21968                         error "subdir shouldn't be migrated to MDT3"
21969         done
21970         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21971         (( count == 3 )) || error "dirs migrated to $count MDTs"
21972 }
21973 run_test 230v "subdir migrated to the MDT where its parent is located"
21974
21975 test_230w() {
21976         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21977         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21978                 skip "Need MDS version at least 2.15.0"
21979
21980         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21981         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21982         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21983
21984         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21985                 error "migrate failed"
21986
21987         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21988                 error "$tdir stripe count mismatch"
21989
21990         for i in $(seq 0 9); do
21991                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21992                         error "d$i is striped"
21993         done
21994 }
21995 run_test 230w "non-recursive mode dir migration"
21996
21997 test_230x() {
21998         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21999         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22000                 skip "Need MDS version at least 2.15.0"
22001
22002         mkdir -p $DIR/$tdir || error "mkdir failed"
22003         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22004
22005         local mdt_name=$(mdtname_from_index 0)
22006         local low=$(do_facet mds2 $LCTL get_param -n \
22007                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22008         local high=$(do_facet mds2 $LCTL get_param -n \
22009                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22010         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22011         local maxage=$(do_facet mds2 $LCTL get_param -n \
22012                 osp.*$mdt_name-osp-MDT0001.maxage)
22013
22014         stack_trap "do_facet mds2 $LCTL set_param -n \
22015                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22016                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22017         stack_trap "do_facet mds2 $LCTL set_param -n \
22018                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22019
22020         do_facet mds2 $LCTL set_param -n \
22021                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22022         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22023         sleep 4
22024         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22025                 error "migrate $tdir should fail"
22026
22027         do_facet mds2 $LCTL set_param -n \
22028                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22029         do_facet mds2 $LCTL set_param -n \
22030                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22031         sleep 4
22032         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22033                 error "migrate failed"
22034         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22035                 error "$tdir stripe count mismatch"
22036 }
22037 run_test 230x "dir migration check space"
22038
22039 test_230y() {
22040         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22041         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22042                 skip "Need MDS version at least 2.15.55.45"
22043
22044         local pid
22045
22046         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22047         $LFS getdirstripe $DIR/$tdir
22048         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22049         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22050         pid=$!
22051         sleep 1
22052
22053         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22054         do_facet mds2 lctl set_param fail_loc=0x1802
22055
22056         wait $pid
22057         do_facet mds2 lctl set_param fail_loc=0
22058         $LFS getdirstripe $DIR/$tdir
22059         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22060         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22061 }
22062 run_test 230y "unlink dir with bad hash type"
22063
22064 test_230z() {
22065         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22066         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22067                 skip "Need MDS version at least 2.15.55.45"
22068
22069         local pid
22070
22071         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22072         $LFS getdirstripe $DIR/$tdir
22073         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22074         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22075         pid=$!
22076         sleep 1
22077
22078         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22079         do_facet mds2 lctl set_param fail_loc=0x1802
22080
22081         wait $pid
22082         do_facet mds2 lctl set_param fail_loc=0
22083         $LFS getdirstripe $DIR/$tdir
22084
22085         # resume migration
22086         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22087                 error "resume migration failed"
22088         $LFS getdirstripe $DIR/$tdir
22089         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22090                 error "migration is not finished"
22091 }
22092 run_test 230z "resume dir migration with bad hash type"
22093
22094 test_231a()
22095 {
22096         # For simplicity this test assumes that max_pages_per_rpc
22097         # is the same across all OSCs
22098         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22099         local bulk_size=$((max_pages * PAGE_SIZE))
22100         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22101                                        head -n 1)
22102
22103         mkdir -p $DIR/$tdir
22104         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22105                 error "failed to set stripe with -S ${brw_size}M option"
22106         stack_trap "rm -rf $DIR/$tdir"
22107
22108         # clear the OSC stats
22109         $LCTL set_param osc.*.stats=0 &>/dev/null
22110         stop_writeback
22111
22112         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22113         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22114                 oflag=direct &>/dev/null || error "dd failed"
22115
22116         sync; sleep 1; sync # just to be safe
22117         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22118         if [ x$nrpcs != "x1" ]; then
22119                 $LCTL get_param osc.*.stats
22120                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22121         fi
22122
22123         start_writeback
22124         # Drop the OSC cache, otherwise we will read from it
22125         cancel_lru_locks osc
22126
22127         # clear the OSC stats
22128         $LCTL set_param osc.*.stats=0 &>/dev/null
22129
22130         # Client reads $bulk_size.
22131         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22132                 iflag=direct &>/dev/null || error "dd failed"
22133
22134         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22135         if [ x$nrpcs != "x1" ]; then
22136                 $LCTL get_param osc.*.stats
22137                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22138         fi
22139 }
22140 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22141
22142 test_231b() {
22143         mkdir -p $DIR/$tdir
22144         stack_trap "rm -rf $DIR/$tdir"
22145         local i
22146         for i in {0..1023}; do
22147                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22148                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22149                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22150         done
22151         sync
22152 }
22153 run_test 231b "must not assert on fully utilized OST request buffer"
22154
22155 test_232a() {
22156         mkdir -p $DIR/$tdir
22157         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22158
22159         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22160         do_facet ost1 $LCTL set_param fail_loc=0x31c
22161
22162         # ignore dd failure
22163         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22164         stack_trap "rm -f $DIR/$tdir/$tfile"
22165
22166         do_facet ost1 $LCTL set_param fail_loc=0
22167         umount_client $MOUNT || error "umount failed"
22168         mount_client $MOUNT || error "mount failed"
22169         stop ost1 || error "cannot stop ost1"
22170         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22171 }
22172 run_test 232a "failed lock should not block umount"
22173
22174 test_232b() {
22175         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22176                 skip "Need MDS version at least 2.10.58"
22177
22178         mkdir -p $DIR/$tdir
22179         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22180         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22181         stack_trap "rm -f $DIR/$tdir/$tfile"
22182         sync
22183         cancel_lru_locks osc
22184
22185         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22186         do_facet ost1 $LCTL set_param fail_loc=0x31c
22187
22188         # ignore failure
22189         $LFS data_version $DIR/$tdir/$tfile || true
22190
22191         do_facet ost1 $LCTL set_param fail_loc=0
22192         umount_client $MOUNT || error "umount failed"
22193         mount_client $MOUNT || error "mount failed"
22194         stop ost1 || error "cannot stop ost1"
22195         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22196 }
22197 run_test 232b "failed data version lock should not block umount"
22198
22199 test_233a() {
22200         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22201                 skip "Need MDS version at least 2.3.64"
22202         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22203
22204         local fid=$($LFS path2fid $MOUNT)
22205
22206         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22207                 error "cannot access $MOUNT using its FID '$fid'"
22208 }
22209 run_test 233a "checking that OBF of the FS root succeeds"
22210
22211 test_233b() {
22212         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22213                 skip "Need MDS version at least 2.5.90"
22214         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22215
22216         local fid=$($LFS path2fid $MOUNT/.lustre)
22217
22218         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22219                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22220
22221         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22222         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22223                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22224 }
22225 run_test 233b "checking that OBF of the FS .lustre succeeds"
22226
22227 test_234() {
22228         local p="$TMP/sanityN-$TESTNAME.parameters"
22229         save_lustre_params client "llite.*.xattr_cache" > $p
22230         lctl set_param llite.*.xattr_cache 1 ||
22231                 skip_env "xattr cache is not supported"
22232
22233         mkdir -p $DIR/$tdir || error "mkdir failed"
22234         touch $DIR/$tdir/$tfile || error "touch failed"
22235         # OBD_FAIL_LLITE_XATTR_ENOMEM
22236         $LCTL set_param fail_loc=0x1405
22237         getfattr -n user.attr $DIR/$tdir/$tfile &&
22238                 error "getfattr should have failed with ENOMEM"
22239         $LCTL set_param fail_loc=0x0
22240         rm -rf $DIR/$tdir
22241
22242         restore_lustre_params < $p
22243         rm -f $p
22244 }
22245 run_test 234 "xattr cache should not crash on ENOMEM"
22246
22247 test_235() {
22248         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22249                 skip "Need MDS version at least 2.4.52"
22250
22251         flock_deadlock $DIR/$tfile
22252         local RC=$?
22253         case $RC in
22254                 0)
22255                 ;;
22256                 124) error "process hangs on a deadlock"
22257                 ;;
22258                 *) error "error executing flock_deadlock $DIR/$tfile"
22259                 ;;
22260         esac
22261 }
22262 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22263
22264 #LU-2935
22265 test_236() {
22266         check_swap_layouts_support
22267
22268         local ref1=/etc/passwd
22269         local ref2=/etc/group
22270         local file1=$DIR/$tdir/f1
22271         local file2=$DIR/$tdir/f2
22272
22273         test_mkdir -c1 $DIR/$tdir
22274         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22275         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22276         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22277         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22278         local fd=$(free_fd)
22279         local cmd="exec $fd<>$file2"
22280         eval $cmd
22281         rm $file2
22282         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22283                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22284         cmd="exec $fd>&-"
22285         eval $cmd
22286         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22287
22288         #cleanup
22289         rm -rf $DIR/$tdir
22290 }
22291 run_test 236 "Layout swap on open unlinked file"
22292
22293 # LU-4659 linkea consistency
22294 test_238() {
22295         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22296                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22297                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22298                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22299
22300         touch $DIR/$tfile
22301         ln $DIR/$tfile $DIR/$tfile.lnk
22302         touch $DIR/$tfile.new
22303         mv $DIR/$tfile.new $DIR/$tfile
22304         local fid1=$($LFS path2fid $DIR/$tfile)
22305         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22306         local path1=$($LFS fid2path $FSNAME "$fid1")
22307         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22308         local path2=$($LFS fid2path $FSNAME "$fid2")
22309         [ $tfile.lnk == $path2 ] ||
22310                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22311         rm -f $DIR/$tfile*
22312 }
22313 run_test 238 "Verify linkea consistency"
22314
22315 test_239A() { # was test_239
22316         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22317                 skip "Need MDS version at least 2.5.60"
22318
22319         local list=$(comma_list $(mdts_nodes))
22320
22321         mkdir -p $DIR/$tdir
22322         createmany -o $DIR/$tdir/f- 5000
22323         unlinkmany $DIR/$tdir/f- 5000
22324         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22325                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22326         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22327                         osp.*MDT*.sync_in_flight" | calc_sum)
22328         [ "$changes" -eq 0 ] || error "$changes not synced"
22329 }
22330 run_test 239A "osp_sync test"
22331
22332 test_239a() { #LU-5297
22333         remote_mds_nodsh && skip "remote MDS with nodsh"
22334
22335         touch $DIR/$tfile
22336         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22337         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22338         chgrp $RUNAS_GID $DIR/$tfile
22339         wait_delete_completed
22340 }
22341 run_test 239a "process invalid osp sync record correctly"
22342
22343 test_239b() { #LU-5297
22344         remote_mds_nodsh && skip "remote MDS with nodsh"
22345
22346         touch $DIR/$tfile1
22347         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22348         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22349         chgrp $RUNAS_GID $DIR/$tfile1
22350         wait_delete_completed
22351         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22352         touch $DIR/$tfile2
22353         chgrp $RUNAS_GID $DIR/$tfile2
22354         wait_delete_completed
22355 }
22356 run_test 239b "process osp sync record with ENOMEM error correctly"
22357
22358 test_240() {
22359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22360         remote_mds_nodsh && skip "remote MDS with nodsh"
22361
22362         mkdir -p $DIR/$tdir
22363
22364         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22365                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22366         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22367                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22368
22369         umount_client $MOUNT || error "umount failed"
22370         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22371         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22372         mount_client $MOUNT || error "failed to mount client"
22373
22374         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22375         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22376 }
22377 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22378
22379 test_241_bio() {
22380         local count=$1
22381         local bsize=$2
22382
22383         for LOOP in $(seq $count); do
22384                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22385                 cancel_lru_locks $OSC || true
22386         done
22387 }
22388
22389 test_241_dio() {
22390         local count=$1
22391         local bsize=$2
22392
22393         for LOOP in $(seq $1); do
22394                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22395                         2>/dev/null
22396         done
22397 }
22398
22399 test_241a() { # was test_241
22400         local bsize=$PAGE_SIZE
22401
22402         (( bsize < 40960 )) && bsize=40960
22403         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22404         ls -la $DIR/$tfile
22405         cancel_lru_locks $OSC
22406         test_241_bio 1000 $bsize &
22407         PID=$!
22408         test_241_dio 1000 $bsize
22409         wait $PID
22410 }
22411 run_test 241a "bio vs dio"
22412
22413 test_241b() {
22414         local bsize=$PAGE_SIZE
22415
22416         (( bsize < 40960 )) && bsize=40960
22417         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22418         ls -la $DIR/$tfile
22419         test_241_dio 1000 $bsize &
22420         PID=$!
22421         test_241_dio 1000 $bsize
22422         wait $PID
22423 }
22424 run_test 241b "dio vs dio"
22425
22426 test_242() {
22427         remote_mds_nodsh && skip "remote MDS with nodsh"
22428
22429         mkdir_on_mdt0 $DIR/$tdir
22430         touch $DIR/$tdir/$tfile
22431
22432         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22433         do_facet mds1 lctl set_param fail_loc=0x105
22434         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22435
22436         do_facet mds1 lctl set_param fail_loc=0
22437         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22438 }
22439 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22440
22441 test_243()
22442 {
22443         test_mkdir $DIR/$tdir
22444         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22445 }
22446 run_test 243 "various group lock tests"
22447
22448 test_244a()
22449 {
22450         test_mkdir $DIR/$tdir
22451         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22452         sendfile_grouplock $DIR/$tdir/$tfile || \
22453                 error "sendfile+grouplock failed"
22454         rm -rf $DIR/$tdir
22455 }
22456 run_test 244a "sendfile with group lock tests"
22457
22458 test_244b()
22459 {
22460         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22461
22462         local threads=50
22463         local size=$((1024*1024))
22464
22465         test_mkdir $DIR/$tdir
22466         for i in $(seq 1 $threads); do
22467                 local file=$DIR/$tdir/file_$((i / 10))
22468                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22469                 local pids[$i]=$!
22470         done
22471         for i in $(seq 1 $threads); do
22472                 wait ${pids[$i]}
22473         done
22474 }
22475 run_test 244b "multi-threaded write with group lock"
22476
22477 test_245a() {
22478         local flagname="multi_mod_rpcs"
22479         local connect_data_name="max_mod_rpcs"
22480         local out
22481
22482         # check if multiple modify RPCs flag is set
22483         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22484                 grep "connect_flags:")
22485         echo "$out"
22486
22487         echo "$out" | grep -qw $flagname
22488         if [ $? -ne 0 ]; then
22489                 echo "connect flag $flagname is not set"
22490                 return
22491         fi
22492
22493         # check if multiple modify RPCs data is set
22494         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22495         echo "$out"
22496
22497         echo "$out" | grep -qw $connect_data_name ||
22498                 error "import should have connect data $connect_data_name"
22499 }
22500 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22501
22502 test_245b() {
22503         local flagname="multi_mod_rpcs"
22504         local connect_data_name="max_mod_rpcs"
22505         local out
22506
22507         remote_mds_nodsh && skip "remote MDS with nodsh"
22508         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22509
22510         # check if multiple modify RPCs flag is set
22511         out=$(do_facet mds1 \
22512               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22513               grep "connect_flags:")
22514         echo "$out"
22515
22516         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22517
22518         # check if multiple modify RPCs data is set
22519         out=$(do_facet mds1 \
22520               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22521
22522         [[ "$out" =~ $connect_data_name ]] ||
22523                 {
22524                         echo "$out"
22525                         error "missing connect data $connect_data_name"
22526                 }
22527 }
22528 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22529
22530 cleanup_247() {
22531         local submount=$1
22532
22533         trap 0
22534         umount_client $submount
22535         rmdir $submount
22536 }
22537
22538 test_247a() {
22539         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22540                 grep -q subtree ||
22541                 skip_env "Fileset feature is not supported"
22542
22543         local submount=${MOUNT}_$tdir
22544
22545         mkdir $MOUNT/$tdir
22546         mkdir -p $submount || error "mkdir $submount failed"
22547         FILESET="$FILESET/$tdir" mount_client $submount ||
22548                 error "mount $submount failed"
22549         trap "cleanup_247 $submount" EXIT
22550         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22551         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22552                 error "read $MOUNT/$tdir/$tfile failed"
22553         cleanup_247 $submount
22554 }
22555 run_test 247a "mount subdir as fileset"
22556
22557 test_247b() {
22558         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22559                 skip_env "Fileset feature is not supported"
22560
22561         local submount=${MOUNT}_$tdir
22562
22563         rm -rf $MOUNT/$tdir
22564         mkdir -p $submount || error "mkdir $submount failed"
22565         SKIP_FILESET=1
22566         FILESET="$FILESET/$tdir" mount_client $submount &&
22567                 error "mount $submount should fail"
22568         rmdir $submount
22569 }
22570 run_test 247b "mount subdir that dose not exist"
22571
22572 test_247c() {
22573         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22574                 skip_env "Fileset feature is not supported"
22575
22576         local submount=${MOUNT}_$tdir
22577
22578         mkdir -p $MOUNT/$tdir/dir1
22579         mkdir -p $submount || error "mkdir $submount failed"
22580         trap "cleanup_247 $submount" EXIT
22581         FILESET="$FILESET/$tdir" mount_client $submount ||
22582                 error "mount $submount failed"
22583         local fid=$($LFS path2fid $MOUNT/)
22584         $LFS fid2path $submount $fid && error "fid2path should fail"
22585         cleanup_247 $submount
22586 }
22587 run_test 247c "running fid2path outside subdirectory root"
22588
22589 test_247d() {
22590         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22591                 skip "Fileset feature is not supported"
22592
22593         local submount=${MOUNT}_$tdir
22594
22595         mkdir -p $MOUNT/$tdir/dir1
22596         mkdir -p $submount || error "mkdir $submount failed"
22597         FILESET="$FILESET/$tdir" mount_client $submount ||
22598                 error "mount $submount failed"
22599         trap "cleanup_247 $submount" EXIT
22600
22601         local td=$submount/dir1
22602         local fid=$($LFS path2fid $td)
22603         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22604
22605         # check that we get the same pathname back
22606         local rootpath
22607         local found
22608         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22609                 echo "$rootpath $fid"
22610                 found=$($LFS fid2path $rootpath "$fid")
22611                 [ -n "$found" ] || error "fid2path should succeed"
22612                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22613         done
22614         # check wrong root path format
22615         rootpath=$submount"_wrong"
22616         found=$($LFS fid2path $rootpath "$fid")
22617         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22618
22619         cleanup_247 $submount
22620 }
22621 run_test 247d "running fid2path inside subdirectory root"
22622
22623 # LU-8037
22624 test_247e() {
22625         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22626                 grep -q subtree ||
22627                 skip "Fileset feature is not supported"
22628
22629         local submount=${MOUNT}_$tdir
22630
22631         mkdir $MOUNT/$tdir
22632         mkdir -p $submount || error "mkdir $submount failed"
22633         FILESET="$FILESET/.." mount_client $submount &&
22634                 error "mount $submount should fail"
22635         rmdir $submount
22636 }
22637 run_test 247e "mount .. as fileset"
22638
22639 test_247f() {
22640         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22641         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22642                 skip "Need at least version 2.14.50.162"
22643         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22644                 skip "Fileset feature is not supported"
22645
22646         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22647         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22648                 error "mkdir remote failed"
22649         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22650                 error "mkdir remote/subdir failed"
22651         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22652                 error "mkdir striped failed"
22653         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22654
22655         local submount=${MOUNT}_$tdir
22656
22657         mkdir -p $submount || error "mkdir $submount failed"
22658         stack_trap "rmdir $submount"
22659
22660         local dir
22661         local fileset=$FILESET
22662         local mdts=$(comma_list $(mdts_nodes))
22663
22664         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22665         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22666                 $tdir/striped/subdir $tdir/striped/.; do
22667                 FILESET="$fileset/$dir" mount_client $submount ||
22668                         error "mount $dir failed"
22669                 umount_client $submount
22670         done
22671 }
22672 run_test 247f "mount striped or remote directory as fileset"
22673
22674 test_subdir_mount_lock()
22675 {
22676         local testdir=$1
22677         local submount=${MOUNT}_$(basename $testdir)
22678
22679         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22680
22681         mkdir -p $submount || error "mkdir $submount failed"
22682         stack_trap "rmdir $submount"
22683
22684         FILESET="$fileset/$testdir" mount_client $submount ||
22685                 error "mount $FILESET failed"
22686         stack_trap "umount $submount"
22687
22688         local mdts=$(comma_list $(mdts_nodes))
22689
22690         local nrpcs
22691
22692         stat $submount > /dev/null || error "stat $submount failed"
22693         cancel_lru_locks $MDC
22694         stat $submount > /dev/null || error "stat $submount failed"
22695         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22696         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22697         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22698         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22699                 awk '/getattr/ {sum += $2} END {print sum}')
22700
22701         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22702 }
22703
22704 test_247g() {
22705         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22706
22707         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22708                 error "mkdir $tdir failed"
22709         test_subdir_mount_lock $tdir
22710 }
22711 run_test 247g "striped directory submount revalidate ROOT from cache"
22712
22713 test_247h() {
22714         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22715         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22716                 skip "Need MDS version at least 2.15.51"
22717
22718         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22719         test_subdir_mount_lock $tdir
22720         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22721         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22722                 error "mkdir $tdir.1 failed"
22723         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22724 }
22725 run_test 247h "remote directory submount revalidate ROOT from cache"
22726
22727 test_248a() {
22728         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22729         [ -z "$fast_read_sav" ] && skip "no fast read support"
22730
22731         # create a large file for fast read verification
22732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22733
22734         # make sure the file is created correctly
22735         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22736                 { rm -f $DIR/$tfile; skip "file creation error"; }
22737
22738         echo "Test 1: verify that fast read is 4 times faster on cache read"
22739
22740         # small read with fast read enabled
22741         $LCTL set_param -n llite.*.fast_read=1
22742         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22743                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22744                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22745         # small read with fast read disabled
22746         $LCTL set_param -n llite.*.fast_read=0
22747         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22748                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22749                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22750
22751         # verify that fast read is 4 times faster for cache read
22752         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22753                 error_not_in_vm "fast read was not 4 times faster: " \
22754                            "$t_fast vs $t_slow"
22755
22756         echo "Test 2: verify the performance between big and small read"
22757         $LCTL set_param -n llite.*.fast_read=1
22758
22759         # 1k non-cache read
22760         cancel_lru_locks osc
22761         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22762                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22763                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22764
22765         # 1M non-cache read
22766         cancel_lru_locks osc
22767         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22768                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22769                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22770
22771         # verify that big IO is not 4 times faster than small IO
22772         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22773                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22774
22775         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22776         rm -f $DIR/$tfile
22777 }
22778 run_test 248a "fast read verification"
22779
22780 test_248b() {
22781         # Default short_io_bytes=16384, try both smaller and larger sizes.
22782         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22783         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22784         echo "bs=53248 count=113 normal buffered write"
22785         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22786                 error "dd of initial data file failed"
22787         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22788
22789         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22790         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22791                 error "dd with sync normal writes failed"
22792         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22793
22794         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22795         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22796                 error "dd with sync small writes failed"
22797         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22798
22799         cancel_lru_locks osc
22800
22801         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22802         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22803         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22804         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22805                 iflag=direct || error "dd with O_DIRECT small read failed"
22806         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22807         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22808                 error "compare $TMP/$tfile.1 failed"
22809
22810         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22811         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22812
22813         # just to see what the maximum tunable value is, and test parsing
22814         echo "test invalid parameter 2MB"
22815         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22816                 error "too-large short_io_bytes allowed"
22817         echo "test maximum parameter 512KB"
22818         # if we can set a larger short_io_bytes, run test regardless of version
22819         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22820                 # older clients may not allow setting it this large, that's OK
22821                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22822                         skip "Need at least client version 2.13.50"
22823                 error "medium short_io_bytes failed"
22824         fi
22825         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22826         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22827
22828         echo "test large parameter 64KB"
22829         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22830         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22831
22832         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22833         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22834                 error "dd with sync large writes failed"
22835         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22836
22837         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22838         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22839         num=$((113 * 4096 / PAGE_SIZE))
22840         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22841         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22842                 error "dd with O_DIRECT large writes failed"
22843         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22844                 error "compare $DIR/$tfile.3 failed"
22845
22846         cancel_lru_locks osc
22847
22848         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22849         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22850                 error "dd with O_DIRECT large read failed"
22851         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22852                 error "compare $TMP/$tfile.2 failed"
22853
22854         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22855         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22856                 error "dd with O_DIRECT large read failed"
22857         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22858                 error "compare $TMP/$tfile.3 failed"
22859 }
22860 run_test 248b "test short_io read and write for both small and large sizes"
22861
22862 test_249() { # LU-7890
22863         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22864                 skip "Need at least version 2.8.54"
22865
22866         rm -f $DIR/$tfile
22867         $LFS setstripe -c 1 $DIR/$tfile
22868         # Offset 2T == 4k * 512M
22869         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22870                 error "dd to 2T offset failed"
22871 }
22872 run_test 249 "Write above 2T file size"
22873
22874 test_250() {
22875         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22876          && skip "no 16TB file size limit on ZFS"
22877
22878         $LFS setstripe -c 1 $DIR/$tfile
22879         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22880         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22881         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22882         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22883                 conv=notrunc,fsync && error "append succeeded"
22884         return 0
22885 }
22886 run_test 250 "Write above 16T limit"
22887
22888 test_251() {
22889         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22890
22891         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22892         #Skip once - writing the first stripe will succeed
22893         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22894         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22895                 error "short write happened"
22896
22897         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22898         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22899                 error "short read happened"
22900
22901         rm -f $DIR/$tfile
22902 }
22903 run_test 251 "Handling short read and write correctly"
22904
22905 test_252() {
22906         remote_mds_nodsh && skip "remote MDS with nodsh"
22907         remote_ost_nodsh && skip "remote OST with nodsh"
22908         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22909                 skip_env "ldiskfs only test"
22910         fi
22911
22912         local tgt
22913         local dev
22914         local out
22915         local uuid
22916         local num
22917         local gen
22918
22919         # check lr_reader on OST0000
22920         tgt=ost1
22921         dev=$(facet_device $tgt)
22922         out=$(do_facet $tgt $LR_READER $dev)
22923         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22924         echo "$out"
22925         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22926         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22927                 error "Invalid uuid returned by $LR_READER on target $tgt"
22928         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22929
22930         # check lr_reader -c on MDT0000
22931         tgt=mds1
22932         dev=$(facet_device $tgt)
22933         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22934                 skip "$LR_READER does not support additional options"
22935         fi
22936         out=$(do_facet $tgt $LR_READER -c $dev)
22937         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22938         echo "$out"
22939         num=$(echo "$out" | grep -c "mdtlov")
22940         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22941                 error "Invalid number of mdtlov clients returned by $LR_READER"
22942         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22943
22944         # check lr_reader -cr on MDT0000
22945         out=$(do_facet $tgt $LR_READER -cr $dev)
22946         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22947         echo "$out"
22948         echo "$out" | grep -q "^reply_data:$" ||
22949                 error "$LR_READER should have returned 'reply_data' section"
22950         num=$(echo "$out" | grep -c "client_generation")
22951         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22952 }
22953 run_test 252 "check lr_reader tool"
22954
22955 test_253() {
22956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22957         remote_mds_nodsh && skip "remote MDS with nodsh"
22958         remote_mgs_nodsh && skip "remote MGS with nodsh"
22959
22960         local ostidx=0
22961         local rc=0
22962         local ost_name=$(ostname_from_index $ostidx)
22963
22964         # on the mdt's osc
22965         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22966         do_facet $SINGLEMDS $LCTL get_param -n \
22967                 osp.$mdtosc_proc1.reserved_mb_high ||
22968                 skip  "remote MDS does not support reserved_mb_high"
22969
22970         rm -rf $DIR/$tdir
22971         wait_mds_ost_sync
22972         wait_delete_completed
22973         mkdir $DIR/$tdir
22974         stack_trap "rm -rf $DIR/$tdir"
22975
22976         pool_add $TESTNAME || error "Pool creation failed"
22977         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22978
22979         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22980                 error "Setstripe failed"
22981
22982         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22983
22984         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22985                     grep "watermarks")
22986         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22987
22988         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22989                         osp.$mdtosc_proc1.prealloc_status)
22990         echo "prealloc_status $oa_status"
22991
22992         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22993                 error "File creation should fail"
22994
22995         #object allocation was stopped, but we still able to append files
22996         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22997                 oflag=append || error "Append failed"
22998
22999         rm -f $DIR/$tdir/$tfile.0
23000
23001         # For this test, we want to delete the files we created to go out of
23002         # space but leave the watermark, so we remain nearly out of space
23003         ost_watermarks_enospc_delete_files $tfile $ostidx
23004
23005         wait_delete_completed
23006
23007         sleep_maxage
23008
23009         for i in $(seq 10 12); do
23010                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23011                         2>/dev/null || error "File creation failed after rm"
23012         done
23013
23014         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23015                         osp.$mdtosc_proc1.prealloc_status)
23016         echo "prealloc_status $oa_status"
23017
23018         if (( oa_status != 0 )); then
23019                 error "Object allocation still disable after rm"
23020         fi
23021 }
23022 run_test 253 "Check object allocation limit"
23023
23024 test_254() {
23025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23026         remote_mds_nodsh && skip "remote MDS with nodsh"
23027
23028         local mdt=$(facet_svc $SINGLEMDS)
23029
23030         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23031                 skip "MDS does not support changelog_size"
23032
23033         local cl_user
23034
23035         changelog_register || error "changelog_register failed"
23036
23037         changelog_clear 0 || error "changelog_clear failed"
23038
23039         local size1=$(do_facet $SINGLEMDS \
23040                       $LCTL get_param -n mdd.$mdt.changelog_size)
23041         echo "Changelog size $size1"
23042
23043         rm -rf $DIR/$tdir
23044         $LFS mkdir -i 0 $DIR/$tdir
23045         # change something
23046         mkdir -p $DIR/$tdir/pics/2008/zachy
23047         touch $DIR/$tdir/pics/2008/zachy/timestamp
23048         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23049         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23050         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23051         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23052         rm $DIR/$tdir/pics/desktop.jpg
23053
23054         local size2=$(do_facet $SINGLEMDS \
23055                       $LCTL get_param -n mdd.$mdt.changelog_size)
23056         echo "Changelog size after work $size2"
23057
23058         (( $size2 > $size1 )) ||
23059                 error "new Changelog size=$size2 less than old size=$size1"
23060 }
23061 run_test 254 "Check changelog size"
23062
23063 ladvise_no_type()
23064 {
23065         local type=$1
23066         local file=$2
23067
23068         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23069                 awk -F: '{print $2}' | grep $type > /dev/null
23070         if [ $? -ne 0 ]; then
23071                 return 0
23072         fi
23073         return 1
23074 }
23075
23076 ladvise_no_ioctl()
23077 {
23078         local file=$1
23079
23080         lfs ladvise -a willread $file > /dev/null 2>&1
23081         if [ $? -eq 0 ]; then
23082                 return 1
23083         fi
23084
23085         lfs ladvise -a willread $file 2>&1 |
23086                 grep "Inappropriate ioctl for device" > /dev/null
23087         if [ $? -eq 0 ]; then
23088                 return 0
23089         fi
23090         return 1
23091 }
23092
23093 percent() {
23094         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23095 }
23096
23097 # run a random read IO workload
23098 # usage: random_read_iops <filename> <filesize> <iosize>
23099 random_read_iops() {
23100         local file=$1
23101         local fsize=$2
23102         local iosize=${3:-4096}
23103
23104         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23105                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23106 }
23107
23108 drop_file_oss_cache() {
23109         local file="$1"
23110         local nodes="$2"
23111
23112         $LFS ladvise -a dontneed $file 2>/dev/null ||
23113                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23114 }
23115
23116 ladvise_willread_performance()
23117 {
23118         local repeat=10
23119         local average_origin=0
23120         local average_cache=0
23121         local average_ladvise=0
23122
23123         for ((i = 1; i <= $repeat; i++)); do
23124                 echo "Iter $i/$repeat: reading without willread hint"
23125                 cancel_lru_locks osc
23126                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23127                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23128                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23129                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23130
23131                 cancel_lru_locks osc
23132                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23133                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23134                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23135
23136                 cancel_lru_locks osc
23137                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23138                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23139                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23140                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23141                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23142         done
23143         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23144         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23145         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23146
23147         speedup_cache=$(percent $average_cache $average_origin)
23148         speedup_ladvise=$(percent $average_ladvise $average_origin)
23149
23150         echo "Average uncached read: $average_origin"
23151         echo "Average speedup with OSS cached read: " \
23152                 "$average_cache = +$speedup_cache%"
23153         echo "Average speedup with ladvise willread: " \
23154                 "$average_ladvise = +$speedup_ladvise%"
23155
23156         local lowest_speedup=20
23157         if (( ${average_cache%.*} < $lowest_speedup )); then
23158                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23159                      " got $average_cache%. Skipping ladvise willread check."
23160                 return 0
23161         fi
23162
23163         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23164         # it is still good to run until then to exercise 'ladvise willread'
23165         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23166                 [ "$ost1_FSTYPE" = "zfs" ] &&
23167                 echo "osd-zfs does not support dontneed or drop_caches" &&
23168                 return 0
23169
23170         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23171         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23172                 error_not_in_vm "Speedup with willread is less than " \
23173                         "$lowest_speedup%, got $average_ladvise%"
23174 }
23175
23176 test_255a() {
23177         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23178                 skip "lustre < 2.8.54 does not support ladvise "
23179         remote_ost_nodsh && skip "remote OST with nodsh"
23180
23181         stack_trap "rm -f $DIR/$tfile"
23182         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23183
23184         ladvise_no_type willread $DIR/$tfile &&
23185                 skip "willread ladvise is not supported"
23186
23187         ladvise_no_ioctl $DIR/$tfile &&
23188                 skip "ladvise ioctl is not supported"
23189
23190         local size_mb=100
23191         local size=$((size_mb * 1048576))
23192         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23193                 error "dd to $DIR/$tfile failed"
23194
23195         lfs ladvise -a willread $DIR/$tfile ||
23196                 error "Ladvise failed with no range argument"
23197
23198         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23199                 error "Ladvise failed with no -l or -e argument"
23200
23201         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23202                 error "Ladvise failed with only -e argument"
23203
23204         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23205                 error "Ladvise failed with only -l argument"
23206
23207         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23208                 error "End offset should not be smaller than start offset"
23209
23210         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23211                 error "End offset should not be equal to start offset"
23212
23213         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23214                 error "Ladvise failed with overflowing -s argument"
23215
23216         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23217                 error "Ladvise failed with overflowing -e argument"
23218
23219         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23220                 error "Ladvise failed with overflowing -l argument"
23221
23222         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23223                 error "Ladvise succeeded with conflicting -l and -e arguments"
23224
23225         echo "Synchronous ladvise should wait"
23226         local delay=8
23227 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23228         do_nodes $(comma_list $(osts_nodes)) \
23229                 $LCTL set_param fail_val=$delay fail_loc=0x237
23230         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23231                 $LCTL set_param fail_loc=0"
23232
23233         local start_ts=$SECONDS
23234         lfs ladvise -a willread $DIR/$tfile ||
23235                 error "Ladvise failed with no range argument"
23236         local end_ts=$SECONDS
23237         local inteval_ts=$((end_ts - start_ts))
23238
23239         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23240                 error "Synchronous advice didn't wait reply"
23241         fi
23242
23243         echo "Asynchronous ladvise shouldn't wait"
23244         local start_ts=$SECONDS
23245         lfs ladvise -a willread -b $DIR/$tfile ||
23246                 error "Ladvise failed with no range argument"
23247         local end_ts=$SECONDS
23248         local inteval_ts=$((end_ts - start_ts))
23249
23250         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23251                 error "Asynchronous advice blocked"
23252         fi
23253
23254         ladvise_willread_performance
23255 }
23256 run_test 255a "check 'lfs ladvise -a willread'"
23257
23258 facet_meminfo() {
23259         local facet=$1
23260         local info=$2
23261
23262         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23263 }
23264
23265 test_255b() {
23266         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23267                 skip "lustre < 2.8.54 does not support ladvise "
23268         remote_ost_nodsh && skip "remote OST with nodsh"
23269
23270         stack_trap "rm -f $DIR/$tfile"
23271         lfs setstripe -c 1 -i 0 $DIR/$tfile
23272
23273         ladvise_no_type dontneed $DIR/$tfile &&
23274                 skip "dontneed ladvise is not supported"
23275
23276         ladvise_no_ioctl $DIR/$tfile &&
23277                 skip "ladvise ioctl is not supported"
23278
23279         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23280                 [ "$ost1_FSTYPE" = "zfs" ] &&
23281                 skip "zfs-osd does not support 'ladvise dontneed'"
23282
23283         local size_mb=100
23284         local size=$((size_mb * 1048576))
23285         # In order to prevent disturbance of other processes, only check 3/4
23286         # of the memory usage
23287         local kibibytes=$((size_mb * 1024 * 3 / 4))
23288
23289         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23290                 error "dd to $DIR/$tfile failed"
23291
23292         #force write to complete before dropping OST cache & checking memory
23293         sync
23294
23295         local total=$(facet_meminfo ost1 MemTotal)
23296         echo "Total memory: $total KiB"
23297
23298         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23299         local before_read=$(facet_meminfo ost1 Cached)
23300         echo "Cache used before read: $before_read KiB"
23301
23302         lfs ladvise -a willread $DIR/$tfile ||
23303                 error "Ladvise willread failed"
23304         local after_read=$(facet_meminfo ost1 Cached)
23305         echo "Cache used after read: $after_read KiB"
23306
23307         lfs ladvise -a dontneed $DIR/$tfile ||
23308                 error "Ladvise dontneed again failed"
23309         local no_read=$(facet_meminfo ost1 Cached)
23310         echo "Cache used after dontneed ladvise: $no_read KiB"
23311
23312         if [ $total -lt $((before_read + kibibytes)) ]; then
23313                 echo "Memory is too small, abort checking"
23314                 return 0
23315         fi
23316
23317         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23318                 error "Ladvise willread should use more memory" \
23319                         "than $kibibytes KiB"
23320         fi
23321
23322         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23323                 error "Ladvise dontneed should release more memory" \
23324                         "than $kibibytes KiB"
23325         fi
23326 }
23327 run_test 255b "check 'lfs ladvise -a dontneed'"
23328
23329 test_255c() {
23330         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23331                 skip "lustre < 2.10.50 does not support lockahead"
23332
23333         local ost1_imp=$(get_osc_import_name client ost1)
23334         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23335                          cut -d'.' -f2)
23336         local count
23337         local new_count
23338         local difference
23339         local i
23340         local rc
23341
23342         test_mkdir -p $DIR/$tdir
23343         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23344
23345         #test 10 returns only success/failure
23346         i=10
23347         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23348         rc=$?
23349         if [ $rc -eq 255 ]; then
23350                 error "Ladvise test${i} failed, ${rc}"
23351         fi
23352
23353         #test 11 counts lock enqueue requests, all others count new locks
23354         i=11
23355         count=$(do_facet ost1 \
23356                 $LCTL get_param -n ost.OSS.ost.stats)
23357         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23358
23359         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23360         rc=$?
23361         if [ $rc -eq 255 ]; then
23362                 error "Ladvise test${i} failed, ${rc}"
23363         fi
23364
23365         new_count=$(do_facet ost1 \
23366                 $LCTL get_param -n ost.OSS.ost.stats)
23367         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23368                    awk '{ print $2 }')
23369
23370         difference="$((new_count - count))"
23371         if [ $difference -ne $rc ]; then
23372                 error "Ladvise test${i}, bad enqueue count, returned " \
23373                       "${rc}, actual ${difference}"
23374         fi
23375
23376         for i in $(seq 12 21); do
23377                 # If we do not do this, we run the risk of having too many
23378                 # locks and starting lock cancellation while we are checking
23379                 # lock counts.
23380                 cancel_lru_locks osc
23381
23382                 count=$($LCTL get_param -n \
23383                        ldlm.namespaces.$imp_name.lock_unused_count)
23384
23385                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23386                 rc=$?
23387                 if [ $rc -eq 255 ]; then
23388                         error "Ladvise test ${i} failed, ${rc}"
23389                 fi
23390
23391                 new_count=$($LCTL get_param -n \
23392                        ldlm.namespaces.$imp_name.lock_unused_count)
23393                 difference="$((new_count - count))"
23394
23395                 # Test 15 output is divided by 100 to map down to valid return
23396                 if [ $i -eq 15 ]; then
23397                         rc="$((rc * 100))"
23398                 fi
23399
23400                 if [ $difference -ne $rc ]; then
23401                         error "Ladvise test ${i}, bad lock count, returned " \
23402                               "${rc}, actual ${difference}"
23403                 fi
23404         done
23405
23406         #test 22 returns only success/failure
23407         i=22
23408         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23409         rc=$?
23410         if [ $rc -eq 255 ]; then
23411                 error "Ladvise test${i} failed, ${rc}"
23412         fi
23413 }
23414 run_test 255c "suite of ladvise lockahead tests"
23415
23416 test_256() {
23417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23418         remote_mds_nodsh && skip "remote MDS with nodsh"
23419         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23420         changelog_users $SINGLEMDS | grep "^cl" &&
23421                 skip "active changelog user"
23422
23423         local cl_user
23424         local cat_sl
23425         local mdt_dev
23426
23427         mdt_dev=$(facet_device $SINGLEMDS)
23428         echo $mdt_dev
23429
23430         changelog_register || error "changelog_register failed"
23431
23432         rm -rf $DIR/$tdir
23433         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23434
23435         changelog_clear 0 || error "changelog_clear failed"
23436
23437         # change something
23438         touch $DIR/$tdir/{1..10}
23439
23440         # stop the MDT
23441         stop $SINGLEMDS || error "Fail to stop MDT"
23442
23443         # remount the MDT
23444         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23445                 error "Fail to start MDT"
23446
23447         #after mount new plainllog is used
23448         touch $DIR/$tdir/{11..19}
23449         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23450         stack_trap "rm -f $tmpfile"
23451         cat_sl=$(do_facet $SINGLEMDS "sync; \
23452                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23453                  llog_reader $tmpfile | grep -c type=1064553b")
23454         do_facet $SINGLEMDS llog_reader $tmpfile
23455
23456         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23457
23458         changelog_clear 0 || error "changelog_clear failed"
23459
23460         cat_sl=$(do_facet $SINGLEMDS "sync; \
23461                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23462                  llog_reader $tmpfile | grep -c type=1064553b")
23463
23464         if (( cat_sl == 2 )); then
23465                 error "Empty plain llog was not deleted from changelog catalog"
23466         elif (( cat_sl != 1 )); then
23467                 error "Active plain llog shouldn't be deleted from catalog"
23468         fi
23469 }
23470 run_test 256 "Check llog delete for empty and not full state"
23471
23472 test_257() {
23473         remote_mds_nodsh && skip "remote MDS with nodsh"
23474         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23475                 skip "Need MDS version at least 2.8.55"
23476
23477         test_mkdir $DIR/$tdir
23478
23479         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23480                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23481         stat $DIR/$tdir
23482
23483 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23484         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23485         local facet=mds$((mdtidx + 1))
23486         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23487         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23488
23489         stop $facet || error "stop MDS failed"
23490         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23491                 error "start MDS fail"
23492         wait_recovery_complete $facet
23493 }
23494 run_test 257 "xattr locks are not lost"
23495
23496 # Verify we take the i_mutex when security requires it
23497 test_258a() {
23498 #define OBD_FAIL_IMUTEX_SEC 0x141c
23499         $LCTL set_param fail_loc=0x141c
23500         touch $DIR/$tfile
23501         chmod u+s $DIR/$tfile
23502         chmod a+rwx $DIR/$tfile
23503         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23504         RC=$?
23505         if [ $RC -ne 0 ]; then
23506                 error "error, failed to take i_mutex, rc=$?"
23507         fi
23508         rm -f $DIR/$tfile
23509 }
23510 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23511
23512 # Verify we do NOT take the i_mutex in the normal case
23513 test_258b() {
23514 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23515         $LCTL set_param fail_loc=0x141d
23516         touch $DIR/$tfile
23517         chmod a+rwx $DIR
23518         chmod a+rw $DIR/$tfile
23519         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23520         RC=$?
23521         if [ $RC -ne 0 ]; then
23522                 error "error, took i_mutex unnecessarily, rc=$?"
23523         fi
23524         rm -f $DIR/$tfile
23525
23526 }
23527 run_test 258b "verify i_mutex security behavior"
23528
23529 test_259() {
23530         local file=$DIR/$tfile
23531         local before
23532         local after
23533
23534         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23535
23536         stack_trap "rm -f $file" EXIT
23537
23538         wait_delete_completed
23539         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23540         echo "before: $before"
23541
23542         $LFS setstripe -i 0 -c 1 $file
23543         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23544         sync_all_data
23545         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23546         echo "after write: $after"
23547
23548 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23549         do_facet ost1 $LCTL set_param fail_loc=0x2301
23550         $TRUNCATE $file 0
23551         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23552         echo "after truncate: $after"
23553
23554         stop ost1
23555         do_facet ost1 $LCTL set_param fail_loc=0
23556         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23557         sleep 2
23558         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23559         echo "after restart: $after"
23560         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23561                 error "missing truncate?"
23562
23563         return 0
23564 }
23565 run_test 259 "crash at delayed truncate"
23566
23567 test_260() {
23568 #define OBD_FAIL_MDC_CLOSE               0x806
23569         $LCTL set_param fail_loc=0x80000806
23570         touch $DIR/$tfile
23571
23572 }
23573 run_test 260 "Check mdc_close fail"
23574
23575 ### Data-on-MDT sanity tests ###
23576 test_270a() {
23577         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23578                 skip "Need MDS version at least 2.10.55 for DoM"
23579
23580         # create DoM file
23581         local dom=$DIR/$tdir/dom_file
23582         local tmp=$DIR/$tdir/tmp_file
23583
23584         mkdir_on_mdt0 $DIR/$tdir
23585
23586         # basic checks for DoM component creation
23587         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23588                 error "Can set MDT layout to non-first entry"
23589
23590         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23591                 error "Can define multiple entries as MDT layout"
23592
23593         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23594
23595         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23596         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23597         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23598
23599         local mdtidx=$($LFS getstripe -m $dom)
23600         local mdtname=MDT$(printf %04x $mdtidx)
23601         local facet=mds$((mdtidx + 1))
23602         local space_check=1
23603
23604         # Skip free space checks with ZFS
23605         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23606
23607         # write
23608         sync
23609         local size_tmp=$((65536 * 3))
23610         local mdtfree1=$(do_facet $facet \
23611                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23612
23613         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23614         # check also direct IO along write
23615         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23616         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23617         sync
23618         cmp $tmp $dom || error "file data is different"
23619         [ $(stat -c%s $dom) == $size_tmp ] ||
23620                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23621         if [ $space_check == 1 ]; then
23622                 local mdtfree2=$(do_facet $facet \
23623                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23624
23625                 # increase in usage from by $size_tmp
23626                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23627                         error "MDT free space wrong after write: " \
23628                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23629         fi
23630
23631         # truncate
23632         local size_dom=10000
23633
23634         $TRUNCATE $dom $size_dom
23635         [ $(stat -c%s $dom) == $size_dom ] ||
23636                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23637         if [ $space_check == 1 ]; then
23638                 mdtfree1=$(do_facet $facet \
23639                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23640                 # decrease in usage from $size_tmp to new $size_dom
23641                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23642                   $(((size_tmp - size_dom) / 1024)) ] ||
23643                         error "MDT free space is wrong after truncate: " \
23644                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23645         fi
23646
23647         # append
23648         cat $tmp >> $dom
23649         sync
23650         size_dom=$((size_dom + size_tmp))
23651         [ $(stat -c%s $dom) == $size_dom ] ||
23652                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23653         if [ $space_check == 1 ]; then
23654                 mdtfree2=$(do_facet $facet \
23655                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23656                 # increase in usage by $size_tmp from previous
23657                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23658                         error "MDT free space is wrong after append: " \
23659                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23660         fi
23661
23662         # delete
23663         rm $dom
23664         if [ $space_check == 1 ]; then
23665                 mdtfree1=$(do_facet $facet \
23666                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23667                 # decrease in usage by $size_dom from previous
23668                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23669                         error "MDT free space is wrong after removal: " \
23670                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23671         fi
23672
23673         # combined striping
23674         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23675                 error "Can't create DoM + OST striping"
23676
23677         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23678         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23679         # check also direct IO along write
23680         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23681         sync
23682         cmp $tmp $dom || error "file data is different"
23683         [ $(stat -c%s $dom) == $size_tmp ] ||
23684                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23685         rm $dom $tmp
23686
23687         return 0
23688 }
23689 run_test 270a "DoM: basic functionality tests"
23690
23691 test_270b() {
23692         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23693                 skip "Need MDS version at least 2.10.55"
23694
23695         local dom=$DIR/$tdir/dom_file
23696         local max_size=1048576
23697
23698         mkdir -p $DIR/$tdir
23699         $LFS setstripe -E $max_size -L mdt $dom
23700
23701         # truncate over the limit
23702         $TRUNCATE $dom $(($max_size + 1)) &&
23703                 error "successful truncate over the maximum size"
23704         # write over the limit
23705         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23706                 error "successful write over the maximum size"
23707         # append over the limit
23708         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23709         echo "12345" >> $dom && error "successful append over the maximum size"
23710         rm $dom
23711
23712         return 0
23713 }
23714 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23715
23716 test_270c() {
23717         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23718                 skip "Need MDS version at least 2.10.55"
23719
23720         mkdir -p $DIR/$tdir
23721         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23722
23723         # check files inherit DoM EA
23724         touch $DIR/$tdir/first
23725         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23726                 error "bad pattern"
23727         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23728                 error "bad stripe count"
23729         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23730                 error "bad stripe size"
23731
23732         # check directory inherits DoM EA and uses it as default
23733         mkdir $DIR/$tdir/subdir
23734         touch $DIR/$tdir/subdir/second
23735         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23736                 error "bad pattern in sub-directory"
23737         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23738                 error "bad stripe count in sub-directory"
23739         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23740                 error "bad stripe size in sub-directory"
23741         return 0
23742 }
23743 run_test 270c "DoM: DoM EA inheritance tests"
23744
23745 test_270d() {
23746         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23747                 skip "Need MDS version at least 2.10.55"
23748
23749         mkdir -p $DIR/$tdir
23750         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23751
23752         # inherit default DoM striping
23753         mkdir $DIR/$tdir/subdir
23754         touch $DIR/$tdir/subdir/f1
23755
23756         # change default directory striping
23757         $LFS setstripe -c 1 $DIR/$tdir/subdir
23758         touch $DIR/$tdir/subdir/f2
23759         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23760                 error "wrong default striping in file 2"
23761         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23762                 error "bad pattern in file 2"
23763         return 0
23764 }
23765 run_test 270d "DoM: change striping from DoM to RAID0"
23766
23767 test_270e() {
23768         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23769                 skip "Need MDS version at least 2.10.55"
23770
23771         mkdir -p $DIR/$tdir/dom
23772         mkdir -p $DIR/$tdir/norm
23773         DOMFILES=20
23774         NORMFILES=10
23775         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23776         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23777
23778         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23779         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23780
23781         # find DoM files by layout
23782         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23783         [ $NUM -eq  $DOMFILES ] ||
23784                 error "lfs find -L: found $NUM, expected $DOMFILES"
23785         echo "Test 1: lfs find 20 DOM files by layout: OK"
23786
23787         # there should be 1 dir with default DOM striping
23788         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23789         [ $NUM -eq  1 ] ||
23790                 error "lfs find -L: found $NUM, expected 1 dir"
23791         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23792
23793         # find DoM files by stripe size
23794         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23795         [ $NUM -eq  $DOMFILES ] ||
23796                 error "lfs find -S: found $NUM, expected $DOMFILES"
23797         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23798
23799         # find files by stripe offset except DoM files
23800         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23801         [ $NUM -eq  $NORMFILES ] ||
23802                 error "lfs find -i: found $NUM, expected $NORMFILES"
23803         echo "Test 5: lfs find no DOM files by stripe index: OK"
23804         return 0
23805 }
23806 run_test 270e "DoM: lfs find with DoM files test"
23807
23808 test_270f() {
23809         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23810                 skip "Need MDS version at least 2.10.55"
23811
23812         local mdtname=${FSNAME}-MDT0000-mdtlov
23813         local dom=$DIR/$tdir/dom_file
23814         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23815                                                 lod.$mdtname.dom_stripesize)
23816         local dom_limit=131072
23817
23818         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23819         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23820                                                 lod.$mdtname.dom_stripesize)
23821         [ ${dom_limit} -eq ${dom_current} ] ||
23822                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23823
23824         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23825         $LFS setstripe -d $DIR/$tdir
23826         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23827                 error "Can't set directory default striping"
23828
23829         # exceed maximum stripe size
23830         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23831                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23832         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23833                 error "Able to create DoM component size more than LOD limit"
23834
23835         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23836         dom_current=$(do_facet mds1 $LCTL get_param -n \
23837                                                 lod.$mdtname.dom_stripesize)
23838         [ 0 -eq ${dom_current} ] ||
23839                 error "Can't set zero DoM stripe limit"
23840         rm $dom
23841
23842         # attempt to create DoM file on server with disabled DoM should
23843         # remove DoM entry from layout and be succeed
23844         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23845                 error "Can't create DoM file (DoM is disabled)"
23846         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23847                 error "File has DoM component while DoM is disabled"
23848         rm $dom
23849
23850         # attempt to create DoM file with only DoM stripe should return error
23851         $LFS setstripe -E $dom_limit -L mdt $dom &&
23852                 error "Able to create DoM-only file while DoM is disabled"
23853
23854         # too low values to be aligned with smallest stripe size 64K
23855         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23856         dom_current=$(do_facet mds1 $LCTL get_param -n \
23857                                                 lod.$mdtname.dom_stripesize)
23858         [ 30000 -eq ${dom_current} ] &&
23859                 error "Can set too small DoM stripe limit"
23860
23861         # 64K is a minimal stripe size in Lustre, expect limit of that size
23862         [ 65536 -eq ${dom_current} ] ||
23863                 error "Limit is not set to 64K but ${dom_current}"
23864
23865         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23866         dom_current=$(do_facet mds1 $LCTL get_param -n \
23867                                                 lod.$mdtname.dom_stripesize)
23868         echo $dom_current
23869         [ 2147483648 -eq ${dom_current} ] &&
23870                 error "Can set too large DoM stripe limit"
23871
23872         do_facet mds1 $LCTL set_param -n \
23873                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23874         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23875                 error "Can't create DoM component size after limit change"
23876         do_facet mds1 $LCTL set_param -n \
23877                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23878         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23879                 error "Can't create DoM file after limit decrease"
23880         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23881                 error "Can create big DoM component after limit decrease"
23882         touch ${dom}_def ||
23883                 error "Can't create file with old default layout"
23884
23885         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23886         return 0
23887 }
23888 run_test 270f "DoM: maximum DoM stripe size checks"
23889
23890 test_270g() {
23891         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23892                 skip "Need MDS version at least 2.13.52"
23893         local dom=$DIR/$tdir/$tfile
23894
23895         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23896         local lodname=${FSNAME}-MDT0000-mdtlov
23897
23898         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23899         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23900         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23901         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23902
23903         local dom_limit=1024
23904         local dom_threshold="50%"
23905
23906         $LFS setstripe -d $DIR/$tdir
23907         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23908                 error "Can't set directory default striping"
23909
23910         do_facet mds1 $LCTL set_param -n \
23911                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23912         # set 0 threshold and create DOM file to change tunable stripesize
23913         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23914         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23915                 error "Failed to create $dom file"
23916         # now tunable dom_cur_stripesize should reach maximum
23917         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23918                                         lod.${lodname}.dom_stripesize_cur_kb)
23919         [[ $dom_current == $dom_limit ]] ||
23920                 error "Current DOM stripesize is not maximum"
23921         rm $dom
23922
23923         # set threshold for further tests
23924         do_facet mds1 $LCTL set_param -n \
23925                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23926         echo "DOM threshold is $dom_threshold free space"
23927         local dom_def
23928         local dom_set
23929         # Spoof bfree to exceed threshold
23930         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23931         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23932         for spfree in 40 20 0 15 30 55; do
23933                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23934                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23935                         error "Failed to create $dom file"
23936                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23937                                         lod.${lodname}.dom_stripesize_cur_kb)
23938                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23939                 [[ $dom_def != $dom_current ]] ||
23940                         error "Default stripe size was not changed"
23941                 if (( spfree > 0 )) ; then
23942                         dom_set=$($LFS getstripe -S $dom)
23943                         (( dom_set == dom_def * 1024 )) ||
23944                                 error "DOM component size is still old"
23945                 else
23946                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23947                                 error "DoM component is set with no free space"
23948                 fi
23949                 rm $dom
23950                 dom_current=$dom_def
23951         done
23952 }
23953 run_test 270g "DoM: default DoM stripe size depends on free space"
23954
23955 test_270h() {
23956         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23957                 skip "Need MDS version at least 2.13.53"
23958
23959         local mdtname=${FSNAME}-MDT0000-mdtlov
23960         local dom=$DIR/$tdir/$tfile
23961         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23962
23963         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23964         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23965
23966         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23967         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23968                 error "can't create OST file"
23969         # mirrored file with DOM entry in the second mirror
23970         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23971                 error "can't create mirror with DoM component"
23972
23973         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23974
23975         # DOM component in the middle and has other enries in the same mirror,
23976         # should succeed but lost DoM component
23977         $LFS setstripe --copy=${dom}_1 $dom ||
23978                 error "Can't create file from OST|DOM mirror layout"
23979         # check new file has no DoM layout after all
23980         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23981                 error "File has DoM component while DoM is disabled"
23982 }
23983 run_test 270h "DoM: DoM stripe removal when disabled on server"
23984
23985 test_270i() {
23986         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23987                 skip "Need MDS version at least 2.14.54"
23988
23989         mkdir $DIR/$tdir
23990         # DoM with plain layout
23991         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23992                 error "default plain layout with DoM must fail"
23993         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23994                 error "setstripe plain file layout with DoM must fail"
23995         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23996                 error "default DoM layout with bad striping must fail"
23997         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23998                 error "setstripe to DoM layout with bad striping must fail"
23999         return 0
24000 }
24001 run_test 270i "DoM: setting invalid DoM striping should fail"
24002
24003 test_270j() {
24004         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24005                 skip "Need MDS version at least 2.15.55.203"
24006
24007         local dom=$DIR/$tdir/$tfile
24008         local odv
24009         local ndv
24010
24011         mkdir -p $DIR/$tdir
24012
24013         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24014
24015         odv=$($LFS data_version $dom)
24016         chmod 666 $dom
24017         mv $dom ${dom}_moved
24018         link ${dom}_moved $dom
24019         setfattr -n user.attrx -v "some_attr" $dom
24020         ndv=$($LFS data_version $dom)
24021         (( $ndv == $odv )) ||
24022                 error "data version was changed by metadata operations"
24023
24024         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24025                 error "failed to write data into $dom"
24026         cancel_lru_locks mdc
24027         ndv=$($LFS data_version $dom)
24028         (( $ndv != $odv )) ||
24029                 error "data version wasn't changed on write"
24030
24031         odv=$ndv
24032         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24033         ndv=$($LFS data_version $dom)
24034         (( $ndv != $odv )) ||
24035                 error "data version wasn't changed on truncate down"
24036
24037         odv=$ndv
24038         $TRUNCATE $dom 25000
24039         ndv=$($LFS data_version $dom)
24040         (( $ndv != $odv )) ||
24041                 error "data version wasn't changed on truncate up"
24042
24043         # check also fallocate for ldiskfs
24044         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24045                 odv=$ndv
24046                 fallocate -l 1048576 $dom
24047                 ndv=$($LFS data_version $dom)
24048                 (( $ndv != $odv )) ||
24049                         error "data version wasn't changed on fallocate"
24050
24051                 odv=$ndv
24052                 fallocate -p --offset 4096 -l 4096 $dom
24053                 ndv=$($LFS data_version $dom)
24054                 (( $ndv != $odv )) ||
24055                         error "data version wasn't changed on fallocate punch"
24056         fi
24057 }
24058 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24059
24060 test_271a() {
24061         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24062                 skip "Need MDS version at least 2.10.55"
24063
24064         local dom=$DIR/$tdir/dom
24065
24066         mkdir -p $DIR/$tdir
24067
24068         $LFS setstripe -E 1024K -L mdt $dom
24069
24070         lctl set_param -n mdc.*.stats=clear
24071         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24072         cat $dom > /dev/null
24073         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24074         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24075         ls $dom
24076         rm -f $dom
24077 }
24078 run_test 271a "DoM: data is cached for read after write"
24079
24080 test_271b() {
24081         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24082                 skip "Need MDS version at least 2.10.55"
24083
24084         local dom=$DIR/$tdir/dom
24085
24086         mkdir -p $DIR/$tdir
24087
24088         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24089
24090         lctl set_param -n mdc.*.stats=clear
24091         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24092         cancel_lru_locks mdc
24093         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24094         # second stat to check size is cached on client
24095         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24096         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24097         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24098         rm -f $dom
24099 }
24100 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24101
24102 test_271ba() {
24103         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24104                 skip "Need MDS version at least 2.10.55"
24105
24106         local dom=$DIR/$tdir/dom
24107
24108         mkdir -p $DIR/$tdir
24109
24110         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24111
24112         lctl set_param -n mdc.*.stats=clear
24113         lctl set_param -n osc.*.stats=clear
24114         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24115         cancel_lru_locks mdc
24116         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24117         # second stat to check size is cached on client
24118         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24119         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24120         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24121         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24122         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24123         rm -f $dom
24124 }
24125 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24126
24127
24128 get_mdc_stats() {
24129         local mdtidx=$1
24130         local param=$2
24131         local mdt=MDT$(printf %04x $mdtidx)
24132
24133         if [ -z $param ]; then
24134                 lctl get_param -n mdc.*$mdt*.stats
24135         else
24136                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24137         fi
24138 }
24139
24140 test_271c() {
24141         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24142                 skip "Need MDS version at least 2.10.55"
24143
24144         local dom=$DIR/$tdir/dom
24145
24146         mkdir -p $DIR/$tdir
24147
24148         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24149
24150         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24151         local facet=mds$((mdtidx + 1))
24152
24153         cancel_lru_locks mdc
24154         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24155         createmany -o $dom 1000
24156         lctl set_param -n mdc.*.stats=clear
24157         smalliomany -w $dom 1000 200
24158         get_mdc_stats $mdtidx
24159         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24160         # Each file has 1 open, 1 IO enqueues, total 2000
24161         # but now we have also +1 getxattr for security.capability, total 3000
24162         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24163         unlinkmany $dom 1000
24164
24165         cancel_lru_locks mdc
24166         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24167         createmany -o $dom 1000
24168         lctl set_param -n mdc.*.stats=clear
24169         smalliomany -w $dom 1000 200
24170         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24171         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24172         # for OPEN and IO lock.
24173         [ $((enq - enq_2)) -ge 1000 ] ||
24174                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24175         unlinkmany $dom 1000
24176         return 0
24177 }
24178 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24179
24180 cleanup_271def_tests() {
24181         trap 0
24182         rm -f $1
24183 }
24184
24185 test_271d() {
24186         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24187                 skip "Need MDS version at least 2.10.57"
24188
24189         local dom=$DIR/$tdir/dom
24190         local tmp=$TMP/$tfile
24191         trap "cleanup_271def_tests $tmp" EXIT
24192
24193         mkdir -p $DIR/$tdir
24194
24195         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24196
24197         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24198
24199         cancel_lru_locks mdc
24200         dd if=/dev/urandom of=$tmp bs=1000 count=1
24201         dd if=$tmp of=$dom bs=1000 count=1
24202         cancel_lru_locks mdc
24203
24204         cat /etc/hosts >> $tmp
24205         lctl set_param -n mdc.*.stats=clear
24206
24207         # append data to the same file it should update local page
24208         echo "Append to the same page"
24209         cat /etc/hosts >> $dom
24210         local num=$(get_mdc_stats $mdtidx ost_read)
24211         local ra=$(get_mdc_stats $mdtidx req_active)
24212         local rw=$(get_mdc_stats $mdtidx req_waittime)
24213
24214         [ -z $num ] || error "$num READ RPC occured"
24215         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24216         echo "... DONE"
24217
24218         # compare content
24219         cmp $tmp $dom || error "file miscompare"
24220
24221         cancel_lru_locks mdc
24222         lctl set_param -n mdc.*.stats=clear
24223
24224         echo "Open and read file"
24225         cat $dom > /dev/null
24226         local num=$(get_mdc_stats $mdtidx ost_read)
24227         local ra=$(get_mdc_stats $mdtidx req_active)
24228         local rw=$(get_mdc_stats $mdtidx req_waittime)
24229
24230         [ -z $num ] || error "$num READ RPC occured"
24231         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24232         echo "... DONE"
24233
24234         # compare content
24235         cmp $tmp $dom || error "file miscompare"
24236
24237         return 0
24238 }
24239 run_test 271d "DoM: read on open (1K file in reply buffer)"
24240
24241 test_271f() {
24242         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24243                 skip "Need MDS version at least 2.10.57"
24244
24245         local dom=$DIR/$tdir/dom
24246         local tmp=$TMP/$tfile
24247         trap "cleanup_271def_tests $tmp" EXIT
24248
24249         mkdir -p $DIR/$tdir
24250
24251         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24252
24253         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24254
24255         cancel_lru_locks mdc
24256         dd if=/dev/urandom of=$tmp bs=265000 count=1
24257         dd if=$tmp of=$dom bs=265000 count=1
24258         cancel_lru_locks mdc
24259         cat /etc/hosts >> $tmp
24260         lctl set_param -n mdc.*.stats=clear
24261
24262         echo "Append to the same page"
24263         cat /etc/hosts >> $dom
24264         local num=$(get_mdc_stats $mdtidx ost_read)
24265         local ra=$(get_mdc_stats $mdtidx req_active)
24266         local rw=$(get_mdc_stats $mdtidx req_waittime)
24267
24268         [ -z $num ] || error "$num READ RPC occured"
24269         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24270         echo "... DONE"
24271
24272         # compare content
24273         cmp $tmp $dom || error "file miscompare"
24274
24275         cancel_lru_locks mdc
24276         lctl set_param -n mdc.*.stats=clear
24277
24278         echo "Open and read file"
24279         cat $dom > /dev/null
24280         local num=$(get_mdc_stats $mdtidx ost_read)
24281         local ra=$(get_mdc_stats $mdtidx req_active)
24282         local rw=$(get_mdc_stats $mdtidx req_waittime)
24283
24284         [ -z $num ] && num=0
24285         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24286         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24287         echo "... DONE"
24288
24289         # compare content
24290         cmp $tmp $dom || error "file miscompare"
24291
24292         return 0
24293 }
24294 run_test 271f "DoM: read on open (200K file and read tail)"
24295
24296 test_271g() {
24297         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24298                 skip "Skipping due to old client or server version"
24299
24300         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24301         # to get layout
24302         $CHECKSTAT -t file $DIR1/$tfile
24303
24304         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24305         MULTIOP_PID=$!
24306         sleep 1
24307         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24308         $LCTL set_param fail_loc=0x80000314
24309         rm $DIR1/$tfile || error "Unlink fails"
24310         RC=$?
24311         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24312         [ $RC -eq 0 ] || error "Failed write to stale object"
24313 }
24314 run_test 271g "Discard DoM data vs client flush race"
24315
24316 test_272a() {
24317         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24318                 skip "Need MDS version at least 2.11.50"
24319
24320         local dom=$DIR/$tdir/dom
24321         mkdir -p $DIR/$tdir
24322
24323         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24324         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24325                 error "failed to write data into $dom"
24326         local old_md5=$(md5sum $dom)
24327
24328         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24329                 error "failed to migrate to the same DoM component"
24330
24331         local new_md5=$(md5sum $dom)
24332
24333         [ "$old_md5" == "$new_md5" ] ||
24334                 error "md5sum differ: $old_md5, $new_md5"
24335
24336         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24337                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24338 }
24339 run_test 272a "DoM migration: new layout with the same DOM component"
24340
24341 test_272b() {
24342         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24343                 skip "Need MDS version at least 2.11.50"
24344
24345         local dom=$DIR/$tdir/dom
24346         mkdir -p $DIR/$tdir
24347         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24348         stack_trap "rm -rf $DIR/$tdir"
24349
24350         local mdtidx=$($LFS getstripe -m $dom)
24351         local mdtname=MDT$(printf %04x $mdtidx)
24352         local facet=mds$((mdtidx + 1))
24353
24354         local mdtfree1=$(do_facet $facet \
24355                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24356         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24357                 error "failed to write data into $dom"
24358         local old_md5=$(md5sum $dom)
24359         cancel_lru_locks mdc
24360         local mdtfree1=$(do_facet $facet \
24361                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24362
24363         $LFS migrate -c2 $dom ||
24364                 error "failed to migrate to the new composite layout"
24365         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24366                 error "MDT stripe was not removed"
24367         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24368                 error "$dir1 shouldn't have DATAVER EA"
24369
24370         cancel_lru_locks mdc
24371         local new_md5=$(md5sum $dom)
24372         [ "$old_md5" == "$new_md5" ] ||
24373                 error "$old_md5 != $new_md5"
24374
24375         # Skip free space checks with ZFS
24376         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24377                 local mdtfree2=$(do_facet $facet \
24378                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24379                 [ $mdtfree2 -gt $mdtfree1 ] ||
24380                         error "MDT space is not freed after migration"
24381         fi
24382         return 0
24383 }
24384 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24385
24386 test_272c() {
24387         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24388                 skip "Need MDS version at least 2.11.50"
24389
24390         local dom=$DIR/$tdir/$tfile
24391         mkdir -p $DIR/$tdir
24392         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24393         stack_trap "rm -rf $DIR/$tdir"
24394
24395         local mdtidx=$($LFS getstripe -m $dom)
24396         local mdtname=MDT$(printf %04x $mdtidx)
24397         local facet=mds$((mdtidx + 1))
24398
24399         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24400                 error "failed to write data into $dom"
24401         local old_md5=$(md5sum $dom)
24402         cancel_lru_locks mdc
24403         local mdtfree1=$(do_facet $facet \
24404                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24405
24406         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24407                 error "failed to migrate to the new composite layout"
24408         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24409                 error "MDT stripe was not removed"
24410
24411         cancel_lru_locks mdc
24412         local new_md5=$(md5sum $dom)
24413         [ "$old_md5" == "$new_md5" ] ||
24414                 error "$old_md5 != $new_md5"
24415
24416         # Skip free space checks with ZFS
24417         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24418                 local mdtfree2=$(do_facet $facet \
24419                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24420                 [ $mdtfree2 -gt $mdtfree1 ] ||
24421                         error "MDS space is not freed after migration"
24422         fi
24423         return 0
24424 }
24425 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24426
24427 test_272d() {
24428         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24429                 skip "Need MDS version at least 2.12.55"
24430
24431         local dom=$DIR/$tdir/$tfile
24432         mkdir -p $DIR/$tdir
24433         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24434
24435         local mdtidx=$($LFS getstripe -m $dom)
24436         local mdtname=MDT$(printf %04x $mdtidx)
24437         local facet=mds$((mdtidx + 1))
24438
24439         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24440                 error "failed to write data into $dom"
24441         local old_md5=$(md5sum $dom)
24442         cancel_lru_locks mdc
24443         local mdtfree1=$(do_facet $facet \
24444                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24445
24446         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24447                 error "failed mirroring to the new composite layout"
24448         $LFS mirror resync $dom ||
24449                 error "failed mirror resync"
24450         $LFS mirror split --mirror-id 1 -d $dom ||
24451                 error "failed mirror split"
24452
24453         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24454                 error "MDT stripe was not removed"
24455
24456         cancel_lru_locks mdc
24457         local new_md5=$(md5sum $dom)
24458         [ "$old_md5" == "$new_md5" ] ||
24459                 error "$old_md5 != $new_md5"
24460
24461         # Skip free space checks with ZFS
24462         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24463                 local mdtfree2=$(do_facet $facet \
24464                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24465                 [ $mdtfree2 -gt $mdtfree1 ] ||
24466                         error "MDS space is not freed after DOM mirror deletion"
24467         fi
24468         return 0
24469 }
24470 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24471
24472 test_272e() {
24473         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24474                 skip "Need MDS version at least 2.12.55"
24475
24476         local dom=$DIR/$tdir/$tfile
24477         mkdir -p $DIR/$tdir
24478         $LFS setstripe -c 2 $dom
24479
24480         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24481                 error "failed to write data into $dom"
24482         local old_md5=$(md5sum $dom)
24483         cancel_lru_locks
24484
24485         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24486                 error "failed mirroring to the DOM layout"
24487         $LFS mirror resync $dom ||
24488                 error "failed mirror resync"
24489         $LFS mirror split --mirror-id 1 -d $dom ||
24490                 error "failed mirror split"
24491
24492         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24493                 error "MDT stripe wasn't set"
24494
24495         cancel_lru_locks
24496         local new_md5=$(md5sum $dom)
24497         [ "$old_md5" == "$new_md5" ] ||
24498                 error "$old_md5 != $new_md5"
24499
24500         return 0
24501 }
24502 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24503
24504 test_272f() {
24505         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24506                 skip "Need MDS version at least 2.12.55"
24507
24508         local dom=$DIR/$tdir/$tfile
24509         mkdir -p $DIR/$tdir
24510         $LFS setstripe -c 2 $dom
24511
24512         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24513                 error "failed to write data into $dom"
24514         local old_md5=$(md5sum $dom)
24515         cancel_lru_locks
24516
24517         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24518                 error "failed migrating to the DOM file"
24519
24520         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24521                 error "MDT stripe wasn't set"
24522
24523         cancel_lru_locks
24524         local new_md5=$(md5sum $dom)
24525         [ "$old_md5" != "$new_md5" ] &&
24526                 error "$old_md5 != $new_md5"
24527
24528         return 0
24529 }
24530 run_test 272f "DoM migration: OST-striped file to DOM file"
24531
24532 test_273a() {
24533         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24534                 skip "Need MDS version at least 2.11.50"
24535
24536         # Layout swap cannot be done if either file has DOM component,
24537         # this will never be supported, migration should be used instead
24538
24539         local dom=$DIR/$tdir/$tfile
24540         mkdir -p $DIR/$tdir
24541
24542         $LFS setstripe -c2 ${dom}_plain
24543         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24544         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24545                 error "can swap layout with DoM component"
24546         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24547                 error "can swap layout with DoM component"
24548
24549         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24550         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24551                 error "can swap layout with DoM component"
24552         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24553                 error "can swap layout with DoM component"
24554         return 0
24555 }
24556 run_test 273a "DoM: layout swapping should fail with DOM"
24557
24558 test_273b() {
24559         mkdir -p $DIR/$tdir
24560         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24561
24562 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24563         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24564
24565         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24566 }
24567 run_test 273b "DoM: race writeback and object destroy"
24568
24569 test_273c() {
24570         mkdir -p $DIR/$tdir
24571         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24572
24573         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24574         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24575
24576         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24577 }
24578 run_test 273c "race writeback and object destroy"
24579
24580 test_275() {
24581         remote_ost_nodsh && skip "remote OST with nodsh"
24582         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24583                 skip "Need OST version >= 2.10.57"
24584
24585         local file=$DIR/$tfile
24586         local oss
24587
24588         oss=$(comma_list $(osts_nodes))
24589
24590         dd if=/dev/urandom of=$file bs=1M count=2 ||
24591                 error "failed to create a file"
24592         stack_trap "rm -f $file"
24593         cancel_lru_locks osc
24594
24595         #lock 1
24596         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24597                 error "failed to read a file"
24598
24599 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24600         $LCTL set_param fail_loc=0x8000031f
24601
24602         cancel_lru_locks osc &
24603         sleep 1
24604
24605 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24606         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24607         #IO takes another lock, but matches the PENDING one
24608         #and places it to the IO RPC
24609         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24610                 error "failed to read a file with PENDING lock"
24611 }
24612 run_test 275 "Read on a canceled duplicate lock"
24613
24614 test_276() {
24615         remote_ost_nodsh && skip "remote OST with nodsh"
24616         local pid
24617
24618         do_facet ost1 "(while true; do \
24619                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24620                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24621         pid=$!
24622
24623         for LOOP in $(seq 20); do
24624                 stop ost1
24625                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24626         done
24627         kill -9 $pid
24628         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24629                 rm $TMP/sanity_276_pid"
24630 }
24631 run_test 276 "Race between mount and obd_statfs"
24632
24633 test_277() {
24634         $LCTL set_param ldlm.namespaces.*.lru_size=0
24635         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24636         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24637                         grep ^used_mb | awk '{print $2}')
24638         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24640                 oflag=direct conv=notrunc
24641         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24642                         grep ^used_mb | awk '{print $2}')
24643         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24644 }
24645 run_test 277 "Direct IO shall drop page cache"
24646
24647 test_278() {
24648         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24649         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24650         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24651                 skip "needs the same host for mdt1 mdt2" && return
24652
24653         local pid1
24654         local pid2
24655
24656 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24657         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24658         stop mds2 &
24659         pid2=$!
24660
24661         stop mds1
24662
24663         echo "Starting MDTs"
24664         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24665         wait $pid2
24666 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24667 #will return NULL
24668         do_facet mds2 $LCTL set_param fail_loc=0
24669
24670         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24671         wait_recovery_complete mds2
24672 }
24673 run_test 278 "Race starting MDS between MDTs stop/start"
24674
24675 test_280() {
24676         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24677                 skip "Need MGS version at least 2.13.52"
24678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24679         combined_mgs_mds || skip "needs combined MGS/MDT"
24680
24681         umount_client $MOUNT
24682 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24683         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24684
24685         mount_client $MOUNT &
24686         sleep 1
24687         stop mgs || error "stop mgs failed"
24688         #for a race mgs would crash
24689         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24690         # make sure we unmount client before remounting
24691         wait
24692         umount_client $MOUNT
24693         mount_client $MOUNT || error "mount client failed"
24694 }
24695 run_test 280 "Race between MGS umount and client llog processing"
24696
24697 cleanup_test_300() {
24698         trap 0
24699         umask $SAVE_UMASK
24700 }
24701 test_striped_dir() {
24702         local mdt_index=$1
24703         local stripe_count
24704         local stripe_index
24705
24706         mkdir -p $DIR/$tdir
24707
24708         SAVE_UMASK=$(umask)
24709         trap cleanup_test_300 RETURN EXIT
24710
24711         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24712                                                 $DIR/$tdir/striped_dir ||
24713                 error "set striped dir error"
24714
24715         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24716         [ "$mode" = "755" ] || error "expect 755 got $mode"
24717
24718         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24719                 error "getdirstripe failed"
24720         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24721         if [ "$stripe_count" != "2" ]; then
24722                 error "1:stripe_count is $stripe_count, expect 2"
24723         fi
24724         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24725         if [ "$stripe_count" != "2" ]; then
24726                 error "2:stripe_count is $stripe_count, expect 2"
24727         fi
24728
24729         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24730         if [ "$stripe_index" != "$mdt_index" ]; then
24731                 error "stripe_index is $stripe_index, expect $mdt_index"
24732         fi
24733
24734         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24735                 error "nlink error after create striped dir"
24736
24737         mkdir $DIR/$tdir/striped_dir/a
24738         mkdir $DIR/$tdir/striped_dir/b
24739
24740         stat $DIR/$tdir/striped_dir/a ||
24741                 error "create dir under striped dir failed"
24742         stat $DIR/$tdir/striped_dir/b ||
24743                 error "create dir under striped dir failed"
24744
24745         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24746                 error "nlink error after mkdir"
24747
24748         rmdir $DIR/$tdir/striped_dir/a
24749         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24750                 error "nlink error after rmdir"
24751
24752         rmdir $DIR/$tdir/striped_dir/b
24753         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24754                 error "nlink error after rmdir"
24755
24756         chattr +i $DIR/$tdir/striped_dir
24757         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24758                 error "immutable flags not working under striped dir!"
24759         chattr -i $DIR/$tdir/striped_dir
24760
24761         rmdir $DIR/$tdir/striped_dir ||
24762                 error "rmdir striped dir error"
24763
24764         cleanup_test_300
24765
24766         true
24767 }
24768
24769 test_300a() {
24770         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24771                 skip "skipped for lustre < 2.7.0"
24772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24773         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24774
24775         test_striped_dir 0 || error "failed on striped dir on MDT0"
24776         test_striped_dir 1 || error "failed on striped dir on MDT0"
24777 }
24778 run_test 300a "basic striped dir sanity test"
24779
24780 test_300b() {
24781         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24782                 skip "skipped for lustre < 2.7.0"
24783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24785
24786         local i
24787         local mtime1
24788         local mtime2
24789         local mtime3
24790
24791         test_mkdir $DIR/$tdir || error "mkdir fail"
24792         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24793                 error "set striped dir error"
24794         for i in {0..9}; do
24795                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24796                 sleep 1
24797                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24798                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24799                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24800                 sleep 1
24801                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24802                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24803                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24804         done
24805         true
24806 }
24807 run_test 300b "check ctime/mtime for striped dir"
24808
24809 test_300c() {
24810         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24811                 skip "skipped for lustre < 2.7.0"
24812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24814
24815         local file_count
24816
24817         mkdir_on_mdt0 $DIR/$tdir
24818         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24819                 error "set striped dir error"
24820
24821         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24822                 error "chown striped dir failed"
24823
24824         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24825                 error "create 5k files failed"
24826
24827         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24828
24829         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24830
24831         rm -rf $DIR/$tdir
24832 }
24833 run_test 300c "chown && check ls under striped directory"
24834
24835 test_300d() {
24836         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24837                 skip "skipped for lustre < 2.7.0"
24838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24839         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24840
24841         local stripe_count
24842         local file
24843
24844         mkdir -p $DIR/$tdir
24845         $LFS setstripe -c 2 $DIR/$tdir
24846
24847         #local striped directory
24848         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24849                 error "set striped dir error"
24850         #look at the directories for debug purposes
24851         ls -l $DIR/$tdir
24852         $LFS getdirstripe $DIR/$tdir
24853         ls -l $DIR/$tdir/striped_dir
24854         $LFS getdirstripe $DIR/$tdir/striped_dir
24855         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24856                 error "create 10 files failed"
24857
24858         #remote striped directory
24859         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24860                 error "set striped dir error"
24861         #look at the directories for debug purposes
24862         ls -l $DIR/$tdir
24863         $LFS getdirstripe $DIR/$tdir
24864         ls -l $DIR/$tdir/remote_striped_dir
24865         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24866         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24867                 error "create 10 files failed"
24868
24869         for file in $(find $DIR/$tdir); do
24870                 stripe_count=$($LFS getstripe -c $file)
24871                 [ $stripe_count -eq 2 ] ||
24872                         error "wrong stripe $stripe_count for $file"
24873         done
24874
24875         rm -rf $DIR/$tdir
24876 }
24877 run_test 300d "check default stripe under striped directory"
24878
24879 test_300e() {
24880         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24881                 skip "Need MDS version at least 2.7.55"
24882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24884
24885         local stripe_count
24886         local file
24887
24888         mkdir -p $DIR/$tdir
24889
24890         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24891                 error "set striped dir error"
24892
24893         touch $DIR/$tdir/striped_dir/a
24894         touch $DIR/$tdir/striped_dir/b
24895         touch $DIR/$tdir/striped_dir/c
24896
24897         mkdir $DIR/$tdir/striped_dir/dir_a
24898         mkdir $DIR/$tdir/striped_dir/dir_b
24899         mkdir $DIR/$tdir/striped_dir/dir_c
24900
24901         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24902                 error "set striped adir under striped dir error"
24903
24904         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24905                 error "set striped bdir under striped dir error"
24906
24907         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24908                 error "set striped cdir under striped dir error"
24909
24910         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24911                 error "rename dir under striped dir fails"
24912
24913         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24914                 error "rename dir under different stripes fails"
24915
24916         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24917                 error "rename file under striped dir should succeed"
24918
24919         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24920                 error "rename dir under striped dir should succeed"
24921
24922         rm -rf $DIR/$tdir
24923 }
24924 run_test 300e "check rename under striped directory"
24925
24926 test_300f() {
24927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24929         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24930                 skip "Need MDS version at least 2.7.55"
24931
24932         local stripe_count
24933         local file
24934
24935         rm -rf $DIR/$tdir
24936         mkdir -p $DIR/$tdir
24937
24938         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24939                 error "set striped dir error"
24940
24941         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24942                 error "set striped dir error"
24943
24944         touch $DIR/$tdir/striped_dir/a
24945         mkdir $DIR/$tdir/striped_dir/dir_a
24946         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24947                 error "create striped dir under striped dir fails"
24948
24949         touch $DIR/$tdir/striped_dir1/b
24950         mkdir $DIR/$tdir/striped_dir1/dir_b
24951         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24952                 error "create striped dir under striped dir fails"
24953
24954         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24955                 error "rename dir under different striped dir should fail"
24956
24957         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24958                 error "rename striped dir under diff striped dir should fail"
24959
24960         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24961                 error "rename file under diff striped dirs fails"
24962
24963         rm -rf $DIR/$tdir
24964 }
24965 run_test 300f "check rename cross striped directory"
24966
24967 test_300_check_default_striped_dir()
24968 {
24969         local dirname=$1
24970         local default_count=$2
24971         local default_index=$3
24972         local stripe_count
24973         local stripe_index
24974         local dir_stripe_index
24975         local dir
24976
24977         echo "checking $dirname $default_count $default_index"
24978         $LFS setdirstripe -D -c $default_count -i $default_index \
24979                                 -H all_char $DIR/$tdir/$dirname ||
24980                 error "set default stripe on striped dir error"
24981         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24982         [ $stripe_count -eq $default_count ] ||
24983                 error "expect $default_count get $stripe_count for $dirname"
24984
24985         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24986         [ $stripe_index -eq $default_index ] ||
24987                 error "expect $default_index get $stripe_index for $dirname"
24988
24989         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24990                                                 error "create dirs failed"
24991
24992         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24993         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24994         for dir in $(find $DIR/$tdir/$dirname/*); do
24995                 stripe_count=$($LFS getdirstripe -c $dir)
24996                 (( $stripe_count == $default_count )) ||
24997                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24998                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24999                 error "stripe count $default_count != $stripe_count for $dir"
25000
25001                 stripe_index=$($LFS getdirstripe -i $dir)
25002                 [ $default_index -eq -1 ] ||
25003                         [ $stripe_index -eq $default_index ] ||
25004                         error "$stripe_index != $default_index for $dir"
25005
25006                 #check default stripe
25007                 stripe_count=$($LFS getdirstripe -D -c $dir)
25008                 [ $stripe_count -eq $default_count ] ||
25009                 error "default count $default_count != $stripe_count for $dir"
25010
25011                 stripe_index=$($LFS getdirstripe -D -i $dir)
25012                 [ $stripe_index -eq $default_index ] ||
25013                 error "default index $default_index != $stripe_index for $dir"
25014         done
25015         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25016 }
25017
25018 test_300g() {
25019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25020         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25021                 skip "Need MDS version at least 2.7.55"
25022
25023         local dir
25024         local stripe_count
25025         local stripe_index
25026
25027         mkdir_on_mdt0 $DIR/$tdir
25028         mkdir $DIR/$tdir/normal_dir
25029
25030         #Checking when client cache stripe index
25031         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25032         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25033                 error "create striped_dir failed"
25034
25035         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25036                 error "create dir0 fails"
25037         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25038         [ $stripe_index -eq 0 ] ||
25039                 error "dir0 expect index 0 got $stripe_index"
25040
25041         mkdir $DIR/$tdir/striped_dir/dir1 ||
25042                 error "create dir1 fails"
25043         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25044         [ $stripe_index -eq 1 ] ||
25045                 error "dir1 expect index 1 got $stripe_index"
25046
25047         #check default stripe count/stripe index
25048         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25049         test_300_check_default_striped_dir normal_dir 1 0
25050         test_300_check_default_striped_dir normal_dir -1 1
25051         test_300_check_default_striped_dir normal_dir 2 -1
25052
25053         #delete default stripe information
25054         echo "delete default stripeEA"
25055         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25056                 error "set default stripe on striped dir error"
25057
25058         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25059         for dir in $(find $DIR/$tdir/normal_dir/*); do
25060                 stripe_count=$($LFS getdirstripe -c $dir)
25061                 [ $stripe_count -eq 0 ] ||
25062                         error "expect 1 get $stripe_count for $dir"
25063         done
25064 }
25065 run_test 300g "check default striped directory for normal directory"
25066
25067 test_300h() {
25068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25069         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25070                 skip "Need MDS version at least 2.7.55"
25071
25072         local dir
25073         local stripe_count
25074
25075         mkdir $DIR/$tdir
25076         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25077                 error "set striped dir error"
25078
25079         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25080         test_300_check_default_striped_dir striped_dir 1 0
25081         test_300_check_default_striped_dir striped_dir -1 1
25082         test_300_check_default_striped_dir striped_dir 2 -1
25083
25084         #delete default stripe information
25085         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25086                 error "set default stripe on striped dir error"
25087
25088         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25089         for dir in $(find $DIR/$tdir/striped_dir/*); do
25090                 stripe_count=$($LFS getdirstripe -c $dir)
25091                 [ $stripe_count -eq 0 ] ||
25092                         error "expect 1 get $stripe_count for $dir"
25093         done
25094 }
25095 run_test 300h "check default striped directory for striped directory"
25096
25097 test_300i() {
25098         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25099         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25100         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25101                 skip "Need MDS version at least 2.7.55"
25102
25103         local stripe_count
25104         local file
25105
25106         mkdir $DIR/$tdir
25107
25108         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25109                 error "set striped dir error"
25110
25111         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25112                 error "create files under striped dir failed"
25113
25114         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25115                 error "set striped hashdir error"
25116
25117         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25118                 error "create dir0 under hash dir failed"
25119         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25120                 error "create dir1 under hash dir failed"
25121         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25122                 error "create dir2 under hash dir failed"
25123
25124         # unfortunately, we need to umount to clear dir layout cache for now
25125         # once we fully implement dir layout, we can drop this
25126         umount_client $MOUNT || error "umount failed"
25127         mount_client $MOUNT || error "mount failed"
25128
25129         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25130         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25131         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25132
25133         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25134                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25135                         error "create crush2 dir $tdir/hashdir/d3 failed"
25136                 $LFS find -H crush2 $DIR/$tdir/hashdir
25137                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25138                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25139
25140                 # mkdir with an invalid hash type (hash=fail_val) from client
25141                 # should be replaced on MDS with a valid (default) hash type
25142                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25143                 $LCTL set_param fail_loc=0x1901 fail_val=99
25144                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25145
25146                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25147                 local expect=$(do_facet mds1 \
25148                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25149                 [[ $hash == $expect ]] ||
25150                         error "d99 hash '$hash' != expected hash '$expect'"
25151         fi
25152
25153         #set the stripe to be unknown hash type on read
25154         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25155         $LCTL set_param fail_loc=0x1901 fail_val=99
25156         for ((i = 0; i < 10; i++)); do
25157                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25158                         error "stat f-$i failed"
25159                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25160         done
25161
25162         touch $DIR/$tdir/striped_dir/f0 &&
25163                 error "create under striped dir with unknown hash should fail"
25164
25165         $LCTL set_param fail_loc=0
25166
25167         umount_client $MOUNT || error "umount failed"
25168         mount_client $MOUNT || error "mount failed"
25169
25170         return 0
25171 }
25172 run_test 300i "client handle unknown hash type striped directory"
25173
25174 test_300j() {
25175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25177         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25178                 skip "Need MDS version at least 2.7.55"
25179
25180         local stripe_count
25181         local file
25182
25183         mkdir $DIR/$tdir
25184
25185         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25186         $LCTL set_param fail_loc=0x1702
25187         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25188                 error "set striped dir error"
25189
25190         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25191                 error "create files under striped dir failed"
25192
25193         $LCTL set_param fail_loc=0
25194
25195         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25196
25197         return 0
25198 }
25199 run_test 300j "test large update record"
25200
25201 test_300k() {
25202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25204         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25205                 skip "Need MDS version at least 2.7.55"
25206
25207         # this test needs a huge transaction
25208         local kb
25209         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25210              osd*.$FSNAME-MDT0000.kbytestotal")
25211         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25212
25213         local stripe_count
25214         local file
25215
25216         mkdir $DIR/$tdir
25217
25218         #define OBD_FAIL_LARGE_STRIPE   0x1703
25219         $LCTL set_param fail_loc=0x1703
25220         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25221                 error "set striped dir error"
25222         $LCTL set_param fail_loc=0
25223
25224         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25225                 error "getstripeddir fails"
25226         rm -rf $DIR/$tdir/striped_dir ||
25227                 error "unlink striped dir fails"
25228
25229         return 0
25230 }
25231 run_test 300k "test large striped directory"
25232
25233 test_300l() {
25234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25236         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25237                 skip "Need MDS version at least 2.7.55"
25238
25239         local stripe_index
25240
25241         test_mkdir -p $DIR/$tdir/striped_dir
25242         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25243                         error "chown $RUNAS_ID failed"
25244         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25245                 error "set default striped dir failed"
25246
25247         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25248         $LCTL set_param fail_loc=0x80000158
25249         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25250
25251         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25252         [ $stripe_index -eq 1 ] ||
25253                 error "expect 1 get $stripe_index for $dir"
25254 }
25255 run_test 300l "non-root user to create dir under striped dir with stale layout"
25256
25257 test_300m() {
25258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25259         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25260         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25261                 skip "Need MDS version at least 2.7.55"
25262
25263         mkdir -p $DIR/$tdir/striped_dir
25264         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25265                 error "set default stripes dir error"
25266
25267         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25268
25269         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25270         [ $stripe_count -eq 0 ] ||
25271                         error "expect 0 get $stripe_count for a"
25272
25273         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25274                 error "set default stripes dir error"
25275
25276         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25277
25278         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25279         [ $stripe_count -eq 0 ] ||
25280                         error "expect 0 get $stripe_count for b"
25281
25282         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25283                 error "set default stripes dir error"
25284
25285         mkdir $DIR/$tdir/striped_dir/c &&
25286                 error "default stripe_index is invalid, mkdir c should fails"
25287
25288         rm -rf $DIR/$tdir || error "rmdir fails"
25289 }
25290 run_test 300m "setstriped directory on single MDT FS"
25291
25292 cleanup_300n() {
25293         local list=$(comma_list $(mdts_nodes))
25294
25295         trap 0
25296         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25297 }
25298
25299 test_300n() {
25300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25302         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25303                 skip "Need MDS version at least 2.7.55"
25304         remote_mds_nodsh && skip "remote MDS with nodsh"
25305
25306         local stripe_index
25307         local list=$(comma_list $(mdts_nodes))
25308
25309         trap cleanup_300n RETURN EXIT
25310         mkdir -p $DIR/$tdir
25311         chmod 777 $DIR/$tdir
25312         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25313                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25314                 error "create striped dir succeeds with gid=0"
25315
25316         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25317         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25318                 error "create striped dir fails with gid=-1"
25319
25320         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25321         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25322                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25323                 error "set default striped dir succeeds with gid=0"
25324
25325
25326         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25327         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25328                 error "set default striped dir fails with gid=-1"
25329
25330
25331         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25332         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25333                                         error "create test_dir fails"
25334         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25335                                         error "create test_dir1 fails"
25336         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25337                                         error "create test_dir2 fails"
25338         cleanup_300n
25339 }
25340 run_test 300n "non-root user to create dir under striped dir with default EA"
25341
25342 test_300o() {
25343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25344         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25345         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25346                 skip "Need MDS version at least 2.7.55"
25347
25348         local numfree1
25349         local numfree2
25350
25351         mkdir -p $DIR/$tdir
25352
25353         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25354         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25355         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25356                 skip "not enough free inodes $numfree1 $numfree2"
25357         fi
25358
25359         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25360         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25361         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25362                 skip "not enough free space $numfree1 $numfree2"
25363         fi
25364
25365         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25366                 error "setdirstripe fails"
25367
25368         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25369                 error "create dirs fails"
25370
25371         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25372         ls $DIR/$tdir/striped_dir > /dev/null ||
25373                 error "ls striped dir fails"
25374         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25375                 error "unlink big striped dir fails"
25376 }
25377 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25378
25379 test_300p() {
25380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25382         remote_mds_nodsh && skip "remote MDS with nodsh"
25383
25384         mkdir_on_mdt0 $DIR/$tdir
25385
25386         #define OBD_FAIL_OUT_ENOSPC     0x1704
25387         do_facet mds2 lctl set_param fail_loc=0x80001704
25388         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25389                  && error "create striped directory should fail"
25390
25391         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25392
25393         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25394         true
25395 }
25396 run_test 300p "create striped directory without space"
25397
25398 test_300q() {
25399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25401
25402         local fd=$(free_fd)
25403         local cmd="exec $fd<$tdir"
25404         cd $DIR
25405         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25406         eval $cmd
25407         cmd="exec $fd<&-"
25408         trap "eval $cmd" EXIT
25409         cd $tdir || error "cd $tdir fails"
25410         rmdir  ../$tdir || error "rmdir $tdir fails"
25411         mkdir local_dir && error "create dir succeeds"
25412         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25413         eval $cmd
25414         return 0
25415 }
25416 run_test 300q "create remote directory under orphan directory"
25417
25418 test_300r() {
25419         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25420                 skip "Need MDS version at least 2.7.55" && return
25421         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25422
25423         mkdir $DIR/$tdir
25424
25425         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25426                 error "set striped dir error"
25427
25428         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25429                 error "getstripeddir fails"
25430
25431         local stripe_count
25432         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25433                       awk '/lmv_stripe_count:/ { print $2 }')
25434
25435         [ $MDSCOUNT -ne $stripe_count ] &&
25436                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25437
25438         rm -rf $DIR/$tdir/striped_dir ||
25439                 error "unlink striped dir fails"
25440 }
25441 run_test 300r "test -1 striped directory"
25442
25443 test_300s_helper() {
25444         local count=$1
25445
25446         local stripe_dir=$DIR/$tdir/striped_dir.$count
25447
25448         $LFS mkdir -c $count $stripe_dir ||
25449                 error "lfs mkdir -c error"
25450
25451         $LFS getdirstripe $stripe_dir ||
25452                 error "lfs getdirstripe fails"
25453
25454         local stripe_count
25455         stripe_count=$($LFS getdirstripe $stripe_dir |
25456                       awk '/lmv_stripe_count:/ { print $2 }')
25457
25458         [ $count -ne $stripe_count ] &&
25459                 error_noexit "bad stripe count $stripe_count expected $count"
25460
25461         local dupe_stripes
25462         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25463                 awk '/0x/ {count[$1] += 1}; END {
25464                         for (idx in count) {
25465                                 if (count[idx]>1) {
25466                                         print "index " idx " count " count[idx]
25467                                 }
25468                         }
25469                 }')
25470
25471         if [[ -n "$dupe_stripes" ]] ; then
25472                 lfs getdirstripe $stripe_dir
25473                 error_noexit "Dupe MDT above: $dupe_stripes "
25474         fi
25475
25476         rm -rf $stripe_dir ||
25477                 error_noexit "unlink $stripe_dir fails"
25478 }
25479
25480 test_300s() {
25481         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25482                 skip "Need MDS version at least 2.7.55" && return
25483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25484
25485         mkdir $DIR/$tdir
25486         for count in $(seq 2 $MDSCOUNT); do
25487                 test_300s_helper $count
25488         done
25489 }
25490 run_test 300s "test lfs mkdir -c without -i"
25491
25492 test_300t() {
25493         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25494                 skip "need MDS 2.14.55 or later"
25495         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25496
25497         local testdir="$DIR/$tdir/striped_dir"
25498         local dir1=$testdir/dir1
25499         local dir2=$testdir/dir2
25500
25501         mkdir -p $testdir
25502
25503         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25504                 error "failed to set default stripe count for $testdir"
25505
25506         mkdir $dir1
25507         local stripe_count=$($LFS getdirstripe -c $dir1)
25508
25509         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25510
25511         local max_count=$((MDSCOUNT - 1))
25512         local mdts=$(comma_list $(mdts_nodes))
25513
25514         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25515         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25516
25517         mkdir $dir2
25518         stripe_count=$($LFS getdirstripe -c $dir2)
25519
25520         (( $stripe_count == $max_count )) || error "wrong stripe count"
25521 }
25522 run_test 300t "test max_mdt_stripecount"
25523
25524 prepare_remote_file() {
25525         mkdir $DIR/$tdir/src_dir ||
25526                 error "create remote source failed"
25527
25528         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25529                  error "cp to remote source failed"
25530         touch $DIR/$tdir/src_dir/a
25531
25532         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25533                 error "create remote target dir failed"
25534
25535         touch $DIR/$tdir/tgt_dir/b
25536
25537         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25538                 error "rename dir cross MDT failed!"
25539
25540         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25541                 error "src_child still exists after rename"
25542
25543         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25544                 error "missing file(a) after rename"
25545
25546         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25547                 error "diff after rename"
25548 }
25549
25550 test_310a() {
25551         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25553
25554         local remote_file=$DIR/$tdir/tgt_dir/b
25555
25556         mkdir -p $DIR/$tdir
25557
25558         prepare_remote_file || error "prepare remote file failed"
25559
25560         #open-unlink file
25561         $OPENUNLINK $remote_file $remote_file ||
25562                 error "openunlink $remote_file failed"
25563         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25564 }
25565 run_test 310a "open unlink remote file"
25566
25567 test_310b() {
25568         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25570
25571         local remote_file=$DIR/$tdir/tgt_dir/b
25572
25573         mkdir -p $DIR/$tdir
25574
25575         prepare_remote_file || error "prepare remote file failed"
25576
25577         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25578         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25579         $CHECKSTAT -t file $remote_file || error "check file failed"
25580 }
25581 run_test 310b "unlink remote file with multiple links while open"
25582
25583 test_310c() {
25584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25585         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25586
25587         local remote_file=$DIR/$tdir/tgt_dir/b
25588
25589         mkdir -p $DIR/$tdir
25590
25591         prepare_remote_file || error "prepare remote file failed"
25592
25593         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25594         multiop_bg_pause $remote_file O_uc ||
25595                         error "mulitop failed for remote file"
25596         MULTIPID=$!
25597         $MULTIOP $DIR/$tfile Ouc
25598         kill -USR1 $MULTIPID
25599         wait $MULTIPID
25600 }
25601 run_test 310c "open-unlink remote file with multiple links"
25602
25603 #LU-4825
25604 test_311() {
25605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25606         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25607         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25608                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25609         remote_mds_nodsh && skip "remote MDS with nodsh"
25610
25611         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25612         local mdts=$(comma_list $(mdts_nodes))
25613
25614         mkdir -p $DIR/$tdir
25615         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25616         createmany -o $DIR/$tdir/$tfile. 1000
25617
25618         # statfs data is not real time, let's just calculate it
25619         old_iused=$((old_iused + 1000))
25620
25621         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25622                         osp.*OST0000*MDT0000.create_count")
25623         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25624                                 osp.*OST0000*MDT0000.max_create_count")
25625         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25626
25627         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25628         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25629         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25630
25631         unlinkmany $DIR/$tdir/$tfile. 1000
25632
25633         do_nodes $mdts "$LCTL set_param -n \
25634                         osp.*OST0000*.max_create_count=$max_count"
25635         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25636                 do_nodes $mdts "$LCTL set_param -n \
25637                                 osp.*OST0000*.create_count=$count"
25638         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25639                         grep "=0" && error "create_count is zero"
25640
25641         local new_iused
25642         for i in $(seq 120); do
25643                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25644                 # system may be too busy to destroy all objs in time, use
25645                 # a somewhat small value to not fail autotest
25646                 [ $((old_iused - new_iused)) -gt 400 ] && break
25647                 sleep 1
25648         done
25649
25650         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25651         [ $((old_iused - new_iused)) -gt 400 ] ||
25652                 error "objs not destroyed after unlink"
25653 }
25654 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25655
25656 zfs_get_objid()
25657 {
25658         local ost=$1
25659         local tf=$2
25660         local fid=($($LFS getstripe $tf | grep 0x))
25661         local seq=${fid[3]#0x}
25662         local objid=${fid[1]}
25663
25664         local vdevdir=$(dirname $(facet_vdevice $ost))
25665         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25666         local zfs_zapid=$(do_facet $ost $cmd |
25667                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25668                           awk '/Object/{getline; print $1}')
25669         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25670                           awk "/$objid = /"'{printf $3}')
25671
25672         echo $zfs_objid
25673 }
25674
25675 zfs_object_blksz() {
25676         local ost=$1
25677         local objid=$2
25678
25679         local vdevdir=$(dirname $(facet_vdevice $ost))
25680         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25681         local blksz=$(do_facet $ost $cmd $objid |
25682                       awk '/dblk/{getline; printf $4}')
25683
25684         case "${blksz: -1}" in
25685                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25686                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25687                 *) ;;
25688         esac
25689
25690         echo $blksz
25691 }
25692
25693 test_312() { # LU-4856
25694         remote_ost_nodsh && skip "remote OST with nodsh"
25695         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25696
25697         local max_blksz=$(do_facet ost1 \
25698                           $ZFS get -p recordsize $(facet_device ost1) |
25699                           awk '!/VALUE/{print $3}')
25700         local tf=$DIR/$tfile
25701
25702         $LFS setstripe -c1 $tf
25703         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25704
25705         # Get ZFS object id
25706         local zfs_objid=$(zfs_get_objid $facet $tf)
25707         # block size change by sequential overwrite
25708         local bs
25709
25710         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25711                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25712
25713                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25714                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25715         done
25716         rm -f $tf
25717
25718         $LFS setstripe -c1 $tf
25719         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25720
25721         # block size change by sequential append write
25722         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25723         zfs_objid=$(zfs_get_objid $facet $tf)
25724         local count
25725
25726         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25727                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25728                         oflag=sync conv=notrunc
25729
25730                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25731                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25732                         error "blksz error, actual $blksz, " \
25733                                 "expected: 2 * $count * $PAGE_SIZE"
25734         done
25735         rm -f $tf
25736
25737         # random write
25738         $LFS setstripe -c1 $tf
25739         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25740         zfs_objid=$(zfs_get_objid $facet $tf)
25741
25742         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25743         blksz=$(zfs_object_blksz $facet $zfs_objid)
25744         (( blksz == PAGE_SIZE )) ||
25745                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25746
25747         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25748         blksz=$(zfs_object_blksz $facet $zfs_objid)
25749         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25750
25751         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25752         blksz=$(zfs_object_blksz $facet $zfs_objid)
25753         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25754 }
25755 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25756
25757 test_313() {
25758         remote_ost_nodsh && skip "remote OST with nodsh"
25759
25760         local file=$DIR/$tfile
25761
25762         rm -f $file
25763         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25764
25765         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25766         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25767         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25768                 error "write should failed"
25769         do_facet ost1 "$LCTL set_param fail_loc=0"
25770         rm -f $file
25771 }
25772 run_test 313 "io should fail after last_rcvd update fail"
25773
25774 test_314() {
25775         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25776
25777         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25778         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25779         rm -f $DIR/$tfile
25780         wait_delete_completed
25781         do_facet ost1 "$LCTL set_param fail_loc=0"
25782 }
25783 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25784
25785 test_315() { # LU-618
25786         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25787
25788         local file=$DIR/$tfile
25789         rm -f $file
25790
25791         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25792                 error "multiop file write failed"
25793         $MULTIOP $file oO_RDONLY:r4063232_c &
25794         PID=$!
25795
25796         sleep 2
25797
25798         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25799         kill -USR1 $PID
25800
25801         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25802         rm -f $file
25803 }
25804 run_test 315 "read should be accounted"
25805
25806 test_316() {
25807         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25808         large_xattr_enabled || skip "ea_inode feature disabled"
25809
25810         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25811         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25812         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25813         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25814
25815         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25816 }
25817 run_test 316 "lfs migrate of file with large_xattr enabled"
25818
25819 test_317() {
25820         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25821                 skip "Need MDS version at least 2.11.53"
25822         if [ "$ost1_FSTYPE" == "zfs" ]; then
25823                 skip "LU-10370: no implementation for ZFS"
25824         fi
25825
25826         local trunc_sz
25827         local grant_blk_size
25828
25829         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25830                         awk '/grant_block_size:/ { print $2; exit; }')
25831         #
25832         # Create File of size 5M. Truncate it to below size's and verify
25833         # blocks count.
25834         #
25835         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25836                 error "Create file $DIR/$tfile failed"
25837         stack_trap "rm -f $DIR/$tfile" EXIT
25838
25839         for trunc_sz in 2097152 4097 4000 509 0; do
25840                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25841                         error "truncate $tfile to $trunc_sz failed"
25842                 local sz=$(stat --format=%s $DIR/$tfile)
25843                 local blk=$(stat --format=%b $DIR/$tfile)
25844                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25845                                      grant_blk_size) * 8))
25846
25847                 if [[ $blk -ne $trunc_blk ]]; then
25848                         $(which stat) $DIR/$tfile
25849                         error "Expected Block $trunc_blk got $blk for $tfile"
25850                 fi
25851
25852                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25853                         error "Expected Size $trunc_sz got $sz for $tfile"
25854         done
25855
25856         #
25857         # sparse file test
25858         # Create file with a hole and write actual 65536 bytes which aligned
25859         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25860         #
25861         local bs=65536
25862         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25863                 error "Create file : $DIR/$tfile"
25864
25865         #
25866         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25867         # blocks. The block count must drop to 8.
25868         #
25869         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25870                 ((bs - grant_blk_size) + 1)))
25871         $TRUNCATE $DIR/$tfile $trunc_sz ||
25872                 error "truncate $tfile to $trunc_sz failed"
25873
25874         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25875         sz=$(stat --format=%s $DIR/$tfile)
25876         blk=$(stat --format=%b $DIR/$tfile)
25877
25878         if [[ $blk -ne $trunc_bsz ]]; then
25879                 $(which stat) $DIR/$tfile
25880                 error "Expected Block $trunc_bsz got $blk for $tfile"
25881         fi
25882
25883         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25884                 error "Expected Size $trunc_sz got $sz for $tfile"
25885 }
25886 run_test 317 "Verify blocks get correctly update after truncate"
25887
25888 test_318() {
25889         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25890         local old_max_active=$($LCTL get_param -n \
25891                             ${llite_name}.max_read_ahead_async_active \
25892                             2>/dev/null)
25893
25894         $LCTL set_param llite.*.max_read_ahead_async_active=256
25895         local max_active=$($LCTL get_param -n \
25896                            ${llite_name}.max_read_ahead_async_active \
25897                            2>/dev/null)
25898         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25899
25900         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25901                 error "set max_read_ahead_async_active should succeed"
25902
25903         $LCTL set_param llite.*.max_read_ahead_async_active=512
25904         max_active=$($LCTL get_param -n \
25905                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25906         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25907
25908         # restore @max_active
25909         [ $old_max_active -ne 0 ] && $LCTL set_param \
25910                 llite.*.max_read_ahead_async_active=$old_max_active
25911
25912         local old_threshold=$($LCTL get_param -n \
25913                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25914         local max_per_file_mb=$($LCTL get_param -n \
25915                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25916
25917         local invalid=$(($max_per_file_mb + 1))
25918         $LCTL set_param \
25919                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25920                         && error "set $invalid should fail"
25921
25922         local valid=$(($invalid - 1))
25923         $LCTL set_param \
25924                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25925                         error "set $valid should succeed"
25926         local threshold=$($LCTL get_param -n \
25927                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25928         [ $threshold -eq $valid ] || error \
25929                 "expect threshold $valid got $threshold"
25930         $LCTL set_param \
25931                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25932 }
25933 run_test 318 "Verify async readahead tunables"
25934
25935 test_319() {
25936         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25937
25938         local before=$(date +%s)
25939         local evict
25940         local mdir=$DIR/$tdir
25941         local file=$mdir/xxx
25942
25943         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25944         touch $file
25945
25946 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25947         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25948         $LFS migrate -m1 $mdir &
25949
25950         sleep 1
25951         dd if=$file of=/dev/null
25952         wait
25953         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25954           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25955
25956         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25957 }
25958 run_test 319 "lost lease lock on migrate error"
25959
25960 test_398a() { # LU-4198
25961         local ost1_imp=$(get_osc_import_name client ost1)
25962         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25963                          cut -d'.' -f2)
25964
25965         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25966         stack_trap "rm -f $DIR/$tfile"
25967         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25968
25969         # request a new lock on client
25970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25971
25972         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25973         local lock_count=$($LCTL get_param -n \
25974                            ldlm.namespaces.$imp_name.lru_size)
25975         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25976
25977         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25978
25979         # no lock cached, should use lockless DIO and not enqueue new lock
25980         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25981         lock_count=$($LCTL get_param -n \
25982                      ldlm.namespaces.$imp_name.lru_size)
25983         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25984
25985         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25986
25987         # no lock cached, should use locked DIO append
25988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25989                 conv=notrunc || error "DIO append failed"
25990         lock_count=$($LCTL get_param -n \
25991                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25992         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25993 }
25994 run_test 398a "direct IO should cancel lock otherwise lockless"
25995
25996 test_398b() { # LU-4198
25997         local before=$(date +%s)
25998         local njobs=4
25999         local size=48
26000
26001         which fio || skip_env "no fio installed"
26002         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26003         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26004
26005         # Single page, multiple pages, stripe size, 4*stripe size
26006         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26007                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26008                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26009                         --numjobs=$njobs --fallocate=none \
26010                         --iodepth=16 --allow_file_create=0 \
26011                         --size=$((size/njobs))M \
26012                         --filename=$DIR/$tfile &
26013                 bg_pid=$!
26014
26015                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26016                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26017                         --numjobs=$njobs --fallocate=none \
26018                         --iodepth=16 --allow_file_create=0 \
26019                         --size=$((size/njobs))M \
26020                         --filename=$DIR/$tfile || true
26021                 wait $bg_pid
26022         done
26023
26024         evict=$(do_facet client $LCTL get_param \
26025                 osc.$FSNAME-OST*-osc-*/state |
26026             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26027
26028         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26029                 (do_facet client $LCTL get_param \
26030                         osc.$FSNAME-OST*-osc-*/state;
26031                     error "eviction happened: $evict before:$before")
26032
26033         rm -f $DIR/$tfile
26034 }
26035 run_test 398b "DIO and buffer IO race"
26036
26037 test_398c() { # LU-4198
26038         local ost1_imp=$(get_osc_import_name client ost1)
26039         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26040                          cut -d'.' -f2)
26041
26042         which fio || skip_env "no fio installed"
26043
26044         saved_debug=$($LCTL get_param -n debug)
26045         $LCTL set_param debug=0
26046
26047         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26048         ((size /= 1024)) # by megabytes
26049         ((size /= 2)) # write half of the OST at most
26050         [ $size -gt 40 ] && size=40 #reduce test time anyway
26051
26052         $LFS setstripe -c 1 $DIR/$tfile
26053
26054         # it seems like ldiskfs reserves more space than necessary if the
26055         # writing blocks are not mapped, so it extends the file firstly
26056         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26057         cancel_lru_locks osc
26058
26059         # clear and verify rpc_stats later
26060         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26061
26062         local njobs=4
26063         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26064         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26065                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26066                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26067                 --filename=$DIR/$tfile
26068         [ $? -eq 0 ] || error "fio write error"
26069
26070         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26071                 error "Locks were requested while doing AIO"
26072
26073         # get the percentage of 1-page I/O
26074         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26075                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26076                 awk '{print $7}')
26077         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26078
26079         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26080         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26081                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26082                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26083                 --filename=$DIR/$tfile
26084         [ $? -eq 0 ] || error "fio mixed read write error"
26085
26086         echo "AIO with large block size ${size}M"
26087         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26088                 --numjobs=1 --fallocate=none --ioengine=libaio \
26089                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26090                 --filename=$DIR/$tfile
26091         [ $? -eq 0 ] || error "fio large block size failed"
26092
26093         rm -f $DIR/$tfile
26094         $LCTL set_param debug="$saved_debug"
26095 }
26096 run_test 398c "run fio to test AIO"
26097
26098 test_398d() { #  LU-13846
26099         which aiocp || skip_env "no aiocp installed"
26100         local aio_file=$DIR/$tfile.aio
26101
26102         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26103
26104         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26105         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26106         stack_trap "rm -f $DIR/$tfile $aio_file"
26107
26108         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26109
26110         # make sure we don't crash and fail properly
26111         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26112                 error "aio not aligned with PAGE SIZE should fail"
26113
26114         rm -f $DIR/$tfile $aio_file
26115 }
26116 run_test 398d "run aiocp to verify block size > stripe size"
26117
26118 test_398e() {
26119         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26120         touch $DIR/$tfile.new
26121         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26122 }
26123 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26124
26125 test_398f() { #  LU-14687
26126         which aiocp || skip_env "no aiocp installed"
26127         local aio_file=$DIR/$tfile.aio
26128
26129         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26130
26131         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26132         stack_trap "rm -f $DIR/$tfile $aio_file"
26133
26134         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26135         $LCTL set_param fail_loc=0x1418
26136         # make sure we don't crash and fail properly
26137         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26138                 error "aio with page allocation failure succeeded"
26139         $LCTL set_param fail_loc=0
26140         diff $DIR/$tfile $aio_file
26141         [[ $? != 0 ]] || error "no diff after failed aiocp"
26142 }
26143 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26144
26145 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26146 # stripe and i/o size must be > stripe size
26147 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26148 # single RPC in flight.  This test shows async DIO submission is working by
26149 # showing multiple RPCs in flight.
26150 test_398g() { #  LU-13798
26151         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26152
26153         # We need to do some i/o first to acquire enough grant to put our RPCs
26154         # in flight; otherwise a new connection may not have enough grant
26155         # available
26156         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26157                 error "parallel dio failed"
26158         stack_trap "rm -f $DIR/$tfile"
26159
26160         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26161         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26162         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26163         stack_trap "$LCTL set_param -n $pages_per_rpc"
26164
26165         # Recreate file so it's empty
26166         rm -f $DIR/$tfile
26167         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26168         #Pause rpc completion to guarantee we see multiple rpcs in flight
26169         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26170         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26171         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26172
26173         # Clear rpc stats
26174         $LCTL set_param osc.*.rpc_stats=c
26175
26176         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26177                 error "parallel dio failed"
26178         stack_trap "rm -f $DIR/$tfile"
26179
26180         $LCTL get_param osc.*-OST0000-*.rpc_stats
26181         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26182                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26183                 grep "8:" | awk '{print $8}')
26184         # We look at the "8 rpcs in flight" field, and verify A) it is present
26185         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26186         # as expected for an 8M DIO to a file with 1M stripes.
26187         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26188
26189         # Verify turning off parallel dio works as expected
26190         # Clear rpc stats
26191         $LCTL set_param osc.*.rpc_stats=c
26192         $LCTL set_param llite.*.parallel_dio=0
26193         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26194
26195         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26196                 error "dio with parallel dio disabled failed"
26197
26198         # Ideally, we would see only one RPC in flight here, but there is an
26199         # unavoidable race between i/o completion and RPC in flight counting,
26200         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26201         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26202         # So instead we just verify it's always < 8.
26203         $LCTL get_param osc.*-OST0000-*.rpc_stats
26204         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26205                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26206                 grep '^$' -B1 | grep . | awk '{print $1}')
26207         [ $ret != "8:" ] ||
26208                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26209 }
26210 run_test 398g "verify parallel dio async RPC submission"
26211
26212 test_398h() { #  LU-13798
26213         local dio_file=$DIR/$tfile.dio
26214
26215         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26216
26217         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26218         stack_trap "rm -f $DIR/$tfile $dio_file"
26219
26220         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26221                 error "parallel dio failed"
26222         diff $DIR/$tfile $dio_file
26223         [[ $? == 0 ]] || error "file diff after aiocp"
26224 }
26225 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26226
26227 test_398i() { #  LU-13798
26228         local dio_file=$DIR/$tfile.dio
26229
26230         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26231
26232         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26233         stack_trap "rm -f $DIR/$tfile $dio_file"
26234
26235         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26236         $LCTL set_param fail_loc=0x1418
26237         # make sure we don't crash and fail properly
26238         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26239                 error "parallel dio page allocation failure succeeded"
26240         diff $DIR/$tfile $dio_file
26241         [[ $? != 0 ]] || error "no diff after failed aiocp"
26242 }
26243 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26244
26245 test_398j() { #  LU-13798
26246         # Stripe size > RPC size but less than i/o size tests split across
26247         # stripes and RPCs for individual i/o op
26248         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26249
26250         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26251         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26252         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26253         stack_trap "$LCTL set_param -n $pages_per_rpc"
26254
26255         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26256                 error "parallel dio write failed"
26257         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26258
26259         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26260                 error "parallel dio read failed"
26261         diff $DIR/$tfile $DIR/$tfile.2
26262         [[ $? == 0 ]] || error "file diff after parallel dio read"
26263 }
26264 run_test 398j "test parallel dio where stripe size > rpc_size"
26265
26266 test_398k() { #  LU-13798
26267         wait_delete_completed
26268         wait_mds_ost_sync
26269
26270         # 4 stripe file; we will cause out of space on OST0
26271         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26272
26273         # Fill OST0 (if it's not too large)
26274         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26275                    head -n1)
26276         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26277                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26278         fi
26279         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26280         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26281                 error "dd should fill OST0"
26282         stack_trap "rm -f $DIR/$tfile.1"
26283
26284         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26285         err=$?
26286
26287         ls -la $DIR/$tfile
26288         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26289                 error "file is not 0 bytes in size"
26290
26291         # dd above should not succeed, but don't error until here so we can
26292         # get debug info above
26293         [[ $err != 0 ]] ||
26294                 error "parallel dio write with enospc succeeded"
26295         stack_trap "rm -f $DIR/$tfile"
26296 }
26297 run_test 398k "test enospc on first stripe"
26298
26299 test_398l() { #  LU-13798
26300         wait_delete_completed
26301         wait_mds_ost_sync
26302
26303         # 4 stripe file; we will cause out of space on OST0
26304         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26305         # happens on the second i/o chunk we issue
26306         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26307
26308         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26309         stack_trap "rm -f $DIR/$tfile"
26310
26311         # Fill OST0 (if it's not too large)
26312         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26313                    head -n1)
26314         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26315                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26316         fi
26317         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26318         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26319                 error "dd should fill OST0"
26320         stack_trap "rm -f $DIR/$tfile.1"
26321
26322         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26323         err=$?
26324         stack_trap "rm -f $DIR/$tfile.2"
26325
26326         # Check that short write completed as expected
26327         ls -la $DIR/$tfile.2
26328         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26329                 error "file is not 1M in size"
26330
26331         # dd above should not succeed, but don't error until here so we can
26332         # get debug info above
26333         [[ $err != 0 ]] ||
26334                 error "parallel dio write with enospc succeeded"
26335
26336         # Truncate source file to same length as output file and diff them
26337         $TRUNCATE $DIR/$tfile 1048576
26338         diff $DIR/$tfile $DIR/$tfile.2
26339         [[ $? == 0 ]] || error "data incorrect after short write"
26340 }
26341 run_test 398l "test enospc on intermediate stripe/RPC"
26342
26343 test_398m() { #  LU-13798
26344         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26345
26346         # Set up failure on OST0, the first stripe:
26347         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26348         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26349         # OST0 is on ost1, OST1 is on ost2.
26350         # So this fail_val specifies OST0
26351         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26352         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26353
26354         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26355                 error "parallel dio write with failure on first stripe succeeded"
26356         stack_trap "rm -f $DIR/$tfile"
26357         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26358
26359         # Place data in file for read
26360         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26361                 error "parallel dio write failed"
26362
26363         # Fail read on OST0, first stripe
26364         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26365         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26366         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26367                 error "parallel dio read with error on first stripe succeeded"
26368         rm -f $DIR/$tfile.2
26369         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26370
26371         # Switch to testing on OST1, second stripe
26372         # Clear file contents, maintain striping
26373         echo > $DIR/$tfile
26374         # Set up failure on OST1, second stripe:
26375         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26376         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26377
26378         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26379                 error "parallel dio write with failure on second stripe succeeded"
26380         stack_trap "rm -f $DIR/$tfile"
26381         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26382
26383         # Place data in file for read
26384         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26385                 error "parallel dio write failed"
26386
26387         # Fail read on OST1, second stripe
26388         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26389         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26390         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26391                 error "parallel dio read with error on second stripe succeeded"
26392         rm -f $DIR/$tfile.2
26393         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26394 }
26395 run_test 398m "test RPC failures with parallel dio"
26396
26397 # Parallel submission of DIO should not cause problems for append, but it's
26398 # important to verify.
26399 test_398n() { #  LU-13798
26400         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26401
26402         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26403                 error "dd to create source file failed"
26404         stack_trap "rm -f $DIR/$tfile"
26405
26406         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26407                 error "parallel dio write with failure on second stripe succeeded"
26408         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26409         diff $DIR/$tfile $DIR/$tfile.1
26410         [[ $? == 0 ]] || error "data incorrect after append"
26411
26412 }
26413 run_test 398n "test append with parallel DIO"
26414
26415 test_398o() {
26416         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26417 }
26418 run_test 398o "right kms with DIO"
26419
26420 test_398p()
26421 {
26422         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26423         which aiocp || skip_env "no aiocp installed"
26424
26425         local stripe_size=$((1024 * 1024)) #1 MiB
26426         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26427         local file_size=$((25 * stripe_size))
26428
26429         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26430         stack_trap "rm -f $DIR/$tfile*"
26431         # Just a bit bigger than the largest size in the test set below
26432         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26433                 error "buffered i/o to create file failed"
26434
26435         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26436                 $((stripe_size * 4)); do
26437
26438                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26439
26440                 echo "bs: $bs, file_size $file_size"
26441                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26442                         $DIR/$tfile.1 $DIR/$tfile.2 &
26443                 pid_dio1=$!
26444                 # Buffered I/O with similar but not the same block size
26445                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26446                         conv=notrunc &
26447                 pid_bio2=$!
26448                 wait $pid_dio1
26449                 rc1=$?
26450                 wait $pid_bio2
26451                 rc2=$?
26452                 if (( rc1 != 0 )); then
26453                         error "aio copy 1 w/bsize $bs failed: $rc1"
26454                 fi
26455                 if (( rc2 != 0 )); then
26456                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26457                 fi
26458
26459                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26460                         error "size incorrect"
26461                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26462                         error "files differ, bsize $bs"
26463                 rm -f $DIR/$tfile.2
26464         done
26465 }
26466 run_test 398p "race aio with buffered i/o"
26467
26468 test_fake_rw() {
26469         local read_write=$1
26470         if [ "$read_write" = "write" ]; then
26471                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26472         elif [ "$read_write" = "read" ]; then
26473                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26474         else
26475                 error "argument error"
26476         fi
26477
26478         # turn off debug for performance testing
26479         local saved_debug=$($LCTL get_param -n debug)
26480         $LCTL set_param debug=0
26481
26482         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26483
26484         # get ost1 size - $FSNAME-OST0000
26485         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26486         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26487         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26488
26489         if [ "$read_write" = "read" ]; then
26490                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26491         fi
26492
26493         local start_time=$(date +%s.%N)
26494         $dd_cmd bs=1M count=$blocks oflag=sync ||
26495                 error "real dd $read_write error"
26496         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26497
26498         if [ "$read_write" = "write" ]; then
26499                 rm -f $DIR/$tfile
26500         fi
26501
26502         # define OBD_FAIL_OST_FAKE_RW           0x238
26503         do_facet ost1 $LCTL set_param fail_loc=0x238
26504
26505         local start_time=$(date +%s.%N)
26506         $dd_cmd bs=1M count=$blocks oflag=sync ||
26507                 error "fake dd $read_write error"
26508         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26509
26510         if [ "$read_write" = "write" ]; then
26511                 # verify file size
26512                 cancel_lru_locks osc
26513                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26514                         error "$tfile size not $blocks MB"
26515         fi
26516         do_facet ost1 $LCTL set_param fail_loc=0
26517
26518         echo "fake $read_write $duration_fake vs. normal $read_write" \
26519                 "$duration in seconds"
26520         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26521                 error_not_in_vm "fake write is slower"
26522
26523         $LCTL set_param -n debug="$saved_debug"
26524         rm -f $DIR/$tfile
26525 }
26526 test_399a() { # LU-7655 for OST fake write
26527         remote_ost_nodsh && skip "remote OST with nodsh"
26528
26529         test_fake_rw write
26530 }
26531 run_test 399a "fake write should not be slower than normal write"
26532
26533 test_399b() { # LU-8726 for OST fake read
26534         remote_ost_nodsh && skip "remote OST with nodsh"
26535         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26536                 skip_env "ldiskfs only test"
26537         fi
26538
26539         test_fake_rw read
26540 }
26541 run_test 399b "fake read should not be slower than normal read"
26542
26543 test_400a() { # LU-1606, was conf-sanity test_74
26544         if ! which $CC > /dev/null 2>&1; then
26545                 skip_env "$CC is not installed"
26546         fi
26547
26548         local extra_flags=''
26549         local out=$TMP/$tfile
26550         local prefix=/usr/include/lustre
26551         local prog
26552
26553         # Oleg removes .c files in his test rig so test if any c files exist
26554         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26555                 skip_env "Needed .c test files are missing"
26556
26557         if ! [[ -d $prefix ]]; then
26558                 # Assume we're running in tree and fixup the include path.
26559                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26560                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26561                 extra_flags+=" -L$LUSTRE/utils/.libs"
26562         fi
26563
26564         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26565                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26566                         error "client api broken"
26567         done
26568         rm -f $out
26569 }
26570 run_test 400a "Lustre client api program can compile and link"
26571
26572 test_400b() { # LU-1606, LU-5011
26573         local header
26574         local out=$TMP/$tfile
26575         local prefix=/usr/include/linux/lustre
26576
26577         # We use a hard coded prefix so that this test will not fail
26578         # when run in tree. There are headers in lustre/include/lustre/
26579         # that are not packaged (like lustre_idl.h) and have more
26580         # complicated include dependencies (like config.h and lnet/types.h).
26581         # Since this test about correct packaging we just skip them when
26582         # they don't exist (see below) rather than try to fixup cppflags.
26583
26584         if ! which $CC > /dev/null 2>&1; then
26585                 skip_env "$CC is not installed"
26586         fi
26587
26588         for header in $prefix/*.h; do
26589                 if ! [[ -f "$header" ]]; then
26590                         continue
26591                 fi
26592
26593                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26594                         continue # lustre_ioctl.h is internal header
26595                 fi
26596
26597                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26598                         error "cannot compile '$header'"
26599         done
26600         rm -f $out
26601 }
26602 run_test 400b "packaged headers can be compiled"
26603
26604 test_401a() { #LU-7437
26605         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26606         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26607
26608         #count the number of parameters by "list_param -R"
26609         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26610         #count the number of parameters by listing proc files
26611         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26612         echo "proc_dirs='$proc_dirs'"
26613         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26614         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26615                       sort -u | wc -l)
26616
26617         [ $params -eq $procs ] ||
26618                 error "found $params parameters vs. $procs proc files"
26619
26620         # test the list_param -D option only returns directories
26621         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26622         #count the number of parameters by listing proc directories
26623         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26624                 sort -u | wc -l)
26625
26626         [ $params -eq $procs ] ||
26627                 error "found $params parameters vs. $procs proc files"
26628 }
26629 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26630
26631 test_401b() {
26632         # jobid_var may not allow arbitrary values, so use jobid_name
26633         # if available
26634         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26635                 local testname=jobid_name tmp='testing%p'
26636         else
26637                 local testname=jobid_var tmp=testing
26638         fi
26639
26640         local save=$($LCTL get_param -n $testname)
26641
26642         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26643                 error "no error returned when setting bad parameters"
26644
26645         local jobid_new=$($LCTL get_param -n foe $testname baz)
26646         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26647
26648         $LCTL set_param -n fog=bam $testname=$save bat=fog
26649         local jobid_old=$($LCTL get_param -n foe $testname bag)
26650         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26651 }
26652 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26653
26654 test_401c() {
26655         # jobid_var may not allow arbitrary values, so use jobid_name
26656         # if available
26657         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26658                 local testname=jobid_name
26659         else
26660                 local testname=jobid_var
26661         fi
26662
26663         local jobid_var_old=$($LCTL get_param -n $testname)
26664         local jobid_var_new
26665
26666         $LCTL set_param $testname= &&
26667                 error "no error returned for 'set_param a='"
26668
26669         jobid_var_new=$($LCTL get_param -n $testname)
26670         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26671                 error "$testname was changed by setting without value"
26672
26673         $LCTL set_param $testname &&
26674                 error "no error returned for 'set_param a'"
26675
26676         jobid_var_new=$($LCTL get_param -n $testname)
26677         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26678                 error "$testname was changed by setting without value"
26679 }
26680 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26681
26682 test_401d() {
26683         # jobid_var may not allow arbitrary values, so use jobid_name
26684         # if available
26685         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26686                 local testname=jobid_name new_value='foo=bar%p'
26687         else
26688                 local testname=jobid_var new_valuie=foo=bar
26689         fi
26690
26691         local jobid_var_old=$($LCTL get_param -n $testname)
26692         local jobid_var_new
26693
26694         $LCTL set_param $testname=$new_value ||
26695                 error "'set_param a=b' did not accept a value containing '='"
26696
26697         jobid_var_new=$($LCTL get_param -n $testname)
26698         [[ "$jobid_var_new" == "$new_value" ]] ||
26699                 error "'set_param a=b' failed on a value containing '='"
26700
26701         # Reset the $testname to test the other format
26702         $LCTL set_param $testname=$jobid_var_old
26703         jobid_var_new=$($LCTL get_param -n $testname)
26704         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26705                 error "failed to reset $testname"
26706
26707         $LCTL set_param $testname $new_value ||
26708                 error "'set_param a b' did not accept a value containing '='"
26709
26710         jobid_var_new=$($LCTL get_param -n $testname)
26711         [[ "$jobid_var_new" == "$new_value" ]] ||
26712                 error "'set_param a b' failed on a value containing '='"
26713
26714         $LCTL set_param $testname $jobid_var_old
26715         jobid_var_new=$($LCTL get_param -n $testname)
26716         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26717                 error "failed to reset $testname"
26718 }
26719 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26720
26721 test_401e() { # LU-14779
26722         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26723                 error "lctl list_param MGC* failed"
26724         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26725         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26726                 error "lctl get_param lru_size failed"
26727 }
26728 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26729
26730 test_402() {
26731         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26732         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26733                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26734         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26735                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26736                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26737         remote_mds_nodsh && skip "remote MDS with nodsh"
26738
26739         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26740 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26741         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26742         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26743                 echo "Touch failed - OK"
26744 }
26745 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26746
26747 test_403() {
26748         local file1=$DIR/$tfile.1
26749         local file2=$DIR/$tfile.2
26750         local tfile=$TMP/$tfile
26751
26752         rm -f $file1 $file2 $tfile
26753
26754         touch $file1
26755         ln $file1 $file2
26756
26757         # 30 sec OBD_TIMEOUT in ll_getattr()
26758         # right before populating st_nlink
26759         $LCTL set_param fail_loc=0x80001409
26760         stat -c %h $file1 > $tfile &
26761
26762         # create an alias, drop all locks and reclaim the dentry
26763         < $file2
26764         cancel_lru_locks mdc
26765         cancel_lru_locks osc
26766         sysctl -w vm.drop_caches=2
26767
26768         wait
26769
26770         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26771
26772         rm -f $tfile $file1 $file2
26773 }
26774 run_test 403 "i_nlink should not drop to zero due to aliasing"
26775
26776 test_404() { # LU-6601
26777         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26778                 skip "Need server version newer than 2.8.52"
26779         remote_mds_nodsh && skip "remote MDS with nodsh"
26780
26781         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26782                 awk '/osp .*-osc-MDT/ { print $4}')
26783
26784         local osp
26785         for osp in $mosps; do
26786                 echo "Deactivate: " $osp
26787                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26788                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26789                         awk -vp=$osp '$4 == p { print $2 }')
26790                 [ $stat = IN ] || {
26791                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26792                         error "deactivate error"
26793                 }
26794                 echo "Activate: " $osp
26795                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26796                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26797                         awk -vp=$osp '$4 == p { print $2 }')
26798                 [ $stat = UP ] || {
26799                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26800                         error "activate error"
26801                 }
26802         done
26803 }
26804 run_test 404 "validate manual {de}activated works properly for OSPs"
26805
26806 test_405() {
26807         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26808         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26809                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26810                         skip "Layout swap lock is not supported"
26811
26812         check_swap_layouts_support
26813         check_swap_layout_no_dom $DIR
26814
26815         test_mkdir $DIR/$tdir
26816         swap_lock_test -d $DIR/$tdir ||
26817                 error "One layout swap locked test failed"
26818 }
26819 run_test 405 "Various layout swap lock tests"
26820
26821 test_406() {
26822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26823         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26824         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26826         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26827                 skip "Need MDS version at least 2.8.50"
26828
26829         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26830         local test_pool=$TESTNAME
26831
26832         pool_add $test_pool || error "pool_add failed"
26833         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26834                 error "pool_add_targets failed"
26835
26836         save_layout_restore_at_exit $MOUNT
26837
26838         # parent set default stripe count only, child will stripe from both
26839         # parent and fs default
26840         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26841                 error "setstripe $MOUNT failed"
26842         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26843         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26844         for i in $(seq 10); do
26845                 local f=$DIR/$tdir/$tfile.$i
26846                 touch $f || error "touch failed"
26847                 local count=$($LFS getstripe -c $f)
26848                 [ $count -eq $OSTCOUNT ] ||
26849                         error "$f stripe count $count != $OSTCOUNT"
26850                 local offset=$($LFS getstripe -i $f)
26851                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26852                 local size=$($LFS getstripe -S $f)
26853                 [ $size -eq $((def_stripe_size * 2)) ] ||
26854                         error "$f stripe size $size != $((def_stripe_size * 2))"
26855                 local pool=$($LFS getstripe -p $f)
26856                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26857         done
26858
26859         # change fs default striping, delete parent default striping, now child
26860         # will stripe from new fs default striping only
26861         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26862                 error "change $MOUNT default stripe failed"
26863         $LFS setstripe -c 0 $DIR/$tdir ||
26864                 error "delete $tdir default stripe failed"
26865         for i in $(seq 11 20); do
26866                 local f=$DIR/$tdir/$tfile.$i
26867                 touch $f || error "touch $f failed"
26868                 local count=$($LFS getstripe -c $f)
26869                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26870                 local offset=$($LFS getstripe -i $f)
26871                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26872                 local size=$($LFS getstripe -S $f)
26873                 [ $size -eq $def_stripe_size ] ||
26874                         error "$f stripe size $size != $def_stripe_size"
26875                 local pool=$($LFS getstripe -p $f)
26876                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26877         done
26878
26879         unlinkmany $DIR/$tdir/$tfile. 1 20
26880
26881         local f=$DIR/$tdir/$tfile
26882         pool_remove_all_targets $test_pool $f
26883         pool_remove $test_pool $f
26884 }
26885 run_test 406 "DNE support fs default striping"
26886
26887 test_407() {
26888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26889         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26890                 skip "Need MDS version at least 2.8.55"
26891         remote_mds_nodsh && skip "remote MDS with nodsh"
26892
26893         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26894                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26895         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26896                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26897         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26898
26899         #define OBD_FAIL_DT_TXN_STOP    0x2019
26900         for idx in $(seq $MDSCOUNT); do
26901                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26902         done
26903         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26904         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26905                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26906         true
26907 }
26908 run_test 407 "transaction fail should cause operation fail"
26909
26910 test_408() {
26911         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26912
26913         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26914         lctl set_param fail_loc=0x8000040a
26915         # let ll_prepare_partial_page() fail
26916         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26917
26918         rm -f $DIR/$tfile
26919
26920         # create at least 100 unused inodes so that
26921         # shrink_icache_memory(0) should not return 0
26922         touch $DIR/$tfile-{0..100}
26923         rm -f $DIR/$tfile-{0..100}
26924         sync
26925
26926         echo 2 > /proc/sys/vm/drop_caches
26927 }
26928 run_test 408 "drop_caches should not hang due to page leaks"
26929
26930 test_409()
26931 {
26932         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26933
26934         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26935         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26936         touch $DIR/$tdir/guard || error "(2) Fail to create"
26937
26938         local PREFIX=$(str_repeat 'A' 128)
26939         echo "Create 1K hard links start at $(date)"
26940         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26941                 error "(3) Fail to hard link"
26942
26943         echo "Links count should be right although linkEA overflow"
26944         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26945         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26946         [ $linkcount -eq 1001 ] ||
26947                 error "(5) Unexpected hard links count: $linkcount"
26948
26949         echo "List all links start at $(date)"
26950         ls -l $DIR/$tdir/foo > /dev/null ||
26951                 error "(6) Fail to list $DIR/$tdir/foo"
26952
26953         echo "Unlink hard links start at $(date)"
26954         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26955                 error "(7) Fail to unlink"
26956         echo "Unlink hard links finished at $(date)"
26957 }
26958 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26959
26960 test_410()
26961 {
26962         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26963                 skip "Need client version at least 2.9.59"
26964         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26965                 skip "Need MODULES build"
26966
26967         # Create a file, and stat it from the kernel
26968         local testfile=$DIR/$tfile
26969         touch $testfile
26970
26971         local run_id=$RANDOM
26972         local my_ino=$(stat --format "%i" $testfile)
26973
26974         # Try to insert the module. This will always fail as the
26975         # module is designed to not be inserted.
26976         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26977             &> /dev/null
26978
26979         # Anything but success is a test failure
26980         dmesg | grep -q \
26981             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26982             error "no inode match"
26983 }
26984 run_test 410 "Test inode number returned from kernel thread"
26985
26986 cleanup_test411_cgroup() {
26987         trap 0
26988         rmdir "$1"
26989 }
26990
26991 test_411() {
26992         local cg_basedir=/sys/fs/cgroup/memory
26993         # LU-9966
26994         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26995                 skip "no setup for cgroup"
26996
26997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26998                 error "test file creation failed"
26999         cancel_lru_locks osc
27000
27001         # Create a very small memory cgroup to force a slab allocation error
27002         local cgdir=$cg_basedir/osc_slab_alloc
27003         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27004         trap "cleanup_test411_cgroup $cgdir" EXIT
27005         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27006         echo 1M > $cgdir/memory.limit_in_bytes
27007
27008         # Should not LBUG, just be killed by oom-killer
27009         # dd will return 0 even allocation failure in some environment.
27010         # So don't check return value
27011         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27012         cleanup_test411_cgroup $cgdir
27013
27014         return 0
27015 }
27016 run_test 411 "Slab allocation error with cgroup does not LBUG"
27017
27018 test_412() {
27019         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27020         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27021                 skip "Need server version at least 2.10.55"
27022
27023         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27024                 error "mkdir failed"
27025         $LFS getdirstripe $DIR/$tdir
27026         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27027         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27028                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27029         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27030         [ $stripe_count -eq 2 ] ||
27031                 error "expect 2 get $stripe_count"
27032
27033         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27034
27035         local index
27036         local index2
27037
27038         # subdirs should be on the same MDT as parent
27039         for i in $(seq 0 $((MDSCOUNT - 1))); do
27040                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27041                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27042                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27043                 (( index == i )) || error "mdt$i/sub on MDT$index"
27044         done
27045
27046         # stripe offset -1, ditto
27047         for i in {1..10}; do
27048                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27049                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27050                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27051                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27052                 (( index == index2 )) ||
27053                         error "qos$i on MDT$index, sub on MDT$index2"
27054         done
27055
27056         local testdir=$DIR/$tdir/inherit
27057
27058         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27059         # inherit 2 levels
27060         for i in 1 2; do
27061                 testdir=$testdir/s$i
27062                 mkdir $testdir || error "mkdir $testdir failed"
27063                 index=$($LFS getstripe -m $testdir)
27064                 (( index == 1 )) ||
27065                         error "$testdir on MDT$index"
27066         done
27067
27068         # not inherit any more
27069         testdir=$testdir/s3
27070         mkdir $testdir || error "mkdir $testdir failed"
27071         getfattr -d -m dmv $testdir | grep dmv &&
27072                 error "default LMV set on $testdir" || true
27073 }
27074 run_test 412 "mkdir on specific MDTs"
27075
27076 TEST413_COUNT=${TEST413_COUNT:-200}
27077
27078 #
27079 # set_maxage() is used by test_413 only.
27080 # This is a helper function to set maxage. Does not return any value.
27081 # Input: maxage to set
27082 #
27083 set_maxage() {
27084         local lmv_qos_maxage
27085         local lod_qos_maxage
27086         local new_maxage=$1
27087
27088         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27089         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27090         stack_trap "$LCTL set_param \
27091                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27092         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27093                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27094         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27095                 lod.*.mdt_qos_maxage=$new_maxage
27096         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27097                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27098 }
27099
27100 generate_uneven_mdts() {
27101         local threshold=$1
27102         local ffree
27103         local bavail
27104         local max
27105         local min
27106         local max_index
27107         local min_index
27108         local tmp
27109         local i
27110
27111         echo
27112         echo "Check for uneven MDTs: "
27113
27114         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27115         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27116         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27117
27118         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27119         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27120         max_index=0
27121         min_index=0
27122         for ((i = 1; i < ${#ffree[@]}; i++)); do
27123                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27124                 if [ $tmp -gt $max ]; then
27125                         max=$tmp
27126                         max_index=$i
27127                 fi
27128                 if [ $tmp -lt $min ]; then
27129                         min=$tmp
27130                         min_index=$i
27131                 fi
27132         done
27133
27134         (( min > 0 )) || skip "low space on MDT$min_index"
27135         (( ${ffree[min_index]} > 0 )) ||
27136                 skip "no free files on MDT$min_index"
27137         (( ${ffree[min_index]} < 10000000 )) ||
27138                 skip "too many free files on MDT$min_index"
27139
27140         # Check if we need to generate uneven MDTs
27141         local diff=$(((max - min) * 100 / min))
27142         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27143         local testdir # individual folder within $testdirp
27144         local start
27145         local cmd
27146
27147         # fallocate is faster to consume space on MDT, if available
27148         if check_fallocate_supported mds$((min_index + 1)); then
27149                 cmd="fallocate -l 128K "
27150         else
27151                 cmd="dd if=/dev/zero bs=128K count=1 of="
27152         fi
27153
27154         echo "using cmd $cmd"
27155         for (( i = 0; diff < threshold; i++ )); do
27156                 testdir=${testdirp}/$i
27157                 [ -d $testdir ] && continue
27158
27159                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27160
27161                 mkdir -p $testdirp
27162                 # generate uneven MDTs, create till $threshold% diff
27163                 echo -n "weight diff=$diff% must be > $threshold% ..."
27164                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27165                 $LFS mkdir -i $min_index $testdir ||
27166                         error "mkdir $testdir failed"
27167                 $LFS setstripe -E 1M -L mdt $testdir ||
27168                         error "setstripe $testdir failed"
27169                 start=$SECONDS
27170                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27171                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27172                 done
27173                 sync; sleep 1; sync
27174
27175                 # wait for QOS to update
27176                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27177
27178                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27179                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27180                 max=$(((${ffree[max_index]} >> 8) *
27181                         (${bavail[max_index]} * bsize >> 16)))
27182                 min=$(((${ffree[min_index]} >> 8) *
27183                         (${bavail[min_index]} * bsize >> 16)))
27184                 (( min > 0 )) || skip "low space on MDT$min_index"
27185                 diff=$(((max - min) * 100 / min))
27186         done
27187
27188         echo "MDT filesfree available: ${ffree[*]}"
27189         echo "MDT blocks available: ${bavail[*]}"
27190         echo "weight diff=$diff%"
27191 }
27192
27193 test_qos_mkdir() {
27194         local mkdir_cmd=$1
27195         local stripe_count=$2
27196         local mdts=$(comma_list $(mdts_nodes))
27197
27198         local testdir
27199         local lmv_qos_prio_free
27200         local lmv_qos_threshold_rr
27201         local lod_qos_prio_free
27202         local lod_qos_threshold_rr
27203         local total
27204         local count
27205         local i
27206
27207         # @total is total directories created if it's testing plain
27208         # directories, otherwise it's total stripe object count for
27209         # striped directories test.
27210         # remote/striped directory unlinking is slow on zfs and may
27211         # timeout, test with fewer directories
27212         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27213
27214         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27215         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27216         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27217                 head -n1)
27218         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27219         stack_trap "$LCTL set_param \
27220                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27221         stack_trap "$LCTL set_param \
27222                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27223
27224         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27225                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27226         lod_qos_prio_free=${lod_qos_prio_free%%%}
27227         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27228                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27229         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27230         stack_trap "do_nodes $mdts $LCTL set_param \
27231                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27232         stack_trap "do_nodes $mdts $LCTL set_param \
27233                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27234
27235         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27236         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27237
27238         testdir=$DIR/$tdir-s$stripe_count/rr
27239
27240         local stripe_index=$($LFS getstripe -m $testdir)
27241         local test_mkdir_rr=true
27242
27243         getfattr -d -m dmv -e hex $testdir | grep dmv
27244         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27245                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27246                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27247                         test_mkdir_rr=false
27248         fi
27249
27250         echo
27251         $test_mkdir_rr &&
27252                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27253                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27254
27255         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27256         for (( i = 0; i < total / stripe_count; i++ )); do
27257                 eval $mkdir_cmd $testdir/subdir$i ||
27258                         error "$mkdir_cmd subdir$i failed"
27259         done
27260
27261         for (( i = 0; i < $MDSCOUNT; i++ )); do
27262                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27263                 echo "$count directories created on MDT$i"
27264                 if $test_mkdir_rr; then
27265                         (( count == total / stripe_count / MDSCOUNT )) ||
27266                                 error "subdirs are not evenly distributed"
27267                 elif (( i == stripe_index )); then
27268                         (( count == total / stripe_count )) ||
27269                                 error "$count subdirs created on MDT$i"
27270                 else
27271                         (( count == 0 )) ||
27272                                 error "$count subdirs created on MDT$i"
27273                 fi
27274
27275                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27276                         count=$($LFS getdirstripe $testdir/* |
27277                                 grep -c -P "^\s+$i\t")
27278                         echo "$count stripes created on MDT$i"
27279                         # deviation should < 5% of average
27280                         delta=$((count - total / MDSCOUNT))
27281                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27282                                 error "stripes are not evenly distributed"
27283                 fi
27284         done
27285
27286         echo
27287         echo "Check for uneven MDTs: "
27288
27289         local ffree
27290         local bavail
27291         local max
27292         local min
27293         local max_index
27294         local min_index
27295         local tmp
27296
27297         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27298         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27299         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27300
27301         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27302         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27303         max_index=0
27304         min_index=0
27305         for ((i = 1; i < ${#ffree[@]}; i++)); do
27306                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27307                 if [ $tmp -gt $max ]; then
27308                         max=$tmp
27309                         max_index=$i
27310                 fi
27311                 if [ $tmp -lt $min ]; then
27312                         min=$tmp
27313                         min_index=$i
27314                 fi
27315         done
27316         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27317
27318         (( min > 0 )) || skip "low space on MDT$min_index"
27319         (( ${ffree[min_index]} < 10000000 )) ||
27320                 skip "too many free files on MDT$min_index"
27321
27322         generate_uneven_mdts 120
27323
27324         echo "MDT filesfree available: ${ffree[*]}"
27325         echo "MDT blocks available: ${bavail[*]}"
27326         echo "weight diff=$(((max - min) * 100 / min))%"
27327         echo
27328         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27329
27330         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27331         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27332         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27333         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27334         # decrease statfs age, so that it can be updated in time
27335         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27336         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27337
27338         sleep 1
27339
27340         testdir=$DIR/$tdir-s$stripe_count/qos
27341
27342         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27343         for (( i = 0; i < total / stripe_count; i++ )); do
27344                 eval $mkdir_cmd $testdir/subdir$i ||
27345                         error "$mkdir_cmd subdir$i failed"
27346         done
27347
27348         max=0
27349         for (( i = 0; i < $MDSCOUNT; i++ )); do
27350                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27351                 (( count > max )) && max=$count
27352                 echo "$count directories created on MDT$i : curmax=$max"
27353         done
27354
27355         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27356
27357         # D-value should > 10% of average
27358         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27359                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27360
27361         # ditto for stripes
27362         if (( stripe_count > 1 )); then
27363                 max=0
27364                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27365                         count=$($LFS getdirstripe $testdir/* |
27366                                 grep -c -P "^\s+$i\t")
27367                         (( count > max )) && max=$count
27368                         echo "$count stripes created on MDT$i"
27369                 done
27370
27371                 min=$($LFS getdirstripe $testdir/* |
27372                         grep -c -P "^\s+$min_index\t")
27373                 (( max - min > total / MDSCOUNT / 10 )) ||
27374                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27375         fi
27376 }
27377
27378 most_full_mdt() {
27379         local ffree
27380         local bavail
27381         local bsize
27382         local min
27383         local min_index
27384         local tmp
27385
27386         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27387         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27388         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27389
27390         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27391         min_index=0
27392         for ((i = 1; i < ${#ffree[@]}; i++)); do
27393                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27394                 (( tmp < min )) && min=$tmp && min_index=$i
27395         done
27396
27397         echo -n $min_index
27398 }
27399
27400 test_413a() {
27401         [ $MDSCOUNT -lt 2 ] &&
27402                 skip "We need at least 2 MDTs for this test"
27403
27404         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27405                 skip "Need server version at least 2.12.52"
27406
27407         local stripe_max=$((MDSCOUNT - 1))
27408         local stripe_count
27409
27410         # let caller set maxage for latest result
27411         set_maxage 1
27412
27413         # fill MDT unevenly
27414         generate_uneven_mdts 120
27415
27416         # test 4-stripe directory at most, otherwise it's too slow
27417         # We are being very defensive. Although Autotest uses 4 MDTs.
27418         # We make sure stripe_max does not go over 4.
27419         (( stripe_max > 4 )) && stripe_max=4
27420         # unlinking striped directory is slow on zfs, and may timeout, only test
27421         # plain directory
27422         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27423         for stripe_count in $(seq 1 $stripe_max); do
27424                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27425                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27426                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27427                         error "mkdir failed"
27428                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27429         done
27430 }
27431 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27432
27433 test_413b() {
27434         [ $MDSCOUNT -lt 2 ] &&
27435                 skip "We need at least 2 MDTs for this test"
27436
27437         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27438                 skip "Need server version at least 2.12.52"
27439
27440         local stripe_max=$((MDSCOUNT - 1))
27441         local testdir
27442         local stripe_count
27443
27444         # let caller set maxage for latest result
27445         set_maxage 1
27446
27447         # fill MDT unevenly
27448         generate_uneven_mdts 120
27449
27450         # test 4-stripe directory at most, otherwise it's too slow
27451         # We are being very defensive. Although Autotest uses 4 MDTs.
27452         # We make sure stripe_max does not go over 4.
27453         (( stripe_max > 4 )) && stripe_max=4
27454         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27455         for stripe_count in $(seq 1 $stripe_max); do
27456                 testdir=$DIR/$tdir-s$stripe_count
27457                 mkdir $testdir || error "mkdir $testdir failed"
27458                 mkdir $testdir/rr || error "mkdir rr failed"
27459                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27460                         error "mkdir qos failed"
27461                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27462                         $testdir/rr || error "setdirstripe rr failed"
27463                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27464                         error "setdirstripe failed"
27465                 test_qos_mkdir "mkdir" $stripe_count
27466         done
27467 }
27468 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27469
27470 test_413c() {
27471         (( $MDSCOUNT >= 2 )) ||
27472                 skip "We need at least 2 MDTs for this test"
27473
27474         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27475                 skip "Need server version at least 2.14.51"
27476
27477         local testdir
27478         local inherit
27479         local inherit_rr
27480         local lmv_qos_maxage
27481         local lod_qos_maxage
27482
27483         # let caller set maxage for latest result
27484         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27485         $LCTL set_param lmv.*.qos_maxage=1
27486         stack_trap "$LCTL set_param \
27487                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27488         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27489                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27490         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27491                 lod.*.mdt_qos_maxage=1
27492         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27493                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27494
27495         # fill MDT unevenly
27496         generate_uneven_mdts 120
27497
27498         testdir=$DIR/${tdir}-s1
27499         mkdir $testdir || error "mkdir $testdir failed"
27500         mkdir $testdir/rr || error "mkdir rr failed"
27501         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27502         # default max_inherit is -1, default max_inherit_rr is 0
27503         $LFS setdirstripe -D -c 1 $testdir/rr ||
27504                 error "setdirstripe rr failed"
27505         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27506                 error "setdirstripe qos failed"
27507         test_qos_mkdir "mkdir" 1
27508
27509         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27510         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27511         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27512         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27513         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27514
27515         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27516         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27517         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27518         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27519         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27520         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27521         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27522                 error "level2 shouldn't have default LMV" || true
27523 }
27524 run_test 413c "mkdir with default LMV max inherit rr"
27525
27526 test_413d() {
27527         (( MDSCOUNT >= 2 )) ||
27528                 skip "We need at least 2 MDTs for this test"
27529
27530         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27531                 skip "Need server version at least 2.14.51"
27532
27533         local lmv_qos_threshold_rr
27534
27535         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27536                 head -n1)
27537         stack_trap "$LCTL set_param \
27538                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27539
27540         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27541         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27542         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27543                 error "$tdir shouldn't have default LMV"
27544         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27545                 error "mkdir sub failed"
27546
27547         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27548
27549         (( count == 100 )) || error "$count subdirs on MDT0"
27550 }
27551 run_test 413d "inherit ROOT default LMV"
27552
27553 test_413e() {
27554         (( MDSCOUNT >= 2 )) ||
27555                 skip "We need at least 2 MDTs for this test"
27556         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27557                 skip "Need server version at least 2.14.55"
27558
27559         local testdir=$DIR/$tdir
27560         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27561         local max_inherit
27562         local sub_max_inherit
27563
27564         mkdir -p $testdir || error "failed to create $testdir"
27565
27566         # set default max-inherit to -1 if stripe count is 0 or 1
27567         $LFS setdirstripe -D -c 1 $testdir ||
27568                 error "failed to set default LMV"
27569         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27570         (( max_inherit == -1 )) ||
27571                 error "wrong max_inherit value $max_inherit"
27572
27573         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27574         $LFS setdirstripe -D -c -1 $testdir ||
27575                 error "failed to set default LMV"
27576         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27577         (( max_inherit > 0 )) ||
27578                 error "wrong max_inherit value $max_inherit"
27579
27580         # and the subdir will decrease the max_inherit by 1
27581         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27582         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27583         (( sub_max_inherit == max_inherit - 1)) ||
27584                 error "wrong max-inherit of subdir $sub_max_inherit"
27585
27586         # check specified --max-inherit and warning message
27587         stack_trap "rm -f $tmpfile"
27588         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27589                 error "failed to set default LMV"
27590         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27591         (( max_inherit == -1 )) ||
27592                 error "wrong max_inherit value $max_inherit"
27593
27594         # check the warning messages
27595         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27596                 error "failed to detect warning string"
27597         fi
27598 }
27599 run_test 413e "check default max-inherit value"
27600
27601 test_fs_dmv_inherit()
27602 {
27603         local testdir=$DIR/$tdir
27604
27605         local count
27606         local inherit
27607         local inherit_rr
27608
27609         for i in 1 2; do
27610                 mkdir $testdir || error "mkdir $testdir failed"
27611                 count=$($LFS getdirstripe -D -c $testdir)
27612                 (( count == 1 )) ||
27613                         error "$testdir default LMV count mismatch $count != 1"
27614                 inherit=$($LFS getdirstripe -D -X $testdir)
27615                 (( inherit == 3 - i )) ||
27616                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27617                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27618                 (( inherit_rr == 3 - i )) ||
27619                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27620                 testdir=$testdir/sub
27621         done
27622
27623         mkdir $testdir || error "mkdir $testdir failed"
27624         count=$($LFS getdirstripe -D -c $testdir)
27625         (( count == 0 )) ||
27626                 error "$testdir default LMV count not zero: $count"
27627 }
27628
27629 test_413f() {
27630         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27631
27632         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27633                 skip "Need server version at least 2.14.55"
27634
27635         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27636                 error "dump $DIR default LMV failed"
27637         stack_trap "setfattr --restore=$TMP/dmv.ea"
27638
27639         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27640                 error "set $DIR default LMV failed"
27641
27642         test_fs_dmv_inherit
27643 }
27644 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27645
27646 test_413g() {
27647         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27648
27649         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27650         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27651                 error "dump $DIR default LMV failed"
27652         stack_trap "setfattr --restore=$TMP/dmv.ea"
27653
27654         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27655                 error "set $DIR default LMV failed"
27656
27657         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27658                 error "mount $MOUNT2 failed"
27659         stack_trap "umount_client $MOUNT2"
27660
27661         local saved_DIR=$DIR
27662
27663         export DIR=$MOUNT2
27664
27665         stack_trap "export DIR=$saved_DIR"
27666
27667         # first check filesystem-wide default LMV inheritance
27668         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27669
27670         # then check subdirs are spread to all MDTs
27671         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27672
27673         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27674
27675         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27676 }
27677 run_test 413g "enforce ROOT default LMV on subdir mount"
27678
27679 test_413h() {
27680         (( MDSCOUNT >= 2 )) ||
27681                 skip "We need at least 2 MDTs for this test"
27682
27683         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27684                 skip "Need server version at least 2.15.50.6"
27685
27686         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27687
27688         stack_trap "$LCTL set_param \
27689                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27690         $LCTL set_param lmv.*.qos_maxage=1
27691
27692         local depth=5
27693         local rr_depth=4
27694         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27695         local count=$((MDSCOUNT * 20))
27696
27697         generate_uneven_mdts 50
27698
27699         mkdir -p $dir || error "mkdir $dir failed"
27700         stack_trap "rm -rf $dir"
27701         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27702                 --max-inherit-rr=$rr_depth $dir
27703
27704         for ((d=0; d < depth + 2; d++)); do
27705                 log "dir=$dir:"
27706                 for ((sub=0; sub < count; sub++)); do
27707                         mkdir $dir/d$sub
27708                 done
27709                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27710                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27711                 # subdirs within $rr_depth should be created round-robin
27712                 if (( d < rr_depth )); then
27713                         (( ${num[0]} != count )) ||
27714                                 error "all objects created on MDT ${num[1]}"
27715                 fi
27716
27717                 dir=$dir/d0
27718         done
27719 }
27720 run_test 413h "don't stick to parent for round-robin dirs"
27721
27722 test_413i() {
27723         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27724
27725         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27726                 skip "Need server version at least 2.14.55"
27727
27728         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27729                 error "dump $DIR default LMV failed"
27730         stack_trap "setfattr --restore=$TMP/dmv.ea"
27731
27732         local testdir=$DIR/$tdir
27733         local def_max_rr=1
27734         local def_max=3
27735         local count
27736
27737         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27738                 --max-inherit-rr=$def_max_rr $DIR ||
27739                 error "set $DIR default LMV failed"
27740
27741         for i in $(seq 2 3); do
27742                 def_max=$((def_max - 1))
27743                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27744
27745                 mkdir $testdir
27746                 # RR is decremented and keeps zeroed once exhausted
27747                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27748                 (( count == def_max_rr )) ||
27749                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27750
27751                 # max-inherit is decremented
27752                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27753                 (( count == def_max )) ||
27754                         error_noexit "$testdir: max-inherit $count != $def_max"
27755
27756                 testdir=$testdir/d$i
27757         done
27758
27759         # d3 is the last inherited from ROOT, no inheritance anymore
27760         # i.e. no the default layout anymore
27761         mkdir -p $testdir/d4/d5
27762         count=$($LFS getdirstripe -D --max-inherit $testdir)
27763         (( count == -1 )) ||
27764                 error_noexit "$testdir: max-inherit $count != -1"
27765
27766         local p_count=$($LFS getdirstripe -i $testdir)
27767
27768         for i in $(seq 4 5); do
27769                 testdir=$testdir/d$i
27770
27771                 # the root default layout is not applied once exhausted
27772                 count=$($LFS getdirstripe -i $testdir)
27773                 (( count == p_count )) ||
27774                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27775         done
27776
27777         $LFS setdirstripe -i 0 $DIR/d2
27778         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27779         (( count == -1 )) ||
27780                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27781 }
27782 run_test 413i "check default layout inheritance"
27783
27784 test_413z() {
27785         local pids=""
27786         local subdir
27787         local pid
27788
27789         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27790                 unlinkmany $subdir/f. $TEST413_COUNT &
27791                 pids="$pids $!"
27792         done
27793
27794         for pid in $pids; do
27795                 wait $pid
27796         done
27797
27798         true
27799 }
27800 run_test 413z "413 test cleanup"
27801
27802 test_414() {
27803 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27804         $LCTL set_param fail_loc=0x80000521
27805         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27806         rm -f $DIR/$tfile
27807 }
27808 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27809
27810 test_415() {
27811         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27812         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27813                 skip "Need server version at least 2.11.52"
27814
27815         # LU-11102
27816         local total=500
27817         local max=120
27818
27819         # this test may be slow on ZFS
27820         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27821
27822         # though this test is designed for striped directory, let's test normal
27823         # directory too since lock is always saved as CoS lock.
27824         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27825         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27826         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27827         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27828         wait_delete_completed_mds
27829
27830         # run a loop without concurrent touch to measure rename duration.
27831         # only for test debug/robustness, NOT part of COS functional test.
27832         local start_time=$SECONDS
27833         for ((i = 0; i < total; i++)); do
27834                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27835                         > /dev/null
27836         done
27837         local baseline=$((SECONDS - start_time))
27838         echo "rename $total files without 'touch' took $baseline sec"
27839
27840         (
27841                 while true; do
27842                         touch $DIR/$tdir
27843                 done
27844         ) &
27845         local setattr_pid=$!
27846
27847         # rename files back to original name so unlinkmany works
27848         start_time=$SECONDS
27849         for ((i = 0; i < total; i++)); do
27850                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27851                         > /dev/null
27852         done
27853         local duration=$((SECONDS - start_time))
27854
27855         kill -9 $setattr_pid
27856
27857         echo "rename $total files with 'touch' took $duration sec"
27858         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27859         (( duration <= max )) ||
27860                 error_not_in_vm "rename took $duration > $max sec"
27861 }
27862 run_test 415 "lock revoke is not missing"
27863
27864 test_416() {
27865         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27866                 skip "Need server version at least 2.11.55"
27867
27868         # define OBD_FAIL_OSD_TXN_START    0x19a
27869         do_facet mds1 lctl set_param fail_loc=0x19a
27870
27871         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27872
27873         true
27874 }
27875 run_test 416 "transaction start failure won't cause system hung"
27876
27877 cleanup_417() {
27878         trap 0
27879         do_nodes $(comma_list $(mdts_nodes)) \
27880                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27881         do_nodes $(comma_list $(mdts_nodes)) \
27882                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27883         do_nodes $(comma_list $(mdts_nodes)) \
27884                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27885 }
27886
27887 test_417() {
27888         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27889         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27890                 skip "Need MDS version at least 2.11.56"
27891
27892         trap cleanup_417 RETURN EXIT
27893
27894         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27895         do_nodes $(comma_list $(mdts_nodes)) \
27896                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27897         $LFS migrate -m 0 $DIR/$tdir.1 &&
27898                 error "migrate dir $tdir.1 should fail"
27899
27900         do_nodes $(comma_list $(mdts_nodes)) \
27901                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27902         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27903                 error "create remote dir $tdir.2 should fail"
27904
27905         do_nodes $(comma_list $(mdts_nodes)) \
27906                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27907         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27908                 error "create striped dir $tdir.3 should fail"
27909         true
27910 }
27911 run_test 417 "disable remote dir, striped dir and dir migration"
27912
27913 # Checks that the outputs of df [-i] and lfs df [-i] match
27914 #
27915 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27916 check_lfs_df() {
27917         local dir=$2
27918         local inodes
27919         local df_out
27920         local lfs_df_out
27921         local count
27922         local passed=false
27923
27924         # blocks or inodes
27925         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27926
27927         for count in {1..100}; do
27928                 do_nodes "$CLIENTS" \
27929                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27930                 sync; sleep 0.2
27931
27932                 # read the lines of interest
27933                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27934                         error "df $inodes $dir | tail -n +2 failed"
27935                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27936                         error "lfs df $inodes $dir | grep summary: failed"
27937
27938                 # skip first substrings of each output as they are different
27939                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27940                 # compare the two outputs
27941                 passed=true
27942                 #  skip "available" on MDT until LU-13997 is fixed.
27943                 #for i in {1..5}; do
27944                 for i in 1 2 4 5; do
27945                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27946                 done
27947                 $passed && break
27948         done
27949
27950         if ! $passed; then
27951                 df -P $inodes $dir
27952                 echo
27953                 lfs df $inodes $dir
27954                 error "df and lfs df $1 output mismatch: "      \
27955                       "df ${inodes}: ${df_out[*]}, "            \
27956                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27957         fi
27958 }
27959
27960 test_418() {
27961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27962
27963         local dir=$DIR/$tdir
27964         local numfiles=$((RANDOM % 4096 + 2))
27965         local numblocks=$((RANDOM % 256 + 1))
27966
27967         wait_delete_completed
27968         test_mkdir $dir
27969
27970         # check block output
27971         check_lfs_df blocks $dir
27972         # check inode output
27973         check_lfs_df inodes $dir
27974
27975         # create a single file and retest
27976         echo "Creating a single file and testing"
27977         createmany -o $dir/$tfile- 1 &>/dev/null ||
27978                 error "creating 1 file in $dir failed"
27979         check_lfs_df blocks $dir
27980         check_lfs_df inodes $dir
27981
27982         # create a random number of files
27983         echo "Creating $((numfiles - 1)) files and testing"
27984         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27985                 error "creating $((numfiles - 1)) files in $dir failed"
27986
27987         # write a random number of blocks to the first test file
27988         echo "Writing $numblocks 4K blocks and testing"
27989         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27990                 count=$numblocks &>/dev/null ||
27991                 error "dd to $dir/${tfile}-0 failed"
27992
27993         # retest
27994         check_lfs_df blocks $dir
27995         check_lfs_df inodes $dir
27996
27997         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27998                 error "unlinking $numfiles files in $dir failed"
27999 }
28000 run_test 418 "df and lfs df outputs match"
28001
28002 test_419()
28003 {
28004         local dir=$DIR/$tdir
28005
28006         mkdir -p $dir
28007         touch $dir/file
28008
28009         cancel_lru_locks mdc
28010
28011         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28012         $LCTL set_param fail_loc=0x1410
28013         cat $dir/file
28014         $LCTL set_param fail_loc=0
28015         rm -rf $dir
28016 }
28017 run_test 419 "Verify open file by name doesn't crash kernel"
28018
28019 test_420()
28020 {
28021         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28022                 skip "Need MDS version at least 2.12.53"
28023
28024         local SAVE_UMASK=$(umask)
28025         local dir=$DIR/$tdir
28026         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28027
28028         mkdir -p $dir
28029         umask 0000
28030         mkdir -m03777 $dir/testdir
28031         ls -dn $dir/testdir
28032         # Need to remove trailing '.' when SELinux is enabled
28033         local dirperms=$(ls -dn $dir/testdir |
28034                          awk '{ sub(/\.$/, "", $1); print $1}')
28035         [ $dirperms == "drwxrwsrwt" ] ||
28036                 error "incorrect perms on $dir/testdir"
28037
28038         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28039                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28040         ls -n $dir/testdir/testfile
28041         local fileperms=$(ls -n $dir/testdir/testfile |
28042                           awk '{ sub(/\.$/, "", $1); print $1}')
28043         [ $fileperms == "-rwxr-xr-x" ] ||
28044                 error "incorrect perms on $dir/testdir/testfile"
28045
28046         umask $SAVE_UMASK
28047 }
28048 run_test 420 "clear SGID bit on non-directories for non-members"
28049
28050 test_421a() {
28051         local cnt
28052         local fid1
28053         local fid2
28054
28055         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28056                 skip "Need MDS version at least 2.12.54"
28057
28058         test_mkdir $DIR/$tdir
28059         createmany -o $DIR/$tdir/f 3
28060         cnt=$(ls -1 $DIR/$tdir | wc -l)
28061         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28062
28063         fid1=$(lfs path2fid $DIR/$tdir/f1)
28064         fid2=$(lfs path2fid $DIR/$tdir/f2)
28065         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28066
28067         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28068         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28069
28070         cnt=$(ls -1 $DIR/$tdir | wc -l)
28071         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28072
28073         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28074         createmany -o $DIR/$tdir/f 3
28075         cnt=$(ls -1 $DIR/$tdir | wc -l)
28076         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28077
28078         fid1=$(lfs path2fid $DIR/$tdir/f1)
28079         fid2=$(lfs path2fid $DIR/$tdir/f2)
28080         echo "remove using fsname $FSNAME"
28081         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28082
28083         cnt=$(ls -1 $DIR/$tdir | wc -l)
28084         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28085 }
28086 run_test 421a "simple rm by fid"
28087
28088 test_421b() {
28089         local cnt
28090         local FID1
28091         local FID2
28092
28093         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28094                 skip "Need MDS version at least 2.12.54"
28095
28096         test_mkdir $DIR/$tdir
28097         createmany -o $DIR/$tdir/f 3
28098         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28099         MULTIPID=$!
28100
28101         FID1=$(lfs path2fid $DIR/$tdir/f1)
28102         FID2=$(lfs path2fid $DIR/$tdir/f2)
28103         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28104
28105         kill -USR1 $MULTIPID
28106         wait
28107
28108         cnt=$(ls $DIR/$tdir | wc -l)
28109         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28110 }
28111 run_test 421b "rm by fid on open file"
28112
28113 test_421c() {
28114         local cnt
28115         local FIDS
28116
28117         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28118                 skip "Need MDS version at least 2.12.54"
28119
28120         test_mkdir $DIR/$tdir
28121         createmany -o $DIR/$tdir/f 3
28122         touch $DIR/$tdir/$tfile
28123         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28124         cnt=$(ls -1 $DIR/$tdir | wc -l)
28125         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28126
28127         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28128         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28129
28130         cnt=$(ls $DIR/$tdir | wc -l)
28131         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28132 }
28133 run_test 421c "rm by fid against hardlinked files"
28134
28135 test_421d() {
28136         local cnt
28137         local FIDS
28138
28139         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28140                 skip "Need MDS version at least 2.12.54"
28141
28142         test_mkdir $DIR/$tdir
28143         createmany -o $DIR/$tdir/f 4097
28144         cnt=$(ls -1 $DIR/$tdir | wc -l)
28145         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28146
28147         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28148         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28149
28150         cnt=$(ls $DIR/$tdir | wc -l)
28151         rm -rf $DIR/$tdir
28152         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28153 }
28154 run_test 421d "rmfid en masse"
28155
28156 test_421e() {
28157         local cnt
28158         local FID
28159
28160         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28161         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28162                 skip "Need MDS version at least 2.12.54"
28163
28164         mkdir -p $DIR/$tdir
28165         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28166         createmany -o $DIR/$tdir/striped_dir/f 512
28167         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28168         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28169
28170         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28171                 sed "s/[/][^:]*://g")
28172         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28173
28174         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28175         rm -rf $DIR/$tdir
28176         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28177 }
28178 run_test 421e "rmfid in DNE"
28179
28180 test_421f() {
28181         local cnt
28182         local FID
28183
28184         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28185                 skip "Need MDS version at least 2.12.54"
28186
28187         test_mkdir $DIR/$tdir
28188         touch $DIR/$tdir/f
28189         cnt=$(ls -1 $DIR/$tdir | wc -l)
28190         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28191
28192         FID=$(lfs path2fid $DIR/$tdir/f)
28193         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28194         # rmfid should fail
28195         cnt=$(ls -1 $DIR/$tdir | wc -l)
28196         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28197
28198         chmod a+rw $DIR/$tdir
28199         ls -la $DIR/$tdir
28200         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28201         # rmfid should fail
28202         cnt=$(ls -1 $DIR/$tdir | wc -l)
28203         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28204
28205         rm -f $DIR/$tdir/f
28206         $RUNAS touch $DIR/$tdir/f
28207         FID=$(lfs path2fid $DIR/$tdir/f)
28208         echo "rmfid as root"
28209         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28210         cnt=$(ls -1 $DIR/$tdir | wc -l)
28211         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28212
28213         rm -f $DIR/$tdir/f
28214         $RUNAS touch $DIR/$tdir/f
28215         cnt=$(ls -1 $DIR/$tdir | wc -l)
28216         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28217         FID=$(lfs path2fid $DIR/$tdir/f)
28218         # rmfid w/o user_fid2path mount option should fail
28219         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28220         cnt=$(ls -1 $DIR/$tdir | wc -l)
28221         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28222
28223         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28224         stack_trap "rmdir $tmpdir"
28225         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28226                 error "failed to mount client'"
28227         stack_trap "umount_client $tmpdir"
28228
28229         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28230         # rmfid should succeed
28231         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28232         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28233
28234         # rmfid shouldn't allow to remove files due to dir's permission
28235         chmod a+rwx $tmpdir/$tdir
28236         touch $tmpdir/$tdir/f
28237         ls -la $tmpdir/$tdir
28238         FID=$(lfs path2fid $tmpdir/$tdir/f)
28239         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28240         return 0
28241 }
28242 run_test 421f "rmfid checks permissions"
28243
28244 test_421g() {
28245         local cnt
28246         local FIDS
28247
28248         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28249         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28250                 skip "Need MDS version at least 2.12.54"
28251
28252         mkdir -p $DIR/$tdir
28253         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28254         createmany -o $DIR/$tdir/striped_dir/f 512
28255         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28256         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28257
28258         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28259                 sed "s/[/][^:]*://g")
28260
28261         rm -f $DIR/$tdir/striped_dir/f1*
28262         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28263         removed=$((512 - cnt))
28264
28265         # few files have been just removed, so we expect
28266         # rmfid to fail on their fids
28267         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28268         [ $removed != $errors ] && error "$errors != $removed"
28269
28270         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28271         rm -rf $DIR/$tdir
28272         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28273 }
28274 run_test 421g "rmfid to return errors properly"
28275
28276 test_421h() {
28277         local mount_other
28278         local mount_ret
28279         local rmfid_ret
28280         local old_fid
28281         local fidA
28282         local fidB
28283         local fidC
28284         local fidD
28285
28286         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28287                 skip "Need MDS version at least 2.15.53"
28288
28289         test_mkdir $DIR/$tdir
28290         test_mkdir $DIR/$tdir/subdir
28291         touch $DIR/$tdir/subdir/file0
28292         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28293         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28294         rm -f $DIR/$tdir/subdir/file0
28295         touch $DIR/$tdir/subdir/fileA
28296         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28297         echo File $DIR/$tdir/subdir/fileA FID $fidA
28298         touch $DIR/$tdir/subdir/fileB
28299         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28300         echo File $DIR/$tdir/subdir/fileB FID $fidB
28301         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28302         touch $DIR/$tdir/subdir/fileC
28303         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28304         echo File $DIR/$tdir/subdir/fileC FID $fidC
28305         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28306         touch $DIR/$tdir/fileD
28307         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28308         echo File $DIR/$tdir/fileD FID $fidD
28309
28310         # mount another client mount point with subdirectory mount
28311         export FILESET=/$tdir/subdir
28312         mount_other=${MOUNT}_other
28313         mount_client $mount_other ${MOUNT_OPTS}
28314         mount_ret=$?
28315         export FILESET=""
28316         (( mount_ret == 0 )) || error "mount $mount_other failed"
28317
28318         echo Removing FIDs:
28319         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28320         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28321         rmfid_ret=$?
28322
28323         umount_client $mount_other || error "umount $mount_other failed"
28324
28325         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28326
28327         # fileA should have been deleted
28328         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28329
28330         # fileB should have been deleted
28331         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28332
28333         # fileC should not have been deleted, fid also exists outside of fileset
28334         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28335
28336         # fileD should not have been deleted, it exists outside of fileset
28337         stat $DIR/$tdir/fileD || error "fileD deleted"
28338 }
28339 run_test 421h "rmfid with fileset mount"
28340
28341 test_422() {
28342         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28343         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28344         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28345         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28346         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28347
28348         local amc=$(at_max_get client)
28349         local amo=$(at_max_get mds1)
28350         local timeout=`lctl get_param -n timeout`
28351
28352         at_max_set 0 client
28353         at_max_set 0 mds1
28354
28355 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28356         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28357                         fail_val=$(((2*timeout + 10)*1000))
28358         touch $DIR/$tdir/d3/file &
28359         sleep 2
28360 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28361         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28362                         fail_val=$((2*timeout + 5))
28363         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28364         local pid=$!
28365         sleep 1
28366         kill -9 $pid
28367         sleep $((2 * timeout))
28368         echo kill $pid
28369         kill -9 $pid
28370         lctl mark touch
28371         touch $DIR/$tdir/d2/file3
28372         touch $DIR/$tdir/d2/file4
28373         touch $DIR/$tdir/d2/file5
28374
28375         wait
28376         at_max_set $amc client
28377         at_max_set $amo mds1
28378
28379         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28380         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28381                 error "Watchdog is always throttled"
28382 }
28383 run_test 422 "kill a process with RPC in progress"
28384
28385 stat_test() {
28386     df -h $MOUNT &
28387     df -h $MOUNT &
28388     df -h $MOUNT &
28389     df -h $MOUNT &
28390     df -h $MOUNT &
28391     df -h $MOUNT &
28392 }
28393
28394 test_423() {
28395     local _stats
28396     # ensure statfs cache is expired
28397     sleep 2;
28398
28399     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28400     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28401
28402     return 0
28403 }
28404 run_test 423 "statfs should return a right data"
28405
28406 test_424() {
28407 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28408         $LCTL set_param fail_loc=0x80000522
28409         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28410         rm -f $DIR/$tfile
28411 }
28412 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28413
28414 test_425() {
28415         test_mkdir -c -1 $DIR/$tdir
28416         $LFS setstripe -c -1 $DIR/$tdir
28417
28418         lru_resize_disable "" 100
28419         stack_trap "lru_resize_enable" EXIT
28420
28421         sleep 5
28422
28423         for i in $(seq $((MDSCOUNT * 125))); do
28424                 local t=$DIR/$tdir/$tfile_$i
28425
28426                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28427                         error_noexit "Create file $t"
28428         done
28429         stack_trap "rm -rf $DIR/$tdir" EXIT
28430
28431         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28432                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28433                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28434
28435                 [ $lock_count -le $lru_size ] ||
28436                         error "osc lock count $lock_count > lru size $lru_size"
28437         done
28438
28439         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28440                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28441                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28442
28443                 [ $lock_count -le $lru_size ] ||
28444                         error "mdc lock count $lock_count > lru size $lru_size"
28445         done
28446 }
28447 run_test 425 "lock count should not exceed lru size"
28448
28449 test_426() {
28450         splice-test -r $DIR/$tfile
28451         splice-test -rd $DIR/$tfile
28452         splice-test $DIR/$tfile
28453         splice-test -d $DIR/$tfile
28454 }
28455 run_test 426 "splice test on Lustre"
28456
28457 test_427() {
28458         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28459         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28460                 skip "Need MDS version at least 2.12.4"
28461         local log
28462
28463         mkdir $DIR/$tdir
28464         mkdir $DIR/$tdir/1
28465         mkdir $DIR/$tdir/2
28466         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28467         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28468
28469         $LFS getdirstripe $DIR/$tdir/1/dir
28470
28471         #first setfattr for creating updatelog
28472         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28473
28474 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28475         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28476         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28477         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28478
28479         sleep 2
28480         fail mds2
28481         wait_recovery_complete mds2 $((2*TIMEOUT))
28482
28483         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28484         echo $log | grep "get update log failed" &&
28485                 error "update log corruption is detected" || true
28486 }
28487 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28488
28489 test_428() {
28490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28491         local cache_limit=$CACHE_MAX
28492
28493         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28494         $LCTL set_param -n llite.*.max_cached_mb=64
28495
28496         mkdir $DIR/$tdir
28497         $LFS setstripe -c 1 $DIR/$tdir
28498         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28499         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28500         #test write
28501         for f in $(seq 4); do
28502                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28503         done
28504         wait
28505
28506         cancel_lru_locks osc
28507         # Test read
28508         for f in $(seq 4); do
28509                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28510         done
28511         wait
28512 }
28513 run_test 428 "large block size IO should not hang"
28514
28515 test_429() { # LU-7915 / LU-10948
28516         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28517         local testfile=$DIR/$tfile
28518         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28519         local new_flag=1
28520         local first_rpc
28521         local second_rpc
28522         local third_rpc
28523
28524         $LCTL get_param $ll_opencache_threshold_count ||
28525                 skip "client does not have opencache parameter"
28526
28527         set_opencache $new_flag
28528         stack_trap "restore_opencache"
28529         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28530                 error "enable opencache failed"
28531         touch $testfile
28532         # drop MDC DLM locks
28533         cancel_lru_locks mdc
28534         # clear MDC RPC stats counters
28535         $LCTL set_param $mdc_rpcstats=clear
28536
28537         # According to the current implementation, we need to run 3 times
28538         # open & close file to verify if opencache is enabled correctly.
28539         # 1st, RPCs are sent for lookup/open and open handle is released on
28540         #      close finally.
28541         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28542         #      so open handle won't be released thereafter.
28543         # 3rd, No RPC is sent out.
28544         $MULTIOP $testfile oc || error "multiop failed"
28545         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28546         echo "1st: $first_rpc RPCs in flight"
28547
28548         $MULTIOP $testfile oc || error "multiop failed"
28549         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28550         echo "2nd: $second_rpc RPCs in flight"
28551
28552         $MULTIOP $testfile oc || error "multiop failed"
28553         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28554         echo "3rd: $third_rpc RPCs in flight"
28555
28556         #verify no MDC RPC is sent
28557         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28558 }
28559 run_test 429 "verify if opencache flag on client side does work"
28560
28561 lseek_test_430() {
28562         local offset
28563         local file=$1
28564
28565         # data at [200K, 400K)
28566         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28567                 error "256K->512K dd fails"
28568         # data at [2M, 3M)
28569         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28570                 error "2M->3M dd fails"
28571         # data at [4M, 5M)
28572         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28573                 error "4M->5M dd fails"
28574         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28575         # start at first component hole #1
28576         printf "Seeking hole from 1000 ... "
28577         offset=$(lseek_test -l 1000 $file)
28578         echo $offset
28579         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28580         printf "Seeking data from 1000 ... "
28581         offset=$(lseek_test -d 1000 $file)
28582         echo $offset
28583         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28584
28585         # start at first component data block
28586         printf "Seeking hole from 300000 ... "
28587         offset=$(lseek_test -l 300000 $file)
28588         echo $offset
28589         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28590         printf "Seeking data from 300000 ... "
28591         offset=$(lseek_test -d 300000 $file)
28592         echo $offset
28593         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28594
28595         # start at the first component but beyond end of object size
28596         printf "Seeking hole from 1000000 ... "
28597         offset=$(lseek_test -l 1000000 $file)
28598         echo $offset
28599         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28600         printf "Seeking data from 1000000 ... "
28601         offset=$(lseek_test -d 1000000 $file)
28602         echo $offset
28603         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28604
28605         # start at second component stripe 2 (empty file)
28606         printf "Seeking hole from 1500000 ... "
28607         offset=$(lseek_test -l 1500000 $file)
28608         echo $offset
28609         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28610         printf "Seeking data from 1500000 ... "
28611         offset=$(lseek_test -d 1500000 $file)
28612         echo $offset
28613         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28614
28615         # start at second component stripe 1 (all data)
28616         printf "Seeking hole from 3000000 ... "
28617         offset=$(lseek_test -l 3000000 $file)
28618         echo $offset
28619         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28620         printf "Seeking data from 3000000 ... "
28621         offset=$(lseek_test -d 3000000 $file)
28622         echo $offset
28623         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28624
28625         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28626                 error "2nd dd fails"
28627         echo "Add data block at 640K...1280K"
28628
28629         # start at before new data block, in hole
28630         printf "Seeking hole from 600000 ... "
28631         offset=$(lseek_test -l 600000 $file)
28632         echo $offset
28633         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28634         printf "Seeking data from 600000 ... "
28635         offset=$(lseek_test -d 600000 $file)
28636         echo $offset
28637         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28638
28639         # start at the first component new data block
28640         printf "Seeking hole from 1000000 ... "
28641         offset=$(lseek_test -l 1000000 $file)
28642         echo $offset
28643         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28644         printf "Seeking data from 1000000 ... "
28645         offset=$(lseek_test -d 1000000 $file)
28646         echo $offset
28647         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28648
28649         # start at second component stripe 2, new data
28650         printf "Seeking hole from 1200000 ... "
28651         offset=$(lseek_test -l 1200000 $file)
28652         echo $offset
28653         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28654         printf "Seeking data from 1200000 ... "
28655         offset=$(lseek_test -d 1200000 $file)
28656         echo $offset
28657         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28658
28659         # start beyond file end
28660         printf "Using offset > filesize ... "
28661         lseek_test -l 4000000 $file && error "lseek should fail"
28662         printf "Using offset > filesize ... "
28663         lseek_test -d 4000000 $file && error "lseek should fail"
28664
28665         printf "Done\n\n"
28666 }
28667
28668 test_430a() {
28669         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28670                 skip "MDT does not support SEEK_HOLE"
28671
28672         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28673                 skip "OST does not support SEEK_HOLE"
28674
28675         local file=$DIR/$tdir/$tfile
28676
28677         mkdir -p $DIR/$tdir
28678
28679         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28680         # OST stripe #1 will have continuous data at [1M, 3M)
28681         # OST stripe #2 is empty
28682         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28683         lseek_test_430 $file
28684         rm $file
28685         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28686         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28687         lseek_test_430 $file
28688         rm $file
28689         $LFS setstripe -c2 -S 512K $file
28690         echo "Two stripes, stripe size 512K"
28691         lseek_test_430 $file
28692         rm $file
28693         # FLR with stale mirror
28694         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28695                        -N -c2 -S 1M $file
28696         echo "Mirrored file:"
28697         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28698         echo "Plain 2 stripes 1M"
28699         lseek_test_430 $file
28700         rm $file
28701 }
28702 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28703
28704 test_430b() {
28705         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28706                 skip "OST does not support SEEK_HOLE"
28707
28708         local offset
28709         local file=$DIR/$tdir/$tfile
28710
28711         mkdir -p $DIR/$tdir
28712         # Empty layout lseek should fail
28713         $MCREATE $file
28714         # seek from 0
28715         printf "Seeking hole from 0 ... "
28716         lseek_test -l 0 $file && error "lseek should fail"
28717         printf "Seeking data from 0 ... "
28718         lseek_test -d 0 $file && error "lseek should fail"
28719         rm $file
28720
28721         # 1M-hole file
28722         $LFS setstripe -E 1M -c2 -E eof $file
28723         $TRUNCATE $file 1048576
28724         printf "Seeking hole from 1000000 ... "
28725         offset=$(lseek_test -l 1000000 $file)
28726         echo $offset
28727         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28728         printf "Seeking data from 1000000 ... "
28729         lseek_test -d 1000000 $file && error "lseek should fail"
28730         rm $file
28731
28732         # full component followed by non-inited one
28733         $LFS setstripe -E 1M -c2 -E eof $file
28734         dd if=/dev/urandom of=$file bs=1M count=1
28735         printf "Seeking hole from 1000000 ... "
28736         offset=$(lseek_test -l 1000000 $file)
28737         echo $offset
28738         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28739         printf "Seeking hole from 1048576 ... "
28740         lseek_test -l 1048576 $file && error "lseek should fail"
28741         # init second component and truncate back
28742         echo "123" >> $file
28743         $TRUNCATE $file 1048576
28744         printf "Seeking hole from 1000000 ... "
28745         offset=$(lseek_test -l 1000000 $file)
28746         echo $offset
28747         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28748         printf "Seeking hole from 1048576 ... "
28749         lseek_test -l 1048576 $file && error "lseek should fail"
28750         # boundary checks for big values
28751         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28752         offset=$(lseek_test -d 0 $file.10g)
28753         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28754         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28755         offset=$(lseek_test -d 0 $file.100g)
28756         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28757         return 0
28758 }
28759 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28760
28761 test_430c() {
28762         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28763                 skip "OST does not support SEEK_HOLE"
28764
28765         local file=$DIR/$tdir/$tfile
28766         local start
28767
28768         mkdir -p $DIR/$tdir
28769         stack_trap "rm -f $file $file.tmp"
28770         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28771
28772         # cp version 8.33+ prefers lseek over fiemap
28773         local ver=$(cp --version | awk '{ print $4; exit; }')
28774
28775         echo "cp $ver installed"
28776         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28777                 start=$SECONDS
28778                 time cp -v $file $file.tmp || error "cp $file failed"
28779                 (( SECONDS - start < 5 )) || {
28780                         strace cp $file $file.tmp |&
28781                                 grep -E "open|read|seek|FIEMAP" |
28782                                 grep -A 100 $file
28783                         error "cp: too long runtime $((SECONDS - start))"
28784                 }
28785         else
28786                 echo "cp test skipped due to $ver < 8.33"
28787         fi
28788
28789         # tar version 1.29+ supports SEEK_HOLE/DATA
28790         ver=$(tar --version | awk '{ print $4; exit; }')
28791         echo "tar $ver installed"
28792         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28793                 start=$SECONDS
28794                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28795                 (( SECONDS - start < 5 )) || {
28796                         strace tar cf $file.tmp --sparse $file |&
28797                                 grep -E "open|read|seek|FIEMAP" |
28798                                 grep -A 100 $file
28799                         error "tar: too long runtime $((SECONDS - start))"
28800                 }
28801         else
28802                 echo "tar test skipped due to $ver < 1.29"
28803         fi
28804 }
28805 run_test 430c "lseek: external tools check"
28806
28807 test_431() { # LU-14187
28808         local file=$DIR/$tdir/$tfile
28809
28810         mkdir -p $DIR/$tdir
28811         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28812         dd if=/dev/urandom of=$file bs=4k count=1
28813         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28814         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28815         #define OBD_FAIL_OST_RESTART_IO 0x251
28816         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28817         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28818         cp $file $file.0
28819         cancel_lru_locks
28820         sync_all_data
28821         echo 3 > /proc/sys/vm/drop_caches
28822         diff  $file $file.0 || error "data diff"
28823 }
28824 run_test 431 "Restart transaction for IO"
28825
28826 cleanup_test_432() {
28827         do_facet mgs $LCTL nodemap_activate 0
28828         wait_nm_sync active
28829 }
28830
28831 test_432() {
28832         local tmpdir=$TMP/dir432
28833
28834         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28835                 skip "Need MDS version at least 2.14.52"
28836
28837         stack_trap cleanup_test_432 EXIT
28838         mkdir $DIR/$tdir
28839         mkdir $tmpdir
28840
28841         do_facet mgs $LCTL nodemap_activate 1
28842         wait_nm_sync active
28843         do_facet mgs $LCTL nodemap_modify --name default \
28844                 --property admin --value 1
28845         do_facet mgs $LCTL nodemap_modify --name default \
28846                 --property trusted --value 1
28847         cancel_lru_locks mdc
28848         wait_nm_sync default admin_nodemap
28849         wait_nm_sync default trusted_nodemap
28850
28851         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28852                grep -ci "Operation not permitted") -ne 0 ]; then
28853                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28854         fi
28855 }
28856 run_test 432 "mv dir from outside Lustre"
28857
28858 test_433() {
28859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28860
28861         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28862                 skip "inode cache not supported"
28863
28864         $LCTL set_param llite.*.inode_cache=0
28865         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28866
28867         local count=256
28868         local before
28869         local after
28870
28871         cancel_lru_locks mdc
28872         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28873         createmany -m $DIR/$tdir/f $count
28874         createmany -d $DIR/$tdir/d $count
28875         ls -l $DIR/$tdir > /dev/null
28876         stack_trap "rm -rf $DIR/$tdir"
28877
28878         before=$(num_objects)
28879         cancel_lru_locks mdc
28880         after=$(num_objects)
28881
28882         # sometimes even @before is less than 2 * count
28883         while (( before - after < count )); do
28884                 sleep 1
28885                 after=$(num_objects)
28886                 wait=$((wait + 1))
28887                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28888                 if (( wait > 60 )); then
28889                         error "inode slab grew from $before to $after"
28890                 fi
28891         done
28892
28893         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28894 }
28895 run_test 433 "ldlm lock cancel releases dentries and inodes"
28896
28897 test_434() {
28898         local file
28899         local getxattr_count
28900         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28901         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28902
28903         [[ $(getenforce) == "Disabled" ]] ||
28904                 skip "lsm selinux module have to be disabled for this test"
28905
28906         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28907                 error "fail to create $DIR/$tdir/ on MDT0000"
28908
28909         touch $DIR/$tdir/$tfile-{001..100}
28910
28911         # disable the xattr cache
28912         save_lustre_params client "llite.*.xattr_cache" > $p
28913         lctl set_param llite.*.xattr_cache=0
28914         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28915
28916         # clear clients mdc stats
28917         clear_stats $mdc_stat_param ||
28918                 error "fail to clear stats on mdc MDT0000"
28919
28920         for file in $DIR/$tdir/$tfile-{001..100}; do
28921                 getfattr -n security.selinux $file |&
28922                         grep -q "Operation not supported" ||
28923                         error "getxattr on security.selinux should return EOPNOTSUPP"
28924         done
28925
28926         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28927         (( getxattr_count < 100 )) ||
28928                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28929 }
28930 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28931
28932 test_440() {
28933         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28934                 source $LUSTRE/scripts/bash-completion/lustre
28935         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28936                 source /usr/share/bash-completion/completions/lustre
28937         else
28938                 skip "bash completion scripts not found"
28939         fi
28940
28941         local lctl_completions
28942         local lfs_completions
28943
28944         lctl_completions=$(_lustre_cmds lctl)
28945         if [[ ! $lctl_completions =~ "get_param" ]]; then
28946                 error "lctl bash completion failed"
28947         fi
28948
28949         lfs_completions=$(_lustre_cmds lfs)
28950         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28951                 error "lfs bash completion failed"
28952         fi
28953 }
28954 run_test 440 "bash completion for lfs, lctl"
28955
28956 prep_801() {
28957         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28958         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28959                 skip "Need server version at least 2.9.55"
28960
28961         start_full_debug_logging
28962 }
28963
28964 post_801() {
28965         stop_full_debug_logging
28966 }
28967
28968 barrier_stat() {
28969         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28970                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28971                            awk '/The barrier for/ { print $7 }')
28972                 echo $st
28973         else
28974                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28975                 echo \'$st\'
28976         fi
28977 }
28978
28979 barrier_expired() {
28980         local expired
28981
28982         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28983                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28984                           awk '/will be expired/ { print $7 }')
28985         else
28986                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28987         fi
28988
28989         echo $expired
28990 }
28991
28992 test_801a() {
28993         prep_801
28994
28995         echo "Start barrier_freeze at: $(date)"
28996         #define OBD_FAIL_BARRIER_DELAY          0x2202
28997         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28998         # Do not reduce barrier time - See LU-11873
28999         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29000
29001         sleep 2
29002         local b_status=$(barrier_stat)
29003         echo "Got barrier status at: $(date)"
29004         [ "$b_status" = "'freezing_p1'" ] ||
29005                 error "(1) unexpected barrier status $b_status"
29006
29007         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29008         wait
29009         b_status=$(barrier_stat)
29010         [ "$b_status" = "'frozen'" ] ||
29011                 error "(2) unexpected barrier status $b_status"
29012
29013         local expired=$(barrier_expired)
29014         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29015         sleep $((expired + 3))
29016
29017         b_status=$(barrier_stat)
29018         [ "$b_status" = "'expired'" ] ||
29019                 error "(3) unexpected barrier status $b_status"
29020
29021         # Do not reduce barrier time - See LU-11873
29022         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29023                 error "(4) fail to freeze barrier"
29024
29025         b_status=$(barrier_stat)
29026         [ "$b_status" = "'frozen'" ] ||
29027                 error "(5) unexpected barrier status $b_status"
29028
29029         echo "Start barrier_thaw at: $(date)"
29030         #define OBD_FAIL_BARRIER_DELAY          0x2202
29031         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29032         do_facet mgs $LCTL barrier_thaw $FSNAME &
29033
29034         sleep 2
29035         b_status=$(barrier_stat)
29036         echo "Got barrier status at: $(date)"
29037         [ "$b_status" = "'thawing'" ] ||
29038                 error "(6) unexpected barrier status $b_status"
29039
29040         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29041         wait
29042         b_status=$(barrier_stat)
29043         [ "$b_status" = "'thawed'" ] ||
29044                 error "(7) unexpected barrier status $b_status"
29045
29046         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29047         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29048         do_facet mgs $LCTL barrier_freeze $FSNAME
29049
29050         b_status=$(barrier_stat)
29051         [ "$b_status" = "'failed'" ] ||
29052                 error "(8) unexpected barrier status $b_status"
29053
29054         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29055         do_facet mgs $LCTL barrier_thaw $FSNAME
29056
29057         post_801
29058 }
29059 run_test 801a "write barrier user interfaces and stat machine"
29060
29061 test_801b() {
29062         prep_801
29063
29064         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29065         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29066         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29067         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29068         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29069
29070         cancel_lru_locks mdc
29071
29072         # 180 seconds should be long enough
29073         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29074
29075         local b_status=$(barrier_stat)
29076         [ "$b_status" = "'frozen'" ] ||
29077                 error "(6) unexpected barrier status $b_status"
29078
29079         mkdir $DIR/$tdir/d0/d10 &
29080         mkdir_pid=$!
29081
29082         touch $DIR/$tdir/d1/f13 &
29083         touch_pid=$!
29084
29085         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29086         ln_pid=$!
29087
29088         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29089         mv_pid=$!
29090
29091         rm -f $DIR/$tdir/d4/f12 &
29092         rm_pid=$!
29093
29094         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29095
29096         # To guarantee taht the 'stat' is not blocked
29097         b_status=$(barrier_stat)
29098         [ "$b_status" = "'frozen'" ] ||
29099                 error "(8) unexpected barrier status $b_status"
29100
29101         # let above commands to run at background
29102         sleep 5
29103
29104         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29105         ps -p $touch_pid || error "(10) touch should be blocked"
29106         ps -p $ln_pid || error "(11) link should be blocked"
29107         ps -p $mv_pid || error "(12) rename should be blocked"
29108         ps -p $rm_pid || error "(13) unlink should be blocked"
29109
29110         b_status=$(barrier_stat)
29111         [ "$b_status" = "'frozen'" ] ||
29112                 error "(14) unexpected barrier status $b_status"
29113
29114         do_facet mgs $LCTL barrier_thaw $FSNAME
29115         b_status=$(barrier_stat)
29116         [ "$b_status" = "'thawed'" ] ||
29117                 error "(15) unexpected barrier status $b_status"
29118
29119         wait $mkdir_pid || error "(16) mkdir should succeed"
29120         wait $touch_pid || error "(17) touch should succeed"
29121         wait $ln_pid || error "(18) link should succeed"
29122         wait $mv_pid || error "(19) rename should succeed"
29123         wait $rm_pid || error "(20) unlink should succeed"
29124
29125         post_801
29126 }
29127 run_test 801b "modification will be blocked by write barrier"
29128
29129 test_801c() {
29130         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29131
29132         prep_801
29133
29134         stop mds2 || error "(1) Fail to stop mds2"
29135
29136         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29137
29138         local b_status=$(barrier_stat)
29139         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29140                 do_facet mgs $LCTL barrier_thaw $FSNAME
29141                 error "(2) unexpected barrier status $b_status"
29142         }
29143
29144         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29145                 error "(3) Fail to rescan barrier bitmap"
29146
29147         # Do not reduce barrier time - See LU-11873
29148         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29149
29150         b_status=$(barrier_stat)
29151         [ "$b_status" = "'frozen'" ] ||
29152                 error "(4) unexpected barrier status $b_status"
29153
29154         do_facet mgs $LCTL barrier_thaw $FSNAME
29155         b_status=$(barrier_stat)
29156         [ "$b_status" = "'thawed'" ] ||
29157                 error "(5) unexpected barrier status $b_status"
29158
29159         local devname=$(mdsdevname 2)
29160
29161         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29162
29163         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29164                 error "(7) Fail to rescan barrier bitmap"
29165
29166         post_801
29167 }
29168 run_test 801c "rescan barrier bitmap"
29169
29170 test_802b() {
29171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29172         remote_mds_nodsh && skip "remote MDS with nodsh"
29173
29174         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29175                 skip "readonly option not available"
29176
29177         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29178
29179         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29180                 error "(2) Fail to copy"
29181
29182         # write back all cached data before setting MDT to readonly
29183         cancel_lru_locks
29184         sync_all_data
29185
29186         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29187         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29188
29189         echo "Modify should be refused"
29190         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29191
29192         echo "Read should be allowed"
29193         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29194                 error "(7) Read should succeed under ro mode"
29195
29196         # disable readonly
29197         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29198 }
29199 run_test 802b "be able to set MDTs to readonly"
29200
29201 test_803a() {
29202         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29203         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29204                 skip "MDS needs to be newer than 2.10.54"
29205
29206         mkdir_on_mdt0 $DIR/$tdir
29207         # Create some objects on all MDTs to trigger related logs objects
29208         for idx in $(seq $MDSCOUNT); do
29209                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29210                         $DIR/$tdir/dir${idx} ||
29211                         error "Fail to create $DIR/$tdir/dir${idx}"
29212         done
29213
29214         wait_delete_completed # ensure old test cleanups are finished
29215         sleep 3
29216         echo "before create:"
29217         $LFS df -i $MOUNT
29218         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29219
29220         for i in {1..10}; do
29221                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29222                         error "Fail to create $DIR/$tdir/foo$i"
29223         done
29224
29225         # sync ZFS-on-MDS to refresh statfs data
29226         wait_zfs_commit mds1
29227         sleep 3
29228         echo "after create:"
29229         $LFS df -i $MOUNT
29230         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29231
29232         # allow for an llog to be cleaned up during the test
29233         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29234                 error "before ($before_used) + 10 > after ($after_used)"
29235
29236         for i in {1..10}; do
29237                 rm -rf $DIR/$tdir/foo$i ||
29238                         error "Fail to remove $DIR/$tdir/foo$i"
29239         done
29240
29241         # sync ZFS-on-MDS to refresh statfs data
29242         wait_zfs_commit mds1
29243         wait_delete_completed
29244         sleep 3 # avoid MDT return cached statfs
29245         echo "after unlink:"
29246         $LFS df -i $MOUNT
29247         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29248
29249         # allow for an llog to be created during the test
29250         [ $after_used -le $((before_used + 1)) ] ||
29251                 error "after ($after_used) > before ($before_used) + 1"
29252 }
29253 run_test 803a "verify agent object for remote object"
29254
29255 test_803b() {
29256         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29257         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29258                 skip "MDS needs to be newer than 2.13.56"
29259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29260
29261         for i in $(seq 0 $((MDSCOUNT - 1))); do
29262                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29263         done
29264
29265         local before=0
29266         local after=0
29267
29268         local tmp
29269
29270         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29271         for i in $(seq 0 $((MDSCOUNT - 1))); do
29272                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29273                         awk '/getattr/ { print $2 }')
29274                 before=$((before + tmp))
29275         done
29276         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29277         for i in $(seq 0 $((MDSCOUNT - 1))); do
29278                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29279                         awk '/getattr/ { print $2 }')
29280                 after=$((after + tmp))
29281         done
29282
29283         [ $before -eq $after ] || error "getattr count $before != $after"
29284 }
29285 run_test 803b "remote object can getattr from cache"
29286
29287 test_804() {
29288         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29289         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29290                 skip "MDS needs to be newer than 2.10.54"
29291         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29292
29293         mkdir -p $DIR/$tdir
29294         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29295                 error "Fail to create $DIR/$tdir/dir0"
29296
29297         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29298         local dev=$(mdsdevname 2)
29299
29300         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29301                 grep ${fid} || error "NOT found agent entry for dir0"
29302
29303         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29304                 error "Fail to create $DIR/$tdir/dir1"
29305
29306         touch $DIR/$tdir/dir1/foo0 ||
29307                 error "Fail to create $DIR/$tdir/dir1/foo0"
29308         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29309         local rc=0
29310
29311         for idx in $(seq $MDSCOUNT); do
29312                 dev=$(mdsdevname $idx)
29313                 do_facet mds${idx} \
29314                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29315                         grep ${fid} && rc=$idx
29316         done
29317
29318         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29319                 error "Fail to rename foo0 to foo1"
29320         if [ $rc -eq 0 ]; then
29321                 for idx in $(seq $MDSCOUNT); do
29322                         dev=$(mdsdevname $idx)
29323                         do_facet mds${idx} \
29324                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29325                         grep ${fid} && rc=$idx
29326                 done
29327         fi
29328
29329         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29330                 error "Fail to rename foo1 to foo2"
29331         if [ $rc -eq 0 ]; then
29332                 for idx in $(seq $MDSCOUNT); do
29333                         dev=$(mdsdevname $idx)
29334                         do_facet mds${idx} \
29335                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29336                         grep ${fid} && rc=$idx
29337                 done
29338         fi
29339
29340         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29341
29342         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29343                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29344         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29345                 error "Fail to rename foo2 to foo0"
29346         unlink $DIR/$tdir/dir1/foo0 ||
29347                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29348         rm -rf $DIR/$tdir/dir0 ||
29349                 error "Fail to rm $DIR/$tdir/dir0"
29350
29351         for idx in $(seq $MDSCOUNT); do
29352                 rc=0
29353
29354                 stop mds${idx}
29355                 dev=$(mdsdevname $idx)
29356                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29357                         rc=$?
29358                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29359                         error "mount mds$idx failed"
29360                 df $MOUNT > /dev/null 2>&1
29361
29362                 # e2fsck should not return error
29363                 [ $rc -eq 0 ] ||
29364                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29365         done
29366 }
29367 run_test 804 "verify agent entry for remote entry"
29368
29369 cleanup_805() {
29370         do_facet $SINGLEMDS zfs set quota=$old $fsset
29371         unlinkmany $DIR/$tdir/f- 1000000
29372         trap 0
29373 }
29374
29375 test_805() {
29376         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29377         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29378         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29379                 skip "netfree not implemented before 0.7"
29380         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29381                 skip "Need MDS version at least 2.10.57"
29382
29383         local fsset
29384         local freekb
29385         local usedkb
29386         local old
29387         local quota
29388         local pref="osd-zfs.$FSNAME-MDT0000."
29389
29390         # limit available space on MDS dataset to meet nospace issue
29391         # quickly. then ZFS 0.7.2 can use reserved space if asked
29392         # properly (using netfree flag in osd_declare_destroy()
29393         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29394         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29395                 gawk '{print $3}')
29396         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29397         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29398         let "usedkb=usedkb-freekb"
29399         let "freekb=freekb/2"
29400         if let "freekb > 5000"; then
29401                 let "freekb=5000"
29402         fi
29403         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29404         trap cleanup_805 EXIT
29405         mkdir_on_mdt0 $DIR/$tdir
29406         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29407                 error "Can't set PFL layout"
29408         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29409         rm -rf $DIR/$tdir || error "not able to remove"
29410         do_facet $SINGLEMDS zfs set quota=$old $fsset
29411         trap 0
29412 }
29413 run_test 805 "ZFS can remove from full fs"
29414
29415 # Size-on-MDS test
29416 check_lsom_data()
29417 {
29418         local file=$1
29419         local expect=$(stat -c %s $file)
29420
29421         check_lsom_size $1 $expect
29422
29423         local blocks=$($LFS getsom -b $file)
29424         expect=$(stat -c %b $file)
29425         [[ $blocks == $expect ]] ||
29426                 error "$file expected blocks: $expect, got: $blocks"
29427 }
29428
29429 check_lsom_size()
29430 {
29431         local size
29432         local expect=$2
29433
29434         cancel_lru_locks mdc
29435
29436         size=$($LFS getsom -s $1)
29437         [[ $size == $expect ]] ||
29438                 error "$file expected size: $expect, got: $size"
29439 }
29440
29441 test_806() {
29442         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29443                 skip "Need MDS version at least 2.11.52"
29444
29445         local bs=1048576
29446
29447         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29448
29449         disable_opencache
29450         stack_trap "restore_opencache"
29451
29452         # single-threaded write
29453         echo "Test SOM for single-threaded write"
29454         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29455                 error "write $tfile failed"
29456         check_lsom_size $DIR/$tfile $bs
29457
29458         local num=32
29459         local size=$(($num * $bs))
29460         local offset=0
29461         local i
29462
29463         echo "Test SOM for single client multi-threaded($num) write"
29464         $TRUNCATE $DIR/$tfile 0
29465         for ((i = 0; i < $num; i++)); do
29466                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29467                 local pids[$i]=$!
29468                 offset=$((offset + $bs))
29469         done
29470         for (( i=0; i < $num; i++ )); do
29471                 wait ${pids[$i]}
29472         done
29473         check_lsom_size $DIR/$tfile $size
29474
29475         $TRUNCATE $DIR/$tfile 0
29476         for ((i = 0; i < $num; i++)); do
29477                 offset=$((offset - $bs))
29478                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29479                 local pids[$i]=$!
29480         done
29481         for (( i=0; i < $num; i++ )); do
29482                 wait ${pids[$i]}
29483         done
29484         check_lsom_size $DIR/$tfile $size
29485
29486         # multi-client writes
29487         num=$(get_node_count ${CLIENTS//,/ })
29488         size=$(($num * $bs))
29489         offset=0
29490         i=0
29491
29492         echo "Test SOM for multi-client ($num) writes"
29493         $TRUNCATE $DIR/$tfile 0
29494         for client in ${CLIENTS//,/ }; do
29495                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29496                 local pids[$i]=$!
29497                 i=$((i + 1))
29498                 offset=$((offset + $bs))
29499         done
29500         for (( i=0; i < $num; i++ )); do
29501                 wait ${pids[$i]}
29502         done
29503         check_lsom_size $DIR/$tfile $offset
29504
29505         i=0
29506         $TRUNCATE $DIR/$tfile 0
29507         for client in ${CLIENTS//,/ }; do
29508                 offset=$((offset - $bs))
29509                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29510                 local pids[$i]=$!
29511                 i=$((i + 1))
29512         done
29513         for (( i=0; i < $num; i++ )); do
29514                 wait ${pids[$i]}
29515         done
29516         check_lsom_size $DIR/$tfile $size
29517
29518         # verify SOM blocks count
29519         echo "Verify SOM block count"
29520         $TRUNCATE $DIR/$tfile 0
29521         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29522                 error "failed to write file $tfile with fdatasync and fstat"
29523         check_lsom_data $DIR/$tfile
29524
29525         $TRUNCATE $DIR/$tfile 0
29526         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29527                 error "failed to write file $tfile with fdatasync"
29528         check_lsom_data $DIR/$tfile
29529
29530         $TRUNCATE $DIR/$tfile 0
29531         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29532                 error "failed to write file $tfile with sync IO"
29533         check_lsom_data $DIR/$tfile
29534
29535         # verify truncate
29536         echo "Test SOM for truncate"
29537         # use ftruncate to sync blocks on close request
29538         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29539         check_lsom_size $DIR/$tfile 16384
29540         check_lsom_data $DIR/$tfile
29541
29542         $TRUNCATE $DIR/$tfile 1234
29543         check_lsom_size $DIR/$tfile 1234
29544         # sync blocks on the MDT
29545         $MULTIOP $DIR/$tfile oc
29546         check_lsom_data $DIR/$tfile
29547 }
29548 run_test 806 "Verify Lazy Size on MDS"
29549
29550 test_807() {
29551         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29552         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29553                 skip "Need MDS version at least 2.11.52"
29554
29555         # Registration step
29556         changelog_register || error "changelog_register failed"
29557         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29558         changelog_users $SINGLEMDS | grep -q $cl_user ||
29559                 error "User $cl_user not found in changelog_users"
29560
29561         rm -rf $DIR/$tdir || error "rm $tdir failed"
29562         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29563         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29564         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29565         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29566                 error "truncate $tdir/trunc failed"
29567
29568         local bs=1048576
29569         echo "Test SOM for single-threaded write with fsync"
29570         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29571                 error "write $tfile failed"
29572         sync;sync;sync
29573
29574         # multi-client wirtes
29575         local num=$(get_node_count ${CLIENTS//,/ })
29576         local offset=0
29577         local i=0
29578
29579         echo "Test SOM for multi-client ($num) writes"
29580         touch $DIR/$tfile || error "touch $tfile failed"
29581         $TRUNCATE $DIR/$tfile 0
29582         for client in ${CLIENTS//,/ }; do
29583                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29584                 local pids[$i]=$!
29585                 i=$((i + 1))
29586                 offset=$((offset + $bs))
29587         done
29588         for (( i=0; i < $num; i++ )); do
29589                 wait ${pids[$i]}
29590         done
29591
29592         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29593         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29594         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29595         check_lsom_data $DIR/$tdir/trunc
29596         check_lsom_data $DIR/$tdir/single_dd
29597         check_lsom_data $DIR/$tfile
29598
29599         rm -rf $DIR/$tdir
29600         # Deregistration step
29601         changelog_deregister || error "changelog_deregister failed"
29602 }
29603 run_test 807 "verify LSOM syncing tool"
29604
29605 check_som_nologged()
29606 {
29607         local lines=$($LFS changelog $FSNAME-MDT0000 |
29608                 grep 'x=trusted.som' | wc -l)
29609         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29610 }
29611
29612 test_808() {
29613         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29614                 skip "Need MDS version at least 2.11.55"
29615
29616         # Registration step
29617         changelog_register || error "changelog_register failed"
29618
29619         touch $DIR/$tfile || error "touch $tfile failed"
29620         check_som_nologged
29621
29622         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29623                 error "write $tfile failed"
29624         check_som_nologged
29625
29626         $TRUNCATE $DIR/$tfile 1234
29627         check_som_nologged
29628
29629         $TRUNCATE $DIR/$tfile 1048576
29630         check_som_nologged
29631
29632         # Deregistration step
29633         changelog_deregister || error "changelog_deregister failed"
29634 }
29635 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29636
29637 check_som_nodata()
29638 {
29639         $LFS getsom $1
29640         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29641 }
29642
29643 test_809() {
29644         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29645                 skip "Need MDS version at least 2.11.56"
29646
29647         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29648                 error "failed to create DoM-only file $DIR/$tfile"
29649         touch $DIR/$tfile || error "touch $tfile failed"
29650         check_som_nodata $DIR/$tfile
29651
29652         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29653                 error "write $tfile failed"
29654         check_som_nodata $DIR/$tfile
29655
29656         $TRUNCATE $DIR/$tfile 1234
29657         check_som_nodata $DIR/$tfile
29658
29659         $TRUNCATE $DIR/$tfile 4097
29660         check_som_nodata $DIR/$file
29661 }
29662 run_test 809 "Verify no SOM xattr store for DoM-only files"
29663
29664 test_810() {
29665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29666         $GSS && skip_env "could not run with gss"
29667         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29668                 skip "OST < 2.12.58 doesn't align checksum"
29669
29670         set_checksums 1
29671         stack_trap "set_checksums $ORIG_CSUM" EXIT
29672         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29673
29674         local csum
29675         local before
29676         local after
29677         for csum in $CKSUM_TYPES; do
29678                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29679                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29680                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29681                         eval set -- $i
29682                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29683                         before=$(md5sum $DIR/$tfile)
29684                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29685                         after=$(md5sum $DIR/$tfile)
29686                         [ "$before" == "$after" ] ||
29687                                 error "$csum: $before != $after bs=$1 seek=$2"
29688                 done
29689         done
29690 }
29691 run_test 810 "partial page writes on ZFS (LU-11663)"
29692
29693 test_812a() {
29694         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29695                 skip "OST < 2.12.51 doesn't support this fail_loc"
29696
29697         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29698         # ensure ost1 is connected
29699         stat $DIR/$tfile >/dev/null || error "can't stat"
29700         wait_osc_import_state client ost1 FULL
29701         # no locks, no reqs to let the connection idle
29702         cancel_lru_locks osc
29703
29704         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29705 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29706         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29707         wait_osc_import_state client ost1 CONNECTING
29708         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29709
29710         stat $DIR/$tfile >/dev/null || error "can't stat file"
29711 }
29712 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29713
29714 test_812b() { # LU-12378
29715         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29716                 skip "OST < 2.12.51 doesn't support this fail_loc"
29717
29718         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29719         # ensure ost1 is connected
29720         stat $DIR/$tfile >/dev/null || error "can't stat"
29721         wait_osc_import_state client ost1 FULL
29722         # no locks, no reqs to let the connection idle
29723         cancel_lru_locks osc
29724
29725         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29726 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29727         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29728         wait_osc_import_state client ost1 CONNECTING
29729         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29730
29731         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29732         wait_osc_import_state client ost1 IDLE
29733 }
29734 run_test 812b "do not drop no resend request for idle connect"
29735
29736 test_812c() {
29737         local old
29738
29739         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29740
29741         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29742         $LFS getstripe $DIR/$tfile
29743         $LCTL set_param osc.*.idle_timeout=10
29744         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29745         # ensure ost1 is connected
29746         stat $DIR/$tfile >/dev/null || error "can't stat"
29747         wait_osc_import_state client ost1 FULL
29748         # no locks, no reqs to let the connection idle
29749         cancel_lru_locks osc
29750
29751 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29752         $LCTL set_param fail_loc=0x80000533
29753         sleep 15
29754         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29755 }
29756 run_test 812c "idle import vs lock enqueue race"
29757
29758 test_813() {
29759         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29760         [ -z "$file_heat_sav" ] && skip "no file heat support"
29761
29762         local readsample
29763         local writesample
29764         local readbyte
29765         local writebyte
29766         local readsample1
29767         local writesample1
29768         local readbyte1
29769         local writebyte1
29770
29771         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29772         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29773
29774         $LCTL set_param -n llite.*.file_heat=1
29775         echo "Turn on file heat"
29776         echo "Period second: $period_second, Decay percentage: $decay_pct"
29777
29778         echo "QQQQ" > $DIR/$tfile
29779         echo "QQQQ" > $DIR/$tfile
29780         echo "QQQQ" > $DIR/$tfile
29781         cat $DIR/$tfile > /dev/null
29782         cat $DIR/$tfile > /dev/null
29783         cat $DIR/$tfile > /dev/null
29784         cat $DIR/$tfile > /dev/null
29785
29786         local out=$($LFS heat_get $DIR/$tfile)
29787
29788         $LFS heat_get $DIR/$tfile
29789         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29790         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29791         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29792         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29793
29794         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29795         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29796         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29797         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29798
29799         sleep $((period_second + 3))
29800         echo "Sleep $((period_second + 3)) seconds..."
29801         # The recursion formula to calculate the heat of the file f is as
29802         # follow:
29803         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29804         # Where Hi is the heat value in the period between time points i*I and
29805         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29806         # to the weight of Ci.
29807         out=$($LFS heat_get $DIR/$tfile)
29808         $LFS heat_get $DIR/$tfile
29809         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29810         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29811         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29812         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29813
29814         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29815                 error "read sample ($readsample) is wrong"
29816         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29817                 error "write sample ($writesample) is wrong"
29818         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29819                 error "read bytes ($readbyte) is wrong"
29820         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29821                 error "write bytes ($writebyte) is wrong"
29822
29823         echo "QQQQ" > $DIR/$tfile
29824         echo "QQQQ" > $DIR/$tfile
29825         echo "QQQQ" > $DIR/$tfile
29826         cat $DIR/$tfile > /dev/null
29827         cat $DIR/$tfile > /dev/null
29828         cat $DIR/$tfile > /dev/null
29829         cat $DIR/$tfile > /dev/null
29830
29831         sleep $((period_second + 3))
29832         echo "Sleep $((period_second + 3)) seconds..."
29833
29834         out=$($LFS heat_get $DIR/$tfile)
29835         $LFS heat_get $DIR/$tfile
29836         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29837         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29838         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29839         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29840
29841         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29842                 4 * $decay_pct) / 100") -eq 1 ] ||
29843                 error "read sample ($readsample1) is wrong"
29844         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29845                 3 * $decay_pct) / 100") -eq 1 ] ||
29846                 error "write sample ($writesample1) is wrong"
29847         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29848                 20 * $decay_pct) / 100") -eq 1 ] ||
29849                 error "read bytes ($readbyte1) is wrong"
29850         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29851                 15 * $decay_pct) / 100") -eq 1 ] ||
29852                 error "write bytes ($writebyte1) is wrong"
29853
29854         echo "Turn off file heat for the file $DIR/$tfile"
29855         $LFS heat_set -o $DIR/$tfile
29856
29857         echo "QQQQ" > $DIR/$tfile
29858         echo "QQQQ" > $DIR/$tfile
29859         echo "QQQQ" > $DIR/$tfile
29860         cat $DIR/$tfile > /dev/null
29861         cat $DIR/$tfile > /dev/null
29862         cat $DIR/$tfile > /dev/null
29863         cat $DIR/$tfile > /dev/null
29864
29865         out=$($LFS heat_get $DIR/$tfile)
29866         $LFS heat_get $DIR/$tfile
29867         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29868         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29869         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29870         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29871
29872         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29873         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29874         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29875         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29876
29877         echo "Trun on file heat for the file $DIR/$tfile"
29878         $LFS heat_set -O $DIR/$tfile
29879
29880         echo "QQQQ" > $DIR/$tfile
29881         echo "QQQQ" > $DIR/$tfile
29882         echo "QQQQ" > $DIR/$tfile
29883         cat $DIR/$tfile > /dev/null
29884         cat $DIR/$tfile > /dev/null
29885         cat $DIR/$tfile > /dev/null
29886         cat $DIR/$tfile > /dev/null
29887
29888         out=$($LFS heat_get $DIR/$tfile)
29889         $LFS heat_get $DIR/$tfile
29890         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29891         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29892         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29893         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29894
29895         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29896         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29897         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29898         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29899
29900         $LFS heat_set -c $DIR/$tfile
29901         $LCTL set_param -n llite.*.file_heat=0
29902         echo "Turn off file heat support for the Lustre filesystem"
29903
29904         echo "QQQQ" > $DIR/$tfile
29905         echo "QQQQ" > $DIR/$tfile
29906         echo "QQQQ" > $DIR/$tfile
29907         cat $DIR/$tfile > /dev/null
29908         cat $DIR/$tfile > /dev/null
29909         cat $DIR/$tfile > /dev/null
29910         cat $DIR/$tfile > /dev/null
29911
29912         out=$($LFS heat_get $DIR/$tfile)
29913         $LFS heat_get $DIR/$tfile
29914         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29915         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29916         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29917         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29918
29919         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29920         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29921         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29922         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29923
29924         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29925         rm -f $DIR/$tfile
29926 }
29927 run_test 813 "File heat verfication"
29928
29929 test_814()
29930 {
29931         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29932         echo -n y >> $DIR/$tfile
29933         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29934         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29935 }
29936 run_test 814 "sparse cp works as expected (LU-12361)"
29937
29938 test_815()
29939 {
29940         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29941         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29942 }
29943 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29944
29945 test_816() {
29946         local ost1_imp=$(get_osc_import_name client ost1)
29947         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29948                          cut -d'.' -f2)
29949
29950         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29951         # ensure ost1 is connected
29952
29953         stat $DIR/$tfile >/dev/null || error "can't stat"
29954         wait_osc_import_state client ost1 FULL
29955         # no locks, no reqs to let the connection idle
29956         cancel_lru_locks osc
29957         lru_resize_disable osc
29958         local before
29959         local now
29960         before=$($LCTL get_param -n \
29961                  ldlm.namespaces.$imp_name.lru_size)
29962
29963         wait_osc_import_state client ost1 IDLE
29964         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29965         now=$($LCTL get_param -n \
29966               ldlm.namespaces.$imp_name.lru_size)
29967         [ $before == $now ] || error "lru_size changed $before != $now"
29968 }
29969 run_test 816 "do not reset lru_resize on idle reconnect"
29970
29971 cleanup_817() {
29972         umount $tmpdir
29973         exportfs -u localhost:$DIR/nfsexp
29974         rm -rf $DIR/nfsexp
29975 }
29976
29977 test_817() {
29978         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29979
29980         mkdir -p $DIR/nfsexp
29981         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29982                 error "failed to export nfs"
29983
29984         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29985         stack_trap cleanup_817 EXIT
29986
29987         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29988                 error "failed to mount nfs to $tmpdir"
29989
29990         cp /bin/true $tmpdir
29991         $DIR/nfsexp/true || error "failed to execute 'true' command"
29992 }
29993 run_test 817 "nfsd won't cache write lock for exec file"
29994
29995 test_818() {
29996         test_mkdir -i0 -c1 $DIR/$tdir
29997         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29998         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29999         stop $SINGLEMDS
30000
30001         # restore osp-syn threads
30002         stack_trap "fail $SINGLEMDS"
30003
30004         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30005         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30006         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30007                 error "start $SINGLEMDS failed"
30008         rm -rf $DIR/$tdir
30009
30010         local testid=$(echo $TESTNAME | tr '_' ' ')
30011
30012         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30013                 grep "run LFSCK" || error "run LFSCK is not suggested"
30014 }
30015 run_test 818 "unlink with failed llog"
30016
30017 test_819a() {
30018         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30019         cancel_lru_locks osc
30020         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30021         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30022         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30023         rm -f $TDIR/$tfile
30024 }
30025 run_test 819a "too big niobuf in read"
30026
30027 test_819b() {
30028         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30029         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30030         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30031         cancel_lru_locks osc
30032         sleep 1
30033         rm -f $TDIR/$tfile
30034 }
30035 run_test 819b "too big niobuf in write"
30036
30037
30038 function test_820_start_ost() {
30039         sleep 5
30040
30041         for num in $(seq $OSTCOUNT); do
30042                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30043         done
30044 }
30045
30046 test_820() {
30047         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30048
30049         mkdir $DIR/$tdir
30050         umount_client $MOUNT || error "umount failed"
30051         for num in $(seq $OSTCOUNT); do
30052                 stop ost$num
30053         done
30054
30055         # mount client with no active OSTs
30056         # so that the client can't initialize max LOV EA size
30057         # from OSC notifications
30058         mount_client $MOUNT || error "mount failed"
30059         # delay OST starting to keep this 0 max EA size for a while
30060         test_820_start_ost &
30061
30062         # create a directory on MDS2
30063         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30064                 error "Failed to create directory"
30065         # open intent should update default EA size
30066         # see mdc_update_max_ea_from_body()
30067         # notice this is the very first RPC to MDS2
30068         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30069         ret=$?
30070         echo $out
30071         # With SSK, this situation can lead to -EPERM being returned.
30072         # In that case, simply retry.
30073         if [ $ret -ne 0 ] && $SHARED_KEY; then
30074                 if echo "$out" | grep -q "not permitted"; then
30075                         cp /etc/services $DIR/$tdir/mds2
30076                         ret=$?
30077                 fi
30078         fi
30079         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30080 }
30081 run_test 820 "update max EA from open intent"
30082
30083 test_823() {
30084         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30085         local OST_MAX_PRECREATE=20000
30086
30087         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30088                 skip "Need MDS version at least 2.14.56"
30089
30090         save_lustre_params mds1 \
30091                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30092         do_facet $SINGLEMDS "$LCTL set_param -n \
30093                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30094         do_facet $SINGLEMDS "$LCTL set_param -n \
30095                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30096
30097         stack_trap "restore_lustre_params < $p; rm $p"
30098
30099         do_facet $SINGLEMDS "$LCTL set_param -n \
30100                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30101
30102         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30103                       osp.$FSNAME-OST0000*MDT0000.create_count")
30104         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30105                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30106         local expect_count=$(((($max/2)/256) * 256))
30107
30108         log "setting create_count to 100200:"
30109         log " -result- count: $count with max: $max, expecting: $expect_count"
30110
30111         [[ $count -eq expect_count ]] ||
30112                 error "Create count not set to max precreate."
30113 }
30114 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30115
30116 test_831() {
30117         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30118                 skip "Need MDS version 2.14.56"
30119
30120         local sync_changes=$(do_facet $SINGLEMDS \
30121                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30122
30123         [ "$sync_changes" -gt 100 ] &&
30124                 skip "Sync changes $sync_changes > 100 already"
30125
30126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30127
30128         $LFS mkdir -i 0 $DIR/$tdir
30129         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30130
30131         save_lustre_params mds1 \
30132                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30133         save_lustre_params mds1 \
30134                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30135
30136         do_facet mds1 "$LCTL set_param -n \
30137                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30138                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30139         stack_trap "restore_lustre_params < $p" EXIT
30140
30141         createmany -o $DIR/$tdir/f- 1000
30142         unlinkmany $DIR/$tdir/f- 1000 &
30143         local UNLINK_PID=$!
30144
30145         while sleep 1; do
30146                 sync_changes=$(do_facet mds1 \
30147                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30148                 # the check in the code is racy, fail the test
30149                 # if the value above the limit by 10.
30150                 [ $sync_changes -gt 110 ] && {
30151                         kill -2 $UNLINK_PID
30152                         wait
30153                         error "osp changes throttling failed, $sync_changes>110"
30154                 }
30155                 kill -0 $UNLINK_PID 2> /dev/null || break
30156         done
30157         wait
30158 }
30159 run_test 831 "throttling unlink/setattr queuing on OSP"
30160
30161 test_832() {
30162         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30163         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30164                 skip "Need MDS version 2.15.52+"
30165         is_rmentry_supported || skip "rm_entry not supported"
30166
30167         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30168         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30169         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30170                 error "mkdir remote_dir failed"
30171         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30172                 error "mkdir striped_dir failed"
30173         touch $DIR/$tdir/file || error "touch file failed"
30174         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30175         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30176 }
30177 run_test 832 "lfs rm_entry"
30178
30179 test_833() {
30180         local file=$DIR/$tfile
30181
30182         stack_trap "rm -f $file" EXIT
30183         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30184
30185         local wpid
30186         local rpid
30187         local rpid2
30188
30189         # Buffered I/O write
30190         (
30191                 while [ ! -e $DIR/sanity.833.lck ]; do
30192                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30193                                 error "failed to write $file"
30194                         sleep 0.$((RANDOM % 4 + 1))
30195                 done
30196         )&
30197         wpid=$!
30198
30199         # Buffered I/O read
30200         (
30201                 while [ ! -e $DIR/sanity.833.lck ]; do
30202                         dd if=$file of=/dev/null bs=1M count=50 ||
30203                                 error "failed to read $file"
30204                         sleep 0.$((RANDOM % 4 + 1))
30205                 done
30206         )&
30207         rpid=$!
30208
30209         # Direct I/O read
30210         (
30211                 while [ ! -e $DIR/sanity.833.lck ]; do
30212                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30213                                 error "failed to read $file in direct I/O mode"
30214                         sleep 0.$((RANDOM % 4 + 1))
30215                 done
30216         )&
30217         rpid2=$!
30218
30219         sleep 30
30220         touch $DIR/sanity.833.lck
30221         wait $wpid || error "$?: buffered write failed"
30222         wait $rpid || error "$?: buffered read failed"
30223         wait $rpid2 || error "$?: direct read failed"
30224 }
30225 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30226
30227 #
30228 # tests that do cleanup/setup should be run at the end
30229 #
30230
30231 test_900() {
30232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30233         local ls
30234
30235         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30236         $LCTL set_param fail_loc=0x903
30237
30238         cancel_lru_locks MGC
30239
30240         FAIL_ON_ERROR=true cleanup
30241         FAIL_ON_ERROR=true setup
30242 }
30243 run_test 900 "umount should not race with any mgc requeue thread"
30244
30245 # LUS-6253/LU-11185
30246 test_901() {
30247         local old
30248         local count
30249         local oldc
30250         local newc
30251         local olds
30252         local news
30253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30254
30255         # some get_param have a bug to handle dot in param name
30256         cancel_lru_locks MGC
30257         old=$(mount -t lustre | wc -l)
30258         # 1 config+sptlrpc
30259         # 2 params
30260         # 3 nodemap
30261         # 4 IR
30262         old=$((old * 4))
30263         oldc=0
30264         count=0
30265         while [ $old -ne $oldc ]; do
30266                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30267                 sleep 1
30268                 ((count++))
30269                 if [ $count -ge $TIMEOUT ]; then
30270                         error "too large timeout"
30271                 fi
30272         done
30273         umount_client $MOUNT || error "umount failed"
30274         mount_client $MOUNT || error "mount failed"
30275         cancel_lru_locks MGC
30276         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30277
30278         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30279
30280         return 0
30281 }
30282 run_test 901 "don't leak a mgc lock on client umount"
30283
30284 # LU-13377
30285 test_902() {
30286         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30287                 skip "client does not have LU-13377 fix"
30288         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30289         $LCTL set_param fail_loc=0x1415
30290         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30291         cancel_lru_locks osc
30292         rm -f $DIR/$tfile
30293 }
30294 run_test 902 "test short write doesn't hang lustre"
30295
30296 # LU-14711
30297 test_903() {
30298         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30299         echo "blah" > $DIR/${tfile}-2
30300         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30301         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30302         $LCTL set_param fail_loc=0x417 fail_val=20
30303
30304         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30305         sleep 1 # To start the destroy
30306         wait_destroy_complete 150 || error "Destroy taking too long"
30307         cat $DIR/$tfile > /dev/null || error "Evicted"
30308 }
30309 run_test 903 "Test long page discard does not cause evictions"
30310
30311 test_904() {
30312         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30313         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30314                 grep -q project || skip "skip project quota not supported"
30315
30316         local testfile="$DIR/$tdir/$tfile"
30317         local xattr="trusted.projid"
30318         local projid
30319         local mdts=$(comma_list $(mdts_nodes))
30320         local saved=$(do_facet mds1 $LCTL get_param -n \
30321                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30322
30323         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30324         stack_trap "do_nodes $mdts $LCTL set_param \
30325                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30326
30327         mkdir -p $DIR/$tdir
30328         touch $testfile
30329         #hide projid xattr on server
30330         $LFS project -p 1 $testfile ||
30331                 error "set $testfile project id failed"
30332         getfattr -m - $testfile | grep $xattr &&
30333                 error "do not show trusted.projid when disabled on server"
30334         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30335         #should be hidden when projid is 0
30336         $LFS project -p 0 $testfile ||
30337                 error "set $testfile project id failed"
30338         getfattr -m - $testfile | grep $xattr &&
30339                 error "do not show trusted.projid with project ID 0"
30340
30341         #still can getxattr explicitly
30342         projid=$(getfattr -n $xattr $testfile |
30343                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30344         [ $projid == "0" ] ||
30345                 error "projid expected 0 not $projid"
30346
30347         #set the projid via setxattr
30348         setfattr -n $xattr -v "1000" $testfile ||
30349                 error "setattr failed with $?"
30350         projid=($($LFS project $testfile))
30351         [ ${projid[0]} == "1000" ] ||
30352                 error "projid expected 1000 not $projid"
30353
30354         #check the new projid via getxattr
30355         $LFS project -p 1001 $testfile ||
30356                 error "set $testfile project id failed"
30357         getfattr -m - $testfile | grep $xattr ||
30358                 error "should show trusted.projid when project ID != 0"
30359         projid=$(getfattr -n $xattr $testfile |
30360                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30361         [ $projid == "1001" ] ||
30362                 error "projid expected 1001 not $projid"
30363
30364         #try to set invalid projid
30365         setfattr -n $xattr -v "4294967295" $testfile &&
30366                 error "set invalid projid should fail"
30367
30368         #remove the xattr means setting projid to 0
30369         setfattr -x $xattr $testfile ||
30370                 error "setfattr failed with $?"
30371         projid=($($LFS project $testfile))
30372         [ ${projid[0]} == "0" ] ||
30373                 error "projid expected 0 not $projid"
30374
30375         #should be hidden when parent has inherit flag and same projid
30376         $LFS project -srp 1002 $DIR/$tdir ||
30377                 error "set $tdir project id failed"
30378         getfattr -m - $testfile | grep $xattr &&
30379                 error "do not show trusted.projid with inherit flag"
30380
30381         #still can getxattr explicitly
30382         projid=$(getfattr -n $xattr $testfile |
30383                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30384         [ $projid == "1002" ] ||
30385                 error "projid expected 1002 not $projid"
30386 }
30387 run_test 904 "virtual project ID xattr"
30388
30389 # LU-8582
30390 test_905() {
30391         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30392                 skip "need OST version >= 2.15.50.220 for fail_loc"
30393
30394         remote_ost_nodsh && skip "remote OST with nodsh"
30395         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30396
30397         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30398
30399         #define OBD_FAIL_OST_OPCODE 0x253
30400         # OST_LADVISE = 21
30401         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30402         $LFS ladvise -a willread $DIR/$tfile &&
30403                 error "unexpected success of ladvise with fault injection"
30404         $LFS ladvise -a willread $DIR/$tfile |&
30405                 grep -q "Operation not supported"
30406         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30407 }
30408 run_test 905 "bad or new opcode should not stuck client"
30409
30410 test_906() {
30411         grep -q io_uring_setup /proc/kallsyms ||
30412                 skip "Client OS does not support io_uring I/O engine"
30413         io_uring_probe || skip "kernel does not support io_uring fully"
30414         which fio || skip_env "no fio installed"
30415         fio --enghelp | grep -q io_uring ||
30416                 skip_env "fio does not support io_uring I/O engine"
30417
30418         local file=$DIR/$tfile
30419         local ioengine="io_uring"
30420         local numjobs=2
30421         local size=50M
30422
30423         fio --name=seqwrite --ioengine=$ioengine        \
30424                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30425                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30426                 error "fio seqwrite $file failed"
30427
30428         fio --name=seqread --ioengine=$ioengine \
30429                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30430                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30431                 error "fio seqread $file failed"
30432
30433         rm -f $file || error "rm -f $file failed"
30434 }
30435 run_test 906 "Simple test for io_uring I/O engine via fio"
30436
30437 complete_test $SECONDS
30438 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30439 check_and_cleanup_lustre
30440 if [ "$I_MOUNTED" != "yes" ]; then
30441         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30442 fi
30443 exit_status