Whamcloud - gitweb
LU-16974 utils: lfs mirror resync to show progress
[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_56xk() {
8322         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8323
8324         local size_mb=5
8325         local file1=$DIR/$tfile
8326
8327         stack_trap "rm -f $file1"
8328         $LFS setstripe -c 1 $file1
8329         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8330                 error "error creating $file1"
8331         $LFS mirror extend -N $file1 || error "can't mirror"
8332         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8333                 error "can't dd"
8334         $LFS getstripe $file1 | grep stale ||
8335                 error "one component must be stale"
8336
8337         local start=$SECONDS
8338         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8339                 error "migrate failed rc = $?"
8340         local elapsed=$((SECONDS - start))
8341         $LFS getstripe $file1 | grep stale &&
8342                 error "all components must be sync"
8343
8344         # with 1MB/s, elapsed should equal size_mb
8345         (( elapsed >= size_mb * 95 / 100 )) ||
8346                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8347
8348         (( elapsed <= size_mb * 120 / 100 )) ||
8349                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8350
8351         (( elapsed <= size_mb * 350 / 100 )) ||
8352                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8353 }
8354 run_test 56xk "lfs mirror resync bandwidth limitation support"
8355
8356 test_56xl() {
8357         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8358         verify_yaml_available || skip_env "YAML verification not installed"
8359
8360         local size_mb=5
8361         local file1=$DIR/$tfile.1
8362         local output_file=$DIR/$tfile.out
8363
8364         stack_trap "rm -f $file1"
8365         $LFS setstripe -c 1 $file1
8366         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8367                 error "error creating $file1"
8368         $LFS mirror extend -N $file1 || error "can't mirror"
8369         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8370                 error "can't dd"
8371         $LFS getstripe $file1 | grep stale ||
8372                 error "one component must be stale"
8373         $LFS getstripe $file1
8374
8375         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8376                 error "resync failed rc = $?"
8377         $LFS getstripe $file1 | grep stale &&
8378                 error "all components must be sync"
8379
8380         cat $output_file
8381         cat $output_file | verify_yaml || error "stats is not valid YAML"
8382 }
8383 run_test 56xl "lfs mirror resync stats support"
8384
8385 test_56y() {
8386         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8387                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8388
8389         local res=""
8390         local dir=$DIR/$tdir
8391         local f1=$dir/file1
8392         local f2=$dir/file2
8393
8394         test_mkdir -p $dir || error "creating dir $dir"
8395         touch $f1 || error "creating std file $f1"
8396         $MULTIOP $f2 H2c || error "creating released file $f2"
8397
8398         # a directory can be raid0, so ask only for files
8399         res=$($LFS find $dir -L raid0 -type f | wc -l)
8400         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8401
8402         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8403         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8404
8405         # only files can be released, so no need to force file search
8406         res=$($LFS find $dir -L released)
8407         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8408
8409         res=$($LFS find $dir -type f \! -L released)
8410         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8411 }
8412 run_test 56y "lfs find -L raid0|released"
8413
8414 test_56z() { # LU-4824
8415         # This checks to make sure 'lfs find' continues after errors
8416         # There are two classes of errors that should be caught:
8417         # - If multiple paths are provided, all should be searched even if one
8418         #   errors out
8419         # - If errors are encountered during the search, it should not terminate
8420         #   early
8421         local dir=$DIR/$tdir
8422         local i
8423
8424         test_mkdir $dir
8425         for i in d{0..9}; do
8426                 test_mkdir $dir/$i
8427                 touch $dir/$i/$tfile
8428         done
8429         $LFS find $DIR/non_existent_dir $dir &&
8430                 error "$LFS find did not return an error"
8431         # Make a directory unsearchable. This should NOT be the last entry in
8432         # directory order.  Arbitrarily pick the 6th entry
8433         chmod 700 $($LFS find $dir -type d | sed '6!d')
8434
8435         $RUNAS $LFS find $DIR/non_existent $dir
8436         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8437
8438         # The user should be able to see 10 directories and 9 files
8439         (( count == 19 )) ||
8440                 error "$LFS find found $count != 19 entries after error"
8441 }
8442 run_test 56z "lfs find should continue after an error"
8443
8444 test_56aa() { # LU-5937
8445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8446
8447         local dir=$DIR/$tdir
8448
8449         mkdir $dir
8450         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8451
8452         createmany -o $dir/striped_dir/${tfile}- 1024
8453         local dirs=$($LFS find --size +8k $dir/)
8454
8455         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8456 }
8457 run_test 56aa "lfs find --size under striped dir"
8458
8459 test_56ab() { # LU-10705
8460         test_mkdir $DIR/$tdir
8461         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8462         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8463         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8464         # Flush writes to ensure valid blocks.  Need to be more thorough for
8465         # ZFS, since blocks are not allocated/returned to client immediately.
8466         sync_all_data
8467         wait_zfs_commit ost1 2
8468         cancel_lru_locks osc
8469         ls -ls $DIR/$tdir
8470
8471         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8472
8473         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8474
8475         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8476         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8477
8478         rm -f $DIR/$tdir/$tfile.[123]
8479 }
8480 run_test 56ab "lfs find --blocks"
8481
8482 # LU-11188
8483 test_56aca() {
8484         local dir="$DIR/$tdir"
8485         local perms=(001 002 003 004 005 006 007
8486                      010 020 030 040 050 060 070
8487                      100 200 300 400 500 600 700
8488                      111 222 333 444 555 666 777)
8489         local perm_minus=(8 8 4 8 4 4 2
8490                           8 8 4 8 4 4 2
8491                           8 8 4 8 4 4 2
8492                           4 4 2 4 2 2 1)
8493         local perm_slash=(8  8 12  8 12 12 14
8494                           8  8 12  8 12 12 14
8495                           8  8 12  8 12 12 14
8496                          16 16 24 16 24 24 28)
8497
8498         test_mkdir "$dir"
8499         for perm in ${perms[*]}; do
8500                 touch "$dir/$tfile.$perm"
8501                 chmod $perm "$dir/$tfile.$perm"
8502         done
8503
8504         for ((i = 0; i < ${#perms[*]}; i++)); do
8505                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8506                 (( $num == 1 )) ||
8507                         error "lfs find -perm ${perms[i]}:"\
8508                               "$num != 1"
8509
8510                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8511                 (( $num == ${perm_minus[i]} )) ||
8512                         error "lfs find -perm -${perms[i]}:"\
8513                               "$num != ${perm_minus[i]}"
8514
8515                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8516                 (( $num == ${perm_slash[i]} )) ||
8517                         error "lfs find -perm /${perms[i]}:"\
8518                               "$num != ${perm_slash[i]}"
8519         done
8520 }
8521 run_test 56aca "check lfs find -perm with octal representation"
8522
8523 test_56acb() {
8524         local dir=$DIR/$tdir
8525         # p is the permission of write and execute for user, group and other
8526         # without the umask. It is used to test +wx.
8527         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8528         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8529         local symbolic=(+t  a+t u+t g+t o+t
8530                         g+s u+s o+s +s o+sr
8531                         o=r,ug+o,u+w
8532                         u+ g+ o+ a+ ugo+
8533                         u- g- o- a- ugo-
8534                         u= g= o= a= ugo=
8535                         o=r,ug+o,u+w u=r,a+u,u+w
8536                         g=r,ugo=g,u+w u+x,+X +X
8537                         u+x,u+X u+X u+x,g+X o+r,+X
8538                         u+x,go+X +wx +rwx)
8539
8540         test_mkdir $dir
8541         for perm in ${perms[*]}; do
8542                 touch "$dir/$tfile.$perm"
8543                 chmod $perm "$dir/$tfile.$perm"
8544         done
8545
8546         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8547                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8548
8549                 (( $num == 1 )) ||
8550                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8551         done
8552 }
8553 run_test 56acb "check lfs find -perm with symbolic representation"
8554
8555 test_56acc() {
8556         local dir=$DIR/$tdir
8557         local tests="17777 787 789 abcd
8558                 ug=uu ug=a ug=gu uo=ou urw
8559                 u+xg+x a=r,u+x,"
8560
8561         test_mkdir $dir
8562         for err in $tests; do
8563                 if $LFS find $dir -perm $err 2>/dev/null; then
8564                         error "lfs find -perm $err: parsing should have failed"
8565                 fi
8566         done
8567 }
8568 run_test 56acc "check parsing error for lfs find -perm"
8569
8570 test_56ba() {
8571         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8572                 skip "Need MDS version at least 2.10.50"
8573
8574         # Create composite files with one component
8575         local dir=$DIR/$tdir
8576
8577         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8578         # Create composite files with three components
8579         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8580         # LU-16904 Create plain layout files
8581         lfs setstripe -c 1 $dir/$tfile-{1..10}
8582
8583         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8584
8585         [[ $nfiles == 10 ]] ||
8586                 error "lfs find -E 1M found $nfiles != 10 files"
8587
8588         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8589         [[ $nfiles == 25 ]] ||
8590                 error "lfs find ! -E 1M found $nfiles != 25 files"
8591
8592         # All files have a component that starts at 0
8593         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8594         [[ $nfiles == 35 ]] ||
8595                 error "lfs find --component-start 0 - $nfiles != 35 files"
8596
8597         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8598         [[ $nfiles == 15 ]] ||
8599                 error "lfs find --component-start 2M - $nfiles != 15 files"
8600
8601         # All files created here have a componenet that does not starts at 2M
8602         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8603         [[ $nfiles == 35 ]] ||
8604                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8605
8606         # Find files with a specified number of components
8607         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8608         [[ $nfiles == 15 ]] ||
8609                 error "lfs find --component-count 3 - $nfiles != 15 files"
8610
8611         # Remember non-composite files have a component count of zero
8612         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8613         [[ $nfiles == 10 ]] ||
8614                 error "lfs find --component-count 0 - $nfiles != 10 files"
8615
8616         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8617         [[ $nfiles == 20 ]] ||
8618                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8619
8620         # All files have a flag called "init"
8621         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8622         [[ $nfiles == 35 ]] ||
8623                 error "lfs find --component-flags init - $nfiles != 35 files"
8624
8625         # Multi-component files will have a component not initialized
8626         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8627         [[ $nfiles == 15 ]] ||
8628                 error "lfs find !--component-flags init - $nfiles != 15 files"
8629
8630         rm -rf $dir
8631
8632 }
8633 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8634
8635 test_56ca() {
8636         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8637                 skip "Need MDS version at least 2.10.57"
8638
8639         local td=$DIR/$tdir
8640         local tf=$td/$tfile
8641         local dir
8642         local nfiles
8643         local cmd
8644         local i
8645         local j
8646
8647         # create mirrored directories and mirrored files
8648         mkdir $td || error "mkdir $td failed"
8649         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8650         createmany -o $tf- 10 || error "create $tf- failed"
8651
8652         for i in $(seq 2); do
8653                 dir=$td/dir$i
8654                 mkdir $dir || error "mkdir $dir failed"
8655                 $LFS mirror create -N$((3 + i)) $dir ||
8656                         error "create mirrored dir $dir failed"
8657                 createmany -o $dir/$tfile- 10 ||
8658                         error "create $dir/$tfile- failed"
8659         done
8660
8661         # change the states of some mirrored files
8662         echo foo > $tf-6
8663         for i in $(seq 2); do
8664                 dir=$td/dir$i
8665                 for j in $(seq 4 9); do
8666                         echo foo > $dir/$tfile-$j
8667                 done
8668         done
8669
8670         # find mirrored files with specific mirror count
8671         cmd="$LFS find --mirror-count 3 --type f $td"
8672         nfiles=$($cmd | wc -l)
8673         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8674
8675         cmd="$LFS find ! --mirror-count 3 --type f $td"
8676         nfiles=$($cmd | wc -l)
8677         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8678
8679         cmd="$LFS find --mirror-count +2 --type f $td"
8680         nfiles=$($cmd | wc -l)
8681         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8682
8683         cmd="$LFS find --mirror-count -6 --type f $td"
8684         nfiles=$($cmd | wc -l)
8685         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8686
8687         # find mirrored files with specific file state
8688         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8689         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8690
8691         cmd="$LFS find --mirror-state=ro --type f $td"
8692         nfiles=$($cmd | wc -l)
8693         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8694
8695         cmd="$LFS find ! --mirror-state=ro --type f $td"
8696         nfiles=$($cmd | wc -l)
8697         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8698
8699         cmd="$LFS find --mirror-state=wp --type f $td"
8700         nfiles=$($cmd | wc -l)
8701         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8702
8703         cmd="$LFS find ! --mirror-state=sp --type f $td"
8704         nfiles=$($cmd | wc -l)
8705         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8706 }
8707 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8708
8709 test_56da() { # LU-14179
8710         local path=$DIR/$tdir
8711
8712         test_mkdir $path
8713         cd $path
8714
8715         local longdir=$(str_repeat 'a' 255)
8716
8717         for i in {1..15}; do
8718                 path=$path/$longdir
8719                 test_mkdir $longdir
8720                 cd $longdir
8721         done
8722
8723         local len=${#path}
8724         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8725
8726         test_mkdir $lastdir
8727         cd $lastdir
8728         # PATH_MAX-1
8729         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8730
8731         # NAME_MAX
8732         touch $(str_repeat 'f' 255)
8733
8734         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8735                 error "lfs find reported an error"
8736
8737         rm -rf $DIR/$tdir
8738 }
8739 run_test 56da "test lfs find with long paths"
8740
8741 test_56ea() { #LU-10378
8742         local path=$DIR/$tdir
8743         local pool=$TESTNAME
8744
8745         # Create ost pool
8746         pool_add $pool || error "pool_add $pool failed"
8747         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8748                 error "adding targets to $pool failed"
8749
8750         # Set default pool on directory before creating file
8751         mkdir $path || error "mkdir $path failed"
8752         $LFS setstripe -p $pool $path ||
8753                 error "set OST pool on $pool failed"
8754         touch $path/$tfile || error "touch $path/$tfile failed"
8755
8756         # Compare basic file attributes from -printf and stat
8757         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8758         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8759
8760         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8761                 error "Attrs from lfs find and stat don't match"
8762
8763         # Compare Lustre attributes from lfs find and lfs getstripe
8764         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8765         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8766         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8767         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8768         local fpool=$($LFS getstripe --pool $path/$tfile)
8769         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8770
8771         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8772                 error "Attrs from lfs find and lfs getstripe don't match"
8773
8774         # Verify behavior for unknown escape/format sequences
8775         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8776
8777         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8778                 error "Escape/format codes don't match"
8779 }
8780 run_test 56ea "test lfs find -printf option"
8781
8782 test_56eb() {
8783         local dir=$DIR/$tdir
8784         local subdir_1=$dir/subdir_1
8785
8786         test_mkdir -p $subdir_1
8787         ln -s subdir_1 $dir/link_1
8788
8789         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8790                 error "symlink is not followed"
8791
8792         $LFS getstripe --no-follow $dir |
8793                 grep "^$dir/link_1 has no stripe info$" ||
8794                 error "symlink should not have stripe info"
8795
8796         touch $dir/testfile
8797         ln -s testfile $dir/file_link_2
8798
8799         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8800                 error "symlink is not followed"
8801
8802         $LFS getstripe --no-follow $dir |
8803                 grep "^$dir/file_link_2 has no stripe info$" ||
8804                 error "symlink should not have stripe info"
8805 }
8806 run_test 56eb "check lfs getstripe on symlink"
8807
8808 test_56ec() {
8809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8810         local dir=$DIR/$tdir
8811         local srcfile=$dir/srcfile
8812         local srcyaml=$dir/srcyaml
8813         local destfile=$dir/destfile
8814
8815         test_mkdir -p $dir
8816
8817         $LFS setstripe -i 1 $srcfile
8818         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8819         # if the setstripe yaml parsing fails for any reason, the command can
8820         # randomly assign the correct OST index, leading to an erroneous
8821         # success. but the chance of false success is low enough that a
8822         # regression should still be quickly caught.
8823         $LFS setstripe --yaml=$srcyaml $destfile
8824
8825         local srcindex=$($LFS getstripe -i $srcfile)
8826         local destindex=$($LFS getstripe -i $destfile)
8827
8828         if [[ ! $srcindex -eq $destindex ]]; then
8829                 error "setstripe did not set OST index correctly"
8830         fi
8831 }
8832 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8833
8834 test_56eda() {
8835         local dir=$DIR/$tdir
8836         local subdir=$dir/subdir
8837         local file1=$dir/$tfile
8838         local file2=$dir/$tfile\2
8839         local link=$dir/$tfile-link
8840         local nfiles
8841
8842         test_mkdir -p $dir
8843         $LFS setdirstripe -c1 $subdir
8844         touch $file1
8845         touch $file2
8846         ln $file2 $link
8847
8848         nfiles=$($LFS find --links 1 $dir | wc -l)
8849         (( $nfiles == 1 )) ||
8850                 error "lfs find --links expected 1 file, got $nfiles"
8851
8852         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8853         (( $nfiles == 2 )) ||
8854                 error "lfs find --links expected 2 files, got $nfiles"
8855
8856         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8857         (( $nfiles == 1 )) ||
8858                 error "lfs find --links expected 1 directory, got $nfiles"
8859 }
8860 run_test 56eda "check lfs find --links"
8861
8862 test_56edb() {
8863         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8864
8865         local dir=$DIR/$tdir
8866         local stripedir=$dir/stripedir
8867         local nfiles
8868
8869         test_mkdir -p $dir
8870
8871         $LFS setdirstripe -c2 $stripedir
8872
8873         $LFS getdirstripe $stripedir
8874
8875         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8876         (( $nfiles == 1 )) ||
8877                 error "lfs find --links expected 1 directory, got $nfiles"
8878 }
8879 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8880
8881 test_56ef() {
8882         local dir=$DIR/$tdir
8883         local dir1=$dir/d1
8884         local dir2=$dir/d2
8885         local nfiles
8886
8887         test_mkdir -p $dir
8888
8889         mkdir $dir1
8890         mkdir $dir2
8891
8892         touch $dir1/f
8893         touch $dir2/f
8894
8895         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8896         (( $nfiles == 2 )) ||
8897                 error "(1) lfs find expected 2 files, got $nfiles"
8898
8899         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8900         (( $nfiles == 2 )) ||
8901                 error "(2) lfs find expected 2 files, got $nfiles"
8902
8903         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8904         (( $nfiles == 2 )) ||
8905                 error "(3) lfs find expected 2 files, got $nfiles"
8906 }
8907 run_test 56ef "lfs find with multiple paths"
8908
8909 test_57a() {
8910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8911         # note test will not do anything if MDS is not local
8912         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8913                 skip_env "ldiskfs only test"
8914         fi
8915         remote_mds_nodsh && skip "remote MDS with nodsh"
8916
8917         local MNTDEV="osd*.*MDT*.mntdev"
8918         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8919         [ -z "$DEV" ] && error "can't access $MNTDEV"
8920         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8921                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8922                         error "can't access $DEV"
8923                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8924                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8925                 rm $TMP/t57a.dump
8926         done
8927 }
8928 run_test 57a "verify MDS filesystem created with large inodes =="
8929
8930 test_57b() {
8931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8932         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8933                 skip_env "ldiskfs only test"
8934         fi
8935         remote_mds_nodsh && skip "remote MDS with nodsh"
8936
8937         local dir=$DIR/$tdir
8938         local filecount=100
8939         local file1=$dir/f1
8940         local fileN=$dir/f$filecount
8941
8942         rm -rf $dir || error "removing $dir"
8943         test_mkdir -c1 $dir
8944         local mdtidx=$($LFS getstripe -m $dir)
8945         local mdtname=MDT$(printf %04x $mdtidx)
8946         local facet=mds$((mdtidx + 1))
8947
8948         echo "mcreating $filecount files"
8949         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8950
8951         # verify that files do not have EAs yet
8952         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8953                 error "$file1 has an EA"
8954         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8955                 error "$fileN has an EA"
8956
8957         sync
8958         sleep 1
8959         df $dir  #make sure we get new statfs data
8960         local mdsfree=$(do_facet $facet \
8961                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8962         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8963         local file
8964
8965         echo "opening files to create objects/EAs"
8966         for file in $(seq -f $dir/f%g 1 $filecount); do
8967                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8968                         error "opening $file"
8969         done
8970
8971         # verify that files have EAs now
8972         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
8973                 error "$file1 missing EA"
8974         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
8975                 error "$fileN missing EA"
8976
8977         sleep 1  #make sure we get new statfs data
8978         df $dir
8979         local mdsfree2=$(do_facet $facet \
8980                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8981         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8982
8983         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8984                 if [ "$mdsfree" != "$mdsfree2" ]; then
8985                         error "MDC before $mdcfree != after $mdcfree2"
8986                 else
8987                         echo "MDC before $mdcfree != after $mdcfree2"
8988                         echo "unable to confirm if MDS has large inodes"
8989                 fi
8990         fi
8991         rm -rf $dir
8992 }
8993 run_test 57b "default LOV EAs are stored inside large inodes ==="
8994
8995 test_58() {
8996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8997         [ -z "$(which wiretest 2>/dev/null)" ] &&
8998                         skip_env "could not find wiretest"
8999
9000         wiretest
9001 }
9002 run_test 58 "verify cross-platform wire constants =============="
9003
9004 test_59() {
9005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9006
9007         echo "touch 130 files"
9008         createmany -o $DIR/f59- 130
9009         echo "rm 130 files"
9010         unlinkmany $DIR/f59- 130
9011         sync
9012         # wait for commitment of removal
9013         wait_delete_completed
9014 }
9015 run_test 59 "verify cancellation of llog records async ========="
9016
9017 TEST60_HEAD="test_60 run $RANDOM"
9018 test_60a() {
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020         remote_mgs_nodsh && skip "remote MGS with nodsh"
9021         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9022                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9023                         skip_env "missing subtest run-llog.sh"
9024
9025         log "$TEST60_HEAD - from kernel mode"
9026         do_facet mgs "$LCTL dk > /dev/null"
9027         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9028         do_facet mgs $LCTL dk > $TMP/$tfile
9029
9030         # LU-6388: test llog_reader
9031         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9032         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9033         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9034                         skip_env "missing llog_reader"
9035         local fstype=$(facet_fstype mgs)
9036         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9037                 skip_env "Only for ldiskfs or zfs type mgs"
9038
9039         local mntpt=$(facet_mntpt mgs)
9040         local mgsdev=$(mgsdevname 1)
9041         local fid_list
9042         local fid
9043         local rec_list
9044         local rec
9045         local rec_type
9046         local obj_file
9047         local path
9048         local seq
9049         local oid
9050         local pass=true
9051
9052         #get fid and record list
9053         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9054                 tail -n 4))
9055         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9056                 tail -n 4))
9057         #remount mgs as ldiskfs or zfs type
9058         stop mgs || error "stop mgs failed"
9059         mount_fstype mgs || error "remount mgs failed"
9060         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9061                 fid=${fid_list[i]}
9062                 rec=${rec_list[i]}
9063                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9064                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9065                 oid=$((16#$oid))
9066
9067                 case $fstype in
9068                         ldiskfs )
9069                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9070                         zfs )
9071                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9072                 esac
9073                 echo "obj_file is $obj_file"
9074                 do_facet mgs $llog_reader $obj_file
9075
9076                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9077                         awk '{ print $3 }' | sed -e "s/^type=//g")
9078                 if [ $rec_type != $rec ]; then
9079                         echo "FAILED test_60a wrong record type $rec_type," \
9080                               "should be $rec"
9081                         pass=false
9082                         break
9083                 fi
9084
9085                 #check obj path if record type is LLOG_LOGID_MAGIC
9086                 if [ "$rec" == "1064553b" ]; then
9087                         path=$(do_facet mgs $llog_reader $obj_file |
9088                                 grep "path=" | awk '{ print $NF }' |
9089                                 sed -e "s/^path=//g")
9090                         if [ $obj_file != $mntpt/$path ]; then
9091                                 echo "FAILED test_60a wrong obj path" \
9092                                       "$montpt/$path, should be $obj_file"
9093                                 pass=false
9094                                 break
9095                         fi
9096                 fi
9097         done
9098         rm -f $TMP/$tfile
9099         #restart mgs before "error", otherwise it will block the next test
9100         stop mgs || error "stop mgs failed"
9101         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9102         $pass || error "test failed, see FAILED test_60a messages for specifics"
9103 }
9104 run_test 60a "llog_test run from kernel module and test llog_reader"
9105
9106 test_60b() { # bug 6411
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108
9109         dmesg > $DIR/$tfile
9110         LLOG_COUNT=$(do_facet mgs dmesg |
9111                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9112                           /llog_[a-z]*.c:[0-9]/ {
9113                                 if (marker)
9114                                         from_marker++
9115                                 from_begin++
9116                           }
9117                           END {
9118                                 if (marker)
9119                                         print from_marker
9120                                 else
9121                                         print from_begin
9122                           }")
9123
9124         [[ $LLOG_COUNT -gt 120 ]] &&
9125                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9126 }
9127 run_test 60b "limit repeated messages from CERROR/CWARN"
9128
9129 test_60c() {
9130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9131
9132         echo "create 5000 files"
9133         createmany -o $DIR/f60c- 5000
9134 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9135         lctl set_param fail_loc=0x80000137
9136         unlinkmany $DIR/f60c- 5000
9137         lctl set_param fail_loc=0
9138 }
9139 run_test 60c "unlink file when mds full"
9140
9141 test_60d() {
9142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9143
9144         SAVEPRINTK=$(lctl get_param -n printk)
9145         # verify "lctl mark" is even working"
9146         MESSAGE="test message ID $RANDOM $$"
9147         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9148         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9149
9150         lctl set_param printk=0 || error "set lnet.printk failed"
9151         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9152         MESSAGE="new test message ID $RANDOM $$"
9153         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9154         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9155         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9156
9157         lctl set_param -n printk="$SAVEPRINTK"
9158 }
9159 run_test 60d "test printk console message masking"
9160
9161 test_60e() {
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163         remote_mds_nodsh && skip "remote MDS with nodsh"
9164
9165         touch $DIR/$tfile
9166 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9167         do_facet mds1 lctl set_param fail_loc=0x15b
9168         rm $DIR/$tfile
9169 }
9170 run_test 60e "no space while new llog is being created"
9171
9172 test_60f() {
9173         local old_path=$($LCTL get_param -n debug_path)
9174
9175         stack_trap "$LCTL set_param debug_path=$old_path"
9176         stack_trap "rm -f $TMP/$tfile*"
9177         rm -f $TMP/$tfile* 2> /dev/null
9178         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9179         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9180         test_mkdir $DIR/$tdir
9181         # retry in case the open is cached and not released
9182         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9183                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9184                 sleep 0.1
9185         done
9186         ls $TMP/$tfile*
9187         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9188 }
9189 run_test 60f "change debug_path works"
9190
9191 test_60g() {
9192         local pid
9193         local i
9194
9195         test_mkdir -c $MDSCOUNT $DIR/$tdir
9196
9197         (
9198                 local index=0
9199                 while true; do
9200                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9201                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9202                                 2>/dev/null
9203                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9204                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9205                         index=$((index + 1))
9206                 done
9207         ) &
9208
9209         pid=$!
9210
9211         for i in {0..100}; do
9212                 # define OBD_FAIL_OSD_TXN_START    0x19a
9213                 local index=$((i % MDSCOUNT + 1))
9214
9215                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9216                         > /dev/null
9217                 sleep 0.01
9218         done
9219
9220         kill -9 $pid
9221
9222         for i in $(seq $MDSCOUNT); do
9223                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9224         done
9225
9226         mkdir $DIR/$tdir/new || error "mkdir failed"
9227         rmdir $DIR/$tdir/new || error "rmdir failed"
9228
9229         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9230                 -t namespace
9231         for i in $(seq $MDSCOUNT); do
9232                 wait_update_facet mds$i "$LCTL get_param -n \
9233                         mdd.$(facet_svc mds$i).lfsck_namespace |
9234                         awk '/^status/ { print \\\$2 }'" "completed"
9235         done
9236
9237         ls -R $DIR/$tdir
9238         rm -rf $DIR/$tdir || error "rmdir failed"
9239 }
9240 run_test 60g "transaction abort won't cause MDT hung"
9241
9242 test_60h() {
9243         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9244                 skip "Need MDS version at least 2.12.52"
9245         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9246
9247         local f
9248
9249         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9250         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9251         for fail_loc in 0x80000188 0x80000189; do
9252                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9253                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9254                         error "mkdir $dir-$fail_loc failed"
9255                 for i in {0..10}; do
9256                         # create may fail on missing stripe
9257                         echo $i > $DIR/$tdir-$fail_loc/$i
9258                 done
9259                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9260                         error "getdirstripe $tdir-$fail_loc failed"
9261                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9262                         error "migrate $tdir-$fail_loc failed"
9263                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9264                         error "getdirstripe $tdir-$fail_loc failed"
9265                 pushd $DIR/$tdir-$fail_loc
9266                 for f in *; do
9267                         echo $f | cmp $f - || error "$f data mismatch"
9268                 done
9269                 popd
9270                 rm -rf $DIR/$tdir-$fail_loc
9271         done
9272 }
9273 run_test 60h "striped directory with missing stripes can be accessed"
9274
9275 function t60i_load() {
9276         mkdir $DIR/$tdir
9277         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9278         $LCTL set_param fail_loc=0x131c fail_val=1
9279         for ((i=0; i<5000; i++)); do
9280                 touch $DIR/$tdir/f$i
9281         done
9282 }
9283
9284 test_60i() {
9285         changelog_register || error "changelog_register failed"
9286         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9287         changelog_users $SINGLEMDS | grep -q $cl_user ||
9288                 error "User $cl_user not found in changelog_users"
9289         changelog_chmask "ALL"
9290         t60i_load &
9291         local PID=$!
9292         for((i=0; i<100; i++)); do
9293                 changelog_dump >/dev/null ||
9294                         error "can't read changelog"
9295         done
9296         kill $PID
9297         wait $PID
9298         changelog_deregister || error "changelog_deregister failed"
9299         $LCTL set_param fail_loc=0
9300 }
9301 run_test 60i "llog: new record vs reader race"
9302
9303 test_60j() {
9304         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9305                 skip "need MDS version at least 2.15.50"
9306         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9307         remote_mds_nodsh && skip "remote MDS with nodsh"
9308         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9309
9310         changelog_users $SINGLEMDS | grep "^cl" &&
9311                 skip "active changelog user"
9312
9313         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9314
9315         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9316                 skip_env "missing llog_reader"
9317
9318         mkdir_on_mdt0 $DIR/$tdir
9319
9320         local f=$DIR/$tdir/$tfile
9321         local mdt_dev
9322         local tmpfile
9323         local plain
9324
9325         changelog_register || error "cannot register changelog user"
9326
9327         # set changelog_mask to ALL
9328         changelog_chmask "ALL"
9329         changelog_clear
9330
9331         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9332         unlinkmany ${f}- 100 || error "unlinkmany failed"
9333
9334         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9335         mdt_dev=$(facet_device $SINGLEMDS)
9336
9337         do_facet $SINGLEMDS sync
9338         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9339                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9340                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9341
9342         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9343
9344         # if $tmpfile is not on EXT3 filesystem for some reason
9345         [[ ${plain:0:1} == 'O' ]] ||
9346                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9347
9348         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9349                 $mdt_dev; stat -c %s $tmpfile")
9350         echo "Truncate llog from $size to $((size - size % 8192))"
9351         size=$((size - size % 8192))
9352         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9353         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9354                 grep -c 'in bitmap only')
9355         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9356
9357         size=$((size - 9000))
9358         echo "Corrupt llog in the middle at $size"
9359         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9360                 count=333 conv=notrunc
9361         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9362                 grep -c 'next chunk')
9363         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9364 }
9365 run_test 60j "llog_reader reports corruptions"
9366
9367 test_61a() {
9368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9369
9370         f="$DIR/f61"
9371         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9372         cancel_lru_locks osc
9373         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9374         sync
9375 }
9376 run_test 61a "mmap() writes don't make sync hang ================"
9377
9378 test_61b() {
9379         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9380 }
9381 run_test 61b "mmap() of unstriped file is successful"
9382
9383 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9384 # Though this test is irrelevant anymore, it helped to reveal some
9385 # other grant bugs (LU-4482), let's keep it.
9386 test_63a() {   # was test_63
9387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9388
9389         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9390
9391         for i in `seq 10` ; do
9392                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9393                 sleep 5
9394                 kill $!
9395                 sleep 1
9396         done
9397
9398         rm -f $DIR/f63 || true
9399 }
9400 run_test 63a "Verify oig_wait interruption does not crash ======="
9401
9402 # bug 2248 - async write errors didn't return to application on sync
9403 # bug 3677 - async write errors left page locked
9404 test_63b() {
9405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9406
9407         debugsave
9408         lctl set_param debug=-1
9409
9410         # ensure we have a grant to do async writes
9411         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9412         rm $DIR/$tfile
9413
9414         sync    # sync lest earlier test intercept the fail_loc
9415
9416         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9417         lctl set_param fail_loc=0x80000406
9418         $MULTIOP $DIR/$tfile Owy && \
9419                 error "sync didn't return ENOMEM"
9420         sync; sleep 2; sync     # do a real sync this time to flush page
9421         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9422                 error "locked page left in cache after async error" || true
9423         debugrestore
9424 }
9425 run_test 63b "async write errors should be returned to fsync ==="
9426
9427 test_64a () {
9428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9429
9430         lfs df $DIR
9431         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9432 }
9433 run_test 64a "verify filter grant calculations (in kernel) ====="
9434
9435 test_64b () {
9436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9437
9438         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9439 }
9440 run_test 64b "check out-of-space detection on client"
9441
9442 test_64c() {
9443         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9444 }
9445 run_test 64c "verify grant shrink"
9446
9447 import_param() {
9448         local tgt=$1
9449         local param=$2
9450
9451         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9452 }
9453
9454 # this does exactly what osc_request.c:osc_announce_cached() does in
9455 # order to calculate max amount of grants to ask from server
9456 want_grant() {
9457         local tgt=$1
9458
9459         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9460         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9461
9462         ((rpc_in_flight++));
9463         nrpages=$((nrpages * rpc_in_flight))
9464
9465         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9466
9467         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9468
9469         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9470         local undirty=$((nrpages * PAGE_SIZE))
9471
9472         local max_extent_pages
9473         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9474         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9475         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9476         local grant_extent_tax
9477         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9478
9479         undirty=$((undirty + nrextents * grant_extent_tax))
9480
9481         echo $undirty
9482 }
9483
9484 # this is size of unit for grant allocation. It should be equal to
9485 # what tgt_grant.c:tgt_grant_chunk() calculates
9486 grant_chunk() {
9487         local tgt=$1
9488         local max_brw_size
9489         local grant_extent_tax
9490
9491         max_brw_size=$(import_param $tgt max_brw_size)
9492
9493         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9494
9495         echo $(((max_brw_size + grant_extent_tax) * 2))
9496 }
9497
9498 test_64d() {
9499         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9500                 skip "OST < 2.10.55 doesn't limit grants enough"
9501
9502         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9503
9504         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9505                 skip "no grant_param connect flag"
9506
9507         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9508
9509         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9510         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9511
9512
9513         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9514         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9515
9516         $LFS setstripe $DIR/$tfile -i 0 -c 1
9517         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9518         ddpid=$!
9519
9520         while kill -0 $ddpid; do
9521                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9522
9523                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9524                         kill $ddpid
9525                         error "cur_grant $cur_grant > $max_cur_granted"
9526                 fi
9527
9528                 sleep 1
9529         done
9530 }
9531 run_test 64d "check grant limit exceed"
9532
9533 check_grants() {
9534         local tgt=$1
9535         local expected=$2
9536         local msg=$3
9537         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9538
9539         ((cur_grants == expected)) ||
9540                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9541 }
9542
9543 round_up_p2() {
9544         echo $((($1 + $2 - 1) & ~($2 - 1)))
9545 }
9546
9547 test_64e() {
9548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9549         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9550                 skip "Need OSS version at least 2.11.56"
9551
9552         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9553         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9554         $LCTL set_param debug=+cache
9555
9556         # Remount client to reset grant
9557         remount_client $MOUNT || error "failed to remount client"
9558         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9559
9560         local init_grants=$(import_param $osc_tgt initial_grant)
9561
9562         check_grants $osc_tgt $init_grants "init grants"
9563
9564         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9565         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9566         local gbs=$(import_param $osc_tgt grant_block_size)
9567
9568         # write random number of bytes from max_brw_size / 4 to max_brw_size
9569         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9570         # align for direct io
9571         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9572         # round to grant consumption unit
9573         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9574
9575         local grants=$((wb_round_up + extent_tax))
9576
9577         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9578         stack_trap "rm -f $DIR/$tfile"
9579
9580         # define OBD_FAIL_TGT_NO_GRANT 0x725
9581         # make the server not grant more back
9582         do_facet ost1 $LCTL set_param fail_loc=0x725
9583         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9584
9585         do_facet ost1 $LCTL set_param fail_loc=0
9586
9587         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9588
9589         rm -f $DIR/$tfile || error "rm failed"
9590
9591         # Remount client to reset grant
9592         remount_client $MOUNT || error "failed to remount client"
9593         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9594
9595         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9596
9597         # define OBD_FAIL_TGT_NO_GRANT 0x725
9598         # make the server not grant more back
9599         do_facet ost1 $LCTL set_param fail_loc=0x725
9600         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9601         do_facet ost1 $LCTL set_param fail_loc=0
9602
9603         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9604 }
9605 run_test 64e "check grant consumption (no grant allocation)"
9606
9607 test_64f() {
9608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9609
9610         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9611         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9612         $LCTL set_param debug=+cache
9613
9614         # Remount client to reset grant
9615         remount_client $MOUNT || error "failed to remount client"
9616         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9617
9618         local init_grants=$(import_param $osc_tgt initial_grant)
9619         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9620         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9621         local gbs=$(import_param $osc_tgt grant_block_size)
9622         local chunk=$(grant_chunk $osc_tgt)
9623
9624         # write random number of bytes from max_brw_size / 4 to max_brw_size
9625         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9626         # align for direct io
9627         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9628         # round to grant consumption unit
9629         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9630
9631         local grants=$((wb_round_up + extent_tax))
9632
9633         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9634         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9635                 error "error writing to $DIR/$tfile"
9636
9637         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9638                 "direct io with grant allocation"
9639
9640         rm -f $DIR/$tfile || error "rm failed"
9641
9642         # Remount client to reset grant
9643         remount_client $MOUNT || error "failed to remount client"
9644         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9645
9646         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9647
9648         local cmd="oO_WRONLY:w${write_bytes}_yc"
9649
9650         $MULTIOP $DIR/$tfile $cmd &
9651         MULTIPID=$!
9652         sleep 1
9653
9654         check_grants $osc_tgt $((init_grants - grants)) \
9655                 "buffered io, not write rpc"
9656
9657         kill -USR1 $MULTIPID
9658         wait
9659
9660         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9661                 "buffered io, one RPC"
9662 }
9663 run_test 64f "check grant consumption (with grant allocation)"
9664
9665 test_64g() {
9666         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9667                 skip "Need MDS version at least 2.14.56"
9668
9669         local mdts=$(comma_list $(mdts_nodes))
9670
9671         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9672                         tr '\n' ' ')
9673         stack_trap "$LCTL set_param $old"
9674
9675         # generate dirty pages and increase dirty granted on MDT
9676         stack_trap "rm -f $DIR/$tfile-*"
9677         for (( i = 0; i < 10; i++)); do
9678                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9679                         error "can't set stripe"
9680                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9681                         error "can't dd"
9682                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9683                         $LFS getstripe $DIR/$tfile-$i
9684                         error "not DoM file"
9685                 }
9686         done
9687
9688         # flush dirty pages
9689         sync
9690
9691         # wait until grant shrink reset grant dirty on MDTs
9692         for ((i = 0; i < 120; i++)); do
9693                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9694                         awk '{sum=sum+$1} END {print sum}')
9695                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9696                 echo "$grant_dirty grants, $vm_dirty pages"
9697                 (( grant_dirty + vm_dirty == 0 )) && break
9698                 (( i == 3 )) && sync &&
9699                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9700                 sleep 1
9701         done
9702
9703         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9704                 awk '{sum=sum+$1} END {print sum}')
9705         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9706 }
9707 run_test 64g "grant shrink on MDT"
9708
9709 test_64h() {
9710         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9711                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9712
9713         local instance=$($LFS getname -i $DIR)
9714         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9715         local num_exps=$(do_facet ost1 \
9716             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9717         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9718         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9719         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9720
9721         # 10MiB is for file to be written, max_brw_size * 16 *
9722         # num_exps is space reserve so that tgt_grant_shrink() decided
9723         # to not shrink
9724         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9725         (( avail * 1024 < expect )) &&
9726                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9727
9728         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9729         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9730         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9731         $LCTL set_param osc.*OST0000*.grant_shrink=1
9732         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9733
9734         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9735         stack_trap "rm -f $DIR/$tfile"
9736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9737
9738         # drop cache so that coming read would do rpc
9739         cancel_lru_locks osc
9740
9741         # shrink interval is set to 10, pause for 7 seconds so that
9742         # grant thread did not wake up yet but coming read entered
9743         # shrink mode for rpc (osc_should_shrink_grant())
9744         sleep 7
9745
9746         declare -a cur_grant_bytes
9747         declare -a tot_granted
9748         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9749         tot_granted[0]=$(do_facet ost1 \
9750             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9751
9752         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9753
9754         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9755         tot_granted[1]=$(do_facet ost1 \
9756             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9757
9758         # grant change should be equal on both sides
9759         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9760                 tot_granted[0] - tot_granted[1])) ||
9761                 error "grant change mismatch, "                                \
9762                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9763                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9764 }
9765 run_test 64h "grant shrink on read"
9766
9767 test_64i() {
9768         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9769                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9770
9771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9772         remote_ost_nodsh && skip "remote OSTs with nodsh"
9773
9774         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9775         stack_trap "rm -f $DIR/$tfile"
9776
9777         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9778
9779         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9780         local instance=$($LFS getname -i $DIR)
9781
9782         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9783         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9784
9785         # shrink grants and simulate rpc loss
9786         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9787         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9788         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9789
9790         fail ost1
9791
9792         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9793
9794         local testid=$(echo $TESTNAME | tr '_' ' ')
9795
9796         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9797                 grep "GRANT, real grant" &&
9798                 error "client has more grants then it owns" || true
9799 }
9800 run_test 64i "shrink on reconnect"
9801
9802 # bug 1414 - set/get directories' stripe info
9803 test_65a() {
9804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9805
9806         test_mkdir $DIR/$tdir
9807         touch $DIR/$tdir/f1
9808         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9809 }
9810 run_test 65a "directory with no stripe info"
9811
9812 test_65b() {
9813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9814
9815         test_mkdir $DIR/$tdir
9816         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9817
9818         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9819                                                 error "setstripe"
9820         touch $DIR/$tdir/f2
9821         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9822 }
9823 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9824
9825 test_65c() {
9826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9827         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9828
9829         test_mkdir $DIR/$tdir
9830         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9831
9832         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9833                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9834         touch $DIR/$tdir/f3
9835         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9836 }
9837 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9838
9839 test_65d() {
9840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9841
9842         test_mkdir $DIR/$tdir
9843         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9844         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9845
9846         if [[ $STRIPECOUNT -le 0 ]]; then
9847                 sc=1
9848         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9849                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9850                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9851         else
9852                 sc=$(($STRIPECOUNT - 1))
9853         fi
9854         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9855         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9856         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9857                 error "lverify failed"
9858 }
9859 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9860
9861 test_65e() {
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863
9864         # LU-16904 delete layout when root is set as PFL layout
9865         save_layout_restore_at_exit $MOUNT
9866         $LFS setstripe -d $MOUNT || error "setstripe failed"
9867
9868         test_mkdir $DIR/$tdir
9869
9870         $LFS setstripe $DIR/$tdir || error "setstripe"
9871         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9872                                         error "no stripe info failed"
9873         touch $DIR/$tdir/f6
9874         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9875 }
9876 run_test 65e "directory setstripe defaults"
9877
9878 test_65f() {
9879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9880
9881         test_mkdir $DIR/${tdir}f
9882         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9883                 error "setstripe succeeded" || true
9884 }
9885 run_test 65f "dir setstripe permission (should return error) ==="
9886
9887 test_65g() {
9888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9889
9890         # LU-16904 delete layout when root is set as PFL layout
9891         save_layout_restore_at_exit $MOUNT
9892         $LFS setstripe -d $MOUNT || error "setstripe failed"
9893
9894         test_mkdir $DIR/$tdir
9895         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9896
9897         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9898                 error "setstripe -S failed"
9899         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9900         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9901                 error "delete default stripe failed"
9902 }
9903 run_test 65g "directory setstripe -d"
9904
9905 test_65h() {
9906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9907
9908         test_mkdir $DIR/$tdir
9909         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9910
9911         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9912                 error "setstripe -S failed"
9913         test_mkdir $DIR/$tdir/dd1
9914         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9915                 error "stripe info inherit failed"
9916 }
9917 run_test 65h "directory stripe info inherit ===================="
9918
9919 test_65i() {
9920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9921
9922         save_layout_restore_at_exit $MOUNT
9923
9924         # bug6367: set non-default striping on root directory
9925         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9926
9927         # bug12836: getstripe on -1 default directory striping
9928         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9929
9930         # bug12836: getstripe -v on -1 default directory striping
9931         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9932
9933         # bug12836: new find on -1 default directory striping
9934         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9935 }
9936 run_test 65i "various tests to set root directory striping"
9937
9938 test_65j() { # bug6367
9939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9940
9941         sync; sleep 1
9942
9943         # if we aren't already remounting for each test, do so for this test
9944         if [ "$I_MOUNTED" = "yes" ]; then
9945                 cleanup || error "failed to unmount"
9946                 setup
9947         fi
9948
9949         save_layout_restore_at_exit $MOUNT
9950
9951         $LFS setstripe -d $MOUNT || error "setstripe failed"
9952 }
9953 run_test 65j "set default striping on root directory (bug 6367)="
9954
9955 cleanup_65k() {
9956         rm -rf $DIR/$tdir
9957         wait_delete_completed
9958         do_facet $SINGLEMDS "lctl set_param -n \
9959                 osp.$ost*MDT0000.max_create_count=$max_count"
9960         do_facet $SINGLEMDS "lctl set_param -n \
9961                 osp.$ost*MDT0000.create_count=$count"
9962         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9963         echo $INACTIVE_OSC "is Activate"
9964
9965         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9966 }
9967
9968 test_65k() { # bug11679
9969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9970         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9971         remote_mds_nodsh && skip "remote MDS with nodsh"
9972
9973         local disable_precreate=true
9974         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9975                 disable_precreate=false
9976
9977         echo "Check OST status: "
9978         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9979                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9980
9981         for OSC in $MDS_OSCS; do
9982                 echo $OSC "is active"
9983                 do_facet $SINGLEMDS lctl --device %$OSC activate
9984         done
9985
9986         for INACTIVE_OSC in $MDS_OSCS; do
9987                 local ost=$(osc_to_ost $INACTIVE_OSC)
9988                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9989                                lov.*md*.target_obd |
9990                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9991
9992                 mkdir -p $DIR/$tdir
9993                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9994                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9995
9996                 echo "Deactivate: " $INACTIVE_OSC
9997                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9998
9999                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10000                               osp.$ost*MDT0000.create_count")
10001                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10002                                   osp.$ost*MDT0000.max_create_count")
10003                 $disable_precreate &&
10004                         do_facet $SINGLEMDS "lctl set_param -n \
10005                                 osp.$ost*MDT0000.max_create_count=0"
10006
10007                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10008                         [ -f $DIR/$tdir/$idx ] && continue
10009                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10010                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10011                                 { cleanup_65k;
10012                                   error "setstripe $idx should succeed"; }
10013                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10014                 done
10015                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10016                 rmdir $DIR/$tdir
10017
10018                 do_facet $SINGLEMDS "lctl set_param -n \
10019                         osp.$ost*MDT0000.max_create_count=$max_count"
10020                 do_facet $SINGLEMDS "lctl set_param -n \
10021                         osp.$ost*MDT0000.create_count=$count"
10022                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10023                 echo $INACTIVE_OSC "is Activate"
10024
10025                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10026         done
10027 }
10028 run_test 65k "validate manual striping works properly with deactivated OSCs"
10029
10030 test_65l() { # bug 12836
10031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10032
10033         test_mkdir -p $DIR/$tdir/test_dir
10034         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10035         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10036 }
10037 run_test 65l "lfs find on -1 stripe dir ========================"
10038
10039 test_65m() {
10040         local layout=$(save_layout $MOUNT)
10041         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10042                 restore_layout $MOUNT $layout
10043                 error "setstripe should fail by non-root users"
10044         }
10045         true
10046 }
10047 run_test 65m "normal user can't set filesystem default stripe"
10048
10049 test_65n() {
10050         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10051         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10052                 skip "Need MDS version at least 2.12.50"
10053         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10054
10055         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10056         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10057         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10058
10059         save_layout_restore_at_exit $MOUNT
10060
10061         # new subdirectory under root directory should not inherit
10062         # the default layout from root
10063         # LU-16904 check if the root is set as PFL layout
10064         local numcomp=$($LFS getstripe --component-count $MOUNT)
10065
10066         if [[ $numcomp -eq 0 ]]; then
10067                 local dir1=$MOUNT/$tdir-1
10068                 mkdir $dir1 || error "mkdir $dir1 failed"
10069                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10070                         error "$dir1 shouldn't have LOV EA"
10071         fi
10072
10073         # delete the default layout on root directory
10074         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10075
10076         local dir2=$MOUNT/$tdir-2
10077         mkdir $dir2 || error "mkdir $dir2 failed"
10078         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10079                 error "$dir2 shouldn't have LOV EA"
10080
10081         # set a new striping pattern on root directory
10082         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10083         local new_def_stripe_size=$((def_stripe_size * 2))
10084         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10085                 error "set stripe size on $MOUNT failed"
10086
10087         # new file created in $dir2 should inherit the new stripe size from
10088         # the filesystem default
10089         local file2=$dir2/$tfile-2
10090         touch $file2 || error "touch $file2 failed"
10091
10092         local file2_stripe_size=$($LFS getstripe -S $file2)
10093         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10094         {
10095                 echo "file2_stripe_size: '$file2_stripe_size'"
10096                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10097                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10098         }
10099
10100         local dir3=$MOUNT/$tdir-3
10101         mkdir $dir3 || error "mkdir $dir3 failed"
10102         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10103         # the root layout, which is the actual default layout that will be used
10104         # when new files are created in $dir3.
10105         local dir3_layout=$(get_layout_param $dir3)
10106         local root_dir_layout=$(get_layout_param $MOUNT)
10107         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10108         {
10109                 echo "dir3_layout: '$dir3_layout'"
10110                 echo "root_dir_layout: '$root_dir_layout'"
10111                 error "$dir3 should show the default layout from $MOUNT"
10112         }
10113
10114         # set OST pool on root directory
10115         local pool=$TESTNAME
10116         pool_add $pool || error "add $pool failed"
10117         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10118                 error "add targets to $pool failed"
10119
10120         $LFS setstripe -p $pool $MOUNT ||
10121                 error "set OST pool on $MOUNT failed"
10122
10123         # new file created in $dir3 should inherit the pool from
10124         # the filesystem default
10125         local file3=$dir3/$tfile-3
10126         touch $file3 || error "touch $file3 failed"
10127
10128         local file3_pool=$($LFS getstripe -p $file3)
10129         [[ "$file3_pool" = "$pool" ]] ||
10130                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10131
10132         local dir4=$MOUNT/$tdir-4
10133         mkdir $dir4 || error "mkdir $dir4 failed"
10134         local dir4_layout=$(get_layout_param $dir4)
10135         root_dir_layout=$(get_layout_param $MOUNT)
10136         echo "$LFS getstripe -d $dir4"
10137         $LFS getstripe -d $dir4
10138         echo "$LFS getstripe -d $MOUNT"
10139         $LFS getstripe -d $MOUNT
10140         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10141         {
10142                 echo "dir4_layout: '$dir4_layout'"
10143                 echo "root_dir_layout: '$root_dir_layout'"
10144                 error "$dir4 should show the default layout from $MOUNT"
10145         }
10146
10147         # new file created in $dir4 should inherit the pool from
10148         # the filesystem default
10149         local file4=$dir4/$tfile-4
10150         touch $file4 || error "touch $file4 failed"
10151
10152         local file4_pool=$($LFS getstripe -p $file4)
10153         [[ "$file4_pool" = "$pool" ]] ||
10154                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10155
10156         # new subdirectory under non-root directory should inherit
10157         # the default layout from its parent directory
10158         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10159                 error "set directory layout on $dir4 failed"
10160
10161         local dir5=$dir4/$tdir-5
10162         mkdir $dir5 || error "mkdir $dir5 failed"
10163
10164         dir4_layout=$(get_layout_param $dir4)
10165         local dir5_layout=$(get_layout_param $dir5)
10166         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10167         {
10168                 echo "dir4_layout: '$dir4_layout'"
10169                 echo "dir5_layout: '$dir5_layout'"
10170                 error "$dir5 should inherit the default layout from $dir4"
10171         }
10172
10173         # though subdir under ROOT doesn't inherit default layout, but
10174         # its sub dir/file should be created with default layout.
10175         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10176         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10177                 skip "Need MDS version at least 2.12.59"
10178
10179         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10180         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10181         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10182
10183         if [ $default_lmv_hash == "none" ]; then
10184                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10185         else
10186                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10187                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10188         fi
10189
10190         $LFS setdirstripe -D -c 2 $MOUNT ||
10191                 error "setdirstripe -D -c 2 failed"
10192         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10193         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10194         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10195
10196         # $dir4 layout includes pool
10197         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10198         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10199                 error "pool lost on setstripe"
10200         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10201         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10202                 error "pool lost on compound layout setstripe"
10203 }
10204 run_test 65n "don't inherit default layout from root for new subdirectories"
10205
10206 test_65o() {
10207         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10208                 skip "need MDS version at least 2.14.57"
10209
10210         # set OST pool on root directory
10211         local pool=$TESTNAME
10212
10213         pool_add $pool || error "add $pool failed"
10214         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10215                 error "add targets to $pool failed"
10216
10217         local dir1=$MOUNT/$tdir
10218
10219         mkdir $dir1 || error "mkdir $dir1 failed"
10220
10221         # set a new striping pattern on root directory
10222         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10223
10224         $LFS setstripe -p $pool $dir1 ||
10225                 error "set directory layout on $dir1 failed"
10226
10227         # $dir1 layout includes pool
10228         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10229         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10230                 error "pool lost on setstripe"
10231         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10232         $LFS getstripe $dir1
10233         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10234                 error "pool lost on compound layout setstripe"
10235
10236         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10237                 error "setdirstripe failed on sub-dir with inherited pool"
10238         $LFS getstripe $dir1/dir2
10239         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10240                 error "pool lost on compound layout setdirstripe"
10241
10242         $LFS setstripe -E -1 -c 1 $dir1
10243         $LFS getstripe -d $dir1
10244         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10245                 error "pool lost on setstripe"
10246 }
10247 run_test 65o "pool inheritance for mdt component"
10248
10249 test_65p () { # LU-16152
10250         local src_dir=$DIR/$tdir/src_dir
10251         local dst_dir=$DIR/$tdir/dst_dir
10252         local yaml_file=$DIR/$tdir/layout.yaml
10253         local border
10254
10255         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10256                 skip "Need at least version 2.15.51"
10257
10258         test_mkdir -p $src_dir
10259         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10260                 error "failed to setstripe"
10261         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10262                 error "failed to getstripe"
10263
10264         test_mkdir -p $dst_dir
10265         $LFS setstripe --yaml $yaml_file $dst_dir ||
10266                 error "failed to setstripe with yaml file"
10267         border=$($LFS getstripe -d $dst_dir |
10268                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10269                 error "failed to getstripe"
10270
10271         # 2048M is 0x80000000, or 2147483648
10272         (( $border == 2147483648 )) ||
10273                 error "failed to handle huge number in yaml layout"
10274 }
10275 run_test 65p "setstripe with yaml file and huge number"
10276
10277 # bug 2543 - update blocks count on client
10278 test_66() {
10279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10280
10281         local COUNT=${COUNT:-8}
10282         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10283         sync; sync_all_data; sync; sync_all_data
10284         cancel_lru_locks osc
10285         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10286         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10287 }
10288 run_test 66 "update inode blocks count on client ==============="
10289
10290 meminfo() {
10291         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10292 }
10293
10294 swap_used() {
10295         swapon -s | awk '($1 == "'$1'") { print $4 }'
10296 }
10297
10298 # bug5265, obdfilter oa2dentry return -ENOENT
10299 # #define OBD_FAIL_SRV_ENOENT 0x217
10300 test_69() {
10301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10302         remote_ost_nodsh && skip "remote OST with nodsh"
10303
10304         f="$DIR/$tfile"
10305         $LFS setstripe -c 1 -i 0 $f
10306         stack_trap "rm -f $f ${f}.2"
10307
10308         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10309
10310         do_facet ost1 lctl set_param fail_loc=0x217
10311         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10312         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10313
10314         do_facet ost1 lctl set_param fail_loc=0
10315         $DIRECTIO write $f 0 2 || error "write error"
10316
10317         cancel_lru_locks osc
10318         $DIRECTIO read $f 0 1 || error "read error"
10319
10320         do_facet ost1 lctl set_param fail_loc=0x217
10321         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10322
10323         do_facet ost1 lctl set_param fail_loc=0
10324 }
10325 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10326
10327 test_71() {
10328         test_mkdir $DIR/$tdir
10329         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10330         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10331 }
10332 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10333
10334 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10336         [ "$RUNAS_ID" = "$UID" ] &&
10337                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10338         # Check that testing environment is properly set up. Skip if not
10339         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10340                 skip_env "User $RUNAS_ID does not exist - skipping"
10341
10342         touch $DIR/$tfile
10343         chmod 777 $DIR/$tfile
10344         chmod ug+s $DIR/$tfile
10345         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10346                 error "$RUNAS dd $DIR/$tfile failed"
10347         # See if we are still setuid/sgid
10348         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10349                 error "S/gid is not dropped on write"
10350         # Now test that MDS is updated too
10351         cancel_lru_locks mdc
10352         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10353                 error "S/gid is not dropped on MDS"
10354         rm -f $DIR/$tfile
10355 }
10356 run_test 72a "Test that remove suid works properly (bug5695) ===="
10357
10358 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10359         local perm
10360
10361         [ "$RUNAS_ID" = "$UID" ] &&
10362                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10363         [ "$RUNAS_ID" -eq 0 ] &&
10364                 skip_env "RUNAS_ID = 0 -- skipping"
10365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10366         # Check that testing environment is properly set up. Skip if not
10367         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10368                 skip_env "User $RUNAS_ID does not exist - skipping"
10369
10370         touch $DIR/${tfile}-f{g,u}
10371         test_mkdir $DIR/${tfile}-dg
10372         test_mkdir $DIR/${tfile}-du
10373         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10374         chmod g+s $DIR/${tfile}-{f,d}g
10375         chmod u+s $DIR/${tfile}-{f,d}u
10376         for perm in 777 2777 4777; do
10377                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10378                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10379                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10380                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10381         done
10382         true
10383 }
10384 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10385
10386 # bug 3462 - multiple simultaneous MDC requests
10387 test_73() {
10388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10389
10390         test_mkdir $DIR/d73-1
10391         test_mkdir $DIR/d73-2
10392         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10393         pid1=$!
10394
10395         lctl set_param fail_loc=0x80000129
10396         $MULTIOP $DIR/d73-1/f73-2 Oc &
10397         sleep 1
10398         lctl set_param fail_loc=0
10399
10400         $MULTIOP $DIR/d73-2/f73-3 Oc &
10401         pid3=$!
10402
10403         kill -USR1 $pid1
10404         wait $pid1 || return 1
10405
10406         sleep 25
10407
10408         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10409         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10410         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10411
10412         rm -rf $DIR/d73-*
10413 }
10414 run_test 73 "multiple MDC requests (should not deadlock)"
10415
10416 test_74a() { # bug 6149, 6184
10417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10418
10419         touch $DIR/f74a
10420         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10421         #
10422         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10423         # will spin in a tight reconnection loop
10424         $LCTL set_param fail_loc=0x8000030e
10425         # get any lock that won't be difficult - lookup works.
10426         ls $DIR/f74a
10427         $LCTL set_param fail_loc=0
10428         rm -f $DIR/f74a
10429         true
10430 }
10431 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10432
10433 test_74b() { # bug 13310
10434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10435
10436         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10437         #
10438         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10439         # will spin in a tight reconnection loop
10440         $LCTL set_param fail_loc=0x8000030e
10441         # get a "difficult" lock
10442         touch $DIR/f74b
10443         $LCTL set_param fail_loc=0
10444         rm -f $DIR/f74b
10445         true
10446 }
10447 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10448
10449 test_74c() {
10450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10451
10452         #define OBD_FAIL_LDLM_NEW_LOCK
10453         $LCTL set_param fail_loc=0x319
10454         touch $DIR/$tfile && error "touch successful"
10455         $LCTL set_param fail_loc=0
10456         true
10457 }
10458 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10459
10460 slab_lic=/sys/kernel/slab/lustre_inode_cache
10461 num_objects() {
10462         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10463         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10464                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10465 }
10466
10467 test_76a() { # Now for b=20433, added originally in b=1443
10468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10469
10470         cancel_lru_locks osc
10471         # there may be some slab objects cached per core
10472         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10473         local before=$(num_objects)
10474         local count=$((512 * cpus))
10475         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10476         local margin=$((count / 10))
10477         if [[ -f $slab_lic/aliases ]]; then
10478                 local aliases=$(cat $slab_lic/aliases)
10479                 (( aliases > 0 )) && margin=$((margin * aliases))
10480         fi
10481
10482         echo "before slab objects: $before"
10483         for i in $(seq $count); do
10484                 touch $DIR/$tfile
10485                 rm -f $DIR/$tfile
10486         done
10487         cancel_lru_locks osc
10488         local after=$(num_objects)
10489         echo "created: $count, after slab objects: $after"
10490         # shared slab counts are not very accurate, allow significant margin
10491         # the main goal is that the cache growth is not permanently > $count
10492         while (( after > before + margin )); do
10493                 sleep 1
10494                 after=$(num_objects)
10495                 wait=$((wait + 1))
10496                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10497                 if (( wait > 60 )); then
10498                         error "inode slab grew from $before+$margin to $after"
10499                 fi
10500         done
10501 }
10502 run_test 76a "confirm clients recycle inodes properly ===="
10503
10504 test_76b() {
10505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10506         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10507
10508         local count=512
10509         local before=$(num_objects)
10510
10511         for i in $(seq $count); do
10512                 mkdir $DIR/$tdir
10513                 rmdir $DIR/$tdir
10514         done
10515
10516         local after=$(num_objects)
10517         local wait=0
10518
10519         while (( after > before )); do
10520                 sleep 1
10521                 after=$(num_objects)
10522                 wait=$((wait + 1))
10523                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10524                 if (( wait > 60 )); then
10525                         error "inode slab grew from $before to $after"
10526                 fi
10527         done
10528
10529         echo "slab objects before: $before, after: $after"
10530 }
10531 run_test 76b "confirm clients recycle directory inodes properly ===="
10532
10533 export ORIG_CSUM=""
10534 set_checksums()
10535 {
10536         # Note: in sptlrpc modes which enable its own bulk checksum, the
10537         # original crc32_le bulk checksum will be automatically disabled,
10538         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10539         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10540         # In this case set_checksums() will not be no-op, because sptlrpc
10541         # bulk checksum will be enabled all through the test.
10542
10543         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10544         lctl set_param -n osc.*.checksums $1
10545         return 0
10546 }
10547
10548 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10549                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10550 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10551                              tr -d [] | head -n1)}
10552 set_checksum_type()
10553 {
10554         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10555         rc=$?
10556         log "set checksum type to $1, rc = $rc"
10557         return $rc
10558 }
10559
10560 get_osc_checksum_type()
10561 {
10562         # arugment 1: OST name, like OST0000
10563         ost=$1
10564         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10565                         sed 's/.*\[\(.*\)\].*/\1/g')
10566         rc=$?
10567         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10568         echo $checksum_type
10569 }
10570
10571 F77_TMP=$TMP/f77-temp
10572 F77SZ=8
10573 setup_f77() {
10574         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10575                 error "error writing to $F77_TMP"
10576 }
10577
10578 test_77a() { # bug 10889
10579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10580         $GSS && skip_env "could not run with gss"
10581
10582         [ ! -f $F77_TMP ] && setup_f77
10583         set_checksums 1
10584         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10585         set_checksums 0
10586         rm -f $DIR/$tfile
10587 }
10588 run_test 77a "normal checksum read/write operation"
10589
10590 test_77b() { # bug 10889
10591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10592         $GSS && skip_env "could not run with gss"
10593
10594         [ ! -f $F77_TMP ] && setup_f77
10595         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10596         $LCTL set_param fail_loc=0x80000409
10597         set_checksums 1
10598
10599         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10600                 error "dd error: $?"
10601         $LCTL set_param fail_loc=0
10602
10603         for algo in $CKSUM_TYPES; do
10604                 cancel_lru_locks osc
10605                 set_checksum_type $algo
10606                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10607                 $LCTL set_param fail_loc=0x80000408
10608                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10609                 $LCTL set_param fail_loc=0
10610         done
10611         set_checksums 0
10612         set_checksum_type $ORIG_CSUM_TYPE
10613         rm -f $DIR/$tfile
10614 }
10615 run_test 77b "checksum error on client write, read"
10616
10617 cleanup_77c() {
10618         trap 0
10619         set_checksums 0
10620         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10621         $check_ost &&
10622                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10623         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10624         $check_ost && [ -n "$ost_file_prefix" ] &&
10625                 do_facet ost1 rm -f ${ost_file_prefix}\*
10626 }
10627
10628 test_77c() {
10629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10630         $GSS && skip_env "could not run with gss"
10631         remote_ost_nodsh && skip "remote OST with nodsh"
10632
10633         local bad1
10634         local osc_file_prefix
10635         local osc_file
10636         local check_ost=false
10637         local ost_file_prefix
10638         local ost_file
10639         local orig_cksum
10640         local dump_cksum
10641         local fid
10642
10643         # ensure corruption will occur on first OSS/OST
10644         $LFS setstripe -i 0 $DIR/$tfile
10645
10646         [ ! -f $F77_TMP ] && setup_f77
10647         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10648                 error "dd write error: $?"
10649         fid=$($LFS path2fid $DIR/$tfile)
10650
10651         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10652         then
10653                 check_ost=true
10654                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10655                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10656         else
10657                 echo "OSS do not support bulk pages dump upon error"
10658         fi
10659
10660         osc_file_prefix=$($LCTL get_param -n debug_path)
10661         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10662
10663         trap cleanup_77c EXIT
10664
10665         set_checksums 1
10666         # enable bulk pages dump upon error on Client
10667         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10668         # enable bulk pages dump upon error on OSS
10669         $check_ost &&
10670                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10671
10672         # flush Client cache to allow next read to reach OSS
10673         cancel_lru_locks osc
10674
10675         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10676         $LCTL set_param fail_loc=0x80000408
10677         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10678         $LCTL set_param fail_loc=0
10679
10680         rm -f $DIR/$tfile
10681
10682         # check cksum dump on Client
10683         osc_file=$(ls ${osc_file_prefix}*)
10684         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10685         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10686         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10687         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10688         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10689                      cksum)
10690         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10691         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10692                 error "dump content does not match on Client"
10693
10694         $check_ost || skip "No need to check cksum dump on OSS"
10695
10696         # check cksum dump on OSS
10697         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10698         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10699         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10700         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10701         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10702                 error "dump content does not match on OSS"
10703
10704         cleanup_77c
10705 }
10706 run_test 77c "checksum error on client read with debug"
10707
10708 test_77d() { # bug 10889
10709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10710         $GSS && skip_env "could not run with gss"
10711
10712         stack_trap "rm -f $DIR/$tfile"
10713         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10714         $LCTL set_param fail_loc=0x80000409
10715         set_checksums 1
10716         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10717                 error "direct write: rc=$?"
10718         $LCTL set_param fail_loc=0
10719         set_checksums 0
10720
10721         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10722         $LCTL set_param fail_loc=0x80000408
10723         set_checksums 1
10724         cancel_lru_locks osc
10725         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10726                 error "direct read: rc=$?"
10727         $LCTL set_param fail_loc=0
10728         set_checksums 0
10729 }
10730 run_test 77d "checksum error on OST direct write, read"
10731
10732 test_77f() { # bug 10889
10733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10734         $GSS && skip_env "could not run with gss"
10735
10736         set_checksums 1
10737         stack_trap "rm -f $DIR/$tfile"
10738         for algo in $CKSUM_TYPES; do
10739                 cancel_lru_locks osc
10740                 set_checksum_type $algo
10741                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10742                 $LCTL set_param fail_loc=0x409
10743                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10744                         error "direct write succeeded"
10745                 $LCTL set_param fail_loc=0
10746         done
10747         set_checksum_type $ORIG_CSUM_TYPE
10748         set_checksums 0
10749 }
10750 run_test 77f "repeat checksum error on write (expect error)"
10751
10752 test_77g() { # bug 10889
10753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10754         $GSS && skip_env "could not run with gss"
10755         remote_ost_nodsh && skip "remote OST with nodsh"
10756
10757         [ ! -f $F77_TMP ] && setup_f77
10758
10759         local file=$DIR/$tfile
10760         stack_trap "rm -f $file" EXIT
10761
10762         $LFS setstripe -c 1 -i 0 $file
10763         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10764         do_facet ost1 lctl set_param fail_loc=0x8000021a
10765         set_checksums 1
10766         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10767                 error "write error: rc=$?"
10768         do_facet ost1 lctl set_param fail_loc=0
10769         set_checksums 0
10770
10771         cancel_lru_locks osc
10772         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10773         do_facet ost1 lctl set_param fail_loc=0x8000021b
10774         set_checksums 1
10775         cmp $F77_TMP $file || error "file compare failed"
10776         do_facet ost1 lctl set_param fail_loc=0
10777         set_checksums 0
10778 }
10779 run_test 77g "checksum error on OST write, read"
10780
10781 test_77k() { # LU-10906
10782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10783         $GSS && skip_env "could not run with gss"
10784
10785         local cksum_param="osc.$FSNAME*.checksums"
10786         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10787         local checksum
10788         local i
10789
10790         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10791         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10792         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10793
10794         for i in 0 1; do
10795                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10796                         error "failed to set checksum=$i on MGS"
10797                 wait_update $HOSTNAME "$get_checksum" $i
10798                 #remount
10799                 echo "remount client, checksum should be $i"
10800                 remount_client $MOUNT || error "failed to remount client"
10801                 checksum=$(eval $get_checksum)
10802                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10803         done
10804         # remove persistent param to avoid races with checksum mountopt below
10805         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10806                 error "failed to delete checksum on MGS"
10807
10808         for opt in "checksum" "nochecksum"; do
10809                 #remount with mount option
10810                 echo "remount client with option $opt, checksum should be $i"
10811                 umount_client $MOUNT || error "failed to umount client"
10812                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10813                         error "failed to mount client with option '$opt'"
10814                 checksum=$(eval $get_checksum)
10815                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10816                 i=$((i - 1))
10817         done
10818
10819         remount_client $MOUNT || error "failed to remount client"
10820 }
10821 run_test 77k "enable/disable checksum correctly"
10822
10823 test_77l() {
10824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10825         $GSS && skip_env "could not run with gss"
10826
10827         set_checksums 1
10828         stack_trap "set_checksums $ORIG_CSUM" EXIT
10829         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10830
10831         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10832
10833         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10834         for algo in $CKSUM_TYPES; do
10835                 set_checksum_type $algo || error "fail to set checksum type $algo"
10836                 osc_algo=$(get_osc_checksum_type OST0000)
10837                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10838
10839                 # no locks, no reqs to let the connection idle
10840                 cancel_lru_locks osc
10841                 lru_resize_disable osc
10842                 wait_osc_import_state client ost1 IDLE
10843
10844                 # ensure ost1 is connected
10845                 stat $DIR/$tfile >/dev/null || error "can't stat"
10846                 wait_osc_import_state client ost1 FULL
10847
10848                 osc_algo=$(get_osc_checksum_type OST0000)
10849                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10850         done
10851         return 0
10852 }
10853 run_test 77l "preferred checksum type is remembered after reconnected"
10854
10855 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10856 rm -f $F77_TMP
10857 unset F77_TMP
10858
10859 test_77m() {
10860         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10861                 skip "Need at least version 2.14.52"
10862         local param=checksum_speed
10863
10864         $LCTL get_param $param || error "reading $param failed"
10865
10866         csum_speeds=$($LCTL get_param -n $param)
10867
10868         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10869                 error "known checksum types are missing"
10870 }
10871 run_test 77m "Verify checksum_speed is correctly read"
10872
10873 check_filefrag_77n() {
10874         local nr_ext=0
10875         local starts=()
10876         local ends=()
10877
10878         while read extidx a b start end rest; do
10879                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10880                         nr_ext=$(( $nr_ext + 1 ))
10881                         starts+=( ${start%..} )
10882                         ends+=( ${end%:} )
10883                 fi
10884         done < <( filefrag -sv $1 )
10885
10886         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10887         return 1
10888 }
10889
10890 test_77n() {
10891         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10892
10893         touch $DIR/$tfile
10894         $TRUNCATE $DIR/$tfile 0
10895         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10896         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10897         check_filefrag_77n $DIR/$tfile ||
10898                 skip "$tfile blocks not contiguous around hole"
10899
10900         set_checksums 1
10901         stack_trap "set_checksums $ORIG_CSUM" EXIT
10902         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10903         stack_trap "rm -f $DIR/$tfile"
10904
10905         for algo in $CKSUM_TYPES; do
10906                 if [[ "$algo" =~ ^t10 ]]; then
10907                         set_checksum_type $algo ||
10908                                 error "fail to set checksum type $algo"
10909                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10910                                 error "fail to read $tfile with $algo"
10911                 fi
10912         done
10913         rm -f $DIR/$tfile
10914         return 0
10915 }
10916 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10917
10918 test_77o() {
10919         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10920                 skip "Need MDS version at least 2.14.55"
10921         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10922                 skip "Need OST version at least 2.14.55"
10923         local ofd=obdfilter
10924         local mdt=mdt
10925
10926         # print OST checksum_type
10927         echo "$ofd.$FSNAME-*.checksum_type:"
10928         do_nodes $(comma_list $(osts_nodes)) \
10929                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10930
10931         # print MDT checksum_type
10932         echo "$mdt.$FSNAME-*.checksum_type:"
10933         do_nodes $(comma_list $(mdts_nodes)) \
10934                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10935
10936         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10937                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10938
10939         (( $o_count == $OSTCOUNT )) ||
10940                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10941
10942         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10943                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10944
10945         (( $m_count == $MDSCOUNT )) ||
10946                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10947 }
10948 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10949
10950 cleanup_test_78() {
10951         trap 0
10952         rm -f $DIR/$tfile
10953 }
10954
10955 test_78() { # bug 10901
10956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10957         remote_ost || skip_env "local OST"
10958
10959         NSEQ=5
10960         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10961         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10962         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10963         echo "MemTotal: $MEMTOTAL"
10964
10965         # reserve 256MB of memory for the kernel and other running processes,
10966         # and then take 1/2 of the remaining memory for the read/write buffers.
10967         if [ $MEMTOTAL -gt 512 ] ;then
10968                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10969         else
10970                 # for those poor memory-starved high-end clusters...
10971                 MEMTOTAL=$((MEMTOTAL / 2))
10972         fi
10973         echo "Mem to use for directio: $MEMTOTAL"
10974
10975         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10976         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10977         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10978         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10979                 head -n1)
10980         echo "Smallest OST: $SMALLESTOST"
10981         [[ $SMALLESTOST -lt 10240 ]] &&
10982                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10983
10984         trap cleanup_test_78 EXIT
10985
10986         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10987                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10988
10989         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10990         echo "File size: $F78SIZE"
10991         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10992         for i in $(seq 1 $NSEQ); do
10993                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10994                 echo directIO rdwr round $i of $NSEQ
10995                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10996         done
10997
10998         cleanup_test_78
10999 }
11000 run_test 78 "handle large O_DIRECT writes correctly ============"
11001
11002 test_79() { # bug 12743
11003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11004
11005         wait_delete_completed
11006
11007         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11008         BKFREE=$(calc_osc_kbytes kbytesfree)
11009         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11010
11011         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11012         DFTOTAL=`echo $STRING | cut -d, -f1`
11013         DFUSED=`echo $STRING  | cut -d, -f2`
11014         DFAVAIL=`echo $STRING | cut -d, -f3`
11015         DFFREE=$(($DFTOTAL - $DFUSED))
11016
11017         ALLOWANCE=$((64 * $OSTCOUNT))
11018
11019         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11020            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11021                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11022         fi
11023         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11024            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11025                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11026         fi
11027         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11028            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11029                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11030         fi
11031 }
11032 run_test 79 "df report consistency check ======================="
11033
11034 test_80() { # bug 10718
11035         remote_ost_nodsh && skip "remote OST with nodsh"
11036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11037
11038         # relax strong synchronous semantics for slow backends like ZFS
11039         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11040                 local soc="obdfilter.*.sync_lock_cancel"
11041                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11042
11043                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11044                 if [ -z "$save" ]; then
11045                         soc="obdfilter.*.sync_on_lock_cancel"
11046                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11047                 fi
11048
11049                 if [ "$save" != "never" ]; then
11050                         local hosts=$(comma_list $(osts_nodes))
11051
11052                         do_nodes $hosts $LCTL set_param $soc=never
11053                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11054                 fi
11055         fi
11056
11057         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11058         sync; sleep 1; sync
11059         local before=$(date +%s)
11060         cancel_lru_locks osc
11061         local after=$(date +%s)
11062         local diff=$((after - before))
11063         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11064
11065         rm -f $DIR/$tfile
11066 }
11067 run_test 80 "Page eviction is equally fast at high offsets too"
11068
11069 test_81a() { # LU-456
11070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11071         remote_ost_nodsh && skip "remote OST with nodsh"
11072
11073         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11074         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11075         do_facet ost1 lctl set_param fail_loc=0x80000228
11076
11077         # write should trigger a retry and success
11078         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11079         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11080         RC=$?
11081         if [ $RC -ne 0 ] ; then
11082                 error "write should success, but failed for $RC"
11083         fi
11084 }
11085 run_test 81a "OST should retry write when get -ENOSPC ==============="
11086
11087 test_81b() { # LU-456
11088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11089         remote_ost_nodsh && skip "remote OST with nodsh"
11090
11091         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11092         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11093         do_facet ost1 lctl set_param fail_loc=0x228
11094
11095         # write should retry several times and return -ENOSPC finally
11096         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11097         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11098         RC=$?
11099         ENOSPC=28
11100         if [ $RC -ne $ENOSPC ] ; then
11101                 error "dd should fail for -ENOSPC, but succeed."
11102         fi
11103 }
11104 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11105
11106 test_99() {
11107         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11108
11109         test_mkdir $DIR/$tdir.cvsroot
11110         chown $RUNAS_ID $DIR/$tdir.cvsroot
11111
11112         cd $TMP
11113         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11114
11115         cd /etc/init.d
11116         # some versions of cvs import exit(1) when asked to import links or
11117         # files they can't read.  ignore those files.
11118         local toignore=$(find . -type l -printf '-I %f\n' -o \
11119                          ! -perm /4 -printf '-I %f\n')
11120         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11121                 $tdir.reposname vtag rtag
11122
11123         cd $DIR
11124         test_mkdir $DIR/$tdir.reposname
11125         chown $RUNAS_ID $DIR/$tdir.reposname
11126         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11127
11128         cd $DIR/$tdir.reposname
11129         $RUNAS touch foo99
11130         $RUNAS cvs add -m 'addmsg' foo99
11131         $RUNAS cvs update
11132         $RUNAS cvs commit -m 'nomsg' foo99
11133         rm -fr $DIR/$tdir.cvsroot
11134 }
11135 run_test 99 "cvs strange file/directory operations"
11136
11137 test_100() {
11138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11139         [[ "$NETTYPE" =~ tcp ]] ||
11140                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11141         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11142         remote_ost_nodsh && skip "remote OST with nodsh"
11143         remote_mds_nodsh && skip "remote MDS with nodsh"
11144         remote_servers || skip "useless for local single node setup"
11145
11146         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11147                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11148
11149                 rc=0
11150                 if (( ${LOCAL/*:/} >= 1024 )); then
11151                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11152                         ss -tna
11153                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11154                 fi
11155         done
11156         (( $rc == 0 )) || error "privileged port not found" )
11157 }
11158 run_test 100 "check local port using privileged port"
11159
11160 function get_named_value()
11161 {
11162     local tag=$1
11163
11164     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11165 }
11166
11167 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11168                    awk '/^max_cached_mb/ { print $2 }')
11169
11170 cleanup_101a() {
11171         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11172         trap 0
11173 }
11174
11175 test_101a() {
11176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11177
11178         local s
11179         local discard
11180         local nreads=10000
11181         local cache_limit=32
11182
11183         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11184         trap cleanup_101a EXIT
11185         $LCTL set_param -n llite.*.read_ahead_stats=0
11186         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11187
11188         #
11189         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11190         #
11191         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11192         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11193
11194         discard=0
11195         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11196                    get_named_value 'read.but.discarded'); do
11197                         discard=$(($discard + $s))
11198         done
11199         cleanup_101a
11200
11201         $LCTL get_param osc.*-osc*.rpc_stats
11202         $LCTL get_param llite.*.read_ahead_stats
11203
11204         # Discard is generally zero, but sometimes a few random reads line up
11205         # and trigger larger readahead, which is wasted & leads to discards.
11206         if [[ $(($discard)) -gt $nreads ]]; then
11207                 error "too many ($discard) discarded pages"
11208         fi
11209         rm -f $DIR/$tfile || true
11210 }
11211 run_test 101a "check read-ahead for random reads"
11212
11213 setup_test101bc() {
11214         test_mkdir $DIR/$tdir
11215         local ssize=$1
11216         local FILE_LENGTH=$2
11217         STRIPE_OFFSET=0
11218
11219         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11220
11221         local list=$(comma_list $(osts_nodes))
11222         set_osd_param $list '' read_cache_enable 0
11223         set_osd_param $list '' writethrough_cache_enable 0
11224
11225         trap cleanup_test101bc EXIT
11226         # prepare the read-ahead file
11227         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11228
11229         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11230                                 count=$FILE_SIZE_MB 2> /dev/null
11231
11232 }
11233
11234 cleanup_test101bc() {
11235         trap 0
11236         rm -rf $DIR/$tdir
11237         rm -f $DIR/$tfile
11238
11239         local list=$(comma_list $(osts_nodes))
11240         set_osd_param $list '' read_cache_enable 1
11241         set_osd_param $list '' writethrough_cache_enable 1
11242 }
11243
11244 calc_total() {
11245         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11246 }
11247
11248 ra_check_101() {
11249         local read_size=$1
11250         local stripe_size=$2
11251         local stride_length=$((stripe_size / read_size))
11252         local stride_width=$((stride_length * OSTCOUNT))
11253         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11254                                 (stride_width - stride_length) ))
11255         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11256                   get_named_value 'read.but.discarded' | calc_total)
11257
11258         if [[ $discard -gt $discard_limit ]]; then
11259                 $LCTL get_param llite.*.read_ahead_stats
11260                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11261         else
11262                 echo "Read-ahead success for size ${read_size}"
11263         fi
11264 }
11265
11266 test_101b() {
11267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11268         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11269
11270         local STRIPE_SIZE=1048576
11271         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11272
11273         if [ $SLOW == "yes" ]; then
11274                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11275         else
11276                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11277         fi
11278
11279         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11280
11281         # prepare the read-ahead file
11282         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11283         cancel_lru_locks osc
11284         for BIDX in 2 4 8 16 32 64 128 256
11285         do
11286                 local BSIZE=$((BIDX*4096))
11287                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11288                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11289                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11290                 $LCTL set_param -n llite.*.read_ahead_stats=0
11291                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11292                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11293                 cancel_lru_locks osc
11294                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11295         done
11296         cleanup_test101bc
11297         true
11298 }
11299 run_test 101b "check stride-io mode read-ahead ================="
11300
11301 test_101c() {
11302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11303
11304         local STRIPE_SIZE=1048576
11305         local FILE_LENGTH=$((STRIPE_SIZE*100))
11306         local nreads=10000
11307         local rsize=65536
11308         local osc_rpc_stats
11309
11310         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11311
11312         cancel_lru_locks osc
11313         $LCTL set_param osc.*.rpc_stats=0
11314         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11315         $LCTL get_param osc.*.rpc_stats
11316         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11317                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11318                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11319                 local size
11320
11321                 if [ $lines -le 20 ]; then
11322                         echo "continue debug"
11323                         continue
11324                 fi
11325                 for size in 1 2 4 8; do
11326                         local rpc=$(echo "$stats" |
11327                                     awk '($1 == "'$size':") {print $2; exit; }')
11328                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11329                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11330                 done
11331                 echo "$osc_rpc_stats check passed!"
11332         done
11333         cleanup_test101bc
11334         true
11335 }
11336 run_test 101c "check stripe_size aligned read-ahead"
11337
11338 test_101d() {
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340
11341         local file=$DIR/$tfile
11342         local sz_MB=${FILESIZE_101d:-80}
11343         local ra_MB=${READAHEAD_MB:-40}
11344
11345         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11346         [ $free_MB -lt $sz_MB ] &&
11347                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11348
11349         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11350         $LFS setstripe -c -1 $file || error "setstripe failed"
11351
11352         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11353         echo Cancel LRU locks on lustre client to flush the client cache
11354         cancel_lru_locks osc
11355
11356         echo Disable read-ahead
11357         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11358         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11359         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11360         $LCTL get_param -n llite.*.max_read_ahead_mb
11361
11362         echo "Reading the test file $file with read-ahead disabled"
11363         local sz_KB=$((sz_MB * 1024 / 4))
11364         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11365         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11366         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11367                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11368
11369         echo "Cancel LRU locks on lustre client to flush the client cache"
11370         cancel_lru_locks osc
11371         echo Enable read-ahead with ${ra_MB}MB
11372         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11373
11374         echo "Reading the test file $file with read-ahead enabled"
11375         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11376                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11377
11378         echo "read-ahead disabled time read $raOFF"
11379         echo "read-ahead enabled time read $raON"
11380
11381         rm -f $file
11382         wait_delete_completed
11383
11384         # use awk for this check instead of bash because it handles decimals
11385         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11386                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11387 }
11388 run_test 101d "file read with and without read-ahead enabled"
11389
11390 test_101e() {
11391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11392
11393         local file=$DIR/$tfile
11394         local size_KB=500  #KB
11395         local count=100
11396         local bsize=1024
11397
11398         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11399         local need_KB=$((count * size_KB))
11400         [[ $free_KB -le $need_KB ]] &&
11401                 skip_env "Need free space $need_KB, have $free_KB"
11402
11403         echo "Creating $count ${size_KB}K test files"
11404         for ((i = 0; i < $count; i++)); do
11405                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11406         done
11407
11408         echo "Cancel LRU locks on lustre client to flush the client cache"
11409         cancel_lru_locks $OSC
11410
11411         echo "Reset readahead stats"
11412         $LCTL set_param -n llite.*.read_ahead_stats=0
11413
11414         for ((i = 0; i < $count; i++)); do
11415                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11416         done
11417
11418         $LCTL get_param llite.*.max_cached_mb
11419         $LCTL get_param llite.*.read_ahead_stats
11420         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11421                      get_named_value 'misses' | calc_total)
11422
11423         for ((i = 0; i < $count; i++)); do
11424                 rm -rf $file.$i 2>/dev/null
11425         done
11426
11427         #10000 means 20% reads are missing in readahead
11428         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11429 }
11430 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11431
11432 test_101f() {
11433         which iozone || skip_env "no iozone installed"
11434
11435         local old_debug=$($LCTL get_param debug)
11436         old_debug=${old_debug#*=}
11437         $LCTL set_param debug="reada mmap"
11438
11439         # create a test file
11440         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11441
11442         echo Cancel LRU locks on lustre client to flush the client cache
11443         cancel_lru_locks osc
11444
11445         echo Reset readahead stats
11446         $LCTL set_param -n llite.*.read_ahead_stats=0
11447
11448         echo mmap read the file with small block size
11449         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11450                 > /dev/null 2>&1
11451
11452         echo checking missing pages
11453         $LCTL get_param llite.*.read_ahead_stats
11454         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11455                         get_named_value 'misses' | calc_total)
11456
11457         $LCTL set_param debug="$old_debug"
11458         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11459         rm -f $DIR/$tfile
11460 }
11461 run_test 101f "check mmap read performance"
11462
11463 test_101g_brw_size_test() {
11464         local mb=$1
11465         local pages=$((mb * 1048576 / PAGE_SIZE))
11466         local file=$DIR/$tfile
11467
11468         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11469                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11470         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11471                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11472                         return 2
11473         done
11474
11475         stack_trap "rm -f $file" EXIT
11476         $LCTL set_param -n osc.*.rpc_stats=0
11477
11478         # 10 RPCs should be enough for the test
11479         local count=10
11480         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11481                 { error "dd write ${mb} MB blocks failed"; return 3; }
11482         cancel_lru_locks osc
11483         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11484                 { error "dd write ${mb} MB blocks failed"; return 4; }
11485
11486         # calculate number of full-sized read and write RPCs
11487         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11488                 sed -n '/pages per rpc/,/^$/p' |
11489                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11490                 END { print reads,writes }'))
11491         # allow one extra full-sized read RPC for async readahead
11492         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11493                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11494         [[ ${rpcs[1]} == $count ]] ||
11495                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11496 }
11497
11498 test_101g() {
11499         remote_ost_nodsh && skip "remote OST with nodsh"
11500
11501         local rpcs
11502         local osts=$(get_facets OST)
11503         local list=$(comma_list $(osts_nodes))
11504         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11505         local brw_size="obdfilter.*.brw_size"
11506
11507         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11508
11509         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11510
11511         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11512                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11513                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11514            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11515                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11516                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11517
11518                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11519                         suffix="M"
11520
11521                 if [[ $orig_mb -lt 16 ]]; then
11522                         save_lustre_params $osts "$brw_size" > $p
11523                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11524                                 error "set 16MB RPC size failed"
11525
11526                         echo "remount client to enable new RPC size"
11527                         remount_client $MOUNT || error "remount_client failed"
11528                 fi
11529
11530                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11531                 # should be able to set brw_size=12, but no rpc_stats for that
11532                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11533         fi
11534
11535         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11536
11537         if [[ $orig_mb -lt 16 ]]; then
11538                 restore_lustre_params < $p
11539                 remount_client $MOUNT || error "remount_client restore failed"
11540         fi
11541
11542         rm -f $p $DIR/$tfile
11543 }
11544 run_test 101g "Big bulk(4/16 MiB) readahead"
11545
11546 test_101h() {
11547         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11548
11549         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11550                 error "dd 70M file failed"
11551         echo Cancel LRU locks on lustre client to flush the client cache
11552         cancel_lru_locks osc
11553
11554         echo "Reset readahead stats"
11555         $LCTL set_param -n llite.*.read_ahead_stats 0
11556
11557         echo "Read 10M of data but cross 64M bundary"
11558         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11559         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11560                      get_named_value 'misses' | calc_total)
11561         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11562         rm -f $p $DIR/$tfile
11563 }
11564 run_test 101h "Readahead should cover current read window"
11565
11566 test_101i() {
11567         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11568                 error "dd 10M file failed"
11569
11570         local max_per_file_mb=$($LCTL get_param -n \
11571                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11572         cancel_lru_locks osc
11573         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11574         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11575                 error "set max_read_ahead_per_file_mb to 1 failed"
11576
11577         echo "Reset readahead stats"
11578         $LCTL set_param llite.*.read_ahead_stats=0
11579
11580         dd if=$DIR/$tfile of=/dev/null bs=2M
11581
11582         $LCTL get_param llite.*.read_ahead_stats
11583         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11584                      awk '/misses/ { print $2 }')
11585         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11586         rm -f $DIR/$tfile
11587 }
11588 run_test 101i "allow current readahead to exceed reservation"
11589
11590 test_101j() {
11591         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11592                 error "setstripe $DIR/$tfile failed"
11593         local file_size=$((1048576 * 16))
11594         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11595         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11596
11597         echo Disable read-ahead
11598         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11599
11600         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11601         for blk in $PAGE_SIZE 1048576 $file_size; do
11602                 cancel_lru_locks osc
11603                 echo "Reset readahead stats"
11604                 $LCTL set_param -n llite.*.read_ahead_stats=0
11605                 local count=$(($file_size / $blk))
11606                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11607                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11608                              get_named_value 'failed.to.fast.read' | calc_total)
11609                 $LCTL get_param -n llite.*.read_ahead_stats
11610                 [ $miss -eq $count ] || error "expected $count got $miss"
11611         done
11612
11613         rm -f $p $DIR/$tfile
11614 }
11615 run_test 101j "A complete read block should be submitted when no RA"
11616
11617 test_readahead_base() {
11618         local file=$DIR/$tfile
11619         local size=$1
11620         local iosz
11621         local ramax
11622         local ranum
11623
11624         $LCTL set_param -n llite.*.read_ahead_stats=0
11625         # The first page is not accounted into readahead
11626         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11627         iosz=$(((size + 1048575) / 1048576 * 1048576))
11628         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11629
11630         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11631         fallocate -l $size $file || error "failed to fallocate $file"
11632         cancel_lru_locks osc
11633         $MULTIOP $file or${iosz}c || error "failed to read $file"
11634         $LCTL get_param -n llite.*.read_ahead_stats
11635         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11636                 awk '/readahead.pages/ { print $7 }' | calc_total)
11637         (( $ranum <= $ramax )) ||
11638                 error "read-ahead pages is $ranum more than $ramax"
11639         rm -rf $file || error "failed to remove $file"
11640 }
11641
11642 test_101m()
11643 {
11644         local file=$DIR/$tfile
11645         local ramax
11646         local ranum
11647         local size
11648         local iosz
11649
11650         check_set_fallocate_or_skip
11651         stack_trap "rm -f $file" EXIT
11652
11653         test_readahead_base 4096
11654
11655         # file size: 16K = 16384
11656         test_readahead_base 16384
11657         test_readahead_base 16385
11658         test_readahead_base 16383
11659
11660         # file size: 1M + 1 = 1048576 + 1
11661         test_readahead_base 1048577
11662         # file size: 1M + 16K
11663         test_readahead_base $((1048576 + 16384))
11664
11665         # file size: stripe_size * (stripe_count - 1) + 16K
11666         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11667         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11668         # file size: stripe_size * stripe_count + 16K
11669         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11670         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11671         # file size: 2 * stripe_size * stripe_count + 16K
11672         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11673         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11674 }
11675 run_test 101m "read ahead for small file and last stripe of the file"
11676
11677 setup_test102() {
11678         test_mkdir $DIR/$tdir
11679         chown $RUNAS_ID $DIR/$tdir
11680         STRIPE_SIZE=65536
11681         STRIPE_OFFSET=1
11682         STRIPE_COUNT=$OSTCOUNT
11683         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11684
11685         trap cleanup_test102 EXIT
11686         cd $DIR
11687         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11688         cd $DIR/$tdir
11689         for num in 1 2 3 4; do
11690                 for count in $(seq 1 $STRIPE_COUNT); do
11691                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11692                                 local size=`expr $STRIPE_SIZE \* $num`
11693                                 local file=file"$num-$idx-$count"
11694                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11695                         done
11696                 done
11697         done
11698
11699         cd $DIR
11700         $1 tar cf $TMP/f102.tar $tdir --xattrs
11701 }
11702
11703 cleanup_test102() {
11704         trap 0
11705         rm -f $TMP/f102.tar
11706         rm -rf $DIR/d0.sanity/d102
11707 }
11708
11709 test_102a() {
11710         [ "$UID" != 0 ] && skip "must run as root"
11711         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11712                 skip_env "must have user_xattr"
11713
11714         [ -z "$(which setfattr 2>/dev/null)" ] &&
11715                 skip_env "could not find setfattr"
11716
11717         local testfile=$DIR/$tfile
11718
11719         touch $testfile
11720         echo "set/get xattr..."
11721         setfattr -n trusted.name1 -v value1 $testfile ||
11722                 error "setfattr -n trusted.name1=value1 $testfile failed"
11723         getfattr -n trusted.name1 $testfile 2> /dev/null |
11724           grep "trusted.name1=.value1" ||
11725                 error "$testfile missing trusted.name1=value1"
11726
11727         setfattr -n user.author1 -v author1 $testfile ||
11728                 error "setfattr -n user.author1=author1 $testfile failed"
11729         getfattr -n user.author1 $testfile 2> /dev/null |
11730           grep "user.author1=.author1" ||
11731                 error "$testfile missing trusted.author1=author1"
11732
11733         echo "listxattr..."
11734         setfattr -n trusted.name2 -v value2 $testfile ||
11735                 error "$testfile unable to set trusted.name2"
11736         setfattr -n trusted.name3 -v value3 $testfile ||
11737                 error "$testfile unable to set trusted.name3"
11738         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11739             grep "trusted.name" | wc -l) -eq 3 ] ||
11740                 error "$testfile missing 3 trusted.name xattrs"
11741
11742         setfattr -n user.author2 -v author2 $testfile ||
11743                 error "$testfile unable to set user.author2"
11744         setfattr -n user.author3 -v author3 $testfile ||
11745                 error "$testfile unable to set user.author3"
11746         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11747             grep "user.author" | wc -l) -eq 3 ] ||
11748                 error "$testfile missing 3 user.author xattrs"
11749
11750         echo "remove xattr..."
11751         setfattr -x trusted.name1 $testfile ||
11752                 error "$testfile error deleting trusted.name1"
11753         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11754                 error "$testfile did not delete trusted.name1 xattr"
11755
11756         setfattr -x user.author1 $testfile ||
11757                 error "$testfile error deleting user.author1"
11758         echo "set lustre special xattr ..."
11759         $LFS setstripe -c1 $testfile
11760         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11761                 awk -F "=" '/trusted.lov/ { print $2 }' )
11762         setfattr -n "trusted.lov" -v $lovea $testfile ||
11763                 error "$testfile doesn't ignore setting trusted.lov again"
11764         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11765                 error "$testfile allow setting invalid trusted.lov"
11766         rm -f $testfile
11767 }
11768 run_test 102a "user xattr test =================================="
11769
11770 check_102b_layout() {
11771         local layout="$*"
11772         local testfile=$DIR/$tfile
11773
11774         echo "test layout '$layout'"
11775         $LFS setstripe $layout $testfile || error "setstripe failed"
11776         $LFS getstripe -y $testfile
11777
11778         echo "get/set/list trusted.lov xattr ..." # b=10930
11779         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11780         [[ "$value" =~ "trusted.lov" ]] ||
11781                 error "can't get trusted.lov from $testfile"
11782         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11783                 error "getstripe failed"
11784
11785         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11786
11787         value=$(cut -d= -f2 <<<$value)
11788         # LU-13168: truncated xattr should fail if short lov_user_md header
11789         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11790                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11791         for len in $lens; do
11792                 echo "setfattr $len $testfile.2"
11793                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11794                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11795         done
11796         local stripe_size=$($LFS getstripe -S $testfile.2)
11797         local stripe_count=$($LFS getstripe -c $testfile.2)
11798         [[ $stripe_size -eq 65536 ]] ||
11799                 error "stripe size $stripe_size != 65536"
11800         [[ $stripe_count -eq $stripe_count_orig ]] ||
11801                 error "stripe count $stripe_count != $stripe_count_orig"
11802         rm $testfile $testfile.2
11803 }
11804
11805 test_102b() {
11806         [ -z "$(which setfattr 2>/dev/null)" ] &&
11807                 skip_env "could not find setfattr"
11808         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11809
11810         # check plain layout
11811         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11812
11813         # and also check composite layout
11814         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11815
11816 }
11817 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11818
11819 test_102c() {
11820         [ -z "$(which setfattr 2>/dev/null)" ] &&
11821                 skip_env "could not find setfattr"
11822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11823
11824         # b10930: get/set/list lustre.lov xattr
11825         echo "get/set/list lustre.lov xattr ..."
11826         test_mkdir $DIR/$tdir
11827         chown $RUNAS_ID $DIR/$tdir
11828         local testfile=$DIR/$tdir/$tfile
11829         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11830                 error "setstripe failed"
11831         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11832                 error "getstripe failed"
11833         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11834         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11835
11836         local testfile2=${testfile}2
11837         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11838                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11839
11840         $RUNAS $MCREATE $testfile2
11841         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11842         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11843         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11844         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11845         [ $stripe_count -eq $STRIPECOUNT ] ||
11846                 error "stripe count $stripe_count != $STRIPECOUNT"
11847 }
11848 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11849
11850 compare_stripe_info1() {
11851         local stripe_index_all_zero=true
11852
11853         for num in 1 2 3 4; do
11854                 for count in $(seq 1 $STRIPE_COUNT); do
11855                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11856                                 local size=$((STRIPE_SIZE * num))
11857                                 local file=file"$num-$offset-$count"
11858                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11859                                 [[ $stripe_size -ne $size ]] &&
11860                                     error "$file: size $stripe_size != $size"
11861                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11862                                 # allow fewer stripes to be created, ORI-601
11863                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11864                                     error "$file: count $stripe_count != $count"
11865                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11866                                 [[ $stripe_index -ne 0 ]] &&
11867                                         stripe_index_all_zero=false
11868                         done
11869                 done
11870         done
11871         $stripe_index_all_zero &&
11872                 error "all files are being extracted starting from OST index 0"
11873         return 0
11874 }
11875
11876 have_xattrs_include() {
11877         tar --help | grep -q xattrs-include &&
11878                 echo --xattrs-include="lustre.*"
11879 }
11880
11881 test_102d() {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11884
11885         XINC=$(have_xattrs_include)
11886         setup_test102
11887         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11888         cd $DIR/$tdir/$tdir
11889         compare_stripe_info1
11890 }
11891 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11892
11893 test_102f() {
11894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11896
11897         XINC=$(have_xattrs_include)
11898         setup_test102
11899         test_mkdir $DIR/$tdir.restore
11900         cd $DIR
11901         tar cf - --xattrs $tdir | tar xf - \
11902                 -C $DIR/$tdir.restore --xattrs $XINC
11903         cd $DIR/$tdir.restore/$tdir
11904         compare_stripe_info1
11905 }
11906 run_test 102f "tar copy files, not keep osts"
11907
11908 grow_xattr() {
11909         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11910                 skip "must have user_xattr"
11911         [ -z "$(which setfattr 2>/dev/null)" ] &&
11912                 skip_env "could not find setfattr"
11913         [ -z "$(which getfattr 2>/dev/null)" ] &&
11914                 skip_env "could not find getfattr"
11915
11916         local xsize=${1:-1024}  # in bytes
11917         local file=$DIR/$tfile
11918         local value="$(generate_string $xsize)"
11919         local xbig=trusted.big
11920         local toobig=$2
11921
11922         touch $file
11923         log "save $xbig on $file"
11924         if [ -z "$toobig" ]
11925         then
11926                 setfattr -n $xbig -v $value $file ||
11927                         error "saving $xbig on $file failed"
11928         else
11929                 setfattr -n $xbig -v $value $file &&
11930                         error "saving $xbig on $file succeeded"
11931                 return 0
11932         fi
11933
11934         local orig=$(get_xattr_value $xbig $file)
11935         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11936
11937         local xsml=trusted.sml
11938         log "save $xsml on $file"
11939         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11940
11941         local new=$(get_xattr_value $xbig $file)
11942         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11943
11944         log "grow $xsml on $file"
11945         setfattr -n $xsml -v "$value" $file ||
11946                 error "growing $xsml on $file failed"
11947
11948         new=$(get_xattr_value $xbig $file)
11949         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11950         log "$xbig still valid after growing $xsml"
11951
11952         rm -f $file
11953 }
11954
11955 test_102h() { # bug 15777
11956         grow_xattr 1024
11957 }
11958 run_test 102h "grow xattr from inside inode to external block"
11959
11960 test_102ha() {
11961         large_xattr_enabled || skip_env "ea_inode feature disabled"
11962
11963         echo "setting xattr of max xattr size: $(max_xattr_size)"
11964         grow_xattr $(max_xattr_size)
11965
11966         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11967         echo "This should fail:"
11968         grow_xattr $(($(max_xattr_size) + 10)) 1
11969 }
11970 run_test 102ha "grow xattr from inside inode to external inode"
11971
11972 test_102i() { # bug 17038
11973         [ -z "$(which getfattr 2>/dev/null)" ] &&
11974                 skip "could not find getfattr"
11975
11976         touch $DIR/$tfile
11977         ln -s $DIR/$tfile $DIR/${tfile}link
11978         getfattr -n trusted.lov $DIR/$tfile ||
11979                 error "lgetxattr on $DIR/$tfile failed"
11980         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11981                 grep -i "no such attr" ||
11982                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11983         rm -f $DIR/$tfile $DIR/${tfile}link
11984 }
11985 run_test 102i "lgetxattr test on symbolic link ============"
11986
11987 test_102j() {
11988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11990
11991         XINC=$(have_xattrs_include)
11992         setup_test102 "$RUNAS"
11993         chown $RUNAS_ID $DIR/$tdir
11994         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11995         cd $DIR/$tdir/$tdir
11996         compare_stripe_info1 "$RUNAS"
11997 }
11998 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11999
12000 test_102k() {
12001         [ -z "$(which setfattr 2>/dev/null)" ] &&
12002                 skip "could not find setfattr"
12003
12004         touch $DIR/$tfile
12005         # b22187 just check that does not crash for regular file.
12006         setfattr -n trusted.lov $DIR/$tfile
12007         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12008         local test_kdir=$DIR/$tdir
12009         test_mkdir $test_kdir
12010         local default_size=$($LFS getstripe -S $test_kdir)
12011         local default_count=$($LFS getstripe -c $test_kdir)
12012         local default_offset=$($LFS getstripe -i $test_kdir)
12013         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12014                 error 'dir setstripe failed'
12015         setfattr -n trusted.lov $test_kdir
12016         local stripe_size=$($LFS getstripe -S $test_kdir)
12017         local stripe_count=$($LFS getstripe -c $test_kdir)
12018         local stripe_offset=$($LFS getstripe -i $test_kdir)
12019         [ $stripe_size -eq $default_size ] ||
12020                 error "stripe size $stripe_size != $default_size"
12021         [ $stripe_count -eq $default_count ] ||
12022                 error "stripe count $stripe_count != $default_count"
12023         [ $stripe_offset -eq $default_offset ] ||
12024                 error "stripe offset $stripe_offset != $default_offset"
12025         rm -rf $DIR/$tfile $test_kdir
12026 }
12027 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12028
12029 test_102l() {
12030         [ -z "$(which getfattr 2>/dev/null)" ] &&
12031                 skip "could not find getfattr"
12032
12033         # LU-532 trusted. xattr is invisible to non-root
12034         local testfile=$DIR/$tfile
12035
12036         touch $testfile
12037
12038         echo "listxattr as user..."
12039         chown $RUNAS_ID $testfile
12040         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12041             grep -q "trusted" &&
12042                 error "$testfile trusted xattrs are user visible"
12043
12044         return 0;
12045 }
12046 run_test 102l "listxattr size test =================================="
12047
12048 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12049         local path=$DIR/$tfile
12050         touch $path
12051
12052         listxattr_size_check $path || error "listattr_size_check $path failed"
12053 }
12054 run_test 102m "Ensure listxattr fails on small bufffer ========"
12055
12056 cleanup_test102
12057
12058 getxattr() { # getxattr path name
12059         # Return the base64 encoding of the value of xattr name on path.
12060         local path=$1
12061         local name=$2
12062
12063         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12064         # file: $path
12065         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12066         #
12067         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12068
12069         getfattr --absolute-names --encoding=base64 --name=$name $path |
12070                 awk -F= -v name=$name '$1 == name {
12071                         print substr($0, index($0, "=") + 1);
12072         }'
12073 }
12074
12075 test_102n() { # LU-4101 mdt: protect internal xattrs
12076         [ -z "$(which setfattr 2>/dev/null)" ] &&
12077                 skip "could not find setfattr"
12078         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12079         then
12080                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12081         fi
12082
12083         local file0=$DIR/$tfile.0
12084         local file1=$DIR/$tfile.1
12085         local xattr0=$TMP/$tfile.0
12086         local xattr1=$TMP/$tfile.1
12087         local namelist="lov lma lmv link fid version som hsm"
12088         local name
12089         local value
12090
12091         rm -rf $file0 $file1 $xattr0 $xattr1
12092         touch $file0 $file1
12093
12094         # Get 'before' xattrs of $file1.
12095         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12096
12097         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12098                 namelist+=" lfsck_namespace"
12099         for name in $namelist; do
12100                 # Try to copy xattr from $file0 to $file1.
12101                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12102
12103                 setfattr --name=trusted.$name --value="$value" $file1 ||
12104                         error "setxattr 'trusted.$name' failed"
12105
12106                 # Try to set a garbage xattr.
12107                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12108
12109                 if [[ x$name == "xlov" ]]; then
12110                         setfattr --name=trusted.lov --value="$value" $file1 &&
12111                         error "setxattr invalid 'trusted.lov' success"
12112                 else
12113                         setfattr --name=trusted.$name --value="$value" $file1 ||
12114                                 error "setxattr invalid 'trusted.$name' failed"
12115                 fi
12116
12117                 # Try to remove the xattr from $file1. We don't care if this
12118                 # appears to succeed or fail, we just don't want there to be
12119                 # any changes or crashes.
12120                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12121         done
12122
12123         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12124         then
12125                 name="lfsck_ns"
12126                 # Try to copy xattr from $file0 to $file1.
12127                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12128
12129                 setfattr --name=trusted.$name --value="$value" $file1 ||
12130                         error "setxattr 'trusted.$name' failed"
12131
12132                 # Try to set a garbage xattr.
12133                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12134
12135                 setfattr --name=trusted.$name --value="$value" $file1 ||
12136                         error "setxattr 'trusted.$name' failed"
12137
12138                 # Try to remove the xattr from $file1. We don't care if this
12139                 # appears to succeed or fail, we just don't want there to be
12140                 # any changes or crashes.
12141                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12142         fi
12143
12144         # Get 'after' xattrs of file1.
12145         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12146
12147         if ! diff $xattr0 $xattr1; then
12148                 error "before and after xattrs of '$file1' differ"
12149         fi
12150
12151         rm -rf $file0 $file1 $xattr0 $xattr1
12152
12153         return 0
12154 }
12155 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12156
12157 test_102p() { # LU-4703 setxattr did not check ownership
12158         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12159                 skip "MDS needs to be at least 2.5.56"
12160
12161         local testfile=$DIR/$tfile
12162
12163         touch $testfile
12164
12165         echo "setfacl as user..."
12166         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12167         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12168
12169         echo "setfattr as user..."
12170         setfacl -m "u:$RUNAS_ID:---" $testfile
12171         $RUNAS setfattr -x system.posix_acl_access $testfile
12172         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12173 }
12174 run_test 102p "check setxattr(2) correctly fails without permission"
12175
12176 test_102q() {
12177         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12178                 skip "MDS needs to be at least 2.6.92"
12179
12180         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12181 }
12182 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12183
12184 test_102r() {
12185         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12186                 skip "MDS needs to be at least 2.6.93"
12187
12188         touch $DIR/$tfile || error "touch"
12189         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12190         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12191         rm $DIR/$tfile || error "rm"
12192
12193         #normal directory
12194         mkdir -p $DIR/$tdir || error "mkdir"
12195         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12196         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12197         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12198                 error "$testfile error deleting user.author1"
12199         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12200                 grep "user.$(basename $tdir)" &&
12201                 error "$tdir did not delete user.$(basename $tdir)"
12202         rmdir $DIR/$tdir || error "rmdir"
12203
12204         #striped directory
12205         test_mkdir $DIR/$tdir
12206         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12207         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12208         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12209                 error "$testfile error deleting user.author1"
12210         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12211                 grep "user.$(basename $tdir)" &&
12212                 error "$tdir did not delete user.$(basename $tdir)"
12213         rmdir $DIR/$tdir || error "rm striped dir"
12214 }
12215 run_test 102r "set EAs with empty values"
12216
12217 test_102s() {
12218         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12219                 skip "MDS needs to be at least 2.11.52"
12220
12221         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12222
12223         save_lustre_params client "llite.*.xattr_cache" > $save
12224
12225         for cache in 0 1; do
12226                 lctl set_param llite.*.xattr_cache=$cache
12227
12228                 rm -f $DIR/$tfile
12229                 touch $DIR/$tfile || error "touch"
12230                 for prefix in lustre security system trusted user; do
12231                         # Note getxattr() may fail with 'Operation not
12232                         # supported' or 'No such attribute' depending
12233                         # on prefix and cache.
12234                         getfattr -n $prefix.n102s $DIR/$tfile &&
12235                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12236                 done
12237         done
12238
12239         restore_lustre_params < $save
12240 }
12241 run_test 102s "getting nonexistent xattrs should fail"
12242
12243 test_102t() {
12244         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12245                 skip "MDS needs to be at least 2.11.52"
12246
12247         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12248
12249         save_lustre_params client "llite.*.xattr_cache" > $save
12250
12251         for cache in 0 1; do
12252                 lctl set_param llite.*.xattr_cache=$cache
12253
12254                 for buf_size in 0 256; do
12255                         rm -f $DIR/$tfile
12256                         touch $DIR/$tfile || error "touch"
12257                         setfattr -n user.multiop $DIR/$tfile
12258                         $MULTIOP $DIR/$tfile oa$buf_size ||
12259                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12260                 done
12261         done
12262
12263         restore_lustre_params < $save
12264 }
12265 run_test 102t "zero length xattr values handled correctly"
12266
12267 run_acl_subtest()
12268 {
12269         local test=$LUSTRE/tests/acl/$1.test
12270         local tmp=$(mktemp -t $1-XXXXXX).test
12271         local bin=$2
12272         local dmn=$3
12273         local grp=$4
12274         local nbd=$5
12275         export LANG=C
12276
12277
12278         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12279         local sedgroups="-e s/:users/:$grp/g"
12280         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12281
12282         sed $sedusers $sedgroups < $test > $tmp
12283         stack_trap "rm -f $tmp"
12284         [[ -s $tmp ]] || error "sed failed to create test script"
12285
12286         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12287         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12288 }
12289
12290 test_103a() {
12291         [ "$UID" != 0 ] && skip "must run as root"
12292         $GSS && skip_env "could not run under gss"
12293         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12294                 skip_env "must have acl enabled"
12295         which setfacl || skip_env "could not find setfacl"
12296         remote_mds_nodsh && skip "remote MDS with nodsh"
12297
12298         local mdts=$(comma_list $(mdts_nodes))
12299         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12300
12301         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12302         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12303
12304         ACLBIN=${ACLBIN:-"bin"}
12305         ACLDMN=${ACLDMN:-"daemon"}
12306         ACLGRP=${ACLGRP:-"users"}
12307         ACLNBD=${ACLNBD:-"nobody"}
12308
12309         if ! id $ACLBIN ||
12310            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12311                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12312                 ACLBIN=$USER0
12313                 if ! id $ACLBIN ; then
12314                         cat /etc/passwd
12315                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12316                 fi
12317         fi
12318         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12319            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12320                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12321                 ACLDMN=$USER1
12322                 if ! id $ACLDMN ; then
12323                         cat /etc/passwd
12324                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12325                 fi
12326         fi
12327         if ! getent group $ACLGRP; then
12328                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12329                 ACLGRP="$TSTUSR"
12330                 if ! getent group $ACLGRP; then
12331                         echo "cannot find group '$ACLGRP', adding it"
12332                         cat /etc/group
12333                         add_group 60000 $ACLGRP
12334                 fi
12335         fi
12336
12337         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12338         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12339         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12340
12341         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12342                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12343                 ACLGRP="$TSTUSR"
12344                 if ! getent group $ACLGRP; then
12345                         echo "cannot find group '$ACLGRP', adding it"
12346                         cat /etc/group
12347                         add_group 60000 $ACLGRP
12348                 fi
12349                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12350                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12351                         cat /etc/group
12352                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12353                 fi
12354         fi
12355
12356         gpasswd -a $ACLDMN $ACLBIN ||
12357                 error "setting client group failed"             # LU-5641
12358         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12359                 error "setting MDS group failed"                # LU-5641
12360
12361         declare -a identity_old
12362
12363         for num in $(seq $MDSCOUNT); do
12364                 switch_identity $num true || identity_old[$num]=$?
12365         done
12366
12367         SAVE_UMASK=$(umask)
12368         umask 0022
12369         mkdir -p $DIR/$tdir
12370         cd $DIR/$tdir
12371
12372         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12373         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12374         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12375         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12376         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12377         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12378         if ! id -u $ACLNBD ||
12379            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12380                 ACLNBD="nfsnobody"
12381                 if ! id -u $ACLNBD; then
12382                         ACLNBD=""
12383                 fi
12384         fi
12385         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12386                 add_group $(id -u $ACLNBD) $ACLNBD
12387                 if ! getent group $ACLNBD; then
12388                         ACLNBD=""
12389                 fi
12390         fi
12391         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12392            [[ -n "$ACLNBD" ]] && which setfattr; then
12393                 run_acl_subtest permissions_xattr \
12394                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12395         elif [[ -z "$ACLNBD" ]]; then
12396                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12397         else
12398                 echo "skip 'permission_xattr' test - missing setfattr command"
12399         fi
12400         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12401
12402         # inheritance test got from HP
12403         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12404         chmod +x make-tree || error "chmod +x failed"
12405         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12406         rm -f make-tree
12407
12408         echo "LU-974 ignore umask when acl is enabled..."
12409         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12410         if [ $MDSCOUNT -ge 2 ]; then
12411                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12412         fi
12413
12414         echo "LU-2561 newly created file is same size as directory..."
12415         if [ "$mds1_FSTYPE" != "zfs" ]; then
12416                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12417         else
12418                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12419         fi
12420
12421         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12422
12423         cd $SAVE_PWD
12424         umask $SAVE_UMASK
12425
12426         for num in $(seq $MDSCOUNT); do
12427                 if [ "${identity_old[$num]}" = 1 ]; then
12428                         switch_identity $num false || identity_old[$num]=$?
12429                 fi
12430         done
12431 }
12432 run_test 103a "acl test"
12433
12434 test_103b() {
12435         declare -a pids
12436         local U
12437
12438         stack_trap "rm -f $DIR/$tfile.*"
12439         for U in {0..511}; do
12440                 {
12441                 local O=$(printf "%04o" $U)
12442
12443                 umask $(printf "%04o" $((511 ^ $O)))
12444                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12445                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12446
12447                 (( $S == ($O & 0666) )) ||
12448                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12449
12450                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12451                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12452                 (( $S == ($O & 0666) )) ||
12453                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12454
12455                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12456                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12457                 (( $S == ($O & 0666) )) ||
12458                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12459                 rm -f $DIR/$tfile.[smp]$0
12460                 } &
12461                 local pid=$!
12462
12463                 # limit the concurrently running threads to 64. LU-11878
12464                 local idx=$((U % 64))
12465                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12466                 pids[idx]=$pid
12467         done
12468         wait
12469 }
12470 run_test 103b "umask lfs setstripe"
12471
12472 test_103c() {
12473         mkdir -p $DIR/$tdir
12474         cp -rp $DIR/$tdir $DIR/$tdir.bak
12475
12476         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12477                 error "$DIR/$tdir shouldn't contain default ACL"
12478         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12479                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12480         true
12481 }
12482 run_test 103c "'cp -rp' won't set empty acl"
12483
12484 test_103e() {
12485         local numacl
12486         local fileacl
12487         local saved_debug=$($LCTL get_param -n debug)
12488
12489         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12490                 skip "MDS needs to be at least 2.14.52"
12491
12492         large_xattr_enabled || skip_env "ea_inode feature disabled"
12493
12494         mkdir -p $DIR/$tdir
12495         # add big LOV EA to cause reply buffer overflow earlier
12496         $LFS setstripe -C 1000 $DIR/$tdir
12497         lctl set_param mdc.*-mdc*.stats=clear
12498
12499         $LCTL set_param debug=0
12500         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12501         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12502
12503         # add a large number of default ACLs (expect 8000+ for 2.13+)
12504         for U in {2..7000}; do
12505                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12506                         error "Able to add just $U default ACLs"
12507         done
12508         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12509         echo "$numacl default ACLs created"
12510
12511         stat $DIR/$tdir || error "Cannot stat directory"
12512         # check file creation
12513         touch $DIR/$tdir/$tfile ||
12514                 error "failed to create $tfile with $numacl default ACLs"
12515         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12516         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12517         echo "$fileacl ACLs were inherited"
12518         (( $fileacl == $numacl )) ||
12519                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12520         # check that new ACLs creation adds new ACLs to inherited ACLs
12521         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12522                 error "Cannot set new ACL"
12523         numacl=$((numacl + 1))
12524         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12525         (( $fileacl == $numacl )) ||
12526                 error "failed to add new ACL: $fileacl != $numacl as expected"
12527         # adds more ACLs to a file to reach their maximum at 8000+
12528         numacl=0
12529         for U in {20000..25000}; do
12530                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12531                 numacl=$((numacl + 1))
12532         done
12533         echo "Added $numacl more ACLs to the file"
12534         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12535         echo "Total $fileacl ACLs in file"
12536         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12537         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12538         rmdir $DIR/$tdir || error "Cannot remove directory"
12539 }
12540 run_test 103e "inheritance of big amount of default ACLs"
12541
12542 test_103f() {
12543         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12544                 skip "MDS needs to be at least 2.14.51"
12545
12546         large_xattr_enabled || skip_env "ea_inode feature disabled"
12547
12548         # enable changelog to consume more internal MDD buffers
12549         changelog_register
12550
12551         mkdir -p $DIR/$tdir
12552         # add big LOV EA
12553         $LFS setstripe -C 1000 $DIR/$tdir
12554         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12555         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12556         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12557         rmdir $DIR/$tdir || error "Cannot remove directory"
12558 }
12559 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12560
12561 test_104a() {
12562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12563
12564         touch $DIR/$tfile
12565         lfs df || error "lfs df failed"
12566         lfs df -ih || error "lfs df -ih failed"
12567         lfs df -h $DIR || error "lfs df -h $DIR failed"
12568         lfs df -i $DIR || error "lfs df -i $DIR failed"
12569         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12570         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12571
12572         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12573         lctl --device %$OSC deactivate
12574         lfs df || error "lfs df with deactivated OSC failed"
12575         lctl --device %$OSC activate
12576         # wait the osc back to normal
12577         wait_osc_import_ready client ost
12578
12579         lfs df || error "lfs df with reactivated OSC failed"
12580         rm -f $DIR/$tfile
12581 }
12582 run_test 104a "lfs df [-ih] [path] test ========================="
12583
12584 test_104b() {
12585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12586         [ $RUNAS_ID -eq $UID ] &&
12587                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12588
12589         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12590                         grep "Permission denied" | wc -l)))
12591         if [ $denied_cnt -ne 0 ]; then
12592                 error "lfs check servers test failed"
12593         fi
12594 }
12595 run_test 104b "$RUNAS lfs check servers test ===================="
12596
12597 #
12598 # Verify $1 is within range of $2.
12599 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12600 # $1 is <= 2% of $2. Else Fail.
12601 #
12602 value_in_range() {
12603         # Strip all units (M, G, T)
12604         actual=$(echo $1 | tr -d A-Z)
12605         expect=$(echo $2 | tr -d A-Z)
12606
12607         expect_lo=$(($expect * 98 / 100)) # 2% below
12608         expect_hi=$(($expect * 102 / 100)) # 2% above
12609
12610         # permit 2% drift above and below
12611         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12612 }
12613
12614 test_104c() {
12615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12616         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12617
12618         local ost_param="osd-zfs.$FSNAME-OST0000."
12619         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12620         local ofacets=$(get_facets OST)
12621         local mfacets=$(get_facets MDS)
12622         local saved_ost_blocks=
12623         local saved_mdt_blocks=
12624
12625         echo "Before recordsize change"
12626         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12627         df=($(df -h | grep "$MOUNT"$))
12628
12629         # For checking.
12630         echo "lfs output : ${lfs_df[*]}"
12631         echo "df  output : ${df[*]}"
12632
12633         for facet in ${ofacets//,/ }; do
12634                 if [ -z $saved_ost_blocks ]; then
12635                         saved_ost_blocks=$(do_facet $facet \
12636                                 lctl get_param -n $ost_param.blocksize)
12637                         echo "OST Blocksize: $saved_ost_blocks"
12638                 fi
12639                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12640                 do_facet $facet zfs set recordsize=32768 $ost
12641         done
12642
12643         # BS too small. Sufficient for functional testing.
12644         for facet in ${mfacets//,/ }; do
12645                 if [ -z $saved_mdt_blocks ]; then
12646                         saved_mdt_blocks=$(do_facet $facet \
12647                                 lctl get_param -n $mdt_param.blocksize)
12648                         echo "MDT Blocksize: $saved_mdt_blocks"
12649                 fi
12650                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12651                 do_facet $facet zfs set recordsize=32768 $mdt
12652         done
12653
12654         # Give new values chance to reflect change
12655         sleep 2
12656
12657         echo "After recordsize change"
12658         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12659         df_after=($(df -h | grep "$MOUNT"$))
12660
12661         # For checking.
12662         echo "lfs output : ${lfs_df_after[*]}"
12663         echo "df  output : ${df_after[*]}"
12664
12665         # Verify lfs df
12666         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12667                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12668         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12669                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12670         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12671                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12672
12673         # Verify df
12674         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12675                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12676         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12677                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12678         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12679                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12680
12681         # Restore MDT recordize back to original
12682         for facet in ${mfacets//,/ }; do
12683                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12684                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12685         done
12686
12687         # Restore OST recordize back to original
12688         for facet in ${ofacets//,/ }; do
12689                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12690                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12691         done
12692
12693         return 0
12694 }
12695 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12696
12697 test_104d() {
12698         (( $RUNAS_ID != $UID )) ||
12699                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12700
12701         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12702                 skip "lustre version doesn't support lctl dl with non-root"
12703
12704         # debugfs only allows root users to access files, so the
12705         # previous move of the "devices" file to debugfs broke
12706         # "lctl dl" for non-root users. The LU-9680 Netlink
12707         # interface again allows non-root users to list devices.
12708         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12709                 error "lctl dl doesn't work for non root"
12710
12711         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12712         [ "$ost_count" -eq $OSTCOUNT ]  ||
12713                 error "lctl dl reports wrong number of OST devices"
12714
12715         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12716         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12717                 error "lctl dl reports wrong number of MDT devices"
12718 }
12719 run_test 104d "$RUNAS lctl dl test"
12720
12721 test_105a() {
12722         # doesn't work on 2.4 kernels
12723         touch $DIR/$tfile
12724         if $(flock_is_enabled); then
12725                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12726         else
12727                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12728         fi
12729         rm -f $DIR/$tfile
12730 }
12731 run_test 105a "flock when mounted without -o flock test ========"
12732
12733 test_105b() {
12734         touch $DIR/$tfile
12735         if $(flock_is_enabled); then
12736                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12737         else
12738                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12739         fi
12740         rm -f $DIR/$tfile
12741 }
12742 run_test 105b "fcntl when mounted without -o flock test ========"
12743
12744 test_105c() {
12745         touch $DIR/$tfile
12746         if $(flock_is_enabled); then
12747                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12748         else
12749                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12750         fi
12751         rm -f $DIR/$tfile
12752 }
12753 run_test 105c "lockf when mounted without -o flock test"
12754
12755 test_105d() { # bug 15924
12756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12757
12758         test_mkdir $DIR/$tdir
12759         flock_is_enabled || skip_env "mount w/o flock enabled"
12760         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12761         $LCTL set_param fail_loc=0x80000315
12762         flocks_test 2 $DIR/$tdir
12763 }
12764 run_test 105d "flock race (should not freeze) ========"
12765
12766 test_105e() { # bug 22660 && 22040
12767         flock_is_enabled || skip_env "mount w/o flock enabled"
12768
12769         touch $DIR/$tfile
12770         flocks_test 3 $DIR/$tfile
12771 }
12772 run_test 105e "Two conflicting flocks from same process"
12773
12774 test_106() { #bug 10921
12775         test_mkdir $DIR/$tdir
12776         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12777         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12778 }
12779 run_test 106 "attempt exec of dir followed by chown of that dir"
12780
12781 test_107() {
12782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12783
12784         CDIR=`pwd`
12785         local file=core
12786
12787         cd $DIR
12788         rm -f $file
12789
12790         local save_pattern=$(sysctl -n kernel.core_pattern)
12791         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12792         sysctl -w kernel.core_pattern=$file
12793         sysctl -w kernel.core_uses_pid=0
12794
12795         ulimit -c unlimited
12796         sleep 60 &
12797         SLEEPPID=$!
12798
12799         sleep 1
12800
12801         kill -s 11 $SLEEPPID
12802         wait $SLEEPPID
12803         if [ -e $file ]; then
12804                 size=`stat -c%s $file`
12805                 [ $size -eq 0 ] && error "Fail to create core file $file"
12806         else
12807                 error "Fail to create core file $file"
12808         fi
12809         rm -f $file
12810         sysctl -w kernel.core_pattern=$save_pattern
12811         sysctl -w kernel.core_uses_pid=$save_uses_pid
12812         cd $CDIR
12813 }
12814 run_test 107 "Coredump on SIG"
12815
12816 test_110() {
12817         test_mkdir $DIR/$tdir
12818         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12819         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12820                 error "mkdir with 256 char should fail, but did not"
12821         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12822                 error "create with 255 char failed"
12823         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12824                 error "create with 256 char should fail, but did not"
12825
12826         ls -l $DIR/$tdir
12827         rm -rf $DIR/$tdir
12828 }
12829 run_test 110 "filename length checking"
12830
12831 test_116a() { # was previously test_116()
12832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12834         remote_mds_nodsh && skip "remote MDS with nodsh"
12835
12836         echo -n "Free space priority "
12837         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12838                 head -n1
12839         declare -a AVAIL
12840         free_min_max
12841
12842         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12843         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12844         stack_trap simple_cleanup_common
12845
12846         # Check if we need to generate uneven OSTs
12847         test_mkdir -p $DIR/$tdir/OST${MINI}
12848         local FILL=$((MINV / 4))
12849         local DIFF=$((MAXV - MINV))
12850         local DIFF2=$((DIFF * 100 / MINV))
12851
12852         local threshold=$(do_facet $SINGLEMDS \
12853                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12854         threshold=${threshold%%%}
12855         echo -n "Check for uneven OSTs: "
12856         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12857
12858         if [[ $DIFF2 -gt $threshold ]]; then
12859                 echo "ok"
12860                 echo "Don't need to fill OST$MINI"
12861         else
12862                 # generate uneven OSTs. Write 2% over the QOS threshold value
12863                 echo "no"
12864                 DIFF=$((threshold - DIFF2 + 2))
12865                 DIFF2=$((MINV * DIFF / 100))
12866                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12867                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12868                         error "setstripe failed"
12869                 DIFF=$((DIFF2 / 2048))
12870                 i=0
12871                 while [ $i -lt $DIFF ]; do
12872                         i=$((i + 1))
12873                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12874                                 bs=2M count=1 2>/dev/null
12875                         echo -n .
12876                 done
12877                 echo .
12878                 sync
12879                 sleep_maxage
12880                 free_min_max
12881         fi
12882
12883         DIFF=$((MAXV - MINV))
12884         DIFF2=$((DIFF * 100 / MINV))
12885         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12886         if [ $DIFF2 -gt $threshold ]; then
12887                 echo "ok"
12888         else
12889                 skip "QOS imbalance criteria not met"
12890         fi
12891
12892         MINI1=$MINI
12893         MINV1=$MINV
12894         MAXI1=$MAXI
12895         MAXV1=$MAXV
12896
12897         # now fill using QOS
12898         $LFS setstripe -c 1 $DIR/$tdir
12899         FILL=$((FILL / 200))
12900         if [ $FILL -gt 600 ]; then
12901                 FILL=600
12902         fi
12903         echo "writing $FILL files to QOS-assigned OSTs"
12904         i=0
12905         while [ $i -lt $FILL ]; do
12906                 i=$((i + 1))
12907                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12908                         count=1 2>/dev/null
12909                 echo -n .
12910         done
12911         echo "wrote $i 200k files"
12912         sync
12913         sleep_maxage
12914
12915         echo "Note: free space may not be updated, so measurements might be off"
12916         free_min_max
12917         DIFF2=$((MAXV - MINV))
12918         echo "free space delta: orig $DIFF final $DIFF2"
12919         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12920         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12921         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12922         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12923         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12924         if [[ $DIFF -gt 0 ]]; then
12925                 FILL=$((DIFF2 * 100 / DIFF - 100))
12926                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12927         fi
12928
12929         # Figure out which files were written where
12930         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12931                awk '/'$MINI1': / {print $2; exit}')
12932         echo $UUID
12933         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12934         echo "$MINC files created on smaller OST $MINI1"
12935         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12936                awk '/'$MAXI1': / {print $2; exit}')
12937         echo $UUID
12938         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12939         echo "$MAXC files created on larger OST $MAXI1"
12940         if [[ $MINC -gt 0 ]]; then
12941                 FILL=$((MAXC * 100 / MINC - 100))
12942                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12943         fi
12944         [[ $MAXC -gt $MINC ]] ||
12945                 error_ignore LU-9 "stripe QOS didn't balance free space"
12946 }
12947 run_test 116a "stripe QOS: free space balance ==================="
12948
12949 test_116b() { # LU-2093
12950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12951         remote_mds_nodsh && skip "remote MDS with nodsh"
12952
12953 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12954         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12955                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12956         [ -z "$old_rr" ] && skip "no QOS"
12957         do_facet $SINGLEMDS lctl set_param \
12958                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12959         mkdir -p $DIR/$tdir
12960         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12961         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12962         do_facet $SINGLEMDS lctl set_param fail_loc=0
12963         rm -rf $DIR/$tdir
12964         do_facet $SINGLEMDS lctl set_param \
12965                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12966 }
12967 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12968
12969 test_117() # bug 10891
12970 {
12971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12972
12973         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12974         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12975         lctl set_param fail_loc=0x21e
12976         > $DIR/$tfile || error "truncate failed"
12977         lctl set_param fail_loc=0
12978         echo "Truncate succeeded."
12979         rm -f $DIR/$tfile
12980 }
12981 run_test 117 "verify osd extend =========="
12982
12983 NO_SLOW_RESENDCOUNT=4
12984 export OLD_RESENDCOUNT=""
12985 set_resend_count () {
12986         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12987         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12988         lctl set_param -n $PROC_RESENDCOUNT $1
12989         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12990 }
12991
12992 # for reduce test_118* time (b=14842)
12993 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12994
12995 # Reset async IO behavior after error case
12996 reset_async() {
12997         FILE=$DIR/reset_async
12998
12999         # Ensure all OSCs are cleared
13000         $LFS setstripe -c -1 $FILE
13001         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13002         sync
13003         rm $FILE
13004 }
13005
13006 test_118a() #bug 11710
13007 {
13008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13009
13010         reset_async
13011
13012         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13013         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13014         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13015
13016         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13017                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13018                 return 1;
13019         fi
13020         rm -f $DIR/$tfile
13021 }
13022 run_test 118a "verify O_SYNC works =========="
13023
13024 test_118b()
13025 {
13026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13027         remote_ost_nodsh && skip "remote OST with nodsh"
13028
13029         reset_async
13030
13031         #define OBD_FAIL_SRV_ENOENT 0x217
13032         set_nodes_failloc "$(osts_nodes)" 0x217
13033         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13034         RC=$?
13035         set_nodes_failloc "$(osts_nodes)" 0
13036         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13037         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13038                     grep -c writeback)
13039
13040         if [[ $RC -eq 0 ]]; then
13041                 error "Must return error due to dropped pages, rc=$RC"
13042                 return 1;
13043         fi
13044
13045         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13046                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13047                 return 1;
13048         fi
13049
13050         echo "Dirty pages not leaked on ENOENT"
13051
13052         # Due to the above error the OSC will issue all RPCs syncronously
13053         # until a subsequent RPC completes successfully without error.
13054         $MULTIOP $DIR/$tfile Ow4096yc
13055         rm -f $DIR/$tfile
13056
13057         return 0
13058 }
13059 run_test 118b "Reclaim dirty pages on fatal error =========="
13060
13061 test_118c()
13062 {
13063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13064
13065         # for 118c, restore the original resend count, LU-1940
13066         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13067                                 set_resend_count $OLD_RESENDCOUNT
13068         remote_ost_nodsh && skip "remote OST with nodsh"
13069
13070         reset_async
13071
13072         #define OBD_FAIL_OST_EROFS               0x216
13073         set_nodes_failloc "$(osts_nodes)" 0x216
13074
13075         # multiop should block due to fsync until pages are written
13076         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13077         MULTIPID=$!
13078         sleep 1
13079
13080         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13081                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13082         fi
13083
13084         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13085                     grep -c writeback)
13086         if [[ $WRITEBACK -eq 0 ]]; then
13087                 error "No page in writeback, writeback=$WRITEBACK"
13088         fi
13089
13090         set_nodes_failloc "$(osts_nodes)" 0
13091         wait $MULTIPID
13092         RC=$?
13093         if [[ $RC -ne 0 ]]; then
13094                 error "Multiop fsync failed, rc=$RC"
13095         fi
13096
13097         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13098         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13099                     grep -c writeback)
13100         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13101                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13102         fi
13103
13104         rm -f $DIR/$tfile
13105         echo "Dirty pages flushed via fsync on EROFS"
13106         return 0
13107 }
13108 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13109
13110 # continue to use small resend count to reduce test_118* time (b=14842)
13111 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13112
13113 test_118d()
13114 {
13115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13116         remote_ost_nodsh && skip "remote OST with nodsh"
13117
13118         reset_async
13119
13120         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13121         set_nodes_failloc "$(osts_nodes)" 0x214
13122         # multiop should block due to fsync until pages are written
13123         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13124         MULTIPID=$!
13125         sleep 1
13126
13127         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13128                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13129         fi
13130
13131         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13132                     grep -c writeback)
13133         if [[ $WRITEBACK -eq 0 ]]; then
13134                 error "No page in writeback, writeback=$WRITEBACK"
13135         fi
13136
13137         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13138         set_nodes_failloc "$(osts_nodes)" 0
13139
13140         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13141         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13142                     grep -c writeback)
13143         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13144                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13145         fi
13146
13147         rm -f $DIR/$tfile
13148         echo "Dirty pages gaurenteed flushed via fsync"
13149         return 0
13150 }
13151 run_test 118d "Fsync validation inject a delay of the bulk =========="
13152
13153 test_118f() {
13154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13155
13156         reset_async
13157
13158         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13159         lctl set_param fail_loc=0x8000040a
13160
13161         # Should simulate EINVAL error which is fatal
13162         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13163         RC=$?
13164         if [[ $RC -eq 0 ]]; then
13165                 error "Must return error due to dropped pages, rc=$RC"
13166         fi
13167
13168         lctl set_param fail_loc=0x0
13169
13170         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13171         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13172         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13173                     grep -c writeback)
13174         if [[ $LOCKED -ne 0 ]]; then
13175                 error "Locked pages remain in cache, locked=$LOCKED"
13176         fi
13177
13178         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13179                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13180         fi
13181
13182         rm -f $DIR/$tfile
13183         echo "No pages locked after fsync"
13184
13185         reset_async
13186         return 0
13187 }
13188 run_test 118f "Simulate unrecoverable OSC side error =========="
13189
13190 test_118g() {
13191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13192
13193         reset_async
13194
13195         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13196         lctl set_param fail_loc=0x406
13197
13198         # simulate local -ENOMEM
13199         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13200         RC=$?
13201
13202         lctl set_param fail_loc=0
13203         if [[ $RC -eq 0 ]]; then
13204                 error "Must return error due to dropped pages, rc=$RC"
13205         fi
13206
13207         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13208         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13209         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13210                         grep -c writeback)
13211         if [[ $LOCKED -ne 0 ]]; then
13212                 error "Locked pages remain in cache, locked=$LOCKED"
13213         fi
13214
13215         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13216                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13217         fi
13218
13219         rm -f $DIR/$tfile
13220         echo "No pages locked after fsync"
13221
13222         reset_async
13223         return 0
13224 }
13225 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13226
13227 test_118h() {
13228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13229         remote_ost_nodsh && skip "remote OST with nodsh"
13230
13231         reset_async
13232
13233         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13234         set_nodes_failloc "$(osts_nodes)" 0x20e
13235         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13236         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13237         RC=$?
13238
13239         set_nodes_failloc "$(osts_nodes)" 0
13240         if [[ $RC -eq 0 ]]; then
13241                 error "Must return error due to dropped pages, rc=$RC"
13242         fi
13243
13244         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13245         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13246         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13247                     grep -c writeback)
13248         if [[ $LOCKED -ne 0 ]]; then
13249                 error "Locked pages remain in cache, locked=$LOCKED"
13250         fi
13251
13252         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13253                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13254         fi
13255
13256         rm -f $DIR/$tfile
13257         echo "No pages locked after fsync"
13258
13259         return 0
13260 }
13261 run_test 118h "Verify timeout in handling recoverables errors  =========="
13262
13263 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13264
13265 test_118i() {
13266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13267         remote_ost_nodsh && skip "remote OST with nodsh"
13268
13269         reset_async
13270
13271         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13272         set_nodes_failloc "$(osts_nodes)" 0x20e
13273
13274         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13275         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13276         PID=$!
13277         sleep 5
13278         set_nodes_failloc "$(osts_nodes)" 0
13279
13280         wait $PID
13281         RC=$?
13282         if [[ $RC -ne 0 ]]; then
13283                 error "got error, but should be not, rc=$RC"
13284         fi
13285
13286         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13287         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13288         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13289         if [[ $LOCKED -ne 0 ]]; then
13290                 error "Locked pages remain in cache, locked=$LOCKED"
13291         fi
13292
13293         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13294                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13295         fi
13296
13297         rm -f $DIR/$tfile
13298         echo "No pages locked after fsync"
13299
13300         return 0
13301 }
13302 run_test 118i "Fix error before timeout in recoverable error  =========="
13303
13304 [ "$SLOW" = "no" ] && set_resend_count 4
13305
13306 test_118j() {
13307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13308         remote_ost_nodsh && skip "remote OST with nodsh"
13309
13310         reset_async
13311
13312         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13313         set_nodes_failloc "$(osts_nodes)" 0x220
13314
13315         # return -EIO from OST
13316         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13317         RC=$?
13318         set_nodes_failloc "$(osts_nodes)" 0x0
13319         if [[ $RC -eq 0 ]]; then
13320                 error "Must return error due to dropped pages, rc=$RC"
13321         fi
13322
13323         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13324         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13325         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13326         if [[ $LOCKED -ne 0 ]]; then
13327                 error "Locked pages remain in cache, locked=$LOCKED"
13328         fi
13329
13330         # in recoverable error on OST we want resend and stay until it finished
13331         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13332                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13333         fi
13334
13335         rm -f $DIR/$tfile
13336         echo "No pages locked after fsync"
13337
13338         return 0
13339 }
13340 run_test 118j "Simulate unrecoverable OST side error =========="
13341
13342 test_118k()
13343 {
13344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13345         remote_ost_nodsh && skip "remote OSTs with nodsh"
13346
13347         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13348         set_nodes_failloc "$(osts_nodes)" 0x20e
13349         test_mkdir $DIR/$tdir
13350
13351         for ((i=0;i<10;i++)); do
13352                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13353                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13354                 SLEEPPID=$!
13355                 sleep 0.500s
13356                 kill $SLEEPPID
13357                 wait $SLEEPPID
13358         done
13359
13360         set_nodes_failloc "$(osts_nodes)" 0
13361         rm -rf $DIR/$tdir
13362 }
13363 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13364
13365 test_118l() # LU-646
13366 {
13367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13368
13369         test_mkdir $DIR/$tdir
13370         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13371         rm -rf $DIR/$tdir
13372 }
13373 run_test 118l "fsync dir"
13374
13375 test_118m() # LU-3066
13376 {
13377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13378
13379         test_mkdir $DIR/$tdir
13380         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13381         rm -rf $DIR/$tdir
13382 }
13383 run_test 118m "fdatasync dir ========="
13384
13385 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13386
13387 test_118n()
13388 {
13389         local begin
13390         local end
13391
13392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13393         remote_ost_nodsh && skip "remote OSTs with nodsh"
13394
13395         # Sleep to avoid a cached response.
13396         #define OBD_STATFS_CACHE_SECONDS 1
13397         sleep 2
13398
13399         # Inject a 10 second delay in the OST_STATFS handler.
13400         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13401         set_nodes_failloc "$(osts_nodes)" 0x242
13402
13403         begin=$SECONDS
13404         stat --file-system $MOUNT > /dev/null
13405         end=$SECONDS
13406
13407         set_nodes_failloc "$(osts_nodes)" 0
13408
13409         if ((end - begin > 20)); then
13410             error "statfs took $((end - begin)) seconds, expected 10"
13411         fi
13412 }
13413 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13414
13415 test_119a() # bug 11737
13416 {
13417         BSIZE=$((512 * 1024))
13418         directio write $DIR/$tfile 0 1 $BSIZE
13419         # We ask to read two blocks, which is more than a file size.
13420         # directio will indicate an error when requested and actual
13421         # sizes aren't equeal (a normal situation in this case) and
13422         # print actual read amount.
13423         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13424         if [ "$NOB" != "$BSIZE" ]; then
13425                 error "read $NOB bytes instead of $BSIZE"
13426         fi
13427         rm -f $DIR/$tfile
13428 }
13429 run_test 119a "Short directIO read must return actual read amount"
13430
13431 test_119b() # bug 11737
13432 {
13433         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13434
13435         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13436         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13437         sync
13438         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13439                 error "direct read failed"
13440         rm -f $DIR/$tfile
13441 }
13442 run_test 119b "Sparse directIO read must return actual read amount"
13443
13444 test_119c() # bug 13099
13445 {
13446         BSIZE=1048576
13447         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13448         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13449         rm -f $DIR/$tfile
13450 }
13451 run_test 119c "Testing for direct read hitting hole"
13452
13453 test_120a() {
13454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13455         remote_mds_nodsh && skip "remote MDS with nodsh"
13456         test_mkdir -i0 -c1 $DIR/$tdir
13457         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13458                 skip_env "no early lock cancel on server"
13459
13460         lru_resize_disable mdc
13461         lru_resize_disable osc
13462         cancel_lru_locks mdc
13463         # asynchronous object destroy at MDT could cause bl ast to client
13464         cancel_lru_locks osc
13465
13466         stat $DIR/$tdir > /dev/null
13467         can1=$(do_facet mds1 \
13468                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13469                awk '/ldlm_cancel/ {print $2}')
13470         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13471                awk '/ldlm_bl_callback/ {print $2}')
13472         test_mkdir -i0 -c1 $DIR/$tdir/d1
13473         can2=$(do_facet mds1 \
13474                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13475                awk '/ldlm_cancel/ {print $2}')
13476         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13477                awk '/ldlm_bl_callback/ {print $2}')
13478         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13479         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13480         lru_resize_enable mdc
13481         lru_resize_enable osc
13482 }
13483 run_test 120a "Early Lock Cancel: mkdir test"
13484
13485 test_120b() {
13486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13487         remote_mds_nodsh && skip "remote MDS with nodsh"
13488         test_mkdir $DIR/$tdir
13489         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13490                 skip_env "no early lock cancel on server"
13491
13492         lru_resize_disable mdc
13493         lru_resize_disable osc
13494         cancel_lru_locks mdc
13495         stat $DIR/$tdir > /dev/null
13496         can1=$(do_facet $SINGLEMDS \
13497                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13498                awk '/ldlm_cancel/ {print $2}')
13499         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13500                awk '/ldlm_bl_callback/ {print $2}')
13501         touch $DIR/$tdir/f1
13502         can2=$(do_facet $SINGLEMDS \
13503                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13504                awk '/ldlm_cancel/ {print $2}')
13505         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13506                awk '/ldlm_bl_callback/ {print $2}')
13507         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13508         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13509         lru_resize_enable mdc
13510         lru_resize_enable osc
13511 }
13512 run_test 120b "Early Lock Cancel: create test"
13513
13514 test_120c() {
13515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13516         remote_mds_nodsh && skip "remote MDS with nodsh"
13517         test_mkdir -i0 -c1 $DIR/$tdir
13518         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13519                 skip "no early lock cancel on server"
13520
13521         lru_resize_disable mdc
13522         lru_resize_disable osc
13523         test_mkdir -i0 -c1 $DIR/$tdir/d1
13524         test_mkdir -i0 -c1 $DIR/$tdir/d2
13525         touch $DIR/$tdir/d1/f1
13526         cancel_lru_locks mdc
13527         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13528         can1=$(do_facet mds1 \
13529                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13530                awk '/ldlm_cancel/ {print $2}')
13531         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13532                awk '/ldlm_bl_callback/ {print $2}')
13533         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13534         can2=$(do_facet mds1 \
13535                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13536                awk '/ldlm_cancel/ {print $2}')
13537         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13538                awk '/ldlm_bl_callback/ {print $2}')
13539         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13540         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13541         lru_resize_enable mdc
13542         lru_resize_enable osc
13543 }
13544 run_test 120c "Early Lock Cancel: link test"
13545
13546 test_120d() {
13547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13548         remote_mds_nodsh && skip "remote MDS with nodsh"
13549         test_mkdir -i0 -c1 $DIR/$tdir
13550         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13551                 skip_env "no early lock cancel on server"
13552
13553         lru_resize_disable mdc
13554         lru_resize_disable osc
13555         touch $DIR/$tdir
13556         cancel_lru_locks mdc
13557         stat $DIR/$tdir > /dev/null
13558         can1=$(do_facet mds1 \
13559                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13560                awk '/ldlm_cancel/ {print $2}')
13561         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13562                awk '/ldlm_bl_callback/ {print $2}')
13563         chmod a+x $DIR/$tdir
13564         can2=$(do_facet mds1 \
13565                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13566                awk '/ldlm_cancel/ {print $2}')
13567         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13568                awk '/ldlm_bl_callback/ {print $2}')
13569         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13570         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13571         lru_resize_enable mdc
13572         lru_resize_enable osc
13573 }
13574 run_test 120d "Early Lock Cancel: setattr test"
13575
13576 test_120e() {
13577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13578         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13579                 skip_env "no early lock cancel on server"
13580         remote_mds_nodsh && skip "remote MDS with nodsh"
13581
13582         local dlmtrace_set=false
13583
13584         test_mkdir -i0 -c1 $DIR/$tdir
13585         lru_resize_disable mdc
13586         lru_resize_disable osc
13587         ! $LCTL get_param debug | grep -q dlmtrace &&
13588                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13589         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13590         cancel_lru_locks mdc
13591         cancel_lru_locks osc
13592         dd if=$DIR/$tdir/f1 of=/dev/null
13593         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13594         # XXX client can not do early lock cancel of OST lock
13595         # during unlink (LU-4206), so cancel osc lock now.
13596         sleep 2
13597         cancel_lru_locks osc
13598         can1=$(do_facet mds1 \
13599                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13600                awk '/ldlm_cancel/ {print $2}')
13601         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13602                awk '/ldlm_bl_callback/ {print $2}')
13603         unlink $DIR/$tdir/f1
13604         sleep 5
13605         can2=$(do_facet mds1 \
13606                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13607                awk '/ldlm_cancel/ {print $2}')
13608         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13609                awk '/ldlm_bl_callback/ {print $2}')
13610         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13611                 $LCTL dk $TMP/cancel.debug.txt
13612         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13613                 $LCTL dk $TMP/blocking.debug.txt
13614         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13615         lru_resize_enable mdc
13616         lru_resize_enable osc
13617 }
13618 run_test 120e "Early Lock Cancel: unlink test"
13619
13620 test_120f() {
13621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13622         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13623                 skip_env "no early lock cancel on server"
13624         remote_mds_nodsh && skip "remote MDS with nodsh"
13625
13626         test_mkdir -i0 -c1 $DIR/$tdir
13627         lru_resize_disable mdc
13628         lru_resize_disable osc
13629         test_mkdir -i0 -c1 $DIR/$tdir/d1
13630         test_mkdir -i0 -c1 $DIR/$tdir/d2
13631         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13632         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13633         cancel_lru_locks mdc
13634         cancel_lru_locks osc
13635         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13636         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13637         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13638         # XXX client can not do early lock cancel of OST lock
13639         # during rename (LU-4206), so cancel osc lock now.
13640         sleep 2
13641         cancel_lru_locks osc
13642         can1=$(do_facet mds1 \
13643                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13644                awk '/ldlm_cancel/ {print $2}')
13645         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13646                awk '/ldlm_bl_callback/ {print $2}')
13647         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13648         sleep 5
13649         can2=$(do_facet mds1 \
13650                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13651                awk '/ldlm_cancel/ {print $2}')
13652         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13653                awk '/ldlm_bl_callback/ {print $2}')
13654         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13655         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13656         lru_resize_enable mdc
13657         lru_resize_enable osc
13658 }
13659 run_test 120f "Early Lock Cancel: rename test"
13660
13661 test_120g() {
13662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13663         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13664                 skip_env "no early lock cancel on server"
13665         remote_mds_nodsh && skip "remote MDS with nodsh"
13666
13667         lru_resize_disable mdc
13668         lru_resize_disable osc
13669         count=10000
13670         echo create $count files
13671         test_mkdir $DIR/$tdir
13672         cancel_lru_locks mdc
13673         cancel_lru_locks osc
13674         t0=$(date +%s)
13675
13676         can0=$(do_facet $SINGLEMDS \
13677                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13678                awk '/ldlm_cancel/ {print $2}')
13679         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13680                awk '/ldlm_bl_callback/ {print $2}')
13681         createmany -o $DIR/$tdir/f $count
13682         sync
13683         can1=$(do_facet $SINGLEMDS \
13684                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13685                awk '/ldlm_cancel/ {print $2}')
13686         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13687                awk '/ldlm_bl_callback/ {print $2}')
13688         t1=$(date +%s)
13689         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13690         echo rm $count files
13691         rm -r $DIR/$tdir
13692         sync
13693         can2=$(do_facet $SINGLEMDS \
13694                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13695                awk '/ldlm_cancel/ {print $2}')
13696         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13697                awk '/ldlm_bl_callback/ {print $2}')
13698         t2=$(date +%s)
13699         echo total: $count removes in $((t2-t1))
13700         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13701         sleep 2
13702         # wait for commitment of removal
13703         lru_resize_enable mdc
13704         lru_resize_enable osc
13705 }
13706 run_test 120g "Early Lock Cancel: performance test"
13707
13708 test_121() { #bug #10589
13709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13710
13711         rm -rf $DIR/$tfile
13712         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13713 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13714         lctl set_param fail_loc=0x310
13715         cancel_lru_locks osc > /dev/null
13716         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13717         lctl set_param fail_loc=0
13718         [[ $reads -eq $writes ]] ||
13719                 error "read $reads blocks, must be $writes blocks"
13720 }
13721 run_test 121 "read cancel race ========="
13722
13723 test_123a_base() { # was test 123, statahead(bug 11401)
13724         local lsx="$1"
13725
13726         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13727
13728         SLOWOK=0
13729         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13730                 log "testing UP system. Performance may be lower than expected."
13731                 SLOWOK=1
13732         fi
13733         running_in_vm && SLOWOK=1
13734
13735         $LCTL set_param mdc.*.batch_stats=0
13736
13737         rm -rf $DIR/$tdir
13738         test_mkdir $DIR/$tdir
13739         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13740         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13741         MULT=10
13742         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13743                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13744
13745                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13746                 lctl set_param -n llite.*.statahead_max 0
13747                 lctl get_param llite.*.statahead_max
13748                 cancel_lru_locks mdc
13749                 cancel_lru_locks osc
13750                 stime=$(date +%s)
13751                 time $lsx $DIR/$tdir | wc -l
13752                 etime=$(date +%s)
13753                 delta=$((etime - stime))
13754                 log "$lsx $i files without statahead: $delta sec"
13755                 lctl set_param llite.*.statahead_max=$max
13756
13757                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13758                          awk '/statahead.wrong:/ { print $NF }')
13759                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13760                 cancel_lru_locks mdc
13761                 cancel_lru_locks osc
13762                 stime=$(date +%s)
13763                 time $lsx $DIR/$tdir | wc -l
13764                 etime=$(date +%s)
13765                 delta_sa=$((etime - stime))
13766                 log "$lsx $i files with statahead: $delta_sa sec"
13767                 lctl get_param -n llite.*.statahead_stats
13768                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13769                          awk '/statahead.wrong:/ { print $NF }')
13770
13771                 [[ $swrong -lt $ewrong ]] &&
13772                         log "statahead was stopped, maybe too many locks held!"
13773                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13774
13775                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13776                         max=$(lctl get_param -n llite.*.statahead_max |
13777                                 head -n 1)
13778                         lctl set_param -n llite.*.statahead_max 0
13779                         lctl get_param llite.*.statahead_max
13780                         cancel_lru_locks mdc
13781                         cancel_lru_locks osc
13782                         stime=$(date +%s)
13783                         time $lsx $DIR/$tdir | wc -l
13784                         etime=$(date +%s)
13785                         delta=$((etime - stime))
13786                         log "$lsx $i files again without statahead: $delta sec"
13787                         lctl set_param llite.*.statahead_max=$max
13788                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13789                                 if [ $SLOWOK -eq 0 ]; then
13790                                         error "$lsx $i files is slower with statahead!"
13791                                 else
13792                                         log "$lsx $i files is slower with statahead!"
13793                                 fi
13794                                 break
13795                         fi
13796                 fi
13797
13798                 [ $delta -gt 20 ] && break
13799                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13800                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13801         done
13802         log "$lsx done"
13803
13804         stime=$(date +%s)
13805         rm -r $DIR/$tdir
13806         sync
13807         etime=$(date +%s)
13808         delta=$((etime - stime))
13809         log "rm -r $DIR/$tdir/: $delta seconds"
13810         log "rm done"
13811         lctl get_param -n llite.*.statahead_stats
13812         $LCTL get_param mdc.*.batch_stats
13813 }
13814
13815 test_123aa() {
13816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13817
13818         test_123a_base "ls -l"
13819 }
13820 run_test 123aa "verify statahead work"
13821
13822 test_123ab() {
13823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13824
13825         statx_supported || skip_env "Test must be statx() syscall supported"
13826
13827         test_123a_base "$STATX -l"
13828 }
13829 run_test 123ab "verify statahead work by using statx"
13830
13831 test_123ac() {
13832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13833
13834         statx_supported || skip_env "Test must be statx() syscall supported"
13835
13836         local rpcs_before
13837         local rpcs_after
13838         local agl_before
13839         local agl_after
13840
13841         cancel_lru_locks $OSC
13842         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13843         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13844                      awk '/agl.total:/ { print $NF }')
13845         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13846         test_123a_base "$STATX --cached=always -D"
13847         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13848                     awk '/agl.total:/ { print $NF }')
13849         [ $agl_before -eq $agl_after ] ||
13850                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13851         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13852         [ $rpcs_after -eq $rpcs_before ] ||
13853                 error "$STATX should not send glimpse RPCs to $OSC"
13854 }
13855 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13856
13857 test_batch_statahead() {
13858         local max=$1
13859         local batch_max=$2
13860         local num=10000
13861         local batch_rpcs
13862         local unbatch_rpcs
13863         local hit_total
13864
13865         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13866         $LCTL set_param mdc.*.batch_stats=0
13867         $LCTL set_param llite.*.statahead_max=$max
13868         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13869         # Verify that batched statahead is faster than one without statahead
13870         test_123a_base "ls -l"
13871
13872         stack_trap "rm -rf $DIR/$tdir" EXIT
13873         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13874         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13875
13876         # unbatched statahead
13877         $LCTL set_param llite.*.statahead_batch_max=0
13878         $LCTL set_param llite.*.statahead_stats=clear
13879         $LCTL set_param mdc.*.stats=clear
13880         cancel_lru_locks mdc
13881         cancel_lru_locks osc
13882         time ls -l $DIR/$tdir | wc -l
13883         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13884         sleep 2
13885         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13886                     awk '/hit.total:/ { print $NF }')
13887         # hit ratio should be larger than 75% (7500).
13888         (( $hit_total > 7500 )) ||
13889                 error "unbatched statahead hit count ($hit_total) is too low"
13890
13891         # batched statahead
13892         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13893         $LCTL set_param llite.*.statahead_stats=clear
13894         $LCTL set_param mdc.*.batch_stats=clear
13895         $LCTL set_param mdc.*.stats=clear
13896         cancel_lru_locks mdc
13897         cancel_lru_locks osc
13898         time ls -l $DIR/$tdir | wc -l
13899         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13900         # wait for statahead thread to quit and update statahead stats
13901         sleep 2
13902         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13903                     awk '/hit.total:/ { print $NF }')
13904         # hit ratio should be larger than 75% (7500).
13905         (( $hit_total > 7500 )) ||
13906                 error "batched statahead hit count ($hit_total) is too low"
13907
13908         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13909         (( $unbatch_rpcs > $batch_rpcs )) ||
13910                 error "batched statahead does not reduce RPC count"
13911         $LCTL get_param mdc.*.batch_stats
13912 }
13913
13914 test_123ad() {
13915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13916
13917         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13918                 skip "Need server version at least 2.15.53"
13919
13920         local max
13921         local batch_max
13922
13923         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13924         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13925
13926         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13927         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13928
13929         test_batch_statahead 32 32
13930         test_batch_statahead 2048 256
13931 }
13932 run_test 123ad "Verify batching statahead works correctly"
13933
13934 test_123b () { # statahead(bug 15027)
13935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13936
13937         test_mkdir $DIR/$tdir
13938         createmany -o $DIR/$tdir/$tfile-%d 1000
13939
13940         cancel_lru_locks mdc
13941         cancel_lru_locks osc
13942
13943 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13944         lctl set_param fail_loc=0x80000803
13945         ls -lR $DIR/$tdir > /dev/null
13946         log "ls done"
13947         lctl set_param fail_loc=0x0
13948         lctl get_param -n llite.*.statahead_stats
13949         rm -r $DIR/$tdir
13950         sync
13951
13952 }
13953 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13954
13955 test_123c() {
13956         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13957
13958         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13959         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13960         touch $DIR/$tdir.1/{1..3}
13961         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13962
13963         remount_client $MOUNT
13964
13965         $MULTIOP $DIR/$tdir.0 Q
13966
13967         # let statahead to complete
13968         ls -l $DIR/$tdir.0 > /dev/null
13969
13970         testid=$(echo $TESTNAME | tr '_' ' ')
13971         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13972                 error "statahead warning" || true
13973 }
13974 run_test 123c "Can not initialize inode warning on DNE statahead"
13975
13976 test_123d() {
13977         local num=100
13978         local swrong
13979         local ewrong
13980
13981         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13982         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13983                 error "setdirstripe $DIR/$tdir failed"
13984         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13985         remount_client $MOUNT
13986         $LCTL get_param llite.*.statahead_max
13987         $LCTL set_param llite.*.statahead_stats=0 ||
13988                 error "clear statahead_stats failed"
13989         swrong=$(lctl get_param -n llite.*.statahead_stats |
13990                  awk '/statahead.wrong:/ { print $NF }')
13991         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13992         # wait for statahead thread finished to update hit/miss stats.
13993         sleep 1
13994         $LCTL get_param -n llite.*.statahead_stats
13995         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13996                  awk '/statahead.wrong:/ { print $NF }')
13997         (( $swrong == $ewrong )) ||
13998                 log "statahead was stopped, maybe too many locks held!"
13999 }
14000 run_test 123d "Statahead on striped directories works correctly"
14001
14002 test_123e() {
14003         local max
14004         local batch_max
14005         local dir=$DIR/$tdir
14006
14007         mkdir $dir || error "mkdir $dir failed"
14008         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14009         stack_trap "rm -rf $dir"
14010
14011         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14012
14013         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14014         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14015         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14016         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14017
14018         $LCTL set_param llite.*.statahead_max=2048
14019         $LCTL set_param llite.*.statahead_batch_max=1024
14020
14021         ls -l $dir
14022         $LCTL get_param mdc.*.batch_stats
14023         $LCTL get_param llite.*.statahead_*
14024 }
14025 run_test 123e "statahead with large wide striping"
14026
14027 test_123f() {
14028         local max
14029         local batch_max
14030         local dir=$DIR/$tdir
14031
14032         mkdir $dir || error "mkdir $dir failed"
14033         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14034         stack_trap "rm -rf $dir"
14035
14036         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14037
14038         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14039         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14040
14041         $LCTL set_param llite.*.statahead_max=64
14042         $LCTL set_param llite.*.statahead_batch_max=64
14043
14044         ls -l $dir
14045         lctl get_param mdc.*.batch_stats
14046         lctl get_param llite.*.statahead_*
14047
14048         $LCTL set_param llite.*.statahead_max=$max
14049         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14050 }
14051 run_test 123f "Retry mechanism with large wide striping files"
14052
14053 test_124a() {
14054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14055         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14056                 skip_env "no lru resize on server"
14057
14058         local NR=2000
14059
14060         test_mkdir $DIR/$tdir
14061
14062         log "create $NR files at $DIR/$tdir"
14063         createmany -o $DIR/$tdir/f $NR ||
14064                 error "failed to create $NR files in $DIR/$tdir"
14065
14066         cancel_lru_locks mdc
14067         ls -l $DIR/$tdir > /dev/null
14068
14069         local NSDIR=""
14070         local LRU_SIZE=0
14071         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14072                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14073                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14074                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14075                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14076                         log "NSDIR=$NSDIR"
14077                         log "NS=$(basename $NSDIR)"
14078                         break
14079                 fi
14080         done
14081
14082         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14083                 skip "Not enough cached locks created!"
14084         fi
14085         log "LRU=$LRU_SIZE"
14086
14087         local SLEEP=30
14088
14089         # We know that lru resize allows one client to hold $LIMIT locks
14090         # for 10h. After that locks begin to be killed by client.
14091         local MAX_HRS=10
14092         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14093         log "LIMIT=$LIMIT"
14094         if [ $LIMIT -lt $LRU_SIZE ]; then
14095                 skip "Limit is too small $LIMIT"
14096         fi
14097
14098         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14099         # killing locks. Some time was spent for creating locks. This means
14100         # that up to the moment of sleep finish we must have killed some of
14101         # them (10-100 locks). This depends on how fast ther were created.
14102         # Many of them were touched in almost the same moment and thus will
14103         # be killed in groups.
14104         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14105
14106         # Use $LRU_SIZE_B here to take into account real number of locks
14107         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14108         local LRU_SIZE_B=$LRU_SIZE
14109         log "LVF=$LVF"
14110         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14111         log "OLD_LVF=$OLD_LVF"
14112         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14113
14114         # Let's make sure that we really have some margin. Client checks
14115         # cached locks every 10 sec.
14116         SLEEP=$((SLEEP+20))
14117         log "Sleep ${SLEEP} sec"
14118         local SEC=0
14119         while ((SEC<$SLEEP)); do
14120                 echo -n "..."
14121                 sleep 5
14122                 SEC=$((SEC+5))
14123                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14124                 echo -n "$LRU_SIZE"
14125         done
14126         echo ""
14127         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14128         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14129
14130         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14131                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14132                 unlinkmany $DIR/$tdir/f $NR
14133                 return
14134         }
14135
14136         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14137         log "unlink $NR files at $DIR/$tdir"
14138         unlinkmany $DIR/$tdir/f $NR
14139 }
14140 run_test 124a "lru resize ======================================="
14141
14142 get_max_pool_limit()
14143 {
14144         local limit=$($LCTL get_param \
14145                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14146         local max=0
14147         for l in $limit; do
14148                 if [[ $l -gt $max ]]; then
14149                         max=$l
14150                 fi
14151         done
14152         echo $max
14153 }
14154
14155 test_124b() {
14156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14157         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14158                 skip_env "no lru resize on server"
14159
14160         LIMIT=$(get_max_pool_limit)
14161
14162         NR=$(($(default_lru_size)*20))
14163         if [[ $NR -gt $LIMIT ]]; then
14164                 log "Limit lock number by $LIMIT locks"
14165                 NR=$LIMIT
14166         fi
14167
14168         IFree=$(mdsrate_inodes_available)
14169         if [ $IFree -lt $NR ]; then
14170                 log "Limit lock number by $IFree inodes"
14171                 NR=$IFree
14172         fi
14173
14174         lru_resize_disable mdc
14175         test_mkdir -p $DIR/$tdir/disable_lru_resize
14176
14177         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14178         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14179         cancel_lru_locks mdc
14180         stime=`date +%s`
14181         PID=""
14182         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14183         PID="$PID $!"
14184         sleep 2
14185         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14186         PID="$PID $!"
14187         sleep 2
14188         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14189         PID="$PID $!"
14190         wait $PID
14191         etime=`date +%s`
14192         nolruresize_delta=$((etime-stime))
14193         log "ls -la time: $nolruresize_delta seconds"
14194         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14195         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14196
14197         lru_resize_enable mdc
14198         test_mkdir -p $DIR/$tdir/enable_lru_resize
14199
14200         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14201         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14202         cancel_lru_locks mdc
14203         stime=`date +%s`
14204         PID=""
14205         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14206         PID="$PID $!"
14207         sleep 2
14208         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14209         PID="$PID $!"
14210         sleep 2
14211         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14212         PID="$PID $!"
14213         wait $PID
14214         etime=`date +%s`
14215         lruresize_delta=$((etime-stime))
14216         log "ls -la time: $lruresize_delta seconds"
14217         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14218
14219         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14220                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14221         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14222                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14223         else
14224                 log "lru resize performs the same with no lru resize"
14225         fi
14226         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14227 }
14228 run_test 124b "lru resize (performance test) ======================="
14229
14230 test_124c() {
14231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14232         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14233                 skip_env "no lru resize on server"
14234
14235         # cache ununsed locks on client
14236         local nr=100
14237         cancel_lru_locks mdc
14238         test_mkdir $DIR/$tdir
14239         createmany -o $DIR/$tdir/f $nr ||
14240                 error "failed to create $nr files in $DIR/$tdir"
14241         ls -l $DIR/$tdir > /dev/null
14242
14243         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14244         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14245         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14246         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14247         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14248
14249         # set lru_max_age to 1 sec
14250         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14251         echo "sleep $((recalc_p * 2)) seconds..."
14252         sleep $((recalc_p * 2))
14253
14254         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14255         # restore lru_max_age
14256         $LCTL set_param -n $nsdir.lru_max_age $max_age
14257         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14258         unlinkmany $DIR/$tdir/f $nr
14259 }
14260 run_test 124c "LRUR cancel very aged locks"
14261
14262 test_124d() {
14263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14264         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14265                 skip_env "no lru resize on server"
14266
14267         # cache ununsed locks on client
14268         local nr=100
14269
14270         lru_resize_disable mdc
14271         stack_trap "lru_resize_enable mdc" EXIT
14272
14273         cancel_lru_locks mdc
14274
14275         # asynchronous object destroy at MDT could cause bl ast to client
14276         test_mkdir $DIR/$tdir
14277         createmany -o $DIR/$tdir/f $nr ||
14278                 error "failed to create $nr files in $DIR/$tdir"
14279         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14280
14281         ls -l $DIR/$tdir > /dev/null
14282
14283         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14284         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14285         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14286         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14287
14288         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14289
14290         # set lru_max_age to 1 sec
14291         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14292         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14293
14294         echo "sleep $((recalc_p * 2)) seconds..."
14295         sleep $((recalc_p * 2))
14296
14297         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14298
14299         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14300 }
14301 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14302
14303 test_125() { # 13358
14304         $LCTL get_param -n llite.*.client_type | grep -q local ||
14305                 skip "must run as local client"
14306         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14307                 skip_env "must have acl enabled"
14308         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14309         id $USER0 || skip_env "missing user $USER0"
14310
14311         test_mkdir $DIR/$tdir
14312         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14313         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14314                 error "setfacl $DIR/$tdir failed"
14315         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14316 }
14317 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14318
14319 test_126() { # bug 12829/13455
14320         $GSS && skip_env "must run as gss disabled"
14321         $LCTL get_param -n llite.*.client_type | grep -q local ||
14322                 skip "must run as local client"
14323         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14324
14325         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14326         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14327         rm -f $DIR/$tfile
14328         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14329 }
14330 run_test 126 "check that the fsgid provided by the client is taken into account"
14331
14332 test_127a() { # bug 15521
14333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14334         local name count samp unit min max sum sumsq
14335         local tmpfile=$TMP/$tfile.tmp
14336
14337         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14338         echo "stats before reset"
14339         stack_trap "rm -f $tmpfile"
14340         local now=$(date +%s)
14341
14342         $LCTL get_param osc.*.stats | tee $tmpfile
14343
14344         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14345         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14346         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14347         local uptime=$(awk '{ print $1 }' /proc/uptime)
14348
14349         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14350         (( ${snapshot_time%\.*} >= $now - 5 &&
14351            ${snapshot_time%\.*} <= $now + 5 )) ||
14352                 error "snapshot_time=$snapshot_time != now=$now"
14353         # elapsed _should_ be from mount, but at least less than uptime
14354         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14355                 error "elapsed=$elapsed > uptime=$uptime"
14356         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14357            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14358                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14359
14360         $LCTL set_param osc.*.stats=0
14361         local reset=$(date +%s)
14362         local fsize=$((2048 * 1024))
14363
14364         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14365         cancel_lru_locks osc
14366         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14367
14368         now=$(date +%s)
14369         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14370         while read name count samp unit min max sum sumsq; do
14371                 [[ "$samp" == "samples" ]] || continue
14372
14373                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14374                 [ ! $min ] && error "Missing min value for $name proc entry"
14375                 eval $name=$count || error "Wrong proc format"
14376
14377                 case $name in
14378                 read_bytes|write_bytes)
14379                         [[ "$unit" =~ "bytes" ]] ||
14380                                 error "unit is not 'bytes': $unit"
14381                         (( $min >= 4096 )) || error "min is too small: $min"
14382                         (( $min <= $fsize )) || error "min is too big: $min"
14383                         (( $max >= 4096 )) || error "max is too small: $max"
14384                         (( $max <= $fsize )) || error "max is too big: $max"
14385                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14386                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14387                                 error "sumsquare is too small: $sumsq"
14388                         (( $sumsq <= $fsize * $fsize )) ||
14389                                 error "sumsquare is too big: $sumsq"
14390                         ;;
14391                 ost_read|ost_write)
14392                         [[ "$unit" =~ "usec" ]] ||
14393                                 error "unit is not 'usec': $unit"
14394                         ;;
14395                 *)      ;;
14396                 esac
14397         done < $tmpfile
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         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14406         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14407         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14408
14409         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14410         (( ${snapshot_time%\.*} >= $now - 5 &&
14411            ${snapshot_time%\.*} <= $now + 5 )) ||
14412                 error "reset snapshot_time=$snapshot_time != now=$now"
14413         # elapsed should be from time of stats reset
14414         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14415            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14416                 error "reset elapsed=$elapsed > $now - $reset"
14417         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14418            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14419                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14420 }
14421 run_test 127a "verify the client stats are sane"
14422
14423 test_127b() { # bug LU-333
14424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14425         local name count samp unit min max sum sumsq
14426
14427         echo "stats before reset"
14428         $LCTL get_param llite.*.stats
14429         $LCTL set_param llite.*.stats=0
14430
14431         # perform 2 reads and writes so MAX is different from SUM.
14432         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14433         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14434         cancel_lru_locks osc
14435         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14436         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14437
14438         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14439         stack_trap "rm -f $TMP/$tfile.tmp"
14440         while read name count samp unit min max sum sumsq; do
14441                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14442                 eval $name=$count || error "Wrong proc format"
14443
14444                 case $name in
14445                 read_bytes|write_bytes)
14446                         [[ "$unit" =~ "bytes" ]] ||
14447                                 error "unit is not 'bytes': $unit"
14448                         (( $count == 2 )) || error "count is not 2: $count"
14449                         (( $min == $PAGE_SIZE )) ||
14450                                 error "min is not $PAGE_SIZE: $min"
14451                         (( $max == $PAGE_SIZE )) ||
14452                                 error "max is not $PAGE_SIZE: $max"
14453                         (( $sum == $PAGE_SIZE * 2 )) ||
14454                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14455                         ;;
14456                 read|write)
14457                         [[ "$unit" =~ "usec" ]] ||
14458                                 error "unit is not 'usec': $unit"
14459                         ;;
14460                 *)      ;;
14461                 esac
14462         done < $TMP/$tfile.tmp
14463
14464         #check that we actually got some stats
14465         [ "$read_bytes" ] || error "Missing read_bytes stats"
14466         [ "$write_bytes" ] || error "Missing write_bytes stats"
14467         [ "$read_bytes" != 0 ] || error "no read done"
14468         [ "$write_bytes" != 0 ] || error "no write done"
14469 }
14470 run_test 127b "verify the llite client stats are sane"
14471
14472 test_127c() { # LU-12394
14473         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14474         local size
14475         local bsize
14476         local reads
14477         local writes
14478         local count
14479
14480         $LCTL set_param llite.*.extents_stats=1
14481         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14482
14483         # Use two stripes so there is enough space in default config
14484         $LFS setstripe -c 2 $DIR/$tfile
14485
14486         # Extent stats start at 0-4K and go in power of two buckets
14487         # LL_HIST_START = 12 --> 2^12 = 4K
14488         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14489         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14490         # small configs
14491         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14492                 do
14493                 # Write and read, 2x each, second time at a non-zero offset
14494                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14495                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14496                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14497                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14498                 rm -f $DIR/$tfile
14499         done
14500
14501         $LCTL get_param llite.*.extents_stats
14502
14503         count=2
14504         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14505                 do
14506                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14507                                 grep -m 1 $bsize)
14508                 reads=$(echo $bucket | awk '{print $5}')
14509                 writes=$(echo $bucket | awk '{print $9}')
14510                 [ "$reads" -eq $count ] ||
14511                         error "$reads reads in < $bsize bucket, expect $count"
14512                 [ "$writes" -eq $count ] ||
14513                         error "$writes writes in < $bsize bucket, expect $count"
14514         done
14515
14516         # Test mmap write and read
14517         $LCTL set_param llite.*.extents_stats=c
14518         size=512
14519         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14520         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14521         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14522
14523         $LCTL get_param llite.*.extents_stats
14524
14525         count=$(((size*1024) / PAGE_SIZE))
14526
14527         bsize=$((2 * PAGE_SIZE / 1024))K
14528
14529         bucket=$($LCTL get_param -n llite.*.extents_stats |
14530                         grep -m 1 $bsize)
14531         reads=$(echo $bucket | awk '{print $5}')
14532         writes=$(echo $bucket | awk '{print $9}')
14533         # mmap writes fault in the page first, creating an additonal read
14534         [ "$reads" -eq $((2 * count)) ] ||
14535                 error "$reads reads in < $bsize bucket, expect $count"
14536         [ "$writes" -eq $count ] ||
14537                 error "$writes writes in < $bsize bucket, expect $count"
14538 }
14539 run_test 127c "test llite extent stats with regular & mmap i/o"
14540
14541 test_128() { # bug 15212
14542         touch $DIR/$tfile
14543         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14544                 find $DIR/$tfile
14545                 find $DIR/$tfile
14546         EOF
14547
14548         result=$(grep error $TMP/$tfile.log)
14549         rm -f $DIR/$tfile $TMP/$tfile.log
14550         [ -z "$result" ] ||
14551                 error "consecutive find's under interactive lfs failed"
14552 }
14553 run_test 128 "interactive lfs for 2 consecutive find's"
14554
14555 set_dir_limits () {
14556         local mntdev
14557         local canondev
14558         local node
14559
14560         local ldproc=/proc/fs/ldiskfs
14561         local facets=$(get_facets MDS)
14562
14563         for facet in ${facets//,/ }; do
14564                 canondev=$(ldiskfs_canon \
14565                            *.$(convert_facet2label $facet).mntdev $facet)
14566                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14567                         ldproc=/sys/fs/ldiskfs
14568                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14569                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14570         done
14571 }
14572
14573 check_mds_dmesg() {
14574         local facets=$(get_facets MDS)
14575         for facet in ${facets//,/ }; do
14576                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14577         done
14578         return 1
14579 }
14580
14581 test_129() {
14582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14583         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14584                 skip "Need MDS version with at least 2.5.56"
14585         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14586                 skip_env "ldiskfs only test"
14587         fi
14588         remote_mds_nodsh && skip "remote MDS with nodsh"
14589
14590         local ENOSPC=28
14591         local has_warning=false
14592
14593         rm -rf $DIR/$tdir
14594         mkdir -p $DIR/$tdir
14595
14596         # block size of mds1
14597         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14598         set_dir_limits $maxsize $((maxsize * 6 / 8))
14599         stack_trap "set_dir_limits 0 0"
14600         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14601         local dirsize=$(stat -c%s "$DIR/$tdir")
14602         local nfiles=0
14603         while (( $dirsize <= $maxsize )); do
14604                 $MCREATE $DIR/$tdir/file_base_$nfiles
14605                 rc=$?
14606                 # check two errors:
14607                 # ENOSPC for ext4 max_dir_size, which has been used since
14608                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14609                 if (( rc == ENOSPC )); then
14610                         set_dir_limits 0 0
14611                         echo "rc=$rc returned as expected after $nfiles files"
14612
14613                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14614                                 error "create failed w/o dir size limit"
14615
14616                         # messages may be rate limited if test is run repeatedly
14617                         check_mds_dmesg '"is approaching max"' ||
14618                                 echo "warning message should be output"
14619                         check_mds_dmesg '"has reached max"' ||
14620                                 echo "reached message should be output"
14621
14622                         dirsize=$(stat -c%s "$DIR/$tdir")
14623
14624                         [[ $dirsize -ge $maxsize ]] && return 0
14625                         error "dirsize $dirsize < $maxsize after $nfiles files"
14626                 elif (( rc != 0 )); then
14627                         break
14628                 fi
14629                 nfiles=$((nfiles + 1))
14630                 dirsize=$(stat -c%s "$DIR/$tdir")
14631         done
14632
14633         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14634 }
14635 run_test 129 "test directory size limit ========================"
14636
14637 OLDIFS="$IFS"
14638 cleanup_130() {
14639         trap 0
14640         IFS="$OLDIFS"
14641         rm -f $DIR/$tfile
14642 }
14643
14644 test_130a() {
14645         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14646         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14647
14648         trap cleanup_130 EXIT RETURN
14649
14650         local fm_file=$DIR/$tfile
14651         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14652         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14653                 error "dd failed for $fm_file"
14654
14655         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14656         filefrag -ves $fm_file
14657         local rc=$?
14658         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14659                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14660         (( $rc == 0 )) || error "filefrag $fm_file failed"
14661
14662         filefrag_op=$(filefrag -ve -k $fm_file |
14663                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14664         local lun=$($LFS getstripe -i $fm_file)
14665
14666         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14667         IFS=$'\n'
14668         local tot_len=0
14669         for line in $filefrag_op; do
14670                 local frag_lun=$(echo $line | cut -d: -f5)
14671                 local ext_len=$(echo $line | cut -d: -f4)
14672
14673                 if (( $frag_lun != $lun )); then
14674                         error "FIEMAP on 1-stripe file($fm_file) failed"
14675                         return
14676                 fi
14677                 (( tot_len += ext_len ))
14678         done
14679
14680         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14681                 error "FIEMAP on 1-stripe file($fm_file) failed"
14682                 return
14683         fi
14684
14685         echo "FIEMAP on single striped file succeeded"
14686 }
14687 run_test 130a "FIEMAP (1-stripe file)"
14688
14689 test_130b() {
14690         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14691
14692         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14693         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14694         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14695                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14696
14697         trap cleanup_130 EXIT RETURN
14698
14699         local fm_file=$DIR/$tfile
14700         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14701                 error "setstripe on $fm_file"
14702
14703         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14704                 error "dd failed on $fm_file"
14705
14706         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14707         filefrag_op=$(filefrag -ve -k $fm_file |
14708                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14709
14710         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14711                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14712
14713         IFS=$'\n'
14714         local tot_len=0
14715         local num_luns=1
14716
14717         for line in $filefrag_op; do
14718                 local frag_lun=$(echo $line | cut -d: -f5 |
14719                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14720                 local ext_len=$(echo $line | cut -d: -f4)
14721                 if (( $frag_lun != $last_lun )); then
14722                         if (( tot_len != 1024 )); then
14723                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14724                                 return
14725                         else
14726                                 (( num_luns += 1 ))
14727                                 tot_len=0
14728                         fi
14729                 fi
14730                 (( tot_len += ext_len ))
14731                 last_lun=$frag_lun
14732         done
14733         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14734                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14735                 return
14736         fi
14737
14738         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14739 }
14740 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14741
14742 test_130c() {
14743         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14744
14745         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14746         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14747         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14748                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14749
14750         trap cleanup_130 EXIT RETURN
14751
14752         local fm_file=$DIR/$tfile
14753         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14754
14755         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14756                 error "dd failed on $fm_file"
14757
14758         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14759         filefrag_op=$(filefrag -ve -k $fm_file |
14760                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14761
14762         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14763                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14764
14765         IFS=$'\n'
14766         local tot_len=0
14767         local num_luns=1
14768         for line in $filefrag_op; do
14769                 local frag_lun=$(echo $line | cut -d: -f5 |
14770                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14771                 local ext_len=$(echo $line | cut -d: -f4)
14772                 if (( $frag_lun != $last_lun )); then
14773                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14774                         if (( logical != 512 )); then
14775                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14776                                 return
14777                         fi
14778                         if (( tot_len != 512 )); then
14779                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14780                                 return
14781                         else
14782                                 (( num_luns += 1 ))
14783                                 tot_len=0
14784                         fi
14785                 fi
14786                 (( tot_len += ext_len ))
14787                 last_lun=$frag_lun
14788         done
14789         if (( num_luns != 2 || tot_len != 512 )); then
14790                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14791                 return
14792         fi
14793
14794         echo "FIEMAP on 2-stripe file with hole succeeded"
14795 }
14796 run_test 130c "FIEMAP (2-stripe file with hole)"
14797
14798 test_130d() {
14799         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14800
14801         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14802         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14803         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14804                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14805
14806         trap cleanup_130 EXIT RETURN
14807
14808         local fm_file=$DIR/$tfile
14809         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14810                         error "setstripe on $fm_file"
14811
14812         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14813         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14814                 error "dd failed on $fm_file"
14815
14816         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14817         filefrag_op=$(filefrag -ve -k $fm_file |
14818                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14819
14820         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14821                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14822
14823         IFS=$'\n'
14824         local tot_len=0
14825         local num_luns=1
14826         for line in $filefrag_op; do
14827                 local frag_lun=$(echo $line | cut -d: -f5 |
14828                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14829                 local ext_len=$(echo $line | cut -d: -f4)
14830                 if (( $frag_lun != $last_lun )); then
14831                         if (( tot_len != 1024 )); then
14832                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14833                                 return
14834                         else
14835                                 (( num_luns += 1 ))
14836                                 local tot_len=0
14837                         fi
14838                 fi
14839                 (( tot_len += ext_len ))
14840                 last_lun=$frag_lun
14841         done
14842         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14843                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14844                 return
14845         fi
14846
14847         echo "FIEMAP on N-stripe file succeeded"
14848 }
14849 run_test 130d "FIEMAP (N-stripe file)"
14850
14851 test_130e() {
14852         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14853
14854         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14855         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14856         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14857                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14858
14859         trap cleanup_130 EXIT RETURN
14860
14861         local fm_file=$DIR/$tfile
14862         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14863         stack_trap "rm -f $fm_file"
14864
14865         local num_blks=512
14866         local expected_len=$(( (num_blks / 2) * 64 ))
14867         for ((i = 0; i < $num_blks; i++)); do
14868                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14869                         conv=notrunc > /dev/null 2>&1
14870         done
14871
14872         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14873         filefrag_op=$(filefrag -ve -k $fm_file |
14874                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14875
14876         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14877
14878         IFS=$'\n'
14879         local tot_len=0
14880         local num_luns=1
14881         for line in $filefrag_op; do
14882                 local frag_lun=$(echo $line | cut -d: -f5)
14883                 local ext_len=$(echo $line | cut -d: -f4)
14884                 if (( $frag_lun != $last_lun )); then
14885                         if (( tot_len != $expected_len )); then
14886                                 error "OST$last_lun $tot_len != $expected_len"
14887                         else
14888                                 (( num_luns += 1 ))
14889                                 tot_len=0
14890                         fi
14891                 fi
14892                 (( tot_len += ext_len ))
14893                 last_lun=$frag_lun
14894         done
14895         if (( num_luns != 2 || tot_len != $expected_len )); then
14896                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14897         fi
14898
14899         echo "FIEMAP with continuation calls succeeded"
14900 }
14901 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14902
14903 test_130f() {
14904         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14905         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14906         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14907                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14908
14909         local fm_file=$DIR/$tfile
14910         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14911                 error "multiop create with lov_delay_create on $fm_file"
14912
14913         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14914         filefrag_extents=$(filefrag -vek $fm_file |
14915                            awk '/extents? found/ { print $2 }')
14916         if (( $filefrag_extents != 0 )); then
14917                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14918         fi
14919
14920         rm -f $fm_file
14921 }
14922 run_test 130f "FIEMAP (unstriped file)"
14923
14924 test_130g() {
14925         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14926                 skip "Need MDS version with at least 2.12.53 for overstriping"
14927         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14928         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14929         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14930                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14931
14932         local file=$DIR/$tfile
14933         local nr=$((OSTCOUNT * 100))
14934
14935         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14936
14937         stack_trap "rm -f $file"
14938         dd if=/dev/zero of=$file count=$nr bs=1M
14939         sync
14940         nr=$($LFS getstripe -c $file)
14941
14942         local extents=$(filefrag -v $file |
14943                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14944
14945         echo "filefrag list $extents extents in file with stripecount $nr"
14946         if (( extents < nr )); then
14947                 $LFS getstripe $file
14948                 filefrag -v $file
14949                 error "filefrag printed $extents < $nr extents"
14950         fi
14951 }
14952 run_test 130g "FIEMAP (overstripe file)"
14953
14954 # Test for writev/readv
14955 test_131a() {
14956         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14957                 error "writev test failed"
14958         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14959                 error "readv failed"
14960         rm -f $DIR/$tfile
14961 }
14962 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14963
14964 test_131b() {
14965         local fsize=$((524288 + 1048576 + 1572864))
14966         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14967                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14968                         error "append writev test failed"
14969
14970         ((fsize += 1572864 + 1048576))
14971         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14972                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14973                         error "append writev test failed"
14974         rm -f $DIR/$tfile
14975 }
14976 run_test 131b "test append writev"
14977
14978 test_131c() {
14979         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14980         error "NOT PASS"
14981 }
14982 run_test 131c "test read/write on file w/o objects"
14983
14984 test_131d() {
14985         rwv -f $DIR/$tfile -w -n 1 1572864
14986         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14987         if [ "$NOB" != 1572864 ]; then
14988                 error "Short read filed: read $NOB bytes instead of 1572864"
14989         fi
14990         rm -f $DIR/$tfile
14991 }
14992 run_test 131d "test short read"
14993
14994 test_131e() {
14995         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14996         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14997         error "read hitting hole failed"
14998         rm -f $DIR/$tfile
14999 }
15000 run_test 131e "test read hitting hole"
15001
15002 check_stats() {
15003         local facet=$1
15004         local op=$2
15005         local want=${3:-0}
15006         local res
15007
15008         # open             11 samples [usecs] 468 4793 13658 35791898
15009         case $facet in
15010         mds*) res=($(do_facet $facet \
15011                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15012                  ;;
15013         ost*) res=($(do_facet $facet \
15014                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15015                  ;;
15016         *) error "Wrong facet '$facet'" ;;
15017         esac
15018         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15019         # if $want is zero, it means any stat increment is ok.
15020         if (( $want > 0 )); then
15021                 local count=${res[1]}
15022
15023                 if (( $count != $want )); then
15024                         if [[ $facet =~ "mds" ]]; then
15025                                 do_nodes $(comma_list $(mdts_nodes)) \
15026                                         $LCTL get_param mdt.*.md_stats
15027                         else
15028                                 do_nodes $(comma_list $(osts-nodes)) \
15029                                         $LCTL get_param obdfilter.*.stats
15030                         fi
15031                         error "The $op counter on $facet is $count, not $want"
15032                 fi
15033         fi
15034 }
15035
15036 test_133a() {
15037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15038         remote_ost_nodsh && skip "remote OST with nodsh"
15039         remote_mds_nodsh && skip "remote MDS with nodsh"
15040         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15041                 skip_env "MDS doesn't support rename stats"
15042
15043         local testdir=$DIR/${tdir}/stats_testdir
15044
15045         mkdir -p $DIR/${tdir}
15046
15047         # clear stats.
15048         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15049         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15050
15051         # verify mdt stats first.
15052         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15053         check_stats $SINGLEMDS "mkdir" 1
15054
15055         # clear "open" from "lfs mkdir" above
15056         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15057         touch ${testdir}/${tfile} || error "touch failed"
15058         check_stats $SINGLEMDS "open" 1
15059         check_stats $SINGLEMDS "close" 1
15060         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15061                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15062                 check_stats $SINGLEMDS "mknod" 2
15063         }
15064         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15065         check_stats $SINGLEMDS "unlink" 1
15066         rm -f ${testdir}/${tfile} || error "file remove failed"
15067         check_stats $SINGLEMDS "unlink" 2
15068
15069         # remove working dir and check mdt stats again.
15070         rmdir ${testdir} || error "rmdir failed"
15071         check_stats $SINGLEMDS "rmdir" 1
15072
15073         local testdir1=$DIR/${tdir}/stats_testdir1
15074         mkdir_on_mdt0 -p ${testdir}
15075         mkdir_on_mdt0 -p ${testdir1}
15076         touch ${testdir1}/test1
15077         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15078         check_stats $SINGLEMDS "crossdir_rename" 1
15079
15080         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15081         check_stats $SINGLEMDS "samedir_rename" 1
15082
15083         rm -rf $DIR/${tdir}
15084 }
15085 run_test 133a "Verifying MDT stats ========================================"
15086
15087 test_133b() {
15088         local res
15089
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         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15097         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15098         touch ${testdir}/${tfile} || error "touch failed"
15099         cancel_lru_locks mdc
15100
15101         # clear stats.
15102         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15103         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15104
15105         # extra mdt stats verification.
15106         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15107         check_stats $SINGLEMDS "setattr" 1
15108         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15109         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15110         then            # LU-1740
15111                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15112                 check_stats $SINGLEMDS "getattr" 1
15113         fi
15114         rm -rf $DIR/${tdir}
15115
15116         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15117         # so the check below is not reliable
15118         [ $MDSCOUNT -eq 1 ] || return 0
15119
15120         # Sleep to avoid a cached response.
15121         #define OBD_STATFS_CACHE_SECONDS 1
15122         sleep 2
15123         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15124         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15125         $LFS df || error "lfs failed"
15126         check_stats $SINGLEMDS "statfs" 1
15127
15128         # check aggregated statfs (LU-10018)
15129         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15130                 return 0
15131         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15132                 return 0
15133         sleep 2
15134         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15135         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15136         df $DIR
15137         check_stats $SINGLEMDS "statfs" 1
15138
15139         # We want to check that the client didn't send OST_STATFS to
15140         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15141         # extra care is needed here.
15142         if remote_mds; then
15143                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15144                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15145
15146                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15147                 [ "$res" ] && error "OST got STATFS"
15148         fi
15149
15150         return 0
15151 }
15152 run_test 133b "Verifying extra MDT stats =================================="
15153
15154 test_133c() {
15155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15156         remote_ost_nodsh && skip "remote OST with nodsh"
15157         remote_mds_nodsh && skip "remote MDS with nodsh"
15158
15159         local testdir=$DIR/$tdir/stats_testdir
15160
15161         test_mkdir -p $testdir
15162
15163         # verify obdfilter stats.
15164         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15165         sync
15166         cancel_lru_locks osc
15167         wait_delete_completed
15168
15169         # clear stats.
15170         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15171         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15172
15173         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15174                 error "dd failed"
15175         sync
15176         cancel_lru_locks osc
15177         check_stats ost1 "write" 1
15178
15179         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15180         check_stats ost1 "read" 1
15181
15182         > $testdir/$tfile || error "truncate failed"
15183         check_stats ost1 "punch" 1
15184
15185         rm -f $testdir/$tfile || error "file remove failed"
15186         wait_delete_completed
15187         check_stats ost1 "destroy" 1
15188
15189         rm -rf $DIR/$tdir
15190 }
15191 run_test 133c "Verifying OST stats ========================================"
15192
15193 order_2() {
15194         local value=$1
15195         local orig=$value
15196         local order=1
15197
15198         while [ $value -ge 2 ]; do
15199                 order=$((order*2))
15200                 value=$((value/2))
15201         done
15202
15203         if [ $orig -gt $order ]; then
15204                 order=$((order*2))
15205         fi
15206         echo $order
15207 }
15208
15209 size_in_KMGT() {
15210     local value=$1
15211     local size=('K' 'M' 'G' 'T');
15212     local i=0
15213     local size_string=$value
15214
15215     while [ $value -ge 1024 ]; do
15216         if [ $i -gt 3 ]; then
15217             #T is the biggest unit we get here, if that is bigger,
15218             #just return XXXT
15219             size_string=${value}T
15220             break
15221         fi
15222         value=$((value >> 10))
15223         if [ $value -lt 1024 ]; then
15224             size_string=${value}${size[$i]}
15225             break
15226         fi
15227         i=$((i + 1))
15228     done
15229
15230     echo $size_string
15231 }
15232
15233 get_rename_size() {
15234         local size=$1
15235         local context=${2:-.}
15236         local sample=$(do_facet $SINGLEMDS $LCTL \
15237                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15238                 grep -A1 $context |
15239                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15240         echo $sample
15241 }
15242
15243 test_133d() {
15244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15245         remote_ost_nodsh && skip "remote OST with nodsh"
15246         remote_mds_nodsh && skip "remote MDS with nodsh"
15247         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15248                 skip_env "MDS doesn't support rename stats"
15249
15250         local testdir1=$DIR/${tdir}/stats_testdir1
15251         local testdir2=$DIR/${tdir}/stats_testdir2
15252         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15253
15254         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15255
15256         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15257         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15258
15259         createmany -o $testdir1/test 512 || error "createmany failed"
15260
15261         # check samedir rename size
15262         mv ${testdir1}/test0 ${testdir1}/test_0
15263
15264         local testdir1_size=$(ls -l $DIR/${tdir} |
15265                 awk '/stats_testdir1/ {print $5}')
15266         local testdir2_size=$(ls -l $DIR/${tdir} |
15267                 awk '/stats_testdir2/ {print $5}')
15268
15269         testdir1_size=$(order_2 $testdir1_size)
15270         testdir2_size=$(order_2 $testdir2_size)
15271
15272         testdir1_size=$(size_in_KMGT $testdir1_size)
15273         testdir2_size=$(size_in_KMGT $testdir2_size)
15274
15275         echo "source rename dir size: ${testdir1_size}"
15276         echo "target rename dir size: ${testdir2_size}"
15277
15278         local cmd="do_facet $SINGLEMDS $LCTL "
15279         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15280
15281         eval $cmd || error "$cmd failed"
15282         local samedir=$($cmd | grep 'same_dir')
15283         local same_sample=$(get_rename_size $testdir1_size)
15284         [ -z "$samedir" ] && error "samedir_rename_size count error"
15285         [[ $same_sample -eq 1 ]] ||
15286                 error "samedir_rename_size error $same_sample"
15287         echo "Check same dir rename stats success"
15288
15289         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15290
15291         # check crossdir rename size
15292         mv ${testdir1}/test_0 ${testdir2}/test_0
15293
15294         testdir1_size=$(ls -l $DIR/${tdir} |
15295                 awk '/stats_testdir1/ {print $5}')
15296         testdir2_size=$(ls -l $DIR/${tdir} |
15297                 awk '/stats_testdir2/ {print $5}')
15298
15299         testdir1_size=$(order_2 $testdir1_size)
15300         testdir2_size=$(order_2 $testdir2_size)
15301
15302         testdir1_size=$(size_in_KMGT $testdir1_size)
15303         testdir2_size=$(size_in_KMGT $testdir2_size)
15304
15305         echo "source rename dir size: ${testdir1_size}"
15306         echo "target rename dir size: ${testdir2_size}"
15307
15308         eval $cmd || error "$cmd failed"
15309         local crossdir=$($cmd | grep 'crossdir')
15310         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15311         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15312         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15313         [[ $src_sample -eq 1 ]] ||
15314                 error "crossdir_rename_size error $src_sample"
15315         [[ $tgt_sample -eq 1 ]] ||
15316                 error "crossdir_rename_size error $tgt_sample"
15317         echo "Check cross dir rename stats success"
15318         rm -rf $DIR/${tdir}
15319 }
15320 run_test 133d "Verifying rename_stats ========================================"
15321
15322 test_133e() {
15323         remote_mds_nodsh && skip "remote MDS with nodsh"
15324         remote_ost_nodsh && skip "remote OST with nodsh"
15325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15326
15327         local testdir=$DIR/${tdir}/stats_testdir
15328         local ctr f0 f1 bs=32768 count=42 sum
15329
15330         mkdir -p ${testdir} || error "mkdir failed"
15331
15332         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15333
15334         for ctr in {write,read}_bytes; do
15335                 sync
15336                 cancel_lru_locks osc
15337
15338                 do_facet ost1 $LCTL set_param -n \
15339                         "obdfilter.*.exports.clear=clear"
15340
15341                 if [ $ctr = write_bytes ]; then
15342                         f0=/dev/zero
15343                         f1=${testdir}/${tfile}
15344                 else
15345                         f0=${testdir}/${tfile}
15346                         f1=/dev/null
15347                 fi
15348
15349                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15350                         error "dd failed"
15351                 sync
15352                 cancel_lru_locks osc
15353
15354                 sum=$(do_facet ost1 $LCTL get_param \
15355                         "obdfilter.*.exports.*.stats" |
15356                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15357                                 $1 == ctr { sum += $7 }
15358                                 END { printf("%0.0f", sum) }')
15359
15360                 if ((sum != bs * count)); then
15361                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15362                 fi
15363         done
15364
15365         rm -rf $DIR/${tdir}
15366 }
15367 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15368
15369 test_133f() {
15370         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15371                 skip "too old lustre for get_param -R ($facet_ver)"
15372
15373         # verifying readability.
15374         $LCTL get_param -R '*' &> /dev/null
15375
15376         # Verifing writability with badarea_io.
15377         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15378         local skipped_params='force_lbug|changelog_mask|daemon_file'
15379         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15380                 egrep -v "$skipped_params" |
15381                 xargs -n 1 find $proc_dirs -name |
15382                 xargs -n 1 badarea_io ||
15383                 error "client badarea_io failed"
15384
15385         # remount the FS in case writes/reads /proc break the FS
15386         cleanup || error "failed to unmount"
15387         setup || error "failed to setup"
15388 }
15389 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15390
15391 test_133g() {
15392         remote_mds_nodsh && skip "remote MDS with nodsh"
15393         remote_ost_nodsh && skip "remote OST with nodsh"
15394
15395         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15396         local proc_dirs_str=$(eval echo $proc_dirs)
15397         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15398         local facet
15399         for facet in mds1 ost1; do
15400                 local facet_ver=$(lustre_version_code $facet)
15401                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15402                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15403                 else
15404                         log "$facet: too old lustre for get_param -R"
15405                 fi
15406                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15407                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15408                                 tr -d = | egrep -v $skipped_params |
15409                                 xargs -n 1 find $proc_dirs_str -name |
15410                                 xargs -n 1 badarea_io" ||
15411                                         error "$facet badarea_io failed"
15412                 else
15413                         skip_noexit "$facet: too old lustre for get_param -R"
15414                 fi
15415         done
15416
15417         # remount the FS in case writes/reads /proc break the FS
15418         cleanup || error "failed to unmount"
15419         setup || error "failed to setup"
15420 }
15421 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15422
15423 test_133h() {
15424         remote_mds_nodsh && skip "remote MDS with nodsh"
15425         remote_ost_nodsh && skip "remote OST with nodsh"
15426         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15427                 skip "Need MDS version at least 2.9.54"
15428
15429         local facet
15430         for facet in client mds1 ost1; do
15431                 # Get the list of files that are missing the terminating newline
15432                 local plist=$(do_facet $facet
15433                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15434                 local ent
15435                 for ent in $plist; do
15436                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15437                                 awk -v FS='\v' -v RS='\v\v' \
15438                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15439                                         print FILENAME}'" 2>/dev/null)
15440                         [ -z $missing ] || {
15441                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15442                                 error "file does not end with newline: $facet-$ent"
15443                         }
15444                 done
15445         done
15446 }
15447 run_test 133h "Proc files should end with newlines"
15448
15449 test_134a() {
15450         remote_mds_nodsh && skip "remote MDS with nodsh"
15451         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15452                 skip "Need MDS version at least 2.7.54"
15453
15454         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15455         cancel_lru_locks mdc
15456
15457         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15458         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15459         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15460
15461         local nr=1000
15462         createmany -o $DIR/$tdir/f $nr ||
15463                 error "failed to create $nr files in $DIR/$tdir"
15464         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15465
15466         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15467         do_facet mds1 $LCTL set_param fail_loc=0x327
15468         do_facet mds1 $LCTL set_param fail_val=500
15469         touch $DIR/$tdir/m
15470
15471         echo "sleep 10 seconds ..."
15472         sleep 10
15473         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15474
15475         do_facet mds1 $LCTL set_param fail_loc=0
15476         do_facet mds1 $LCTL set_param fail_val=0
15477         [ $lck_cnt -lt $unused ] ||
15478                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15479
15480         rm $DIR/$tdir/m
15481         unlinkmany $DIR/$tdir/f $nr
15482 }
15483 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15484
15485 test_134b() {
15486         remote_mds_nodsh && skip "remote MDS with nodsh"
15487         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15488                 skip "Need MDS version at least 2.7.54"
15489
15490         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15491         cancel_lru_locks mdc
15492
15493         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15494                         ldlm.lock_reclaim_threshold_mb)
15495         # disable reclaim temporarily
15496         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15497
15498         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15499         do_facet mds1 $LCTL set_param fail_loc=0x328
15500         do_facet mds1 $LCTL set_param fail_val=500
15501
15502         $LCTL set_param debug=+trace
15503
15504         local nr=600
15505         createmany -o $DIR/$tdir/f $nr &
15506         local create_pid=$!
15507
15508         echo "Sleep $TIMEOUT seconds ..."
15509         sleep $TIMEOUT
15510         if ! ps -p $create_pid  > /dev/null 2>&1; then
15511                 do_facet mds1 $LCTL set_param fail_loc=0
15512                 do_facet mds1 $LCTL set_param fail_val=0
15513                 do_facet mds1 $LCTL set_param \
15514                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15515                 error "createmany finished incorrectly!"
15516         fi
15517         do_facet mds1 $LCTL set_param fail_loc=0
15518         do_facet mds1 $LCTL set_param fail_val=0
15519         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15520         wait $create_pid || return 1
15521
15522         unlinkmany $DIR/$tdir/f $nr
15523 }
15524 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15525
15526 test_135() {
15527         remote_mds_nodsh && skip "remote MDS with nodsh"
15528         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15529                 skip "Need MDS version at least 2.13.50"
15530         local fname
15531
15532         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15533
15534 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15535         #set only one record at plain llog
15536         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15537
15538         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15539
15540         #fill already existed plain llog each 64767
15541         #wrapping whole catalog
15542         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15543
15544         createmany -o $DIR/$tdir/$tfile_ 64700
15545         for (( i = 0; i < 64700; i = i + 2 ))
15546         do
15547                 rm $DIR/$tdir/$tfile_$i &
15548                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15549                 local pid=$!
15550                 wait $pid
15551         done
15552
15553         #waiting osp synchronization
15554         wait_delete_completed
15555 }
15556 run_test 135 "Race catalog processing"
15557
15558 test_136() {
15559         remote_mds_nodsh && skip "remote MDS with nodsh"
15560         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15561                 skip "Need MDS version at least 2.13.50"
15562         local fname
15563
15564         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15565         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15566         #set only one record at plain llog
15567 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15568         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15569
15570         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15571
15572         #fill already existed 2 plain llogs each 64767
15573         #wrapping whole catalog
15574         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15575         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15576         wait_delete_completed
15577
15578         createmany -o $DIR/$tdir/$tfile_ 10
15579         sleep 25
15580
15581         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15582         for (( i = 0; i < 10; i = i + 3 ))
15583         do
15584                 rm $DIR/$tdir/$tfile_$i &
15585                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15586                 local pid=$!
15587                 wait $pid
15588                 sleep 7
15589                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15590         done
15591
15592         #waiting osp synchronization
15593         wait_delete_completed
15594 }
15595 run_test 136 "Race catalog processing 2"
15596
15597 test_140() { #bug-17379
15598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15599
15600         test_mkdir $DIR/$tdir
15601         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15602         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15603
15604         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15605         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15606         local i=0
15607         while i=$((i + 1)); do
15608                 test_mkdir $i
15609                 cd $i || error "Changing to $i"
15610                 ln -s ../stat stat || error "Creating stat symlink"
15611                 # Read the symlink until ELOOP present,
15612                 # not LBUGing the system is considered success,
15613                 # we didn't overrun the stack.
15614                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15615                 if [ $ret -ne 0 ]; then
15616                         if [ $ret -eq 40 ]; then
15617                                 break  # -ELOOP
15618                         else
15619                                 error "Open stat symlink"
15620                                         return
15621                         fi
15622                 fi
15623         done
15624         i=$((i - 1))
15625         echo "The symlink depth = $i"
15626         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15627                 error "Invalid symlink depth"
15628
15629         # Test recursive symlink
15630         ln -s symlink_self symlink_self
15631         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15632         echo "open symlink_self returns $ret"
15633         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15634 }
15635 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15636
15637 test_150a() {
15638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15639
15640         local TF="$TMP/$tfile"
15641
15642         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15643         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15644         cp $TF $DIR/$tfile
15645         cancel_lru_locks $OSC
15646         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15647         remount_client $MOUNT
15648         df -P $MOUNT
15649         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15650
15651         $TRUNCATE $TF 6000
15652         $TRUNCATE $DIR/$tfile 6000
15653         cancel_lru_locks $OSC
15654         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15655
15656         echo "12345" >>$TF
15657         echo "12345" >>$DIR/$tfile
15658         cancel_lru_locks $OSC
15659         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15660
15661         echo "12345" >>$TF
15662         echo "12345" >>$DIR/$tfile
15663         cancel_lru_locks $OSC
15664         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15665 }
15666 run_test 150a "truncate/append tests"
15667
15668 test_150b() {
15669         check_set_fallocate_or_skip
15670         local out
15671
15672         touch $DIR/$tfile
15673         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15674         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15675                 skip_eopnotsupp "$out|check_fallocate failed"
15676 }
15677 run_test 150b "Verify fallocate (prealloc) functionality"
15678
15679 test_150bb() {
15680         check_set_fallocate_or_skip
15681
15682         touch $DIR/$tfile
15683         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15684         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15685         > $DIR/$tfile
15686         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15687         # precomputed md5sum for 20MB of zeroes
15688         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15689         local sum=($(md5sum $DIR/$tfile))
15690
15691         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15692
15693         check_set_fallocate 1
15694
15695         > $DIR/$tfile
15696         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15697         sum=($(md5sum $DIR/$tfile))
15698
15699         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15700 }
15701 run_test 150bb "Verify fallocate modes both zero space"
15702
15703 test_150c() {
15704         check_set_fallocate_or_skip
15705         local striping="-c2"
15706
15707         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15708         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15709         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15710         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15711         local want=$((OSTCOUNT * 1048576))
15712
15713         # Must allocate all requested space, not more than 5% extra
15714         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15715                 error "bytes $bytes is not $want"
15716
15717         rm -f $DIR/$tfile
15718
15719         echo "verify fallocate on PFL file"
15720
15721         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15722
15723         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15724                 error "Create $DIR/$tfile failed"
15725         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15726         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15727         want=$((512 * 1048576))
15728
15729         # Must allocate all requested space, not more than 5% extra
15730         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15731                 error "bytes $bytes is not $want"
15732 }
15733 run_test 150c "Verify fallocate Size and Blocks"
15734
15735 test_150d() {
15736         check_set_fallocate_or_skip
15737         local striping="-c2"
15738
15739         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15740
15741         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15742         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15743                 error "setstripe failed"
15744         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15745         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15746         local want=$((OSTCOUNT * 1048576))
15747
15748         # Must allocate all requested space, not more than 5% extra
15749         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15750                 error "bytes $bytes is not $want"
15751 }
15752 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15753
15754 test_150e() {
15755         check_set_fallocate_or_skip
15756
15757         echo "df before:"
15758         $LFS df
15759         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15760         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15761                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15762
15763         # Find OST with Minimum Size
15764         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15765                        sort -un | head -1)
15766
15767         # Get 100MB per OST of the available space to reduce run time
15768         # else 60% of the available space if we are running SLOW tests
15769         if [ $SLOW == "no" ]; then
15770                 local space=$((1024 * 100 * OSTCOUNT))
15771         else
15772                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15773         fi
15774
15775         fallocate -l${space}k $DIR/$tfile ||
15776                 error "fallocate ${space}k $DIR/$tfile failed"
15777         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15778
15779         # get size immediately after fallocate. This should be correctly
15780         # updated
15781         local size=$(stat -c '%s' $DIR/$tfile)
15782         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15783
15784         # Sleep for a while for statfs to get updated. And not pull from cache.
15785         sleep 2
15786
15787         echo "df after fallocate:"
15788         $LFS df
15789
15790         (( size / 1024 == space )) || error "size $size != requested $space"
15791         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15792                 error "used $used < space $space"
15793
15794         rm $DIR/$tfile || error "rm failed"
15795         sync
15796         wait_delete_completed
15797
15798         echo "df after unlink:"
15799         $LFS df
15800 }
15801 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15802
15803 test_150f() {
15804         local size
15805         local blocks
15806         local want_size_before=20480 # in bytes
15807         local want_blocks_before=40 # 512 sized blocks
15808         local want_blocks_after=24  # 512 sized blocks
15809         local length=$(((want_blocks_before - want_blocks_after) * 512))
15810
15811         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15812                 skip "need at least 2.14.0 for fallocate punch"
15813
15814         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15815                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15816         fi
15817
15818         check_set_fallocate_or_skip
15819         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15820
15821         [[ "x$DOM" == "xyes" ]] &&
15822                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15823
15824         echo "Verify fallocate punch: Range within the file range"
15825         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15826                 error "dd failed for bs 4096 and count 5"
15827
15828         # Call fallocate with punch range which is within the file range
15829         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15830                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15831         # client must see changes immediately after fallocate
15832         size=$(stat -c '%s' $DIR/$tfile)
15833         blocks=$(stat -c '%b' $DIR/$tfile)
15834
15835         # Verify punch worked.
15836         (( blocks == want_blocks_after )) ||
15837                 error "punch failed: blocks $blocks != $want_blocks_after"
15838
15839         (( size == want_size_before )) ||
15840                 error "punch failed: size $size != $want_size_before"
15841
15842         # Verify there is hole in file
15843         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15844         # precomputed md5sum
15845         local expect="4a9a834a2db02452929c0a348273b4aa"
15846
15847         cksum=($(md5sum $DIR/$tfile))
15848         [[ "${cksum[0]}" == "$expect" ]] ||
15849                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15850
15851         # Start second sub-case for fallocate punch.
15852         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15853         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15854                 error "dd failed for bs 4096 and count 5"
15855
15856         # Punch range less than block size will have no change in block count
15857         want_blocks_after=40  # 512 sized blocks
15858
15859         # Punch overlaps two blocks and less than blocksize
15860         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15861                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15862         size=$(stat -c '%s' $DIR/$tfile)
15863         blocks=$(stat -c '%b' $DIR/$tfile)
15864
15865         # Verify punch worked.
15866         (( blocks == want_blocks_after )) ||
15867                 error "punch failed: blocks $blocks != $want_blocks_after"
15868
15869         (( size == want_size_before )) ||
15870                 error "punch failed: size $size != $want_size_before"
15871
15872         # Verify if range is really zero'ed out. We expect Zeros.
15873         # precomputed md5sum
15874         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15875         cksum=($(md5sum $DIR/$tfile))
15876         [[ "${cksum[0]}" == "$expect" ]] ||
15877                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15878 }
15879 run_test 150f "Verify fallocate punch functionality"
15880
15881 test_150g() {
15882         local space
15883         local size
15884         local blocks
15885         local blocks_after
15886         local size_after
15887         local BS=4096 # Block size in bytes
15888
15889         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15890                 skip "need at least 2.14.0 for fallocate punch"
15891
15892         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15893                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15894         fi
15895
15896         check_set_fallocate_or_skip
15897         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15898
15899         if [[ "x$DOM" == "xyes" ]]; then
15900                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15901                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15902         else
15903                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15904                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15905         fi
15906
15907         # Get 100MB per OST of the available space to reduce run time
15908         # else 60% of the available space if we are running SLOW tests
15909         if [ $SLOW == "no" ]; then
15910                 space=$((1024 * 100 * OSTCOUNT))
15911         else
15912                 # Find OST with Minimum Size
15913                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15914                         sort -un | head -1)
15915                 echo "min size OST: $space"
15916                 space=$(((space * 60)/100 * OSTCOUNT))
15917         fi
15918         # space in 1k units, round to 4k blocks
15919         local blkcount=$((space * 1024 / $BS))
15920
15921         echo "Verify fallocate punch: Very large Range"
15922         fallocate -l${space}k $DIR/$tfile ||
15923                 error "fallocate ${space}k $DIR/$tfile failed"
15924         # write 1M at the end, start and in the middle
15925         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15926                 error "dd failed: bs $BS count 256"
15927         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15928                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15929         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15930                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15931
15932         # Gather stats.
15933         size=$(stat -c '%s' $DIR/$tfile)
15934
15935         # gather punch length.
15936         local punch_size=$((size - (BS * 2)))
15937
15938         echo "punch_size = $punch_size"
15939         echo "size - punch_size: $((size - punch_size))"
15940         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15941
15942         # Call fallocate to punch all except 2 blocks. We leave the
15943         # first and the last block
15944         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15945         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15946                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15947
15948         size_after=$(stat -c '%s' $DIR/$tfile)
15949         blocks_after=$(stat -c '%b' $DIR/$tfile)
15950
15951         # Verify punch worked.
15952         # Size should be kept
15953         (( size == size_after )) ||
15954                 error "punch failed: size $size != $size_after"
15955
15956         # two 4k data blocks to remain plus possible 1 extra extent block
15957         (( blocks_after <= ((BS / 512) * 3) )) ||
15958                 error "too many blocks remains: $blocks_after"
15959
15960         # Verify that file has hole between the first and the last blocks
15961         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15962         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15963
15964         echo "Hole at [$hole_start, $hole_end)"
15965         (( hole_start == BS )) ||
15966                 error "no hole at offset $BS after punch"
15967
15968         (( hole_end == BS + punch_size )) ||
15969                 error "data at offset $hole_end < $((BS + punch_size))"
15970 }
15971 run_test 150g "Verify fallocate punch on large range"
15972
15973 test_150h() {
15974         local file=$DIR/$tfile
15975         local size
15976
15977         check_set_fallocate_or_skip
15978         statx_supported || skip_env "Test must be statx() syscall supported"
15979
15980         # fallocate() does not update the size information on the MDT
15981         fallocate -l 16K $file || error "failed to fallocate $file"
15982         cancel_lru_locks $OSC
15983         # STATX with cached-always mode will not send glimpse RPCs to OST,
15984         # it uses the caching attrs on the client side as much as possible.
15985         size=$($STATX --cached=always -c %s $file)
15986         [ $size == 16384 ] ||
15987                 error "size after fallocate() is $size, expected 16384"
15988 }
15989 run_test 150h "Verify extend fallocate updates the file size"
15990
15991 #LU-2902 roc_hit was not able to read all values from lproc
15992 function roc_hit_init() {
15993         local list=$(comma_list $(osts_nodes))
15994         local dir=$DIR/$tdir-check
15995         local file=$dir/$tfile
15996         local BEFORE
15997         local AFTER
15998         local idx
15999
16000         test_mkdir $dir
16001         #use setstripe to do a write to every ost
16002         for i in $(seq 0 $((OSTCOUNT-1))); do
16003                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16004                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16005                 idx=$(printf %04x $i)
16006                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16007                         awk '$1 == "cache_access" {sum += $7}
16008                                 END { printf("%0.0f", sum) }')
16009
16010                 cancel_lru_locks osc
16011                 cat $file >/dev/null
16012
16013                 AFTER=$(get_osd_param $list *OST*$idx stats |
16014                         awk '$1 == "cache_access" {sum += $7}
16015                                 END { printf("%0.0f", sum) }')
16016
16017                 echo BEFORE:$BEFORE AFTER:$AFTER
16018                 if ! let "AFTER - BEFORE == 4"; then
16019                         rm -rf $dir
16020                         error "roc_hit is not safe to use"
16021                 fi
16022                 rm $file
16023         done
16024
16025         rm -rf $dir
16026 }
16027
16028 function roc_hit() {
16029         local list=$(comma_list $(osts_nodes))
16030         echo $(get_osd_param $list '' stats |
16031                 awk '$1 == "cache_hit" {sum += $7}
16032                         END { printf("%0.0f", sum) }')
16033 }
16034
16035 function set_cache() {
16036         local on=1
16037
16038         if [ "$2" == "off" ]; then
16039                 on=0;
16040         fi
16041         local list=$(comma_list $(osts_nodes))
16042         set_osd_param $list '' $1_cache_enable $on
16043
16044         cancel_lru_locks osc
16045 }
16046
16047 test_151() {
16048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16049         remote_ost_nodsh && skip "remote OST with nodsh"
16050         (( CLIENT_VERSION == OST1_VERSION )) ||
16051                 skip "LU-13081: no interop testing for OSS cache"
16052
16053         local CPAGES=3
16054         local list=$(comma_list $(osts_nodes))
16055
16056         # check whether obdfilter is cache capable at all
16057         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16058                 skip "not cache-capable obdfilter"
16059         fi
16060
16061         # check cache is enabled on all obdfilters
16062         if get_osd_param $list '' read_cache_enable | grep 0; then
16063                 skip "oss cache is disabled"
16064         fi
16065
16066         set_osd_param $list '' writethrough_cache_enable 1
16067
16068         # check write cache is enabled on all obdfilters
16069         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16070                 skip "oss write cache is NOT enabled"
16071         fi
16072
16073         roc_hit_init
16074
16075         #define OBD_FAIL_OBD_NO_LRU  0x609
16076         do_nodes $list $LCTL set_param fail_loc=0x609
16077
16078         # pages should be in the case right after write
16079         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16080                 error "dd failed"
16081
16082         local BEFORE=$(roc_hit)
16083         cancel_lru_locks osc
16084         cat $DIR/$tfile >/dev/null
16085         local AFTER=$(roc_hit)
16086
16087         do_nodes $list $LCTL set_param fail_loc=0
16088
16089         if ! let "AFTER - BEFORE == CPAGES"; then
16090                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16091         fi
16092
16093         cancel_lru_locks osc
16094         # invalidates OST cache
16095         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16096         set_osd_param $list '' read_cache_enable 0
16097         cat $DIR/$tfile >/dev/null
16098
16099         # now data shouldn't be found in the cache
16100         BEFORE=$(roc_hit)
16101         cancel_lru_locks osc
16102         cat $DIR/$tfile >/dev/null
16103         AFTER=$(roc_hit)
16104         if let "AFTER - BEFORE != 0"; then
16105                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16106         fi
16107
16108         set_osd_param $list '' read_cache_enable 1
16109         rm -f $DIR/$tfile
16110 }
16111 run_test 151 "test cache on oss and controls ==============================="
16112
16113 test_152() {
16114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16115
16116         local TF="$TMP/$tfile"
16117
16118         # simulate ENOMEM during write
16119 #define OBD_FAIL_OST_NOMEM      0x226
16120         lctl set_param fail_loc=0x80000226
16121         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16122         cp $TF $DIR/$tfile
16123         sync || error "sync failed"
16124         lctl set_param fail_loc=0
16125
16126         # discard client's cache
16127         cancel_lru_locks osc
16128
16129         # simulate ENOMEM during read
16130         lctl set_param fail_loc=0x80000226
16131         cmp $TF $DIR/$tfile || error "cmp failed"
16132         lctl set_param fail_loc=0
16133
16134         rm -f $TF
16135 }
16136 run_test 152 "test read/write with enomem ============================"
16137
16138 test_153() {
16139         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16140 }
16141 run_test 153 "test if fdatasync does not crash ======================="
16142
16143 dot_lustre_fid_permission_check() {
16144         local fid=$1
16145         local ffid=$MOUNT/.lustre/fid/$fid
16146         local test_dir=$2
16147
16148         echo "stat fid $fid"
16149         stat $ffid || error "stat $ffid failed."
16150         echo "touch fid $fid"
16151         touch $ffid || error "touch $ffid failed."
16152         echo "write to fid $fid"
16153         cat /etc/hosts > $ffid || error "write $ffid failed."
16154         echo "read fid $fid"
16155         diff /etc/hosts $ffid || error "read $ffid failed."
16156         echo "append write to fid $fid"
16157         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16158         echo "rename fid $fid"
16159         mv $ffid $test_dir/$tfile.1 &&
16160                 error "rename $ffid to $tfile.1 should fail."
16161         touch $test_dir/$tfile.1
16162         mv $test_dir/$tfile.1 $ffid &&
16163                 error "rename $tfile.1 to $ffid should fail."
16164         rm -f $test_dir/$tfile.1
16165         echo "truncate fid $fid"
16166         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16167         echo "link fid $fid"
16168         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16169         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16170                 id $USER0 || skip_env "missing user $USER0"
16171                 echo "setfacl fid $fid"
16172                 setfacl -R -m u:$USER0:rwx $ffid ||
16173                         error "setfacl $ffid failed"
16174                 echo "getfacl fid $fid"
16175                 getfacl $ffid || error "getfacl $ffid failed."
16176         fi
16177         echo "unlink fid $fid"
16178         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16179         echo "mknod fid $fid"
16180         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16181
16182         fid=[0xf00000400:0x1:0x0]
16183         ffid=$MOUNT/.lustre/fid/$fid
16184
16185         echo "stat non-exist fid $fid"
16186         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16187         echo "write to non-exist fid $fid"
16188         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16189         echo "link new fid $fid"
16190         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16191
16192         mkdir -p $test_dir/$tdir
16193         touch $test_dir/$tdir/$tfile
16194         fid=$($LFS path2fid $test_dir/$tdir)
16195         rc=$?
16196         [ $rc -ne 0 ] &&
16197                 error "error: could not get fid for $test_dir/$dir/$tfile."
16198
16199         ffid=$MOUNT/.lustre/fid/$fid
16200
16201         echo "ls $fid"
16202         ls $ffid || error "ls $ffid failed."
16203         echo "touch $fid/$tfile.1"
16204         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16205
16206         echo "touch $MOUNT/.lustre/fid/$tfile"
16207         touch $MOUNT/.lustre/fid/$tfile && \
16208                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16209
16210         echo "setxattr to $MOUNT/.lustre/fid"
16211         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16212
16213         echo "listxattr for $MOUNT/.lustre/fid"
16214         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16215
16216         echo "delxattr from $MOUNT/.lustre/fid"
16217         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16218
16219         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16220         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16221                 error "touch invalid fid should fail."
16222
16223         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16224         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16225                 error "touch non-normal fid should fail."
16226
16227         echo "rename $tdir to $MOUNT/.lustre/fid"
16228         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16229                 error "rename to $MOUNT/.lustre/fid should fail."
16230
16231         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16232         then            # LU-3547
16233                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16234                 local new_obf_mode=777
16235
16236                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16237                 chmod $new_obf_mode $DIR/.lustre/fid ||
16238                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16239
16240                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16241                 [ $obf_mode -eq $new_obf_mode ] ||
16242                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16243
16244                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16245                 chmod $old_obf_mode $DIR/.lustre/fid ||
16246                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16247         fi
16248
16249         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16250         fid=$($LFS path2fid $test_dir/$tfile-2)
16251
16252         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16253         then # LU-5424
16254                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16255                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16256                         error "create lov data thru .lustre failed"
16257         fi
16258         echo "cp /etc/passwd $test_dir/$tfile-2"
16259         cp /etc/passwd $test_dir/$tfile-2 ||
16260                 error "copy to $test_dir/$tfile-2 failed."
16261         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16262         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16263                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16264
16265         rm -rf $test_dir/tfile.lnk
16266         rm -rf $test_dir/$tfile-2
16267 }
16268
16269 test_154A() {
16270         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16271                 skip "Need MDS version at least 2.4.1"
16272
16273         local tf=$DIR/$tfile
16274         touch $tf
16275
16276         local fid=$($LFS path2fid $tf)
16277         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16278
16279         # check that we get the same pathname back
16280         local rootpath
16281         local found
16282         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16283                 echo "$rootpath $fid"
16284                 found=$($LFS fid2path $rootpath "$fid")
16285                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16286                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16287         done
16288
16289         # check wrong root path format
16290         rootpath=$MOUNT"_wrong"
16291         found=$($LFS fid2path $rootpath "$fid")
16292         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16293 }
16294 run_test 154A "lfs path2fid and fid2path basic checks"
16295
16296 test_154B() {
16297         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16298                 skip "Need MDS version at least 2.4.1"
16299
16300         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16301         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16302         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16303         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16304
16305         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16306         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16307
16308         # check that we get the same pathname
16309         echo "PFID: $PFID, name: $name"
16310         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16311         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16312         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16313                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16314
16315         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16316 }
16317 run_test 154B "verify the ll_decode_linkea tool"
16318
16319 test_154a() {
16320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16321         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16322         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16323                 skip "Need MDS version at least 2.2.51"
16324         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16325
16326         cp /etc/hosts $DIR/$tfile
16327
16328         fid=$($LFS path2fid $DIR/$tfile)
16329         rc=$?
16330         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16331
16332         dot_lustre_fid_permission_check "$fid" $DIR ||
16333                 error "dot lustre permission check $fid failed"
16334
16335         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16336
16337         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16338
16339         touch $MOUNT/.lustre/file &&
16340                 error "creation is not allowed under .lustre"
16341
16342         mkdir $MOUNT/.lustre/dir &&
16343                 error "mkdir is not allowed under .lustre"
16344
16345         rm -rf $DIR/$tfile
16346 }
16347 run_test 154a "Open-by-FID"
16348
16349 test_154b() {
16350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16351         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16352         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16353         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16354                 skip "Need MDS version at least 2.2.51"
16355
16356         local remote_dir=$DIR/$tdir/remote_dir
16357         local MDTIDX=1
16358         local rc=0
16359
16360         mkdir -p $DIR/$tdir
16361         $LFS mkdir -i $MDTIDX $remote_dir ||
16362                 error "create remote directory failed"
16363
16364         cp /etc/hosts $remote_dir/$tfile
16365
16366         fid=$($LFS path2fid $remote_dir/$tfile)
16367         rc=$?
16368         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16369
16370         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16371                 error "dot lustre permission check $fid failed"
16372         rm -rf $DIR/$tdir
16373 }
16374 run_test 154b "Open-by-FID for remote directory"
16375
16376 test_154c() {
16377         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16378                 skip "Need MDS version at least 2.4.1"
16379
16380         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16381         local FID1=$($LFS path2fid $DIR/$tfile.1)
16382         local FID2=$($LFS path2fid $DIR/$tfile.2)
16383         local FID3=$($LFS path2fid $DIR/$tfile.3)
16384
16385         local N=1
16386         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16387                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16388                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16389                 local want=FID$N
16390                 [ "$FID" = "${!want}" ] ||
16391                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16392                 N=$((N + 1))
16393         done
16394
16395         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16396         do
16397                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16398                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16399                 N=$((N + 1))
16400         done
16401 }
16402 run_test 154c "lfs path2fid and fid2path multiple arguments"
16403
16404 test_154d() {
16405         remote_mds_nodsh && skip "remote MDS with nodsh"
16406         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16407                 skip "Need MDS version at least 2.5.53"
16408
16409         if remote_mds; then
16410                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16411         else
16412                 nid="0@lo"
16413         fi
16414         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16415         local fd
16416         local cmd
16417
16418         rm -f $DIR/$tfile
16419         touch $DIR/$tfile
16420
16421         local fid=$($LFS path2fid $DIR/$tfile)
16422         # Open the file
16423         fd=$(free_fd)
16424         cmd="exec $fd<$DIR/$tfile"
16425         eval $cmd
16426         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16427         echo "$fid_list" | grep "$fid"
16428         rc=$?
16429
16430         cmd="exec $fd>/dev/null"
16431         eval $cmd
16432         if [ $rc -ne 0 ]; then
16433                 error "FID $fid not found in open files list $fid_list"
16434         fi
16435 }
16436 run_test 154d "Verify open file fid"
16437
16438 test_154e()
16439 {
16440         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16441                 skip "Need MDS version at least 2.6.50"
16442
16443         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16444                 error ".lustre returned by readdir"
16445         fi
16446 }
16447 run_test 154e ".lustre is not returned by readdir"
16448
16449 test_154f() {
16450         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16451
16452         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16453         mkdir_on_mdt0 $DIR/$tdir
16454         # test dirs inherit from its stripe
16455         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16456         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16457         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16458         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16459         touch $DIR/f
16460
16461         # get fid of parents
16462         local FID0=$($LFS path2fid $DIR/$tdir)
16463         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16464         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16465         local FID3=$($LFS path2fid $DIR)
16466
16467         # check that path2fid --parents returns expected <parent_fid>/name
16468         # 1) test for a directory (single parent)
16469         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16470         [ "$parent" == "$FID0/foo1" ] ||
16471                 error "expected parent: $FID0/foo1, got: $parent"
16472
16473         # 2) test for a file with nlink > 1 (multiple parents)
16474         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16475         echo "$parent" | grep -F "$FID1/$tfile" ||
16476                 error "$FID1/$tfile not returned in parent list"
16477         echo "$parent" | grep -F "$FID2/link" ||
16478                 error "$FID2/link not returned in parent list"
16479
16480         # 3) get parent by fid
16481         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16482         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16483         echo "$parent" | grep -F "$FID1/$tfile" ||
16484                 error "$FID1/$tfile not returned in parent list (by fid)"
16485         echo "$parent" | grep -F "$FID2/link" ||
16486                 error "$FID2/link not returned in parent list (by fid)"
16487
16488         # 4) test for entry in root directory
16489         parent=$($LFS path2fid --parents $DIR/f)
16490         echo "$parent" | grep -F "$FID3/f" ||
16491                 error "$FID3/f not returned in parent list"
16492
16493         # 5) test it on root directory
16494         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16495                 error "$MOUNT should not have parents"
16496
16497         # enable xattr caching and check that linkea is correctly updated
16498         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16499         save_lustre_params client "llite.*.xattr_cache" > $save
16500         lctl set_param llite.*.xattr_cache 1
16501
16502         # 6.1) linkea update on rename
16503         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16504
16505         # get parents by fid
16506         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16507         # foo1 should no longer be returned in parent list
16508         echo "$parent" | grep -F "$FID1" &&
16509                 error "$FID1 should no longer be in parent list"
16510         # the new path should appear
16511         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16512                 error "$FID2/$tfile.moved is not in parent list"
16513
16514         # 6.2) linkea update on unlink
16515         rm -f $DIR/$tdir/foo2/link
16516         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16517         # foo2/link should no longer be returned in parent list
16518         echo "$parent" | grep -F "$FID2/link" &&
16519                 error "$FID2/link should no longer be in parent list"
16520         true
16521
16522         rm -f $DIR/f
16523         restore_lustre_params < $save
16524         rm -f $save
16525 }
16526 run_test 154f "get parent fids by reading link ea"
16527
16528 test_154g()
16529 {
16530         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16531            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16532                 skip "Need MDS version at least 2.6.92"
16533
16534         mkdir_on_mdt0 $DIR/$tdir
16535         llapi_fid_test -d $DIR/$tdir
16536 }
16537 run_test 154g "various llapi FID tests"
16538
16539 test_154h()
16540 {
16541         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16542                 skip "Need client at least version 2.15.55.1"
16543
16544         # Create an empty file
16545         touch $DIR/$tfile
16546
16547         # Get FID (interactive mode) and save under $TMP/$tfile.log
16548         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16549                 path2fid $DIR/$tfile
16550         EOF
16551
16552         fid=$(cat $TMP/$tfile.log)
16553         # $fid should not be empty
16554         [[ ! -z $fid ]] || error "FID is empty"
16555         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16556 }
16557 run_test 154h "Verify interactive path2fid"
16558
16559 test_155_small_load() {
16560     local temp=$TMP/$tfile
16561     local file=$DIR/$tfile
16562
16563     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16564         error "dd of=$temp bs=6096 count=1 failed"
16565     cp $temp $file
16566     cancel_lru_locks $OSC
16567     cmp $temp $file || error "$temp $file differ"
16568
16569     $TRUNCATE $temp 6000
16570     $TRUNCATE $file 6000
16571     cmp $temp $file || error "$temp $file differ (truncate1)"
16572
16573     echo "12345" >>$temp
16574     echo "12345" >>$file
16575     cmp $temp $file || error "$temp $file differ (append1)"
16576
16577     echo "12345" >>$temp
16578     echo "12345" >>$file
16579     cmp $temp $file || error "$temp $file differ (append2)"
16580
16581     rm -f $temp $file
16582     true
16583 }
16584
16585 test_155_big_load() {
16586         remote_ost_nodsh && skip "remote OST with nodsh"
16587
16588         local temp=$TMP/$tfile
16589         local file=$DIR/$tfile
16590
16591         free_min_max
16592         local cache_size=$(do_facet ost$((MAXI+1)) \
16593                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16594
16595         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16596         # pre-set value
16597         if [ -z "$cache_size" ]; then
16598                 cache_size=256
16599         fi
16600         local large_file_size=$((cache_size * 2))
16601
16602         echo "OSS cache size: $cache_size KB"
16603         echo "Large file size: $large_file_size KB"
16604
16605         [ $MAXV -le $large_file_size ] &&
16606                 skip_env "max available OST size needs > $large_file_size KB"
16607
16608         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16609
16610         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16611                 error "dd of=$temp bs=$large_file_size count=1k failed"
16612         cp $temp $file
16613         ls -lh $temp $file
16614         cancel_lru_locks osc
16615         cmp $temp $file || error "$temp $file differ"
16616
16617         rm -f $temp $file
16618         true
16619 }
16620
16621 save_writethrough() {
16622         local facets=$(get_facets OST)
16623
16624         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16625 }
16626
16627 test_155a() {
16628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16629
16630         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16631
16632         save_writethrough $p
16633
16634         set_cache read on
16635         set_cache writethrough on
16636         test_155_small_load
16637         restore_lustre_params < $p
16638         rm -f $p
16639 }
16640 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16641
16642 test_155b() {
16643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16644
16645         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16646
16647         save_writethrough $p
16648
16649         set_cache read on
16650         set_cache writethrough off
16651         test_155_small_load
16652         restore_lustre_params < $p
16653         rm -f $p
16654 }
16655 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16656
16657 test_155c() {
16658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16659
16660         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16661
16662         save_writethrough $p
16663
16664         set_cache read off
16665         set_cache writethrough on
16666         test_155_small_load
16667         restore_lustre_params < $p
16668         rm -f $p
16669 }
16670 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16671
16672 test_155d() {
16673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16674
16675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16676
16677         save_writethrough $p
16678
16679         set_cache read off
16680         set_cache writethrough off
16681         test_155_small_load
16682         restore_lustre_params < $p
16683         rm -f $p
16684 }
16685 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16686
16687 test_155e() {
16688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16689
16690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16691
16692         save_writethrough $p
16693
16694         set_cache read on
16695         set_cache writethrough on
16696         test_155_big_load
16697         restore_lustre_params < $p
16698         rm -f $p
16699 }
16700 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16701
16702 test_155f() {
16703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16704
16705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16706
16707         save_writethrough $p
16708
16709         set_cache read on
16710         set_cache writethrough off
16711         test_155_big_load
16712         restore_lustre_params < $p
16713         rm -f $p
16714 }
16715 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16716
16717 test_155g() {
16718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16719
16720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16721
16722         save_writethrough $p
16723
16724         set_cache read off
16725         set_cache writethrough on
16726         test_155_big_load
16727         restore_lustre_params < $p
16728         rm -f $p
16729 }
16730 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16731
16732 test_155h() {
16733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16734
16735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16736
16737         save_writethrough $p
16738
16739         set_cache read off
16740         set_cache writethrough off
16741         test_155_big_load
16742         restore_lustre_params < $p
16743         rm -f $p
16744 }
16745 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16746
16747 test_156() {
16748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16749         remote_ost_nodsh && skip "remote OST with nodsh"
16750         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16751                 skip "stats not implemented on old servers"
16752         [ "$ost1_FSTYPE" = "zfs" ] &&
16753                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16754         (( CLIENT_VERSION == OST1_VERSION )) ||
16755                 skip "LU-13081: no interop testing for OSS cache"
16756
16757         local CPAGES=3
16758         local BEFORE
16759         local AFTER
16760         local file="$DIR/$tfile"
16761         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16762
16763         save_writethrough $p
16764         roc_hit_init
16765
16766         log "Turn on read and write cache"
16767         set_cache read on
16768         set_cache writethrough on
16769
16770         log "Write data and read it back."
16771         log "Read should be satisfied from the cache."
16772         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16773         BEFORE=$(roc_hit)
16774         cancel_lru_locks osc
16775         cat $file >/dev/null
16776         AFTER=$(roc_hit)
16777         if ! let "AFTER - BEFORE == CPAGES"; then
16778                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16779         else
16780                 log "cache hits: before: $BEFORE, after: $AFTER"
16781         fi
16782
16783         log "Read again; it should be satisfied from the cache."
16784         BEFORE=$AFTER
16785         cancel_lru_locks osc
16786         cat $file >/dev/null
16787         AFTER=$(roc_hit)
16788         if ! let "AFTER - BEFORE == CPAGES"; then
16789                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16790         else
16791                 log "cache hits:: before: $BEFORE, after: $AFTER"
16792         fi
16793
16794         log "Turn off the read cache and turn on the write cache"
16795         set_cache read off
16796         set_cache writethrough on
16797
16798         log "Read again; it should be satisfied from the cache."
16799         BEFORE=$(roc_hit)
16800         cancel_lru_locks osc
16801         cat $file >/dev/null
16802         AFTER=$(roc_hit)
16803         if ! let "AFTER - BEFORE == CPAGES"; then
16804                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16805         else
16806                 log "cache hits:: before: $BEFORE, after: $AFTER"
16807         fi
16808
16809         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16810                 # > 2.12.56 uses pagecache if cached
16811                 log "Read again; it should not be satisfied from the cache."
16812                 BEFORE=$AFTER
16813                 cancel_lru_locks osc
16814                 cat $file >/dev/null
16815                 AFTER=$(roc_hit)
16816                 if ! let "AFTER - BEFORE == 0"; then
16817                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16818                 else
16819                         log "cache hits:: before: $BEFORE, after: $AFTER"
16820                 fi
16821         fi
16822
16823         log "Write data and read it back."
16824         log "Read should be satisfied from the cache."
16825         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16826         BEFORE=$(roc_hit)
16827         cancel_lru_locks osc
16828         cat $file >/dev/null
16829         AFTER=$(roc_hit)
16830         if ! let "AFTER - BEFORE == CPAGES"; then
16831                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16832         else
16833                 log "cache hits:: before: $BEFORE, after: $AFTER"
16834         fi
16835
16836         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16837                 # > 2.12.56 uses pagecache if cached
16838                 log "Read again; it should not be satisfied from the cache."
16839                 BEFORE=$AFTER
16840                 cancel_lru_locks osc
16841                 cat $file >/dev/null
16842                 AFTER=$(roc_hit)
16843                 if ! let "AFTER - BEFORE == 0"; then
16844                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16845                 else
16846                         log "cache hits:: before: $BEFORE, after: $AFTER"
16847                 fi
16848         fi
16849
16850         log "Turn off read and write cache"
16851         set_cache read off
16852         set_cache writethrough off
16853
16854         log "Write data and read it back"
16855         log "It should not be satisfied from the cache."
16856         rm -f $file
16857         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16858         cancel_lru_locks osc
16859         BEFORE=$(roc_hit)
16860         cat $file >/dev/null
16861         AFTER=$(roc_hit)
16862         if ! let "AFTER - BEFORE == 0"; then
16863                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16864         else
16865                 log "cache hits:: before: $BEFORE, after: $AFTER"
16866         fi
16867
16868         log "Turn on the read cache and turn off the write cache"
16869         set_cache read on
16870         set_cache writethrough off
16871
16872         log "Write data and read it back"
16873         log "It should not be satisfied from the cache."
16874         rm -f $file
16875         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16876         BEFORE=$(roc_hit)
16877         cancel_lru_locks osc
16878         cat $file >/dev/null
16879         AFTER=$(roc_hit)
16880         if ! let "AFTER - BEFORE == 0"; then
16881                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16882         else
16883                 log "cache hits:: before: $BEFORE, after: $AFTER"
16884         fi
16885
16886         log "Read again; it should be satisfied from the cache."
16887         BEFORE=$(roc_hit)
16888         cancel_lru_locks osc
16889         cat $file >/dev/null
16890         AFTER=$(roc_hit)
16891         if ! let "AFTER - BEFORE == CPAGES"; then
16892                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16893         else
16894                 log "cache hits:: before: $BEFORE, after: $AFTER"
16895         fi
16896
16897         restore_lustre_params < $p
16898         rm -f $p $file
16899 }
16900 run_test 156 "Verification of tunables"
16901
16902 test_160a() {
16903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16904         remote_mds_nodsh && skip "remote MDS with nodsh"
16905         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16906                 skip "Need MDS version at least 2.2.0"
16907
16908         changelog_register || error "changelog_register failed"
16909         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16910         changelog_users $SINGLEMDS | grep -q $cl_user ||
16911                 error "User $cl_user not found in changelog_users"
16912
16913         mkdir_on_mdt0 $DIR/$tdir
16914
16915         # change something
16916         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16917         changelog_clear 0 || error "changelog_clear failed"
16918         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16919         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16920         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16921         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16922         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16923         rm $DIR/$tdir/pics/desktop.jpg
16924
16925         echo "verifying changelog mask"
16926         changelog_chmask "-MKDIR"
16927         changelog_chmask "-CLOSE"
16928
16929         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16930         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16931
16932         changelog_chmask "+MKDIR"
16933         changelog_chmask "+CLOSE"
16934
16935         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16936         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16937
16938         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16939         CLOSES=$(changelog_dump | grep -c "CLOSE")
16940         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16941         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16942
16943         # verify contents
16944         echo "verifying target fid"
16945         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16946         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16947         [ "$fidc" == "$fidf" ] ||
16948                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16949         echo "verifying parent fid"
16950         # The FID returned from the Changelog may be the directory shard on
16951         # a different MDT, and not the FID returned by path2fid on the parent.
16952         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16953         # since this is what will matter when recreating this file in the tree.
16954         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16955         local pathp=$($LFS fid2path $MOUNT "$fidp")
16956         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16957                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16958
16959         echo "getting records for $cl_user"
16960         changelog_users $SINGLEMDS
16961         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16962         local nclr=3
16963         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16964                 error "changelog_clear failed"
16965         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16966         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16967         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16968                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16969
16970         local min0_rec=$(changelog_users $SINGLEMDS |
16971                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16972         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16973                           awk '{ print $1; exit; }')
16974
16975         changelog_dump | tail -n 5
16976         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16977         [ $first_rec == $((min0_rec + 1)) ] ||
16978                 error "first index should be $min0_rec + 1 not $first_rec"
16979
16980         # LU-3446 changelog index reset on MDT restart
16981         local cur_rec1=$(changelog_users $SINGLEMDS |
16982                          awk '/^current.index:/ { print $NF }')
16983         changelog_clear 0 ||
16984                 error "clear all changelog records for $cl_user failed"
16985         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16986         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16987                 error "Fail to start $SINGLEMDS"
16988         local cur_rec2=$(changelog_users $SINGLEMDS |
16989                          awk '/^current.index:/ { print $NF }')
16990         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16991         [ $cur_rec1 == $cur_rec2 ] ||
16992                 error "current index should be $cur_rec1 not $cur_rec2"
16993
16994         echo "verifying users from this test are deregistered"
16995         changelog_deregister || error "changelog_deregister failed"
16996         changelog_users $SINGLEMDS | grep -q $cl_user &&
16997                 error "User '$cl_user' still in changelog_users"
16998
16999         # lctl get_param -n mdd.*.changelog_users
17000         # current_index: 144
17001         # ID    index (idle seconds)
17002         # cl3   144   (2) mask=<list>
17003         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17004                 # this is the normal case where all users were deregistered
17005                 # make sure no new records are added when no users are present
17006                 local last_rec1=$(changelog_users $SINGLEMDS |
17007                                   awk '/^current.index:/ { print $NF }')
17008                 touch $DIR/$tdir/chloe
17009                 local last_rec2=$(changelog_users $SINGLEMDS |
17010                                   awk '/^current.index:/ { print $NF }')
17011                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17012                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17013         else
17014                 # any changelog users must be leftovers from a previous test
17015                 changelog_users $SINGLEMDS
17016                 echo "other changelog users; can't verify off"
17017         fi
17018 }
17019 run_test 160a "changelog sanity"
17020
17021 test_160b() { # LU-3587
17022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17023         remote_mds_nodsh && skip "remote MDS with nodsh"
17024         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17025                 skip "Need MDS version at least 2.2.0"
17026
17027         changelog_register || error "changelog_register failed"
17028         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17029         changelog_users $SINGLEMDS | grep -q $cl_user ||
17030                 error "User '$cl_user' not found in changelog_users"
17031
17032         local longname1=$(str_repeat a 255)
17033         local longname2=$(str_repeat b 255)
17034
17035         cd $DIR
17036         echo "creating very long named file"
17037         touch $longname1 || error "create of '$longname1' failed"
17038         echo "renaming very long named file"
17039         mv $longname1 $longname2
17040
17041         changelog_dump | grep RENME | tail -n 5
17042         rm -f $longname2
17043 }
17044 run_test 160b "Verify that very long rename doesn't crash in changelog"
17045
17046 test_160c() {
17047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17048         remote_mds_nodsh && skip "remote MDS with nodsh"
17049
17050         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17051                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17052                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17053                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17054
17055         local rc=0
17056
17057         # Registration step
17058         changelog_register || error "changelog_register failed"
17059
17060         rm -rf $DIR/$tdir
17061         mkdir -p $DIR/$tdir
17062         $MCREATE $DIR/$tdir/foo_160c
17063         changelog_chmask "-TRUNC"
17064         $TRUNCATE $DIR/$tdir/foo_160c 200
17065         changelog_chmask "+TRUNC"
17066         $TRUNCATE $DIR/$tdir/foo_160c 199
17067         changelog_dump | tail -n 5
17068         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17069         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17070 }
17071 run_test 160c "verify that changelog log catch the truncate event"
17072
17073 test_160d() {
17074         remote_mds_nodsh && skip "remote MDS with nodsh"
17075         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17077         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17078                 skip "Need MDS version at least 2.7.60"
17079
17080         # Registration step
17081         changelog_register || error "changelog_register failed"
17082
17083         mkdir -p $DIR/$tdir/migrate_dir
17084         changelog_clear 0 || error "changelog_clear failed"
17085
17086         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17087         changelog_dump | tail -n 5
17088         local migrates=$(changelog_dump | grep -c "MIGRT")
17089         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17090 }
17091 run_test 160d "verify that changelog log catch the migrate event"
17092
17093 test_160e() {
17094         remote_mds_nodsh && skip "remote MDS with nodsh"
17095
17096         # Create a user
17097         changelog_register || error "changelog_register failed"
17098
17099         local MDT0=$(facet_svc $SINGLEMDS)
17100         local rc
17101
17102         # No user (expect fail)
17103         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17104         rc=$?
17105         if [ $rc -eq 0 ]; then
17106                 error "Should fail without user"
17107         elif [ $rc -ne 4 ]; then
17108                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17109         fi
17110
17111         # Delete a future user (expect fail)
17112         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17113         rc=$?
17114         if [ $rc -eq 0 ]; then
17115                 error "Deleted non-existant user cl77"
17116         elif [ $rc -ne 2 ]; then
17117                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17118         fi
17119
17120         # Clear to a bad index (1 billion should be safe)
17121         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17122         rc=$?
17123
17124         if [ $rc -eq 0 ]; then
17125                 error "Successfully cleared to invalid CL index"
17126         elif [ $rc -ne 22 ]; then
17127                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17128         fi
17129 }
17130 run_test 160e "changelog negative testing (should return errors)"
17131
17132 test_160f() {
17133         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17134         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17135                 skip "Need MDS version at least 2.10.56"
17136
17137         local mdts=$(comma_list $(mdts_nodes))
17138
17139         # Create a user
17140         changelog_register || error "first changelog_register failed"
17141         changelog_register || error "second changelog_register failed"
17142         local cl_users
17143         declare -A cl_user1
17144         declare -A cl_user2
17145         local user_rec1
17146         local user_rec2
17147         local i
17148
17149         # generate some changelog records to accumulate on each MDT
17150         # use all_char because created files should be evenly distributed
17151         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17152                 error "test_mkdir $tdir failed"
17153         log "$(date +%s): creating first files"
17154         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17155                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17156                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17157         done
17158
17159         # check changelogs have been generated
17160         local start=$SECONDS
17161         local idle_time=$((MDSCOUNT * 5 + 5))
17162         local nbcl=$(changelog_dump | wc -l)
17163         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17164
17165         for param in "changelog_max_idle_time=$idle_time" \
17166                      "changelog_gc=1" \
17167                      "changelog_min_gc_interval=2" \
17168                      "changelog_min_free_cat_entries=3"; do
17169                 local MDT0=$(facet_svc $SINGLEMDS)
17170                 local var="${param%=*}"
17171                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17172
17173                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17174                 do_nodes $mdts $LCTL set_param mdd.*.$param
17175         done
17176
17177         # force cl_user2 to be idle (1st part), but also cancel the
17178         # cl_user1 records so that it is not evicted later in the test.
17179         local sleep1=$((idle_time / 2))
17180         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17181         sleep $sleep1
17182
17183         # simulate changelog catalog almost full
17184         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17185         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17186
17187         for i in $(seq $MDSCOUNT); do
17188                 cl_users=(${CL_USERS[mds$i]})
17189                 cl_user1[mds$i]="${cl_users[0]}"
17190                 cl_user2[mds$i]="${cl_users[1]}"
17191
17192                 [ -n "${cl_user1[mds$i]}" ] ||
17193                         error "mds$i: no user registered"
17194                 [ -n "${cl_user2[mds$i]}" ] ||
17195                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17196
17197                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17198                 [ -n "$user_rec1" ] ||
17199                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17200                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17201                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17202                 [ -n "$user_rec2" ] ||
17203                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17204                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17205                      "$user_rec1 + 2 == $user_rec2"
17206                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17207                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17208                               "$user_rec1 + 2, but is $user_rec2"
17209                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17210                 [ -n "$user_rec2" ] ||
17211                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17212                 [ $user_rec1 == $user_rec2 ] ||
17213                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17214                               "$user_rec1, but is $user_rec2"
17215         done
17216
17217         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17218         local sleep2=$((idle_time - (SECONDS - start) + 1))
17219         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17220         sleep $sleep2
17221
17222         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17223         # cl_user1 should be OK because it recently processed records.
17224         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17225         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17226                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17227                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17228         done
17229
17230         # ensure gc thread is done
17231         for i in $(mdts_nodes); do
17232                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17233                         error "$i: GC-thread not done"
17234         done
17235
17236         local first_rec
17237         for (( i = 1; i <= MDSCOUNT; i++ )); do
17238                 # check cl_user1 still registered
17239                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17240                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17241                 # check cl_user2 unregistered
17242                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17243                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17244
17245                 # check changelogs are present and starting at $user_rec1 + 1
17246                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17247                 [ -n "$user_rec1" ] ||
17248                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17249                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17250                             awk '{ print $1; exit; }')
17251
17252                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17253                 [ $((user_rec1 + 1)) == $first_rec ] ||
17254                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17255         done
17256 }
17257 run_test 160f "changelog garbage collect (timestamped users)"
17258
17259 test_160g() {
17260         remote_mds_nodsh && skip "remote MDS with nodsh"
17261         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17262                 skip "Need MDS version at least 2.14.55"
17263
17264         local mdts=$(comma_list $(mdts_nodes))
17265
17266         # Create a user
17267         changelog_register || error "first changelog_register failed"
17268         changelog_register || error "second changelog_register failed"
17269         local cl_users
17270         declare -A cl_user1
17271         declare -A cl_user2
17272         local user_rec1
17273         local user_rec2
17274         local i
17275
17276         # generate some changelog records to accumulate on each MDT
17277         # use all_char because created files should be evenly distributed
17278         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17279                 error "test_mkdir $tdir failed"
17280         for ((i = 0; i < MDSCOUNT; i++)); do
17281                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17282                         error "create $DIR/$tdir/d$i.1 failed"
17283         done
17284
17285         # check changelogs have been generated
17286         local nbcl=$(changelog_dump | wc -l)
17287         (( $nbcl > 0 )) || error "no changelogs found"
17288
17289         # reduce the max_idle_indexes value to make sure we exceed it
17290         for param in "changelog_max_idle_indexes=2" \
17291                      "changelog_gc=1" \
17292                      "changelog_min_gc_interval=2"; do
17293                 local MDT0=$(facet_svc $SINGLEMDS)
17294                 local var="${param%=*}"
17295                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17296
17297                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17298                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17299                         error "unable to set mdd.*.$param"
17300         done
17301
17302         local start=$SECONDS
17303         for i in $(seq $MDSCOUNT); do
17304                 cl_users=(${CL_USERS[mds$i]})
17305                 cl_user1[mds$i]="${cl_users[0]}"
17306                 cl_user2[mds$i]="${cl_users[1]}"
17307
17308                 [ -n "${cl_user1[mds$i]}" ] ||
17309                         error "mds$i: user1 is not registered"
17310                 [ -n "${cl_user2[mds$i]}" ] ||
17311                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17312
17313                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17314                 [ -n "$user_rec1" ] ||
17315                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17316                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17317                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17318                 [ -n "$user_rec2" ] ||
17319                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17320                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17321                      "$user_rec1 + 2 == $user_rec2"
17322                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17323                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17324                               "expected $user_rec1 + 2, but is $user_rec2"
17325                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17326                 [ -n "$user_rec2" ] ||
17327                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17328                 [ $user_rec1 == $user_rec2 ] ||
17329                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17330                               "expected $user_rec1, but is $user_rec2"
17331         done
17332
17333         # ensure we are past the previous changelog_min_gc_interval set above
17334         local sleep2=$((start + 2 - SECONDS))
17335         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17336         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17337         # cl_user1 should be OK because it recently processed records.
17338         for ((i = 0; i < MDSCOUNT; i++)); do
17339                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17340                         error "create $DIR/$tdir/d$i.3 failed"
17341         done
17342
17343         # ensure gc thread is done
17344         for i in $(mdts_nodes); do
17345                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17346                         error "$i: GC-thread not done"
17347         done
17348
17349         local first_rec
17350         for (( i = 1; i <= MDSCOUNT; i++ )); do
17351                 # check cl_user1 still registered
17352                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17353                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17354                 # check cl_user2 unregistered
17355                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17356                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17357
17358                 # check changelogs are present and starting at $user_rec1 + 1
17359                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17360                 [ -n "$user_rec1" ] ||
17361                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17362                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17363                             awk '{ print $1; exit; }')
17364
17365                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17366                 [ $((user_rec1 + 1)) == $first_rec ] ||
17367                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17368         done
17369 }
17370 run_test 160g "changelog garbage collect on idle records"
17371
17372 test_160h() {
17373         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17374         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17375                 skip "Need MDS version at least 2.10.56"
17376
17377         local mdts=$(comma_list $(mdts_nodes))
17378
17379         # Create a user
17380         changelog_register || error "first changelog_register failed"
17381         changelog_register || error "second changelog_register failed"
17382         local cl_users
17383         declare -A cl_user1
17384         declare -A cl_user2
17385         local user_rec1
17386         local user_rec2
17387         local i
17388
17389         # generate some changelog records to accumulate on each MDT
17390         # use all_char because created files should be evenly distributed
17391         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17392                 error "test_mkdir $tdir failed"
17393         for ((i = 0; i < MDSCOUNT; i++)); do
17394                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17395                         error "create $DIR/$tdir/d$i.1 failed"
17396         done
17397
17398         # check changelogs have been generated
17399         local nbcl=$(changelog_dump | wc -l)
17400         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17401
17402         for param in "changelog_max_idle_time=10" \
17403                      "changelog_gc=1" \
17404                      "changelog_min_gc_interval=2"; do
17405                 local MDT0=$(facet_svc $SINGLEMDS)
17406                 local var="${param%=*}"
17407                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17408
17409                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17410                 do_nodes $mdts $LCTL set_param mdd.*.$param
17411         done
17412
17413         # force cl_user2 to be idle (1st part)
17414         sleep 9
17415
17416         for i in $(seq $MDSCOUNT); do
17417                 cl_users=(${CL_USERS[mds$i]})
17418                 cl_user1[mds$i]="${cl_users[0]}"
17419                 cl_user2[mds$i]="${cl_users[1]}"
17420
17421                 [ -n "${cl_user1[mds$i]}" ] ||
17422                         error "mds$i: no user registered"
17423                 [ -n "${cl_user2[mds$i]}" ] ||
17424                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17425
17426                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17427                 [ -n "$user_rec1" ] ||
17428                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17429                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17430                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17431                 [ -n "$user_rec2" ] ||
17432                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17433                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17434                      "$user_rec1 + 2 == $user_rec2"
17435                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17436                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17437                               "$user_rec1 + 2, but is $user_rec2"
17438                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17439                 [ -n "$user_rec2" ] ||
17440                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17441                 [ $user_rec1 == $user_rec2 ] ||
17442                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17443                               "$user_rec1, but is $user_rec2"
17444         done
17445
17446         # force cl_user2 to be idle (2nd part) and to reach
17447         # changelog_max_idle_time
17448         sleep 2
17449
17450         # force each GC-thread start and block then
17451         # one per MDT/MDD, set fail_val accordingly
17452         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17453         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17454
17455         # generate more changelogs to trigger fail_loc
17456         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17457                 error "create $DIR/$tdir/${tfile}bis failed"
17458
17459         # stop MDT to stop GC-thread, should be done in back-ground as it will
17460         # block waiting for the thread to be released and exit
17461         declare -A stop_pids
17462         for i in $(seq $MDSCOUNT); do
17463                 stop mds$i &
17464                 stop_pids[mds$i]=$!
17465         done
17466
17467         for i in $(mdts_nodes); do
17468                 local facet
17469                 local nb=0
17470                 local facets=$(facets_up_on_host $i)
17471
17472                 for facet in ${facets//,/ }; do
17473                         if [[ $facet == mds* ]]; then
17474                                 nb=$((nb + 1))
17475                         fi
17476                 done
17477                 # ensure each MDS's gc threads are still present and all in "R"
17478                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17479                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17480                         error "$i: expected $nb GC-thread"
17481                 wait_update $i \
17482                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17483                         "R" 20 ||
17484                         error "$i: GC-thread not found in R-state"
17485                 # check umounts of each MDT on MDS have reached kthread_stop()
17486                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17487                         error "$i: expected $nb umount"
17488                 wait_update $i \
17489                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17490                         error "$i: umount not found in D-state"
17491         done
17492
17493         # release all GC-threads
17494         do_nodes $mdts $LCTL set_param fail_loc=0
17495
17496         # wait for MDT stop to complete
17497         for i in $(seq $MDSCOUNT); do
17498                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17499         done
17500
17501         # XXX
17502         # may try to check if any orphan changelog records are present
17503         # via ldiskfs/zfs and llog_reader...
17504
17505         # re-start/mount MDTs
17506         for i in $(seq $MDSCOUNT); do
17507                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17508                         error "Fail to start mds$i"
17509         done
17510
17511         local first_rec
17512         for i in $(seq $MDSCOUNT); do
17513                 # check cl_user1 still registered
17514                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17515                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17516                 # check cl_user2 unregistered
17517                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17518                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17519
17520                 # check changelogs are present and starting at $user_rec1 + 1
17521                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17522                 [ -n "$user_rec1" ] ||
17523                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17524                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17525                             awk '{ print $1; exit; }')
17526
17527                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17528                 [ $((user_rec1 + 1)) == $first_rec ] ||
17529                         error "mds$i: first index should be $user_rec1 + 1, " \
17530                               "but is $first_rec"
17531         done
17532 }
17533 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17534               "during mount"
17535
17536 test_160i() {
17537
17538         local mdts=$(comma_list $(mdts_nodes))
17539
17540         changelog_register || error "first changelog_register failed"
17541
17542         # generate some changelog records to accumulate on each MDT
17543         # use all_char because created files should be evenly distributed
17544         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17545                 error "test_mkdir $tdir failed"
17546         for ((i = 0; i < MDSCOUNT; i++)); do
17547                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17548                         error "create $DIR/$tdir/d$i.1 failed"
17549         done
17550
17551         # check changelogs have been generated
17552         local nbcl=$(changelog_dump | wc -l)
17553         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17554
17555         # simulate race between register and unregister
17556         # XXX as fail_loc is set per-MDS, with DNE configs the race
17557         # simulation will only occur for one MDT per MDS and for the
17558         # others the normal race scenario will take place
17559         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17560         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17561         do_nodes $mdts $LCTL set_param fail_val=1
17562
17563         # unregister 1st user
17564         changelog_deregister &
17565         local pid1=$!
17566         # wait some time for deregister work to reach race rdv
17567         sleep 2
17568         # register 2nd user
17569         changelog_register || error "2nd user register failed"
17570
17571         wait $pid1 || error "1st user deregister failed"
17572
17573         local i
17574         local last_rec
17575         declare -A LAST_REC
17576         for i in $(seq $MDSCOUNT); do
17577                 if changelog_users mds$i | grep "^cl"; then
17578                         # make sure new records are added with one user present
17579                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17580                                           awk '/^current.index:/ { print $NF }')
17581                 else
17582                         error "mds$i has no user registered"
17583                 fi
17584         done
17585
17586         # generate more changelog records to accumulate on each MDT
17587         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17588                 error "create $DIR/$tdir/${tfile}bis failed"
17589
17590         for i in $(seq $MDSCOUNT); do
17591                 last_rec=$(changelog_users $SINGLEMDS |
17592                            awk '/^current.index:/ { print $NF }')
17593                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17594                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17595                         error "changelogs are off on mds$i"
17596         done
17597 }
17598 run_test 160i "changelog user register/unregister race"
17599
17600 test_160j() {
17601         remote_mds_nodsh && skip "remote MDS with nodsh"
17602         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17603                 skip "Need MDS version at least 2.12.56"
17604
17605         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17606         stack_trap "umount $MOUNT2" EXIT
17607
17608         changelog_register || error "first changelog_register failed"
17609         stack_trap "changelog_deregister" EXIT
17610
17611         # generate some changelog
17612         # use all_char because created files should be evenly distributed
17613         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17614                 error "mkdir $tdir failed"
17615         for ((i = 0; i < MDSCOUNT; i++)); do
17616                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17617                         error "create $DIR/$tdir/d$i.1 failed"
17618         done
17619
17620         # open the changelog device
17621         exec 3>/dev/changelog-$FSNAME-MDT0000
17622         stack_trap "exec 3>&-" EXIT
17623         exec 4</dev/changelog-$FSNAME-MDT0000
17624         stack_trap "exec 4<&-" EXIT
17625
17626         # umount the first lustre mount
17627         umount $MOUNT
17628         stack_trap "mount_client $MOUNT" EXIT
17629
17630         # read changelog, which may or may not fail, but should not crash
17631         cat <&4 >/dev/null
17632
17633         # clear changelog
17634         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17635         changelog_users $SINGLEMDS | grep -q $cl_user ||
17636                 error "User $cl_user not found in changelog_users"
17637
17638         printf 'clear:'$cl_user':0' >&3
17639 }
17640 run_test 160j "client can be umounted while its chanangelog is being used"
17641
17642 test_160k() {
17643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17644         remote_mds_nodsh && skip "remote MDS with nodsh"
17645
17646         mkdir -p $DIR/$tdir/1/1
17647
17648         changelog_register || error "changelog_register failed"
17649         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17650
17651         changelog_users $SINGLEMDS | grep -q $cl_user ||
17652                 error "User '$cl_user' not found in changelog_users"
17653 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17654         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17655         rmdir $DIR/$tdir/1/1 & sleep 1
17656         mkdir $DIR/$tdir/2
17657         touch $DIR/$tdir/2/2
17658         rm -rf $DIR/$tdir/2
17659
17660         wait
17661         sleep 4
17662
17663         changelog_dump | grep rmdir || error "rmdir not recorded"
17664 }
17665 run_test 160k "Verify that changelog records are not lost"
17666
17667 # Verifies that a file passed as a parameter has recently had an operation
17668 # performed on it that has generated an MTIME changelog which contains the
17669 # correct parent FID. As files might reside on a different MDT from the
17670 # parent directory in DNE configurations, the FIDs are translated to paths
17671 # before being compared, which should be identical
17672 compare_mtime_changelog() {
17673         local file="${1}"
17674         local mdtidx
17675         local mtime
17676         local cl_fid
17677         local pdir
17678         local dir
17679
17680         mdtidx=$($LFS getstripe --mdt-index $file)
17681         mdtidx=$(printf "%04x" $mdtidx)
17682
17683         # Obtain the parent FID from the MTIME changelog
17684         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17685         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17686
17687         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17688         [ -z "$cl_fid" ] && error "parent FID not present"
17689
17690         # Verify that the path for the parent FID is the same as the path for
17691         # the test directory
17692         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17693
17694         dir=$(dirname $1)
17695
17696         [[ "${pdir%/}" == "$dir" ]] ||
17697                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17698 }
17699
17700 test_160l() {
17701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17702
17703         remote_mds_nodsh && skip "remote MDS with nodsh"
17704         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17705                 skip "Need MDS version at least 2.13.55"
17706
17707         local cl_user
17708
17709         changelog_register || error "changelog_register failed"
17710         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17711
17712         changelog_users $SINGLEMDS | grep -q $cl_user ||
17713                 error "User '$cl_user' not found in changelog_users"
17714
17715         # Clear some types so that MTIME changelogs are generated
17716         changelog_chmask "-CREAT"
17717         changelog_chmask "-CLOSE"
17718
17719         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17720
17721         # Test CL_MTIME during setattr
17722         touch $DIR/$tdir/$tfile
17723         compare_mtime_changelog $DIR/$tdir/$tfile
17724
17725         # Test CL_MTIME during close
17726         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17727         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17728 }
17729 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17730
17731 test_160m() {
17732         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17733         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17734                 skip "Need MDS version at least 2.14.51"
17735         local cl_users
17736         local cl_user1
17737         local cl_user2
17738         local pid1
17739
17740         # Create a user
17741         changelog_register || error "first changelog_register failed"
17742         changelog_register || error "second changelog_register failed"
17743
17744         cl_users=(${CL_USERS[mds1]})
17745         cl_user1="${cl_users[0]}"
17746         cl_user2="${cl_users[1]}"
17747         # generate some changelog records to accumulate on MDT0
17748         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17749         createmany -m $DIR/$tdir/$tfile 50 ||
17750                 error "create $DIR/$tdir/$tfile failed"
17751         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17752         rm -f $DIR/$tdir
17753
17754         # check changelogs have been generated
17755         local nbcl=$(changelog_dump | wc -l)
17756         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17757
17758 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17759         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17760
17761         __changelog_clear mds1 $cl_user1 +10
17762         __changelog_clear mds1 $cl_user2 0 &
17763         pid1=$!
17764         sleep 2
17765         __changelog_clear mds1 $cl_user1 0 ||
17766                 error "fail to cancel record for $cl_user1"
17767         wait $pid1
17768         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17769 }
17770 run_test 160m "Changelog clear race"
17771
17772 test_160n() {
17773         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17774         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17775                 skip "Need MDS version at least 2.14.51"
17776         local cl_users
17777         local cl_user1
17778         local cl_user2
17779         local pid1
17780         local first_rec
17781         local last_rec=0
17782
17783         # Create a user
17784         changelog_register || error "first changelog_register failed"
17785
17786         cl_users=(${CL_USERS[mds1]})
17787         cl_user1="${cl_users[0]}"
17788
17789         # generate some changelog records to accumulate on MDT0
17790         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17791         first_rec=$(changelog_users $SINGLEMDS |
17792                         awk '/^current.index:/ { print $NF }')
17793         while (( last_rec < (( first_rec + 65000)) )); do
17794                 createmany -m $DIR/$tdir/$tfile 10000 ||
17795                         error "create $DIR/$tdir/$tfile failed"
17796
17797                 for i in $(seq 0 10000); do
17798                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17799                                 > /dev/null
17800                 done
17801
17802                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17803                         error "unlinkmany failed unlink"
17804                 last_rec=$(changelog_users $SINGLEMDS |
17805                         awk '/^current.index:/ { print $NF }')
17806                 echo last record $last_rec
17807                 (( last_rec == 0 )) && error "no changelog found"
17808         done
17809
17810 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17811         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17812
17813         __changelog_clear mds1 $cl_user1 0 &
17814         pid1=$!
17815         sleep 2
17816         __changelog_clear mds1 $cl_user1 0 ||
17817                 error "fail to cancel record for $cl_user1"
17818         wait $pid1
17819         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17820 }
17821 run_test 160n "Changelog destroy race"
17822
17823 test_160o() {
17824         local mdt="$(facet_svc $SINGLEMDS)"
17825
17826         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17827         remote_mds_nodsh && skip "remote MDS with nodsh"
17828         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17829                 skip "Need MDS version at least 2.14.52"
17830
17831         changelog_register --user test_160o -m unlnk+close+open ||
17832                 error "changelog_register failed"
17833
17834         do_facet $SINGLEMDS $LCTL --device $mdt \
17835                                 changelog_register -u "Tt3_-#" &&
17836                 error "bad symbols in name should fail"
17837
17838         do_facet $SINGLEMDS $LCTL --device $mdt \
17839                                 changelog_register -u test_160o &&
17840                 error "the same name registration should fail"
17841
17842         do_facet $SINGLEMDS $LCTL --device $mdt \
17843                         changelog_register -u test_160toolongname &&
17844                 error "too long name registration should fail"
17845
17846         changelog_chmask "MARK+HSM"
17847         lctl get_param mdd.*.changelog*mask
17848         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17849         changelog_users $SINGLEMDS | grep -q $cl_user ||
17850                 error "User $cl_user not found in changelog_users"
17851         #verify username
17852         echo $cl_user | grep -q test_160o ||
17853                 error "User $cl_user has no specific name 'test160o'"
17854
17855         # change something
17856         changelog_clear 0 || error "changelog_clear failed"
17857         # generate some changelog records to accumulate on MDT0
17858         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17859         touch $DIR/$tdir/$tfile                 # open 1
17860
17861         OPENS=$(changelog_dump | grep -c "OPEN")
17862         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17863
17864         # must be no MKDIR it wasn't set as user mask
17865         MKDIR=$(changelog_dump | grep -c "MKDIR")
17866         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17867
17868         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17869                                 mdd.$mdt.changelog_current_mask -n)
17870         # register maskless user
17871         changelog_register || error "changelog_register failed"
17872         # effective mask should be not changed because it is not minimal
17873         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17874                                 mdd.$mdt.changelog_current_mask -n)
17875         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17876         # set server mask to minimal value
17877         changelog_chmask "MARK"
17878         # check effective mask again, should be treated as DEFMASK now
17879         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17880                                 mdd.$mdt.changelog_current_mask -n)
17881         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17882
17883         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17884                 # set server mask back to some value
17885                 changelog_chmask "CLOSE,UNLNK"
17886                 # check effective mask again, should not remain as DEFMASK
17887                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17888                                 mdd.$mdt.changelog_current_mask -n)
17889                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17890         fi
17891
17892         do_facet $SINGLEMDS $LCTL --device $mdt \
17893                                 changelog_deregister -u test_160o ||
17894                 error "cannot deregister by name"
17895 }
17896 run_test 160o "changelog user name and mask"
17897
17898 test_160p() {
17899         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17900         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17901                 skip "Need MDS version at least 2.14.51"
17902         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17903         local cl_users
17904         local cl_user1
17905         local entry_count
17906
17907         # Create a user
17908         changelog_register || error "first changelog_register failed"
17909
17910         cl_users=(${CL_USERS[mds1]})
17911         cl_user1="${cl_users[0]}"
17912
17913         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17914         createmany -m $DIR/$tdir/$tfile 50 ||
17915                 error "create $DIR/$tdir/$tfile failed"
17916         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17917         rm -rf $DIR/$tdir
17918
17919         # check changelogs have been generated
17920         entry_count=$(changelog_dump | wc -l)
17921         ((entry_count != 0)) || error "no changelog entries found"
17922
17923         # remove changelog_users and check that orphan entries are removed
17924         stop mds1
17925         local dev=$(mdsdevname 1)
17926         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17927         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17928         entry_count=$(changelog_dump | wc -l)
17929         ((entry_count == 0)) ||
17930                 error "found $entry_count changelog entries, expected none"
17931 }
17932 run_test 160p "Changelog orphan cleanup with no users"
17933
17934 test_160q() {
17935         local mdt="$(facet_svc $SINGLEMDS)"
17936         local clu
17937
17938         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17939         remote_mds_nodsh && skip "remote MDS with nodsh"
17940         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17941                 skip "Need MDS version at least 2.14.54"
17942
17943         # set server mask to minimal value like server init does
17944         changelog_chmask "MARK"
17945         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17946                 error "changelog_register failed"
17947         # check effective mask again, should be treated as DEFMASK now
17948         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17949                                 mdd.$mdt.changelog_current_mask -n)
17950         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17951                 error "changelog_deregister failed"
17952         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17953 }
17954 run_test 160q "changelog effective mask is DEFMASK if not set"
17955
17956 test_160s() {
17957         remote_mds_nodsh && skip "remote MDS with nodsh"
17958         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17959                 skip "Need MDS version at least 2.14.55"
17960
17961         local mdts=$(comma_list $(mdts_nodes))
17962
17963         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17964         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17965                                        fail_val=$((24 * 3600 * 10))
17966
17967         # Create a user which is 10 days old
17968         changelog_register || error "first changelog_register failed"
17969         local cl_users
17970         declare -A cl_user1
17971         local i
17972
17973         # generate some changelog records to accumulate on each MDT
17974         # use all_char because created files should be evenly distributed
17975         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17976                 error "test_mkdir $tdir failed"
17977         for ((i = 0; i < MDSCOUNT; i++)); do
17978                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17979                         error "create $DIR/$tdir/d$i.1 failed"
17980         done
17981
17982         # check changelogs have been generated
17983         local nbcl=$(changelog_dump | wc -l)
17984         (( nbcl > 0 )) || error "no changelogs found"
17985
17986         # reduce the max_idle_indexes value to make sure we exceed it
17987         for param in "changelog_max_idle_indexes=2097446912" \
17988                      "changelog_max_idle_time=2592000" \
17989                      "changelog_gc=1" \
17990                      "changelog_min_gc_interval=2"; do
17991                 local MDT0=$(facet_svc $SINGLEMDS)
17992                 local var="${param%=*}"
17993                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17994
17995                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17996                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17997                         error "unable to set mdd.*.$param"
17998         done
17999
18000         local start=$SECONDS
18001         for i in $(seq $MDSCOUNT); do
18002                 cl_users=(${CL_USERS[mds$i]})
18003                 cl_user1[mds$i]="${cl_users[0]}"
18004
18005                 [[ -n "${cl_user1[mds$i]}" ]] ||
18006                         error "mds$i: no user registered"
18007         done
18008
18009         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18010         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18011
18012         # ensure we are past the previous changelog_min_gc_interval set above
18013         local sleep2=$((start + 2 - SECONDS))
18014         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18015
18016         # Generate one more changelog to trigger GC
18017         for ((i = 0; i < MDSCOUNT; i++)); do
18018                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18019                         error "create $DIR/$tdir/d$i.3 failed"
18020         done
18021
18022         # ensure gc thread is done
18023         for node in $(mdts_nodes); do
18024                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18025                         error "$node: GC-thread not done"
18026         done
18027
18028         do_nodes $mdts $LCTL set_param fail_loc=0
18029
18030         for (( i = 1; i <= MDSCOUNT; i++ )); do
18031                 # check cl_user1 is purged
18032                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18033                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18034         done
18035         return 0
18036 }
18037 run_test 160s "changelog garbage collect on idle records * time"
18038
18039 test_160t() {
18040         remote_mds_nodsh && skip "remote MDS with nodsh"
18041         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18042                 skip "Need MDS version at least 2.15.50"
18043
18044         local MDT0=$(facet_svc $SINGLEMDS)
18045         local cl_users
18046         local cl_user1
18047         local cl_user2
18048         local start
18049
18050         changelog_register --user user1 -m all ||
18051                 error "user1 failed to register"
18052
18053         mkdir_on_mdt0 $DIR/$tdir
18054         # create default overstripe to maximize changelog size
18055         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18056         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18057         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18058
18059         # user2 consumes less records so less space
18060         changelog_register --user user2 || error "user2 failed to register"
18061         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18062         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18063
18064         # check changelogs have been generated
18065         local nbcl=$(changelog_dump | wc -l)
18066         (( nbcl > 0 )) || error "no changelogs found"
18067
18068         # reduce the changelog_min_gc_interval to force check
18069         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18070                 local var="${param%=*}"
18071                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18072
18073                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18074                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18075                         error "unable to set mdd.*.$param"
18076         done
18077
18078         start=$SECONDS
18079         cl_users=(${CL_USERS[mds1]})
18080         cl_user1="${cl_users[0]}"
18081         cl_user2="${cl_users[1]}"
18082
18083         [[ -n $cl_user1 ]] ||
18084                 error "mds1: user #1 isn't registered"
18085         [[ -n $cl_user2 ]] ||
18086                 error "mds1: user #2 isn't registered"
18087
18088         # ensure we are past the previous changelog_min_gc_interval set above
18089         local sleep2=$((start + 2 - SECONDS))
18090         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18091
18092         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18093         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18094                         fail_val=$(((llog_size1 + llog_size2) / 2))
18095
18096         # Generate more changelog to trigger GC
18097         createmany -o $DIR/$tdir/u3_ 4 ||
18098                 error "create failed for more files"
18099
18100         # ensure gc thread is done
18101         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18102                 error "mds1: GC-thread not done"
18103
18104         do_facet mds1 $LCTL set_param fail_loc=0
18105
18106         # check cl_user1 is purged
18107         changelog_users mds1 | grep -q "$cl_user1" &&
18108                 error "User $cl_user1 is registered"
18109         # check cl_user2 is not purged
18110         changelog_users mds1 | grep -q "$cl_user2" ||
18111                 error "User $cl_user2 is not registered"
18112 }
18113 run_test 160t "changelog garbage collect on lack of space"
18114
18115 test_161a() {
18116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18117
18118         test_mkdir -c1 $DIR/$tdir
18119         cp /etc/hosts $DIR/$tdir/$tfile
18120         test_mkdir -c1 $DIR/$tdir/foo1
18121         test_mkdir -c1 $DIR/$tdir/foo2
18122         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18123         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18124         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18125         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18126         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18127         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18128                 $LFS fid2path $DIR $FID
18129                 error "bad link ea"
18130         fi
18131         # middle
18132         rm $DIR/$tdir/foo2/zachary
18133         # last
18134         rm $DIR/$tdir/foo2/thor
18135         # first
18136         rm $DIR/$tdir/$tfile
18137         # rename
18138         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18139         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18140                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18141         rm $DIR/$tdir/foo2/maggie
18142
18143         # overflow the EA
18144         local longname=$tfile.avg_len_is_thirty_two_
18145         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18146                 error_noexit 'failed to unlink many hardlinks'" EXIT
18147         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18148                 error "failed to hardlink many files"
18149         links=$($LFS fid2path $DIR $FID | wc -l)
18150         echo -n "${links}/1000 links in link EA"
18151         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18152 }
18153 run_test 161a "link ea sanity"
18154
18155 test_161b() {
18156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18157         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18158
18159         local MDTIDX=1
18160         local remote_dir=$DIR/$tdir/remote_dir
18161
18162         mkdir -p $DIR/$tdir
18163         $LFS mkdir -i $MDTIDX $remote_dir ||
18164                 error "create remote directory failed"
18165
18166         cp /etc/hosts $remote_dir/$tfile
18167         mkdir -p $remote_dir/foo1
18168         mkdir -p $remote_dir/foo2
18169         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18170         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18171         ln $remote_dir/$tfile $remote_dir/foo1/luna
18172         ln $remote_dir/$tfile $remote_dir/foo2/thor
18173
18174         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18175                      tr -d ']')
18176         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18177                 $LFS fid2path $DIR $FID
18178                 error "bad link ea"
18179         fi
18180         # middle
18181         rm $remote_dir/foo2/zachary
18182         # last
18183         rm $remote_dir/foo2/thor
18184         # first
18185         rm $remote_dir/$tfile
18186         # rename
18187         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18188         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18189         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18190                 $LFS fid2path $DIR $FID
18191                 error "bad link rename"
18192         fi
18193         rm $remote_dir/foo2/maggie
18194
18195         # overflow the EA
18196         local longname=filename_avg_len_is_thirty_two_
18197         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18198                 error "failed to hardlink many files"
18199         links=$($LFS fid2path $DIR $FID | wc -l)
18200         echo -n "${links}/1000 links in link EA"
18201         [[ ${links} -gt 60 ]] ||
18202                 error "expected at least 60 links in link EA"
18203         unlinkmany $remote_dir/foo2/$longname 1000 ||
18204         error "failed to unlink many hardlinks"
18205 }
18206 run_test 161b "link ea sanity under remote directory"
18207
18208 test_161c() {
18209         remote_mds_nodsh && skip "remote MDS with nodsh"
18210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18211         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18212                 skip "Need MDS version at least 2.1.5"
18213
18214         # define CLF_RENAME_LAST 0x0001
18215         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18216         changelog_register || error "changelog_register failed"
18217
18218         rm -rf $DIR/$tdir
18219         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18220         touch $DIR/$tdir/foo_161c
18221         touch $DIR/$tdir/bar_161c
18222         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18223         changelog_dump | grep RENME | tail -n 5
18224         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18225         changelog_clear 0 || error "changelog_clear failed"
18226         if [ x$flags != "x0x1" ]; then
18227                 error "flag $flags is not 0x1"
18228         fi
18229
18230         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18231         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18232         touch $DIR/$tdir/foo_161c
18233         touch $DIR/$tdir/bar_161c
18234         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18235         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18236         changelog_dump | grep RENME | tail -n 5
18237         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18238         changelog_clear 0 || error "changelog_clear failed"
18239         if [ x$flags != "x0x0" ]; then
18240                 error "flag $flags is not 0x0"
18241         fi
18242         echo "rename overwrite a target having nlink > 1," \
18243                 "changelog record has flags of $flags"
18244
18245         # rename doesn't overwrite a target (changelog flag 0x0)
18246         touch $DIR/$tdir/foo_161c
18247         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18248         changelog_dump | grep RENME | tail -n 5
18249         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18250         changelog_clear 0 || error "changelog_clear failed"
18251         if [ x$flags != "x0x0" ]; then
18252                 error "flag $flags is not 0x0"
18253         fi
18254         echo "rename doesn't overwrite a target," \
18255                 "changelog record has flags of $flags"
18256
18257         # define CLF_UNLINK_LAST 0x0001
18258         # unlink a file having nlink = 1 (changelog flag 0x1)
18259         rm -f $DIR/$tdir/foo2_161c
18260         changelog_dump | grep UNLNK | tail -n 5
18261         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18262         changelog_clear 0 || error "changelog_clear failed"
18263         if [ x$flags != "x0x1" ]; then
18264                 error "flag $flags is not 0x1"
18265         fi
18266         echo "unlink a file having nlink = 1," \
18267                 "changelog record has flags of $flags"
18268
18269         # unlink a file having nlink > 1 (changelog flag 0x0)
18270         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18271         rm -f $DIR/$tdir/foobar_161c
18272         changelog_dump | grep UNLNK | tail -n 5
18273         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18274         changelog_clear 0 || error "changelog_clear failed"
18275         if [ x$flags != "x0x0" ]; then
18276                 error "flag $flags is not 0x0"
18277         fi
18278         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18279 }
18280 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18281
18282 test_161d() {
18283         remote_mds_nodsh && skip "remote MDS with nodsh"
18284         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18285
18286         local pid
18287         local fid
18288
18289         changelog_register || error "changelog_register failed"
18290
18291         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18292         # interfer with $MOUNT/.lustre/fid/ access
18293         mkdir $DIR/$tdir
18294         [[ $? -eq 0 ]] || error "mkdir failed"
18295
18296         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18297         $LCTL set_param fail_loc=0x8000140c
18298         # 5s pause
18299         $LCTL set_param fail_val=5
18300
18301         # create file
18302         echo foofoo > $DIR/$tdir/$tfile &
18303         pid=$!
18304
18305         # wait for create to be delayed
18306         sleep 2
18307
18308         ps -p $pid
18309         [[ $? -eq 0 ]] || error "create should be blocked"
18310
18311         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18312         stack_trap "rm -f $tempfile"
18313         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18314         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18315         # some delay may occur during ChangeLog publishing and file read just
18316         # above, that could allow file write to happen finally
18317         [[ -s $tempfile ]] && echo "file should be empty"
18318
18319         $LCTL set_param fail_loc=0
18320
18321         wait $pid
18322         [[ $? -eq 0 ]] || error "create failed"
18323 }
18324 run_test 161d "create with concurrent .lustre/fid access"
18325
18326 check_path() {
18327         local expected="$1"
18328         shift
18329         local fid="$2"
18330
18331         local path
18332         path=$($LFS fid2path "$@")
18333         local rc=$?
18334
18335         if [ $rc -ne 0 ]; then
18336                 error "path looked up of '$expected' failed: rc=$rc"
18337         elif [ "$path" != "$expected" ]; then
18338                 error "path looked up '$path' instead of '$expected'"
18339         else
18340                 echo "FID '$fid' resolves to path '$path' as expected"
18341         fi
18342 }
18343
18344 test_162a() { # was test_162
18345         test_mkdir -p -c1 $DIR/$tdir/d2
18346         touch $DIR/$tdir/d2/$tfile
18347         touch $DIR/$tdir/d2/x1
18348         touch $DIR/$tdir/d2/x2
18349         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18350         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18351         # regular file
18352         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18353         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18354
18355         # softlink
18356         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18357         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18358         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18359
18360         # softlink to wrong file
18361         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18362         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18363         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18364
18365         # hardlink
18366         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18367         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18368         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18369         # fid2path dir/fsname should both work
18370         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18371         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18372
18373         # hardlink count: check that there are 2 links
18374         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18375         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18376
18377         # hardlink indexing: remove the first link
18378         rm $DIR/$tdir/d2/p/q/r/hlink
18379         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18380 }
18381 run_test 162a "path lookup sanity"
18382
18383 test_162b() {
18384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18386
18387         mkdir $DIR/$tdir
18388         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18389                                 error "create striped dir failed"
18390
18391         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18392                                         tail -n 1 | awk '{print $2}')
18393         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18394
18395         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18396         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18397
18398         # regular file
18399         for ((i=0;i<5;i++)); do
18400                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18401                         error "get fid for f$i failed"
18402                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18403
18404                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18405                         error "get fid for d$i failed"
18406                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18407         done
18408
18409         return 0
18410 }
18411 run_test 162b "striped directory path lookup sanity"
18412
18413 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18414 test_162c() {
18415         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18416                 skip "Need MDS version at least 2.7.51"
18417
18418         local lpath=$tdir.local
18419         local rpath=$tdir.remote
18420
18421         test_mkdir $DIR/$lpath
18422         test_mkdir $DIR/$rpath
18423
18424         for ((i = 0; i <= 101; i++)); do
18425                 lpath="$lpath/$i"
18426                 mkdir $DIR/$lpath
18427                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18428                         error "get fid for local directory $DIR/$lpath failed"
18429                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18430
18431                 rpath="$rpath/$i"
18432                 test_mkdir $DIR/$rpath
18433                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18434                         error "get fid for remote directory $DIR/$rpath failed"
18435                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18436         done
18437
18438         return 0
18439 }
18440 run_test 162c "fid2path works with paths 100 or more directories deep"
18441
18442 oalr_event_count() {
18443         local event="${1}"
18444         local trace="${2}"
18445
18446         awk -v name="${FSNAME}-OST0000" \
18447             -v event="${event}" \
18448             '$1 == "TRACE" && $2 == event && $3 == name' \
18449             "${trace}" |
18450         wc -l
18451 }
18452
18453 oalr_expect_event_count() {
18454         local event="${1}"
18455         local trace="${2}"
18456         local expect="${3}"
18457         local count
18458
18459         count=$(oalr_event_count "${event}" "${trace}")
18460         if ((count == expect)); then
18461                 return 0
18462         fi
18463
18464         error_noexit "${event} event count was '${count}', expected ${expect}"
18465         cat "${trace}" >&2
18466         exit 1
18467 }
18468
18469 cleanup_165() {
18470         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18471         stop ost1
18472         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18473 }
18474
18475 setup_165() {
18476         sync # Flush previous IOs so we can count log entries.
18477         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18478         stack_trap cleanup_165 EXIT
18479 }
18480
18481 test_165a() {
18482         local trace="/tmp/${tfile}.trace"
18483         local rc
18484         local count
18485
18486         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18487                 skip "OFD access log unsupported"
18488
18489         setup_165
18490         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18491         sleep 5
18492
18493         do_facet ost1 ofd_access_log_reader --list
18494         stop ost1
18495
18496         do_facet ost1 killall -TERM ofd_access_log_reader
18497         wait
18498         rc=$?
18499
18500         if ((rc != 0)); then
18501                 error "ofd_access_log_reader exited with rc = '${rc}'"
18502         fi
18503
18504         # Parse trace file for discovery events:
18505         oalr_expect_event_count alr_log_add "${trace}" 1
18506         oalr_expect_event_count alr_log_eof "${trace}" 1
18507         oalr_expect_event_count alr_log_free "${trace}" 1
18508 }
18509 run_test 165a "ofd access log discovery"
18510
18511 test_165b() {
18512         local trace="/tmp/${tfile}.trace"
18513         local file="${DIR}/${tfile}"
18514         local pfid1
18515         local pfid2
18516         local -a entry
18517         local rc
18518         local count
18519         local size
18520         local flags
18521
18522         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18523                 skip "OFD access log unsupported"
18524
18525         setup_165
18526         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18527         sleep 5
18528
18529         do_facet ost1 ofd_access_log_reader --list
18530
18531         lfs setstripe -c 1 -i 0 "${file}"
18532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18533                 error "cannot create '${file}'"
18534
18535         sleep 5
18536         do_facet ost1 killall -TERM ofd_access_log_reader
18537         wait
18538         rc=$?
18539
18540         if ((rc != 0)); then
18541                 error "ofd_access_log_reader exited with rc = '${rc}'"
18542         fi
18543
18544         oalr_expect_event_count alr_log_entry "${trace}" 1
18545
18546         pfid1=$($LFS path2fid "${file}")
18547
18548         # 1     2             3   4    5     6   7    8    9     10
18549         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18550         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18551
18552         echo "entry = '${entry[*]}'" >&2
18553
18554         pfid2=${entry[4]}
18555         if [[ "${pfid1}" != "${pfid2}" ]]; then
18556                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18557         fi
18558
18559         size=${entry[8]}
18560         if ((size != 1048576)); then
18561                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18562         fi
18563
18564         flags=${entry[10]}
18565         if [[ "${flags}" != "w" ]]; then
18566                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18567         fi
18568
18569         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18570         sleep 5
18571
18572         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18573                 error "cannot read '${file}'"
18574         sleep 5
18575
18576         do_facet ost1 killall -TERM ofd_access_log_reader
18577         wait
18578         rc=$?
18579
18580         if ((rc != 0)); then
18581                 error "ofd_access_log_reader exited with rc = '${rc}'"
18582         fi
18583
18584         oalr_expect_event_count alr_log_entry "${trace}" 1
18585
18586         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18587         echo "entry = '${entry[*]}'" >&2
18588
18589         pfid2=${entry[4]}
18590         if [[ "${pfid1}" != "${pfid2}" ]]; then
18591                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18592         fi
18593
18594         size=${entry[8]}
18595         if ((size != 524288)); then
18596                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18597         fi
18598
18599         flags=${entry[10]}
18600         if [[ "${flags}" != "r" ]]; then
18601                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18602         fi
18603 }
18604 run_test 165b "ofd access log entries are produced and consumed"
18605
18606 test_165c() {
18607         local trace="/tmp/${tfile}.trace"
18608         local file="${DIR}/${tdir}/${tfile}"
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 --debug=- --trace=- > "${trace}" &
18617         sleep 5
18618
18619         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18620
18621         # 4096 / 64 = 64. Create twice as many entries.
18622         for ((i = 0; i < 128; i++)); do
18623                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18624                         error "cannot create file"
18625         done
18626
18627         sync
18628
18629         do_facet ost1 killall -TERM ofd_access_log_reader
18630         wait
18631         rc=$?
18632         if ((rc != 0)); then
18633                 error "ofd_access_log_reader exited with rc = '${rc}'"
18634         fi
18635
18636         unlinkmany  "${file}-%d" 128
18637 }
18638 run_test 165c "full ofd access logs do not block IOs"
18639
18640 oal_get_read_count() {
18641         local stats="$1"
18642
18643         # STATS lustre-OST0001 alr_read_count 1
18644
18645         do_facet ost1 cat "${stats}" |
18646         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18647              END { print count; }'
18648 }
18649
18650 oal_expect_read_count() {
18651         local stats="$1"
18652         local count
18653         local expect="$2"
18654
18655         # Ask ofd_access_log_reader to write stats.
18656         do_facet ost1 killall -USR1 ofd_access_log_reader
18657
18658         # Allow some time for things to happen.
18659         sleep 1
18660
18661         count=$(oal_get_read_count "${stats}")
18662         if ((count == expect)); then
18663                 return 0
18664         fi
18665
18666         error_noexit "bad read count, got ${count}, expected ${expect}"
18667         do_facet ost1 cat "${stats}" >&2
18668         exit 1
18669 }
18670
18671 test_165d() {
18672         local stats="/tmp/${tfile}.stats"
18673         local file="${DIR}/${tdir}/${tfile}"
18674         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18675
18676         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18677                 skip "OFD access log unsupported"
18678
18679         test_mkdir "${DIR}/${tdir}"
18680
18681         setup_165
18682         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18683         sleep 5
18684
18685         lfs setstripe -c 1 -i 0 "${file}"
18686
18687         do_facet ost1 lctl set_param "${param}=rw"
18688         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18689                 error "cannot create '${file}'"
18690         oal_expect_read_count "${stats}" 1
18691
18692         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18693                 error "cannot read '${file}'"
18694         oal_expect_read_count "${stats}" 2
18695
18696         do_facet ost1 lctl set_param "${param}=r"
18697         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18698                 error "cannot create '${file}'"
18699         oal_expect_read_count "${stats}" 2
18700
18701         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18702                 error "cannot read '${file}'"
18703         oal_expect_read_count "${stats}" 3
18704
18705         do_facet ost1 lctl set_param "${param}=w"
18706         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18707                 error "cannot create '${file}'"
18708         oal_expect_read_count "${stats}" 4
18709
18710         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18711                 error "cannot read '${file}'"
18712         oal_expect_read_count "${stats}" 4
18713
18714         do_facet ost1 lctl set_param "${param}=0"
18715         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18716                 error "cannot create '${file}'"
18717         oal_expect_read_count "${stats}" 4
18718
18719         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18720                 error "cannot read '${file}'"
18721         oal_expect_read_count "${stats}" 4
18722
18723         do_facet ost1 killall -TERM ofd_access_log_reader
18724         wait
18725         rc=$?
18726         if ((rc != 0)); then
18727                 error "ofd_access_log_reader exited with rc = '${rc}'"
18728         fi
18729 }
18730 run_test 165d "ofd_access_log mask works"
18731
18732 test_165e() {
18733         local stats="/tmp/${tfile}.stats"
18734         local file0="${DIR}/${tdir}-0/${tfile}"
18735         local file1="${DIR}/${tdir}-1/${tfile}"
18736
18737         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18738                 skip "OFD access log unsupported"
18739
18740         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18741
18742         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18743         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18744
18745         lfs setstripe -c 1 -i 0 "${file0}"
18746         lfs setstripe -c 1 -i 0 "${file1}"
18747
18748         setup_165
18749         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18750         sleep 5
18751
18752         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18753                 error "cannot create '${file0}'"
18754         sync
18755         oal_expect_read_count "${stats}" 0
18756
18757         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18758                 error "cannot create '${file1}'"
18759         sync
18760         oal_expect_read_count "${stats}" 1
18761
18762         do_facet ost1 killall -TERM ofd_access_log_reader
18763         wait
18764         rc=$?
18765         if ((rc != 0)); then
18766                 error "ofd_access_log_reader exited with rc = '${rc}'"
18767         fi
18768 }
18769 run_test 165e "ofd_access_log MDT index filter works"
18770
18771 test_165f() {
18772         local trace="/tmp/${tfile}.trace"
18773         local rc
18774         local count
18775
18776         setup_165
18777         do_facet ost1 timeout 60 ofd_access_log_reader \
18778                 --exit-on-close --debug=- --trace=- > "${trace}" &
18779         sleep 5
18780         stop ost1
18781
18782         wait
18783         rc=$?
18784
18785         if ((rc != 0)); then
18786                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18787                 cat "${trace}"
18788                 exit 1
18789         fi
18790 }
18791 run_test 165f "ofd_access_log_reader --exit-on-close works"
18792
18793 test_169() {
18794         # do directio so as not to populate the page cache
18795         log "creating a 10 Mb file"
18796         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18797                 error "multiop failed while creating a file"
18798         log "starting reads"
18799         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18800         log "truncating the file"
18801         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18802                 error "multiop failed while truncating the file"
18803         log "killing dd"
18804         kill %+ || true # reads might have finished
18805         echo "wait until dd is finished"
18806         wait
18807         log "removing the temporary file"
18808         rm -rf $DIR/$tfile || error "tmp file removal failed"
18809 }
18810 run_test 169 "parallel read and truncate should not deadlock"
18811
18812 test_170() {
18813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18814
18815         $LCTL clear     # bug 18514
18816         $LCTL debug_daemon start $TMP/${tfile}_log_good
18817         touch $DIR/$tfile
18818         $LCTL debug_daemon stop
18819         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18820                 error "sed failed to read log_good"
18821
18822         $LCTL debug_daemon start $TMP/${tfile}_log_good
18823         rm -rf $DIR/$tfile
18824         $LCTL debug_daemon stop
18825
18826         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18827                error "lctl df log_bad failed"
18828
18829         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18830         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18831
18832         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18833         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18834
18835         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18836                 error "bad_line good_line1 good_line2 are empty"
18837
18838         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18839         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18840         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18841
18842         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18843         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18844         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18845
18846         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18847                 error "bad_line_new good_line_new are empty"
18848
18849         local expected_good=$((good_line1 + good_line2*2))
18850
18851         rm -f $TMP/${tfile}*
18852         # LU-231, short malformed line may not be counted into bad lines
18853         if [ $bad_line -ne $bad_line_new ] &&
18854                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18855                 error "expected $bad_line bad lines, but got $bad_line_new"
18856                 return 1
18857         fi
18858
18859         if [ $expected_good -ne $good_line_new ]; then
18860                 error "expected $expected_good good lines, but got $good_line_new"
18861                 return 2
18862         fi
18863         true
18864 }
18865 run_test 170 "test lctl df to handle corrupted log ====================="
18866
18867 test_171() { # bug20592
18868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18869
18870         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18871         $LCTL set_param fail_loc=0x50e
18872         $LCTL set_param fail_val=3000
18873         multiop_bg_pause $DIR/$tfile O_s || true
18874         local MULTIPID=$!
18875         kill -USR1 $MULTIPID
18876         # cause log dump
18877         sleep 3
18878         wait $MULTIPID
18879         if dmesg | grep "recursive fault"; then
18880                 error "caught a recursive fault"
18881         fi
18882         $LCTL set_param fail_loc=0
18883         true
18884 }
18885 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18886
18887 test_172() {
18888
18889         #define OBD_FAIL_OBD_CLEANUP  0x60e
18890         $LCTL set_param fail_loc=0x60e
18891         umount $MOUNT || error "umount $MOUNT failed"
18892         stack_trap "mount_client $MOUNT"
18893
18894         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18895                 error "no client OBDs are remained"
18896
18897         $LCTL dl | while read devno state type name foo; do
18898                 case $type in
18899                 lov|osc|lmv|mdc)
18900                         $LCTL --device $name cleanup
18901                         $LCTL --device $name detach
18902                         ;;
18903                 *)
18904                         # skip server devices
18905                         ;;
18906                 esac
18907         done
18908
18909         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18910                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18911                 error "some client OBDs are still remained"
18912         fi
18913
18914 }
18915 run_test 172 "manual device removal with lctl cleanup/detach ======"
18916
18917 # it would be good to share it with obdfilter-survey/iokit-libecho code
18918 setup_obdecho_osc () {
18919         local rc=0
18920         local ost_nid=$1
18921         local obdfilter_name=$2
18922         echo "Creating new osc for $obdfilter_name on $ost_nid"
18923         # make sure we can find loopback nid
18924         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18925
18926         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18927                            ${obdfilter_name}_osc_UUID || rc=2; }
18928         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18929                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18930         return $rc
18931 }
18932
18933 cleanup_obdecho_osc () {
18934         local obdfilter_name=$1
18935         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18936         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18937         return 0
18938 }
18939
18940 obdecho_test() {
18941         local OBD=$1
18942         local node=$2
18943         local pages=${3:-64}
18944         local rc=0
18945         local id
18946
18947         local count=10
18948         local obd_size=$(get_obd_size $node $OBD)
18949         local page_size=$(get_page_size $node)
18950         if [[ -n "$obd_size" ]]; then
18951                 local new_count=$((obd_size / (pages * page_size / 1024)))
18952                 [[ $new_count -ge $count ]] || count=$new_count
18953         fi
18954
18955         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18956         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18957                            rc=2; }
18958         if [ $rc -eq 0 ]; then
18959             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18960             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18961         fi
18962         echo "New object id is $id"
18963         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18964                            rc=4; }
18965         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18966                            "test_brw $count w v $pages $id" || rc=4; }
18967         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18968                            rc=4; }
18969         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18970                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18971         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18972                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18973         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18974         return $rc
18975 }
18976
18977 test_180a() {
18978         skip "obdecho on osc is no longer supported"
18979 }
18980 run_test 180a "test obdecho on osc"
18981
18982 test_180b() {
18983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18984         remote_ost_nodsh && skip "remote OST with nodsh"
18985
18986         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18987                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18988                 error "failed to load module obdecho"
18989
18990         local target=$(do_facet ost1 $LCTL dl |
18991                        awk '/obdfilter/ { print $4; exit; }')
18992
18993         if [ -n "$target" ]; then
18994                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18995         else
18996                 do_facet ost1 $LCTL dl
18997                 error "there is no obdfilter target on ost1"
18998         fi
18999 }
19000 run_test 180b "test obdecho directly on obdfilter"
19001
19002 test_180c() { # LU-2598
19003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19004         remote_ost_nodsh && skip "remote OST with nodsh"
19005         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19006                 skip "Need MDS version at least 2.4.0"
19007
19008         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19009                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19010                 error "failed to load module obdecho"
19011
19012         local target=$(do_facet ost1 $LCTL dl |
19013                        awk '/obdfilter/ { print $4; exit; }')
19014
19015         if [ -n "$target" ]; then
19016                 local pages=16384 # 64MB bulk I/O RPC size
19017
19018                 obdecho_test "$target" ost1 "$pages" ||
19019                         error "obdecho_test with pages=$pages failed with $?"
19020         else
19021                 do_facet ost1 $LCTL dl
19022                 error "there is no obdfilter target on ost1"
19023         fi
19024 }
19025 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19026
19027 test_181() { # bug 22177
19028         test_mkdir $DIR/$tdir
19029         # create enough files to index the directory
19030         createmany -o $DIR/$tdir/foobar 4000
19031         # print attributes for debug purpose
19032         lsattr -d .
19033         # open dir
19034         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19035         MULTIPID=$!
19036         # remove the files & current working dir
19037         unlinkmany $DIR/$tdir/foobar 4000
19038         rmdir $DIR/$tdir
19039         kill -USR1 $MULTIPID
19040         wait $MULTIPID
19041         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19042         return 0
19043 }
19044 run_test 181 "Test open-unlinked dir ========================"
19045
19046 test_182a() {
19047         local fcount=1000
19048         local tcount=10
19049
19050         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19051
19052         $LCTL set_param mdc.*.rpc_stats=clear
19053
19054         for (( i = 0; i < $tcount; i++ )) ; do
19055                 mkdir $DIR/$tdir/$i
19056         done
19057
19058         for (( i = 0; i < $tcount; i++ )) ; do
19059                 createmany -o $DIR/$tdir/$i/f- $fcount &
19060         done
19061         wait
19062
19063         for (( i = 0; i < $tcount; i++ )) ; do
19064                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19065         done
19066         wait
19067
19068         $LCTL get_param mdc.*.rpc_stats
19069
19070         rm -rf $DIR/$tdir
19071 }
19072 run_test 182a "Test parallel modify metadata operations from mdc"
19073
19074 test_182b() {
19075         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19076         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19077         local dcount=1000
19078         local tcount=10
19079         local stime
19080         local etime
19081         local delta
19082
19083         do_facet mds1 $LCTL list_param \
19084                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19085                 skip "MDS lacks parallel RPC handling"
19086
19087         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19088
19089         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19090                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19091
19092         stime=$(date +%s)
19093         createmany -i 0 -d $DIR/$tdir/t- $tcount
19094
19095         for (( i = 0; i < $tcount; i++ )) ; do
19096                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19097         done
19098         wait
19099         etime=$(date +%s)
19100         delta=$((etime - stime))
19101         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19102
19103         stime=$(date +%s)
19104         for (( i = 0; i < $tcount; i++ )) ; do
19105                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19106         done
19107         wait
19108         etime=$(date +%s)
19109         delta=$((etime - stime))
19110         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19111
19112         rm -rf $DIR/$tdir
19113
19114         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19115
19116         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19117
19118         stime=$(date +%s)
19119         createmany -i 0 -d $DIR/$tdir/t- $tcount
19120
19121         for (( i = 0; i < $tcount; i++ )) ; do
19122                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19123         done
19124         wait
19125         etime=$(date +%s)
19126         delta=$((etime - stime))
19127         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19128
19129         stime=$(date +%s)
19130         for (( i = 0; i < $tcount; i++ )) ; do
19131                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19132         done
19133         wait
19134         etime=$(date +%s)
19135         delta=$((etime - stime))
19136         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19137
19138         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19139 }
19140 run_test 182b "Test parallel modify metadata operations from osp"
19141
19142 test_183() { # LU-2275
19143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19144         remote_mds_nodsh && skip "remote MDS with nodsh"
19145         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19146                 skip "Need MDS version at least 2.3.56"
19147
19148         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19149         echo aaa > $DIR/$tdir/$tfile
19150
19151 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19152         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19153
19154         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19155         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19156
19157         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19158
19159         # Flush negative dentry cache
19160         touch $DIR/$tdir/$tfile
19161
19162         # We are not checking for any leaked references here, they'll
19163         # become evident next time we do cleanup with module unload.
19164         rm -rf $DIR/$tdir
19165 }
19166 run_test 183 "No crash or request leak in case of strange dispositions ========"
19167
19168 # test suite 184 is for LU-2016, LU-2017
19169 test_184a() {
19170         check_swap_layouts_support
19171
19172         dir0=$DIR/$tdir/$testnum
19173         test_mkdir -p -c1 $dir0
19174         ref1=/etc/passwd
19175         ref2=/etc/group
19176         file1=$dir0/f1
19177         file2=$dir0/f2
19178         $LFS setstripe -c1 $file1
19179         cp $ref1 $file1
19180         $LFS setstripe -c2 $file2
19181         cp $ref2 $file2
19182         gen1=$($LFS getstripe -g $file1)
19183         gen2=$($LFS getstripe -g $file2)
19184
19185         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19186         gen=$($LFS getstripe -g $file1)
19187         [[ $gen1 != $gen ]] ||
19188                 error "Layout generation on $file1 does not change"
19189         gen=$($LFS getstripe -g $file2)
19190         [[ $gen2 != $gen ]] ||
19191                 error "Layout generation on $file2 does not change"
19192
19193         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19194         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19195
19196         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19197 }
19198 run_test 184a "Basic layout swap"
19199
19200 test_184b() {
19201         check_swap_layouts_support
19202
19203         dir0=$DIR/$tdir/$testnum
19204         mkdir -p $dir0 || error "creating dir $dir0"
19205         file1=$dir0/f1
19206         file2=$dir0/f2
19207         file3=$dir0/f3
19208         dir1=$dir0/d1
19209         dir2=$dir0/d2
19210         mkdir $dir1 $dir2
19211         $LFS setstripe -c1 $file1
19212         $LFS setstripe -c2 $file2
19213         $LFS setstripe -c1 $file3
19214         chown $RUNAS_ID $file3
19215         gen1=$($LFS getstripe -g $file1)
19216         gen2=$($LFS getstripe -g $file2)
19217
19218         $LFS swap_layouts $dir1 $dir2 &&
19219                 error "swap of directories layouts should fail"
19220         $LFS swap_layouts $dir1 $file1 &&
19221                 error "swap of directory and file layouts should fail"
19222         $RUNAS $LFS swap_layouts $file1 $file2 &&
19223                 error "swap of file we cannot write should fail"
19224         $LFS swap_layouts $file1 $file3 &&
19225                 error "swap of file with different owner should fail"
19226         /bin/true # to clear error code
19227 }
19228 run_test 184b "Forbidden layout swap (will generate errors)"
19229
19230 test_184c() {
19231         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19232         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19233         check_swap_layouts_support
19234         check_swap_layout_no_dom $DIR
19235
19236         local dir0=$DIR/$tdir/$testnum
19237         mkdir -p $dir0 || error "creating dir $dir0"
19238
19239         local ref1=$dir0/ref1
19240         local ref2=$dir0/ref2
19241         local file1=$dir0/file1
19242         local file2=$dir0/file2
19243         # create a file large enough for the concurrent test
19244         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19245         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19246         echo "ref file size: ref1($(stat -c %s $ref1))," \
19247              "ref2($(stat -c %s $ref2))"
19248
19249         cp $ref2 $file2
19250         dd if=$ref1 of=$file1 bs=16k &
19251         local DD_PID=$!
19252
19253         # Make sure dd starts to copy file, but wait at most 5 seconds
19254         local loops=0
19255         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19256
19257         $LFS swap_layouts $file1 $file2
19258         local rc=$?
19259         wait $DD_PID
19260         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19261         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19262
19263         # how many bytes copied before swapping layout
19264         local copied=$(stat -c %s $file2)
19265         local remaining=$(stat -c %s $ref1)
19266         remaining=$((remaining - copied))
19267         echo "Copied $copied bytes before swapping layout..."
19268
19269         cmp -n $copied $file1 $ref2 | grep differ &&
19270                 error "Content mismatch [0, $copied) of ref2 and file1"
19271         cmp -n $copied $file2 $ref1 ||
19272                 error "Content mismatch [0, $copied) of ref1 and file2"
19273         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19274                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19275
19276         # clean up
19277         rm -f $ref1 $ref2 $file1 $file2
19278 }
19279 run_test 184c "Concurrent write and layout swap"
19280
19281 test_184d() {
19282         check_swap_layouts_support
19283         check_swap_layout_no_dom $DIR
19284         [ -z "$(which getfattr 2>/dev/null)" ] &&
19285                 skip_env "no getfattr command"
19286
19287         local file1=$DIR/$tdir/$tfile-1
19288         local file2=$DIR/$tdir/$tfile-2
19289         local file3=$DIR/$tdir/$tfile-3
19290         local lovea1
19291         local lovea2
19292
19293         mkdir -p $DIR/$tdir
19294         touch $file1 || error "create $file1 failed"
19295         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19296                 error "create $file2 failed"
19297         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19298                 error "create $file3 failed"
19299         lovea1=$(get_layout_param $file1)
19300
19301         $LFS swap_layouts $file2 $file3 ||
19302                 error "swap $file2 $file3 layouts failed"
19303         $LFS swap_layouts $file1 $file2 ||
19304                 error "swap $file1 $file2 layouts failed"
19305
19306         lovea2=$(get_layout_param $file2)
19307         echo "$lovea1"
19308         echo "$lovea2"
19309         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19310
19311         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19312         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19313 }
19314 run_test 184d "allow stripeless layouts swap"
19315
19316 test_184e() {
19317         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19318                 skip "Need MDS version at least 2.6.94"
19319         check_swap_layouts_support
19320         check_swap_layout_no_dom $DIR
19321         [ -z "$(which getfattr 2>/dev/null)" ] &&
19322                 skip_env "no getfattr command"
19323
19324         local file1=$DIR/$tdir/$tfile-1
19325         local file2=$DIR/$tdir/$tfile-2
19326         local file3=$DIR/$tdir/$tfile-3
19327         local lovea
19328
19329         mkdir -p $DIR/$tdir
19330         touch $file1 || error "create $file1 failed"
19331         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19332                 error "create $file2 failed"
19333         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19334                 error "create $file3 failed"
19335
19336         $LFS swap_layouts $file1 $file2 ||
19337                 error "swap $file1 $file2 layouts failed"
19338
19339         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19340         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19341
19342         echo 123 > $file1 || error "Should be able to write into $file1"
19343
19344         $LFS swap_layouts $file1 $file3 ||
19345                 error "swap $file1 $file3 layouts failed"
19346
19347         echo 123 > $file1 || error "Should be able to write into $file1"
19348
19349         rm -rf $file1 $file2 $file3
19350 }
19351 run_test 184e "Recreate layout after stripeless layout swaps"
19352
19353 test_184f() {
19354         # Create a file with name longer than sizeof(struct stat) ==
19355         # 144 to see if we can get chars from the file name to appear
19356         # in the returned striping. Note that 'f' == 0x66.
19357         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19358
19359         mkdir -p $DIR/$tdir
19360         mcreate $DIR/$tdir/$file
19361         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19362                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19363         fi
19364 }
19365 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19366
19367 test_185() { # LU-2441
19368         # LU-3553 - no volatile file support in old servers
19369         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19370                 skip "Need MDS version at least 2.3.60"
19371
19372         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19373         touch $DIR/$tdir/spoo
19374         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19375         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19376                 error "cannot create/write a volatile file"
19377         [ "$FILESET" == "" ] &&
19378         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19379                 error "FID is still valid after close"
19380
19381         multiop_bg_pause $DIR/$tdir Vw4096_c
19382         local multi_pid=$!
19383
19384         local OLD_IFS=$IFS
19385         IFS=":"
19386         local fidv=($fid)
19387         IFS=$OLD_IFS
19388         # assume that the next FID for this client is sequential, since stdout
19389         # is unfortunately eaten by multiop_bg_pause
19390         local n=$((${fidv[1]} + 1))
19391         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19392         if [ "$FILESET" == "" ]; then
19393                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19394                         error "FID is missing before close"
19395         fi
19396         kill -USR1 $multi_pid
19397         # 1 second delay, so if mtime change we will see it
19398         sleep 1
19399         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19400         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19401 }
19402 run_test 185 "Volatile file support"
19403
19404 function create_check_volatile() {
19405         local idx=$1
19406         local tgt
19407
19408         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19409         local PID=$!
19410         sleep 1
19411         local FID=$(cat /tmp/${tfile}.fid)
19412         [ "$FID" == "" ] && error "can't get FID for volatile"
19413         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19414         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19415         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19416         kill -USR1 $PID
19417         wait
19418         sleep 1
19419         cancel_lru_locks mdc # flush opencache
19420         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19421         return 0
19422 }
19423
19424 test_185a(){
19425         # LU-12516 - volatile creation via .lustre
19426         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19427                 skip "Need MDS version at least 2.3.55"
19428
19429         create_check_volatile 0
19430         [ $MDSCOUNT -lt 2 ] && return 0
19431
19432         # DNE case
19433         create_check_volatile 1
19434
19435         return 0
19436 }
19437 run_test 185a "Volatile file creation in .lustre/fid/"
19438
19439 test_187a() {
19440         remote_mds_nodsh && skip "remote MDS with nodsh"
19441         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19442                 skip "Need MDS version at least 2.3.0"
19443
19444         local dir0=$DIR/$tdir/$testnum
19445         mkdir -p $dir0 || error "creating dir $dir0"
19446
19447         local file=$dir0/file1
19448         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19449         stack_trap "rm -f $file"
19450         local dv1=$($LFS data_version $file)
19451         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19452         local dv2=$($LFS data_version $file)
19453         [[ $dv1 != $dv2 ]] ||
19454                 error "data version did not change on write $dv1 == $dv2"
19455 }
19456 run_test 187a "Test data version change"
19457
19458 test_187b() {
19459         remote_mds_nodsh && skip "remote MDS with nodsh"
19460         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19461                 skip "Need MDS version at least 2.3.0"
19462
19463         local dir0=$DIR/$tdir/$testnum
19464         mkdir -p $dir0 || error "creating dir $dir0"
19465
19466         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19467         [[ ${DV[0]} != ${DV[1]} ]] ||
19468                 error "data version did not change on write"\
19469                       " ${DV[0]} == ${DV[1]}"
19470
19471         # clean up
19472         rm -f $file1
19473 }
19474 run_test 187b "Test data version change on volatile file"
19475
19476 test_200() {
19477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19478         remote_mgs_nodsh && skip "remote MGS with nodsh"
19479         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19480
19481         local POOL=${POOL:-cea1}
19482         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19483         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19484         # Pool OST targets
19485         local first_ost=0
19486         local last_ost=$(($OSTCOUNT - 1))
19487         local ost_step=2
19488         local ost_list=$(seq $first_ost $ost_step $last_ost)
19489         local ost_range="$first_ost $last_ost $ost_step"
19490         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19491         local file_dir=$POOL_ROOT/file_tst
19492         local subdir=$test_path/subdir
19493         local rc=0
19494
19495         while : ; do
19496                 # former test_200a test_200b
19497                 pool_add $POOL                          || { rc=$? ; break; }
19498                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19499                 # former test_200c test_200d
19500                 mkdir -p $test_path
19501                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19502                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19503                 mkdir -p $subdir
19504                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19505                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19506                                                         || { rc=$? ; break; }
19507                 # former test_200e test_200f
19508                 local files=$((OSTCOUNT*3))
19509                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19510                                                         || { rc=$? ; break; }
19511                 pool_create_files $POOL $file_dir $files "$ost_list" \
19512                                                         || { rc=$? ; break; }
19513                 # former test_200g test_200h
19514                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19515                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19516
19517                 # former test_201a test_201b test_201c
19518                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19519
19520                 local f=$test_path/$tfile
19521                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19522                 pool_remove $POOL $f                    || { rc=$? ; break; }
19523                 break
19524         done
19525
19526         destroy_test_pools
19527
19528         return $rc
19529 }
19530 run_test 200 "OST pools"
19531
19532 # usage: default_attr <count | size | offset>
19533 default_attr() {
19534         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19535 }
19536
19537 # usage: check_default_stripe_attr
19538 check_default_stripe_attr() {
19539         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19540         case $1 in
19541         --stripe-count|-c)
19542                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19543         --stripe-size|-S)
19544                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19545         --stripe-index|-i)
19546                 EXPECTED=-1;;
19547         *)
19548                 error "unknown getstripe attr '$1'"
19549         esac
19550
19551         [ $ACTUAL == $EXPECTED ] ||
19552                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19553 }
19554
19555 test_204a() {
19556         test_mkdir $DIR/$tdir
19557         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19558
19559         check_default_stripe_attr --stripe-count
19560         check_default_stripe_attr --stripe-size
19561         check_default_stripe_attr --stripe-index
19562 }
19563 run_test 204a "Print default stripe attributes"
19564
19565 test_204b() {
19566         test_mkdir $DIR/$tdir
19567         $LFS setstripe --stripe-count 1 $DIR/$tdir
19568
19569         check_default_stripe_attr --stripe-size
19570         check_default_stripe_attr --stripe-index
19571 }
19572 run_test 204b "Print default stripe size and offset"
19573
19574 test_204c() {
19575         test_mkdir $DIR/$tdir
19576         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19577
19578         check_default_stripe_attr --stripe-count
19579         check_default_stripe_attr --stripe-index
19580 }
19581 run_test 204c "Print default stripe count and offset"
19582
19583 test_204d() {
19584         test_mkdir $DIR/$tdir
19585         $LFS setstripe --stripe-index 0 $DIR/$tdir
19586
19587         check_default_stripe_attr --stripe-count
19588         check_default_stripe_attr --stripe-size
19589 }
19590 run_test 204d "Print default stripe count and size"
19591
19592 test_204e() {
19593         test_mkdir $DIR/$tdir
19594         $LFS setstripe -d $DIR/$tdir
19595
19596         # LU-16904 check if root is set as PFL layout
19597         local numcomp=$($LFS getstripe --component-count $MOUNT)
19598
19599         if [[ $numcomp -gt 0 ]]; then
19600                 check_default_stripe_attr --stripe-count
19601         else
19602                 check_default_stripe_attr --stripe-count --raw
19603         fi
19604         check_default_stripe_attr --stripe-size --raw
19605         check_default_stripe_attr --stripe-index --raw
19606 }
19607 run_test 204e "Print raw stripe attributes"
19608
19609 test_204f() {
19610         test_mkdir $DIR/$tdir
19611         $LFS setstripe --stripe-count 1 $DIR/$tdir
19612
19613         check_default_stripe_attr --stripe-size --raw
19614         check_default_stripe_attr --stripe-index --raw
19615 }
19616 run_test 204f "Print raw stripe size and offset"
19617
19618 test_204g() {
19619         test_mkdir $DIR/$tdir
19620         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19621
19622         check_default_stripe_attr --stripe-count --raw
19623         check_default_stripe_attr --stripe-index --raw
19624 }
19625 run_test 204g "Print raw stripe count and offset"
19626
19627 test_204h() {
19628         test_mkdir $DIR/$tdir
19629         $LFS setstripe --stripe-index 0 $DIR/$tdir
19630
19631         check_default_stripe_attr --stripe-count --raw
19632         check_default_stripe_attr --stripe-size --raw
19633 }
19634 run_test 204h "Print raw stripe count and size"
19635
19636 # Figure out which job scheduler is being used, if any,
19637 # or use a fake one
19638 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19639         JOBENV=SLURM_JOB_ID
19640 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19641         JOBENV=LSB_JOBID
19642 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19643         JOBENV=PBS_JOBID
19644 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19645         JOBENV=LOADL_STEP_ID
19646 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19647         JOBENV=JOB_ID
19648 else
19649         $LCTL list_param jobid_name > /dev/null 2>&1
19650         if [ $? -eq 0 ]; then
19651                 JOBENV=nodelocal
19652         else
19653                 JOBENV=FAKE_JOBID
19654         fi
19655 fi
19656 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19657
19658 verify_jobstats() {
19659         local cmd=($1)
19660         shift
19661         local facets="$@"
19662
19663 # we don't really need to clear the stats for this test to work, since each
19664 # command has a unique jobid, but it makes debugging easier if needed.
19665 #       for facet in $facets; do
19666 #               local dev=$(convert_facet2label $facet)
19667 #               # clear old jobstats
19668 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19669 #       done
19670
19671         # use a new JobID for each test, or we might see an old one
19672         [ "$JOBENV" = "FAKE_JOBID" ] &&
19673                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19674
19675         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19676
19677         [ "$JOBENV" = "nodelocal" ] && {
19678                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19679                 $LCTL set_param jobid_name=$FAKE_JOBID
19680                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19681         }
19682
19683         log "Test: ${cmd[*]}"
19684         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19685
19686         if [ $JOBENV = "FAKE_JOBID" ]; then
19687                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19688         else
19689                 ${cmd[*]}
19690         fi
19691
19692         # all files are created on OST0000
19693         for facet in $facets; do
19694                 local stats="*.$(convert_facet2label $facet).job_stats"
19695
19696                 # strip out libtool wrappers for in-tree executables
19697                 if (( $(do_facet $facet lctl get_param $stats |
19698                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19699                         do_facet $facet lctl get_param $stats
19700                         error "No jobstats for $JOBVAL found on $facet::$stats"
19701                 fi
19702         done
19703 }
19704
19705 jobstats_set() {
19706         local new_jobenv=$1
19707
19708         set_persistent_param_and_check client "jobid_var" \
19709                 "$FSNAME.sys.jobid_var" $new_jobenv
19710 }
19711
19712 test_205a() { # Job stats
19713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19714         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19715                 skip "Need MDS version with at least 2.7.1"
19716         remote_mgs_nodsh && skip "remote MGS with nodsh"
19717         remote_mds_nodsh && skip "remote MDS with nodsh"
19718         remote_ost_nodsh && skip "remote OST with nodsh"
19719         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19720                 skip "Server doesn't support jobstats"
19721         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19722
19723         local old_jobenv=$($LCTL get_param -n jobid_var)
19724         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19725         stack_trap "jobstats_set $old_jobenv" EXIT
19726
19727         changelog_register
19728
19729         local old_jobid_name=$($LCTL get_param jobid_name)
19730         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19731
19732         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19733                                 mdt.*.job_cleanup_interval | head -n 1)
19734         local new_interval=5
19735         do_facet $SINGLEMDS \
19736                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19737         stack_trap "do_facet $SINGLEMDS \
19738                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19739         local start=$SECONDS
19740
19741         local cmd
19742         # mkdir
19743         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19744         verify_jobstats "$cmd" "$SINGLEMDS"
19745         # rmdir
19746         cmd="rmdir $DIR/$tdir"
19747         verify_jobstats "$cmd" "$SINGLEMDS"
19748         # mkdir on secondary MDT
19749         if [ $MDSCOUNT -gt 1 ]; then
19750                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19751                 verify_jobstats "$cmd" "mds2"
19752         fi
19753         # mknod
19754         cmd="mknod $DIR/$tfile c 1 3"
19755         verify_jobstats "$cmd" "$SINGLEMDS"
19756         # unlink
19757         cmd="rm -f $DIR/$tfile"
19758         verify_jobstats "$cmd" "$SINGLEMDS"
19759         # create all files on OST0000 so verify_jobstats can find OST stats
19760         # open & close
19761         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19762         verify_jobstats "$cmd" "$SINGLEMDS"
19763         # setattr
19764         cmd="touch $DIR/$tfile"
19765         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19766         # write
19767         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19768         verify_jobstats "$cmd" "ost1"
19769         # read
19770         cancel_lru_locks osc
19771         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19772         verify_jobstats "$cmd" "ost1"
19773         # truncate
19774         cmd="$TRUNCATE $DIR/$tfile 0"
19775         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19776         # rename
19777         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19778         verify_jobstats "$cmd" "$SINGLEMDS"
19779         # jobstats expiry - sleep until old stats should be expired
19780         local left=$((new_interval + 5 - (SECONDS - start)))
19781         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19782                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19783                         "0" $left
19784         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19785         verify_jobstats "$cmd" "$SINGLEMDS"
19786         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19787             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19788
19789         # Ensure that jobid are present in changelog (if supported by MDS)
19790         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19791                 changelog_dump | tail -10
19792                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19793                 [ $jobids -eq 9 ] ||
19794                         error "Wrong changelog jobid count $jobids != 9"
19795
19796                 # LU-5862
19797                 JOBENV="disable"
19798                 jobstats_set $JOBENV
19799                 touch $DIR/$tfile
19800                 changelog_dump | grep $tfile
19801                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19802                 [ $jobids -eq 0 ] ||
19803                         error "Unexpected jobids when jobid_var=$JOBENV"
19804         fi
19805
19806         # test '%j' access to environment variable - if supported
19807         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19808                 JOBENV="JOBCOMPLEX"
19809                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19810
19811                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19812         fi
19813
19814         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19815                 JOBENV="JOBCOMPLEX"
19816                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19817
19818                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19819         fi
19820
19821         # test '%j' access to per-session jobid - if supported
19822         if lctl list_param jobid_this_session > /dev/null 2>&1
19823         then
19824                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19825                 lctl set_param jobid_this_session=$USER
19826
19827                 JOBENV="JOBCOMPLEX"
19828                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19829
19830                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19831         fi
19832 }
19833 run_test 205a "Verify job stats"
19834
19835 # LU-13117, LU-13597, LU-16599
19836 test_205b() {
19837         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19838                 skip "Need MDS version at least 2.13.54.91"
19839
19840         local job_stats="mdt.*.job_stats"
19841         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19842
19843         do_facet mds1 $LCTL set_param $job_stats=clear
19844
19845         # Setting jobid_var to USER might not be supported
19846         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19847         $LCTL set_param jobid_var=USER || true
19848         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19849         $LCTL set_param jobid_name="%j.%e.%u"
19850
19851         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19852         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19853                 { do_facet mds1 $LCTL get_param $job_stats;
19854                   error "Unexpected jobid found"; }
19855         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19856                 { do_facet mds1 $LCTL get_param $job_stats;
19857                   error "wrong job_stats format found"; }
19858
19859         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19860                 echo "MDS does not yet escape jobid" && return 0
19861
19862         mkdir_on_mdt0 $DIR/$tdir
19863         $LCTL set_param jobid_var=TEST205b
19864         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19865         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19866                       awk '/has\\x20sp/ {print $3}')
19867         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19868                   error "jobid not escaped"; }
19869
19870         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19871                 # need to run such a command on mds1:
19872                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19873                 #
19874                 # there might be multiple MDTs on single mds server, so need to
19875                 # specifiy MDT0000. Or the command will fail due to other MDTs
19876                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19877                         error "cannot clear escaped jobid in job_stats";
19878         else
19879                 echo "MDS does not support clearing escaped jobid"
19880         fi
19881 }
19882 run_test 205b "Verify job stats jobid and output format"
19883
19884 # LU-13733
19885 test_205c() {
19886         $LCTL set_param llite.*.stats=0
19887         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19888         $LCTL get_param llite.*.stats
19889         $LCTL get_param llite.*.stats | grep \
19890                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19891                         error "wrong client stats format found"
19892 }
19893 run_test 205c "Verify client stats format"
19894
19895 test_205d() {
19896         local file=$DIR/$tdir/$tfile
19897
19898         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19899                 skip "need lustre >= 2.15.53 for lljobstat"
19900         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19901                 skip "need lustre >= 2.15.53 for lljobstat"
19902         verify_yaml_available || skip_env "YAML verification not installed"
19903
19904         test_mkdir -i 0 $DIR/$tdir
19905         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19906         stack_trap "rm -rf $DIR/$tdir"
19907
19908         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19909                 error "failed to write data to $file"
19910         mv $file $file.2
19911
19912         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19913         echo -n 'verify rename_stats...'
19914         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19915                 verify_yaml || error "rename_stats is not valid YAML"
19916         echo " OK"
19917
19918         echo -n 'verify mdt job_stats...'
19919         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19920                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19921         echo " OK"
19922
19923         echo -n 'verify ost job_stats...'
19924         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19925                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19926         echo " OK"
19927 }
19928 run_test 205d "verify the format of some stats files"
19929
19930 test_205e() {
19931         local ops_comma
19932         local file=$DIR/$tdir/$tfile
19933         local -a cli_params
19934
19935         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19936                 skip "need lustre >= 2.15.53 for lljobstat"
19937         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19938                 skip "need lustre >= 2.15.53 for lljobstat"
19939         verify_yaml_available || skip_env "YAML verification not installed"
19940
19941         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19942         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19943         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19944
19945         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19946         stack_trap "rm -rf $DIR/$tdir"
19947
19948         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19949                 error "failed to create $file on ost1"
19950         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19951                 error "failed to write data to $file"
19952
19953         do_facet mds1 "$LCTL get_param *.*.job_stats"
19954         do_facet ost1 "$LCTL get_param *.*.job_stats"
19955
19956         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19957         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19958                 error "The output of lljobstat is not an valid YAML"
19959
19960         # verify that job dd.0 does exist and has some ops on ost1
19961         # typically this line is like:
19962         # - 205e.dd.0:            {ops: 20, ...}
19963         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19964                     awk '$2=="205e.dd.0:" {print $4}')
19965
19966         (( ${ops_comma%,} >= 10 )) ||
19967                 error "cannot find job 205e.dd.0 with ops >= 10"
19968 }
19969 run_test 205e "verify the output of lljobstat"
19970
19971 test_205f() {
19972         verify_yaml_available || skip_env "YAML verification not installed"
19973
19974         # check both qos_ost_weights and qos_mdt_weights
19975         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19976         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19977                 error "qos_ost_weights is not valid YAML"
19978 }
19979 run_test 205f "verify qos_ost_weights YAML format "
19980
19981 __test_205_jobstats_dump() {
19982         local -a pids
19983         local nbr_instance=$1
19984
19985         while true; do
19986                 if (( ${#pids[@]} >= nbr_instance )); then
19987                         wait ${pids[@]}
19988                         pids=()
19989                 fi
19990
19991                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19992                 pids+=( $! )
19993         done
19994 }
19995
19996 __test_205_cleanup() {
19997         kill $@
19998         # Clear all job entries
19999         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20000 }
20001
20002 test_205g() {
20003         local -a mds1_params
20004         local -a cli_params
20005         local pids
20006         local interval=5
20007
20008         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20009         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20010         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20011
20012         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20013         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20014         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20015
20016         # start jobs loop
20017         export TEST205G_ID=205g
20018         stack_trap "unset TEST205G_ID" EXIT
20019         while true; do
20020                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20021         done & pids="$! "
20022
20023         __test_205_jobstats_dump 4 & pids+="$! "
20024         stack_trap "__test_205_cleanup $pids" EXIT INT
20025
20026         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20027 }
20028 run_test 205g "stress test for job_stats procfile"
20029
20030 test_205h() {
20031         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20032
20033         local dir=$DIR/$tdir
20034         local f=$dir/$tfile
20035         local f2=$dir/$tfile-2
20036         local f3=$dir/$tfile-3
20037         local subdir=$DIR/dir
20038         local val
20039
20040         local mdts=$(comma_list $(mdts_nodes))
20041         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20042         local client_saved=$($LCTL get_param -n jobid_var)
20043
20044         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20045         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20046
20047         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20048                 error "failed to set job_xattr parameter to user.job"
20049         $LCTL set_param jobid_var=procname.uid ||
20050                 error "failed to set jobid_var parameter"
20051
20052         test_mkdir $dir
20053
20054         touch $f
20055         val=$(getfattr -n user.job $f | grep user.job)
20056         [[ $val = user.job=\"touch.0\" ]] ||
20057                 error "expected user.job=\"touch.0\", got '$val'"
20058
20059         mkdir $subdir
20060         val=$(getfattr -n user.job $subdir | grep user.job)
20061         [[ $val = user.job=\"mkdir.0\" ]] ||
20062                 error "expected user.job=\"mkdir.0\", got '$val'"
20063
20064         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20065                 error "failed to set job_xattr parameter to NONE"
20066
20067         touch $f2
20068         val=$(getfattr -d $f2)
20069         [[ -z $val ]] ||
20070                 error "expected no user xattr, got '$val'"
20071
20072         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20073                 error "failed to set job_xattr parameter to trusted.job"
20074
20075         touch $f3
20076         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20077         [[ $val = trusted.job=\"touch.0\" ]] ||
20078                 error "expected trusted.job=\"touch.0\", got '$val'"
20079 }
20080 run_test 205h "check jobid xattr is stored correctly"
20081
20082 test_205i() {
20083         local mdts=$(comma_list $(mdts_nodes))
20084         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20085
20086         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20087
20088         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20089                 error "failed to set mdt.*.job_xattr to user.1234567"
20090
20091         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20092                 error "failed to reject too long job_xattr name"
20093
20094         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20095                 error "failed to reject job_xattr name in bad format"
20096
20097         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20098                 error "failed to reject job_xattr name with invalid character"
20099
20100         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20101                         xargs $LCTL set_param" &&
20102                 error "failed to reject job_xattr name with non-ascii character"
20103
20104         return 0
20105 }
20106 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20107
20108 # LU-1480, LU-1773 and LU-1657
20109 test_206() {
20110         mkdir -p $DIR/$tdir
20111         $LFS setstripe -c -1 $DIR/$tdir
20112 #define OBD_FAIL_LOV_INIT 0x1403
20113         $LCTL set_param fail_loc=0xa0001403
20114         $LCTL set_param fail_val=1
20115         touch $DIR/$tdir/$tfile || true
20116 }
20117 run_test 206 "fail lov_init_raid0() doesn't lbug"
20118
20119 test_207a() {
20120         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20121         local fsz=`stat -c %s $DIR/$tfile`
20122         cancel_lru_locks mdc
20123
20124         # do not return layout in getattr intent
20125 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20126         $LCTL set_param fail_loc=0x170
20127         local sz=`stat -c %s $DIR/$tfile`
20128
20129         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20130
20131         rm -rf $DIR/$tfile
20132 }
20133 run_test 207a "can refresh layout at glimpse"
20134
20135 test_207b() {
20136         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20137         local cksum=`md5sum $DIR/$tfile`
20138         local fsz=`stat -c %s $DIR/$tfile`
20139         cancel_lru_locks mdc
20140         cancel_lru_locks osc
20141
20142         # do not return layout in getattr intent
20143 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20144         $LCTL set_param fail_loc=0x171
20145
20146         # it will refresh layout after the file is opened but before read issues
20147         echo checksum is "$cksum"
20148         echo "$cksum" |md5sum -c --quiet || error "file differs"
20149
20150         rm -rf $DIR/$tfile
20151 }
20152 run_test 207b "can refresh layout at open"
20153
20154 test_208() {
20155         # FIXME: in this test suite, only RD lease is used. This is okay
20156         # for now as only exclusive open is supported. After generic lease
20157         # is done, this test suite should be revised. - Jinshan
20158
20159         remote_mds_nodsh && skip "remote MDS with nodsh"
20160         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20161                 skip "Need MDS version at least 2.4.52"
20162
20163         echo "==== test 1: verify get lease work"
20164         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20165
20166         echo "==== test 2: verify lease can be broken by upcoming open"
20167         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20168         local PID=$!
20169         sleep 2
20170
20171         $MULTIOP $DIR/$tfile oO_RDWR:c
20172         kill -USR1 $PID && wait $PID || error "break lease error"
20173
20174         echo "==== test 3: verify lease can't be granted if an open already exists"
20175         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20176         local PID=$!
20177         sleep 2
20178
20179         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20180         kill -USR1 $PID && wait $PID || error "open file error"
20181
20182         echo "==== test 4: lease can sustain over recovery"
20183         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20184         PID=$!
20185         sleep 2
20186
20187         fail mds1
20188
20189         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20190
20191         echo "==== test 5: lease broken can't be regained by replay"
20192         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20193         PID=$!
20194         sleep 2
20195
20196         # open file to break lease and then recovery
20197         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20198         fail mds1
20199
20200         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20201
20202         rm -f $DIR/$tfile
20203 }
20204 run_test 208 "Exclusive open"
20205
20206 test_209() {
20207         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20208                 skip_env "must have disp_stripe"
20209
20210         touch $DIR/$tfile
20211         sync; sleep 5; sync;
20212
20213         echo 3 > /proc/sys/vm/drop_caches
20214         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20215                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20216         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20217
20218         # open/close 500 times
20219         for i in $(seq 500); do
20220                 cat $DIR/$tfile
20221         done
20222
20223         echo 3 > /proc/sys/vm/drop_caches
20224         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20225                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20226         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20227
20228         echo "before: $req_before, after: $req_after"
20229         [ $((req_after - req_before)) -ge 300 ] &&
20230                 error "open/close requests are not freed"
20231         return 0
20232 }
20233 run_test 209 "read-only open/close requests should be freed promptly"
20234
20235 test_210() {
20236         local pid
20237
20238         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20239         pid=$!
20240         sleep 1
20241
20242         $LFS getstripe $DIR/$tfile
20243         kill -USR1 $pid
20244         wait $pid || error "multiop failed"
20245
20246         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20247         pid=$!
20248         sleep 1
20249
20250         $LFS getstripe $DIR/$tfile
20251         kill -USR1 $pid
20252         wait $pid || error "multiop failed"
20253 }
20254 run_test 210 "lfs getstripe does not break leases"
20255
20256 test_212() {
20257         size=`date +%s`
20258         size=$((size % 8192 + 1))
20259         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20260         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20261         rm -f $DIR/f212 $DIR/f212.xyz
20262 }
20263 run_test 212 "Sendfile test ============================================"
20264
20265 test_213() {
20266         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20267         cancel_lru_locks osc
20268         lctl set_param fail_loc=0x8000040f
20269         # generate a read lock
20270         cat $DIR/$tfile > /dev/null
20271         # write to the file, it will try to cancel the above read lock.
20272         cat /etc/hosts >> $DIR/$tfile
20273 }
20274 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20275
20276 test_214() { # for bug 20133
20277         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20278         for (( i=0; i < 340; i++ )) ; do
20279                 touch $DIR/$tdir/d214c/a$i
20280         done
20281
20282         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20283         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20284         ls $DIR/d214c || error "ls $DIR/d214c failed"
20285         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20286         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20287 }
20288 run_test 214 "hash-indexed directory test - bug 20133"
20289
20290 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20291 create_lnet_proc_files() {
20292         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20293 }
20294
20295 # counterpart of create_lnet_proc_files
20296 remove_lnet_proc_files() {
20297         rm -f $TMP/lnet_$1.sys
20298 }
20299
20300 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20301 # 3rd arg as regexp for body
20302 check_lnet_proc_stats() {
20303         local l=$(cat "$TMP/lnet_$1" |wc -l)
20304         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20305
20306         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20307 }
20308
20309 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20310 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20311 # optional and can be regexp for 2nd line (lnet.routes case)
20312 check_lnet_proc_entry() {
20313         local blp=2          # blp stands for 'position of 1st line of body'
20314         [ -z "$5" ] || blp=3 # lnet.routes case
20315
20316         local l=$(cat "$TMP/lnet_$1" |wc -l)
20317         # subtracting one from $blp because the body can be empty
20318         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20319
20320         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20321                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20322
20323         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20324                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20325
20326         # bail out if any unexpected line happened
20327         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20328         [ "$?" != 0 ] || error "$2 misformatted"
20329 }
20330
20331 test_215() { # for bugs 18102, 21079, 21517
20332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20333
20334         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20335         local P='[1-9][0-9]*'           # positive numeric
20336         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20337         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20338         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20339         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20340
20341         local L1 # regexp for 1st line
20342         local L2 # regexp for 2nd line (optional)
20343         local BR # regexp for the rest (body)
20344
20345         # lnet.stats should look as 11 space-separated non-negative numerics
20346         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20347         create_lnet_proc_files "stats"
20348         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20349         remove_lnet_proc_files "stats"
20350
20351         # lnet.routes should look like this:
20352         # Routing disabled/enabled
20353         # net hops priority state router
20354         # where net is a string like tcp0, hops > 0, priority >= 0,
20355         # state is up/down,
20356         # router is a string like 192.168.1.1@tcp2
20357         L1="^Routing (disabled|enabled)$"
20358         L2="^net +hops +priority +state +router$"
20359         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20360         create_lnet_proc_files "routes"
20361         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20362         remove_lnet_proc_files "routes"
20363
20364         # lnet.routers should look like this:
20365         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20366         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20367         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20368         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20369         L1="^ref +rtr_ref +alive +router$"
20370         BR="^$P +$P +(up|down) +$NID$"
20371         create_lnet_proc_files "routers"
20372         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20373         remove_lnet_proc_files "routers"
20374
20375         # lnet.peers should look like this:
20376         # nid refs state last max rtr min tx min queue
20377         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20378         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20379         # numeric (0 or >0 or <0), queue >= 0.
20380         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20381         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20382         create_lnet_proc_files "peers"
20383         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20384         remove_lnet_proc_files "peers"
20385
20386         # lnet.buffers  should look like this:
20387         # pages count credits min
20388         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20389         L1="^pages +count +credits +min$"
20390         BR="^ +$N +$N +$I +$I$"
20391         create_lnet_proc_files "buffers"
20392         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20393         remove_lnet_proc_files "buffers"
20394
20395         # lnet.nis should look like this:
20396         # nid status alive refs peer rtr max tx min
20397         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20398         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20399         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20400         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20401         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20402         create_lnet_proc_files "nis"
20403         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20404         remove_lnet_proc_files "nis"
20405
20406         # can we successfully write to lnet.stats?
20407         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20408 }
20409 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20410
20411 test_216() { # bug 20317
20412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20413         remote_ost_nodsh && skip "remote OST with nodsh"
20414
20415         local node
20416         local facets=$(get_facets OST)
20417         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20418
20419         save_lustre_params client "osc.*.contention_seconds" > $p
20420         save_lustre_params $facets \
20421                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20422         save_lustre_params $facets \
20423                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20424         save_lustre_params $facets \
20425                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20426         clear_stats osc.*.osc_stats
20427
20428         # agressive lockless i/o settings
20429         do_nodes $(comma_list $(osts_nodes)) \
20430                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20431                         ldlm.namespaces.filter-*.contended_locks=0 \
20432                         ldlm.namespaces.filter-*.contention_seconds=60"
20433         lctl set_param -n osc.*.contention_seconds=60
20434
20435         $DIRECTIO write $DIR/$tfile 0 10 4096
20436         $CHECKSTAT -s 40960 $DIR/$tfile
20437
20438         # disable lockless i/o
20439         do_nodes $(comma_list $(osts_nodes)) \
20440                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20441                         ldlm.namespaces.filter-*.contended_locks=32 \
20442                         ldlm.namespaces.filter-*.contention_seconds=0"
20443         lctl set_param -n osc.*.contention_seconds=0
20444         clear_stats osc.*.osc_stats
20445
20446         dd if=/dev/zero of=$DIR/$tfile count=0
20447         $CHECKSTAT -s 0 $DIR/$tfile
20448
20449         restore_lustre_params <$p
20450         rm -f $p
20451         rm $DIR/$tfile
20452 }
20453 run_test 216 "check lockless direct write updates file size and kms correctly"
20454
20455 test_217() { # bug 22430
20456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20457
20458         local node
20459
20460         for node in $(nodes_list); do
20461                 local nid=$(host_nids_address $node $NETTYPE)
20462                 local node_ip=$(do_node $node getent ahostsv4 $node |
20463                                 awk '{ print $1; exit; }')
20464
20465                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20466                 # if hostname matches any NID, use hostname for better testing
20467                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20468                         echo "lctl ping node $node@$NETTYPE"
20469                         lctl ping $node@$NETTYPE
20470                 else # otherwise, at least test 'lctl ping' is working
20471                         echo "lctl ping nid $(h2nettype $nid)"
20472                         lctl ping $(h2nettype $nid)
20473                         echo "skipping $node (no hyphen detected)"
20474                 fi
20475         done
20476 }
20477 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20478
20479 test_218() {
20480         # do directio so as not to populate the page cache
20481         log "creating a 10 Mb file"
20482         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20483                 error "multiop failed while creating a file"
20484         log "starting reads"
20485         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20486         log "truncating the file"
20487         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20488                 error "multiop failed while truncating the file"
20489         log "killing dd"
20490         kill %+ || true # reads might have finished
20491         echo "wait until dd is finished"
20492         wait
20493         log "removing the temporary file"
20494         rm -rf $DIR/$tfile || error "tmp file removal failed"
20495 }
20496 run_test 218 "parallel read and truncate should not deadlock"
20497
20498 test_219() {
20499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20500
20501         # write one partial page
20502         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20503         # set no grant so vvp_io_commit_write will do sync write
20504         $LCTL set_param fail_loc=0x411
20505         # write a full page at the end of file
20506         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20507
20508         $LCTL set_param fail_loc=0
20509         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20510         $LCTL set_param fail_loc=0x411
20511         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20512
20513         # LU-4201
20514         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20515         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20516 }
20517 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20518
20519 test_220() { #LU-325
20520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20521         remote_ost_nodsh && skip "remote OST with nodsh"
20522         remote_mds_nodsh && skip "remote MDS with nodsh"
20523         remote_mgs_nodsh && skip "remote MGS with nodsh"
20524
20525         local OSTIDX=0
20526
20527         # create on MDT0000 so the last_id and next_id are correct
20528         mkdir_on_mdt0 $DIR/$tdir
20529         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20530         OST=${OST%_UUID}
20531
20532         # on the mdt's osc
20533         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20534         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20535                         osp.$mdtosc_proc1.prealloc_last_id)
20536         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20537                         osp.$mdtosc_proc1.prealloc_next_id)
20538
20539         $LFS df -i
20540
20541         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20542         #define OBD_FAIL_OST_ENOINO              0x229
20543         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20544         create_pool $FSNAME.$TESTNAME || return 1
20545         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20546
20547         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20548
20549         MDSOBJS=$((last_id - next_id))
20550         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20551
20552         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20553         echo "OST still has $count kbytes free"
20554
20555         echo "create $MDSOBJS files @next_id..."
20556         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20557
20558         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20559                         osp.$mdtosc_proc1.prealloc_last_id)
20560         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20561                         osp.$mdtosc_proc1.prealloc_next_id)
20562
20563         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20564         $LFS df -i
20565
20566         echo "cleanup..."
20567
20568         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20569         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20570
20571         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20572                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20573         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20574                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20575         echo "unlink $MDSOBJS files @$next_id..."
20576         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20577 }
20578 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20579
20580 test_221() {
20581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20582
20583         dd if=`which date` of=$MOUNT/date oflag=sync
20584         chmod +x $MOUNT/date
20585
20586         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20587         $LCTL set_param fail_loc=0x80001401
20588
20589         $MOUNT/date > /dev/null
20590         rm -f $MOUNT/date
20591 }
20592 run_test 221 "make sure fault and truncate race to not cause OOM"
20593
20594 test_222a () {
20595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20596
20597         rm -rf $DIR/$tdir
20598         test_mkdir $DIR/$tdir
20599         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20600         createmany -o $DIR/$tdir/$tfile 10
20601         cancel_lru_locks mdc
20602         cancel_lru_locks osc
20603         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20604         $LCTL set_param fail_loc=0x31a
20605         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20606         $LCTL set_param fail_loc=0
20607         rm -r $DIR/$tdir
20608 }
20609 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20610
20611 test_222b () {
20612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20613
20614         rm -rf $DIR/$tdir
20615         test_mkdir $DIR/$tdir
20616         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20617         createmany -o $DIR/$tdir/$tfile 10
20618         cancel_lru_locks mdc
20619         cancel_lru_locks osc
20620         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20621         $LCTL set_param fail_loc=0x31a
20622         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20623         $LCTL set_param fail_loc=0
20624 }
20625 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20626
20627 test_223 () {
20628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20629
20630         rm -rf $DIR/$tdir
20631         test_mkdir $DIR/$tdir
20632         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20633         createmany -o $DIR/$tdir/$tfile 10
20634         cancel_lru_locks mdc
20635         cancel_lru_locks osc
20636         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20637         $LCTL set_param fail_loc=0x31b
20638         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20639         $LCTL set_param fail_loc=0
20640         rm -r $DIR/$tdir
20641 }
20642 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20643
20644 test_224a() { # LU-1039, MRP-303
20645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20646         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20647         $LCTL set_param fail_loc=0x508
20648         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20649         $LCTL set_param fail_loc=0
20650         df $DIR
20651 }
20652 run_test 224a "Don't panic on bulk IO failure"
20653
20654 test_224bd_sub() { # LU-1039, MRP-303
20655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20656         local timeout=$1
20657
20658         shift
20659         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20660
20661         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20662
20663         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20664         cancel_lru_locks osc
20665         set_checksums 0
20666         stack_trap "set_checksums $ORIG_CSUM" EXIT
20667         local at_max_saved=0
20668
20669         # adaptive timeouts may prevent seeing the issue
20670         if at_is_enabled; then
20671                 at_max_saved=$(at_max_get mds)
20672                 at_max_set 0 mds client
20673                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20674         fi
20675
20676         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20677         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20678         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20679
20680         do_facet ost1 $LCTL set_param fail_loc=0
20681         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20682         df $DIR
20683 }
20684
20685 test_224b() {
20686         test_224bd_sub 3 error "dd failed"
20687 }
20688 run_test 224b "Don't panic on bulk IO failure"
20689
20690 test_224c() { # LU-6441
20691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20692         remote_mds_nodsh && skip "remote MDS with nodsh"
20693
20694         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20695         save_writethrough $p
20696         set_cache writethrough on
20697
20698         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20699         local at_max=$($LCTL get_param -n at_max)
20700         local timeout=$($LCTL get_param -n timeout)
20701         local test_at="at_max"
20702         local param_at="$FSNAME.sys.at_max"
20703         local test_timeout="timeout"
20704         local param_timeout="$FSNAME.sys.timeout"
20705
20706         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20707
20708         set_persistent_param_and_check client "$test_at" "$param_at" 0
20709         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20710
20711         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20712         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20713         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20714         stack_trap "rm -f $DIR/$tfile"
20715         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20716         sync
20717         do_facet ost1 "$LCTL set_param fail_loc=0"
20718
20719         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20720         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20721                 $timeout
20722
20723         $LCTL set_param -n $pages_per_rpc
20724         restore_lustre_params < $p
20725         rm -f $p
20726 }
20727 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20728
20729 test_224d() { # LU-11169
20730         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20731 }
20732 run_test 224d "Don't corrupt data on bulk IO timeout"
20733
20734 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20735 test_225a () {
20736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20737         if [ -z ${MDSSURVEY} ]; then
20738                 skip_env "mds-survey not found"
20739         fi
20740         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20741                 skip "Need MDS version at least 2.2.51"
20742
20743         local mds=$(facet_host $SINGLEMDS)
20744         local target=$(do_nodes $mds 'lctl dl' |
20745                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20746
20747         local cmd1="file_count=1000 thrhi=4"
20748         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20749         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20750         local cmd="$cmd1 $cmd2 $cmd3"
20751
20752         rm -f ${TMP}/mds_survey*
20753         echo + $cmd
20754         eval $cmd || error "mds-survey with zero-stripe failed"
20755         cat ${TMP}/mds_survey*
20756         rm -f ${TMP}/mds_survey*
20757 }
20758 run_test 225a "Metadata survey sanity with zero-stripe"
20759
20760 test_225b () {
20761         if [ -z ${MDSSURVEY} ]; then
20762                 skip_env "mds-survey not found"
20763         fi
20764         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20765                 skip "Need MDS version at least 2.2.51"
20766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20767         remote_mds_nodsh && skip "remote MDS with nodsh"
20768         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20769                 skip_env "Need to mount OST to test"
20770         fi
20771
20772         local mds=$(facet_host $SINGLEMDS)
20773         local target=$(do_nodes $mds 'lctl dl' |
20774                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20775
20776         local cmd1="file_count=1000 thrhi=4"
20777         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20778         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20779         local cmd="$cmd1 $cmd2 $cmd3"
20780
20781         rm -f ${TMP}/mds_survey*
20782         echo + $cmd
20783         eval $cmd || error "mds-survey with stripe_count failed"
20784         cat ${TMP}/mds_survey*
20785         rm -f ${TMP}/mds_survey*
20786 }
20787 run_test 225b "Metadata survey sanity with stripe_count = 1"
20788
20789 mcreate_path2fid () {
20790         local mode=$1
20791         local major=$2
20792         local minor=$3
20793         local name=$4
20794         local desc=$5
20795         local path=$DIR/$tdir/$name
20796         local fid
20797         local rc
20798         local fid_path
20799
20800         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20801                 error "cannot create $desc"
20802
20803         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20804         rc=$?
20805         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20806
20807         fid_path=$($LFS fid2path $MOUNT $fid)
20808         rc=$?
20809         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20810
20811         [ "$path" == "$fid_path" ] ||
20812                 error "fid2path returned $fid_path, expected $path"
20813
20814         echo "pass with $path and $fid"
20815 }
20816
20817 test_226a () {
20818         rm -rf $DIR/$tdir
20819         mkdir -p $DIR/$tdir
20820
20821         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20822         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20823         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20824         mcreate_path2fid 0040666 0 0 dir "directory"
20825         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20826         mcreate_path2fid 0100666 0 0 file "regular file"
20827         mcreate_path2fid 0120666 0 0 link "symbolic link"
20828         mcreate_path2fid 0140666 0 0 sock "socket"
20829 }
20830 run_test 226a "call path2fid and fid2path on files of all type"
20831
20832 test_226b () {
20833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20834
20835         local MDTIDX=1
20836
20837         rm -rf $DIR/$tdir
20838         mkdir -p $DIR/$tdir
20839         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20840                 error "create remote directory failed"
20841         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20842         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20843                                 "character special file (null)"
20844         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20845                                 "character special file (no device)"
20846         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20847         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20848                                 "block special file (loop)"
20849         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20850         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20851         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20852 }
20853 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20854
20855 test_226c () {
20856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20857         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20858                 skip "Need MDS version at least 2.13.55"
20859
20860         local submnt=/mnt/submnt
20861         local srcfile=/etc/passwd
20862         local dstfile=$submnt/passwd
20863         local path
20864         local fid
20865
20866         rm -rf $DIR/$tdir
20867         rm -rf $submnt
20868         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20869                 error "create remote directory failed"
20870         mkdir -p $submnt || error "create $submnt failed"
20871         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20872                 error "mount $submnt failed"
20873         stack_trap "umount $submnt" EXIT
20874
20875         cp $srcfile $dstfile
20876         fid=$($LFS path2fid $dstfile)
20877         path=$($LFS fid2path $submnt "$fid")
20878         [ "$path" = "$dstfile" ] ||
20879                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20880 }
20881 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20882
20883 test_226e () {
20884         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
20885                 skip "Need client at least version 2.15.56"
20886
20887         # Define filename with 'newline' and a space
20888         local testfile="Test"$'\n'"file 01"
20889         # Define link name with multiple 'newline' and a space
20890         local linkfile="Link"$'\n'"file "$'\n'"01"
20891         # Remove prior hard link
20892         rm -f $DIR/"$linkfile"
20893
20894         # Create file
20895         touch $DIR/"$testfile"
20896         # Create link
20897         ln $DIR/"$testfile" $DIR/"$linkfile"
20898
20899         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
20900                 error "getstripe failed on $DIR/$testfile"
20901
20902         # Call with -0 option
20903         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
20904                 echo "FILE:" | grep -c "FILE:")
20905
20906         # With -0 option the output should be exactly 2 lines.
20907         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
20908 }
20909 run_test 226e "Verify path2fid -0 option with newline and space"
20910
20911 # LU-1299 Executing or running ldd on a truncated executable does not
20912 # cause an out-of-memory condition.
20913 test_227() {
20914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20915         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20916
20917         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20918         chmod +x $MOUNT/date
20919
20920         $MOUNT/date > /dev/null
20921         ldd $MOUNT/date > /dev/null
20922         rm -f $MOUNT/date
20923 }
20924 run_test 227 "running truncated executable does not cause OOM"
20925
20926 # LU-1512 try to reuse idle OI blocks
20927 test_228a() {
20928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20929         remote_mds_nodsh && skip "remote MDS with nodsh"
20930         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20931
20932         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20933         local myDIR=$DIR/$tdir
20934
20935         mkdir -p $myDIR
20936         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20937         $LCTL set_param fail_loc=0x80001002
20938         createmany -o $myDIR/t- 10000
20939         $LCTL set_param fail_loc=0
20940         # The guard is current the largest FID holder
20941         touch $myDIR/guard
20942         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20943                     tr -d '[')
20944         local IDX=$(($SEQ % 64))
20945
20946         do_facet $SINGLEMDS sync
20947         # Make sure journal flushed.
20948         sleep 6
20949         local blk1=$(do_facet $SINGLEMDS \
20950                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20951                      grep Blockcount | awk '{print $4}')
20952
20953         # Remove old files, some OI blocks will become idle.
20954         unlinkmany $myDIR/t- 10000
20955         # Create new files, idle OI blocks should be reused.
20956         createmany -o $myDIR/t- 2000
20957         do_facet $SINGLEMDS sync
20958         # Make sure journal flushed.
20959         sleep 6
20960         local blk2=$(do_facet $SINGLEMDS \
20961                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20962                      grep Blockcount | awk '{print $4}')
20963
20964         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20965 }
20966 run_test 228a "try to reuse idle OI blocks"
20967
20968 test_228b() {
20969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20970         remote_mds_nodsh && skip "remote MDS with nodsh"
20971         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20972
20973         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20974         local myDIR=$DIR/$tdir
20975
20976         mkdir -p $myDIR
20977         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20978         $LCTL set_param fail_loc=0x80001002
20979         createmany -o $myDIR/t- 10000
20980         $LCTL set_param fail_loc=0
20981         # The guard is current the largest FID holder
20982         touch $myDIR/guard
20983         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20984                     tr -d '[')
20985         local IDX=$(($SEQ % 64))
20986
20987         do_facet $SINGLEMDS sync
20988         # Make sure journal flushed.
20989         sleep 6
20990         local blk1=$(do_facet $SINGLEMDS \
20991                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20992                      grep Blockcount | awk '{print $4}')
20993
20994         # Remove old files, some OI blocks will become idle.
20995         unlinkmany $myDIR/t- 10000
20996
20997         # stop the MDT
20998         stop $SINGLEMDS || error "Fail to stop MDT."
20999         # remount the MDT
21000         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21001                 error "Fail to start MDT."
21002
21003         client_up || error "Fail to df."
21004         # Create new files, idle OI blocks should be reused.
21005         createmany -o $myDIR/t- 2000
21006         do_facet $SINGLEMDS sync
21007         # Make sure journal flushed.
21008         sleep 6
21009         local blk2=$(do_facet $SINGLEMDS \
21010                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21011                      grep Blockcount | awk '{print $4}')
21012
21013         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21014 }
21015 run_test 228b "idle OI blocks can be reused after MDT restart"
21016
21017 #LU-1881
21018 test_228c() {
21019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21020         remote_mds_nodsh && skip "remote MDS with nodsh"
21021         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21022
21023         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21024         local myDIR=$DIR/$tdir
21025
21026         mkdir -p $myDIR
21027         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21028         $LCTL set_param fail_loc=0x80001002
21029         # 20000 files can guarantee there are index nodes in the OI file
21030         createmany -o $myDIR/t- 20000
21031         $LCTL set_param fail_loc=0
21032         # The guard is current the largest FID holder
21033         touch $myDIR/guard
21034         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21035                     tr -d '[')
21036         local IDX=$(($SEQ % 64))
21037
21038         do_facet $SINGLEMDS sync
21039         # Make sure journal flushed.
21040         sleep 6
21041         local blk1=$(do_facet $SINGLEMDS \
21042                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21043                      grep Blockcount | awk '{print $4}')
21044
21045         # Remove old files, some OI blocks will become idle.
21046         unlinkmany $myDIR/t- 20000
21047         rm -f $myDIR/guard
21048         # The OI file should become empty now
21049
21050         # Create new files, idle OI blocks should be reused.
21051         createmany -o $myDIR/t- 2000
21052         do_facet $SINGLEMDS sync
21053         # Make sure journal flushed.
21054         sleep 6
21055         local blk2=$(do_facet $SINGLEMDS \
21056                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21057                      grep Blockcount | awk '{print $4}')
21058
21059         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21060 }
21061 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21062
21063 test_229() { # LU-2482, LU-3448
21064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21065         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21066         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21067                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21068
21069         rm -f $DIR/$tfile
21070
21071         # Create a file with a released layout and stripe count 2.
21072         $MULTIOP $DIR/$tfile H2c ||
21073                 error "failed to create file with released layout"
21074
21075         $LFS getstripe -v $DIR/$tfile
21076
21077         local pattern=$($LFS getstripe -L $DIR/$tfile)
21078         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21079
21080         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21081                 error "getstripe"
21082         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21083         stat $DIR/$tfile || error "failed to stat released file"
21084
21085         chown $RUNAS_ID $DIR/$tfile ||
21086                 error "chown $RUNAS_ID $DIR/$tfile failed"
21087
21088         chgrp $RUNAS_ID $DIR/$tfile ||
21089                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21090
21091         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21092         rm $DIR/$tfile || error "failed to remove released file"
21093 }
21094 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21095
21096 test_230a() {
21097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21098         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21099         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21100                 skip "Need MDS version at least 2.11.52"
21101
21102         local MDTIDX=1
21103
21104         test_mkdir $DIR/$tdir
21105         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21106         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21107         [ $mdt_idx -ne 0 ] &&
21108                 error "create local directory on wrong MDT $mdt_idx"
21109
21110         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21111                         error "create remote directory failed"
21112         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21113         [ $mdt_idx -ne $MDTIDX ] &&
21114                 error "create remote directory on wrong MDT $mdt_idx"
21115
21116         createmany -o $DIR/$tdir/test_230/t- 10 ||
21117                 error "create files on remote directory failed"
21118         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21119         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21120         rm -r $DIR/$tdir || error "unlink remote directory failed"
21121 }
21122 run_test 230a "Create remote directory and files under the remote directory"
21123
21124 test_230b() {
21125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21126         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21127         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21128                 skip "Need MDS version at least 2.11.52"
21129
21130         local MDTIDX=1
21131         local mdt_index
21132         local i
21133         local file
21134         local pid
21135         local stripe_count
21136         local migrate_dir=$DIR/$tdir/migrate_dir
21137         local other_dir=$DIR/$tdir/other_dir
21138
21139         test_mkdir $DIR/$tdir
21140         test_mkdir -i0 -c1 $migrate_dir
21141         test_mkdir -i0 -c1 $other_dir
21142         for ((i=0; i<10; i++)); do
21143                 mkdir -p $migrate_dir/dir_${i}
21144                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21145                         error "create files under remote dir failed $i"
21146         done
21147
21148         cp /etc/passwd $migrate_dir/$tfile
21149         cp /etc/passwd $other_dir/$tfile
21150         chattr +SAD $migrate_dir
21151         chattr +SAD $migrate_dir/$tfile
21152
21153         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21154         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21155         local old_dir_mode=$(stat -c%f $migrate_dir)
21156         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21157
21158         mkdir -p $migrate_dir/dir_default_stripe2
21159         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21160         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21161
21162         mkdir -p $other_dir
21163         ln $migrate_dir/$tfile $other_dir/luna
21164         ln $migrate_dir/$tfile $migrate_dir/sofia
21165         ln $other_dir/$tfile $migrate_dir/david
21166         ln -s $migrate_dir/$tfile $other_dir/zachary
21167         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21168         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21169
21170         local len
21171         local lnktgt
21172
21173         # inline symlink
21174         for len in 58 59 60; do
21175                 lnktgt=$(str_repeat 'l' $len)
21176                 touch $migrate_dir/$lnktgt
21177                 ln -s $lnktgt $migrate_dir/${len}char_ln
21178         done
21179
21180         # PATH_MAX
21181         for len in 4094 4095; do
21182                 lnktgt=$(str_repeat 'l' $len)
21183                 ln -s $lnktgt $migrate_dir/${len}char_ln
21184         done
21185
21186         # NAME_MAX
21187         for len in 254 255; do
21188                 touch $migrate_dir/$(str_repeat 'l' $len)
21189         done
21190
21191         $LFS migrate -m $MDTIDX $migrate_dir ||
21192                 error "fails on migrating remote dir to MDT1"
21193
21194         echo "migratate to MDT1, then checking.."
21195         for ((i = 0; i < 10; i++)); do
21196                 for file in $(find $migrate_dir/dir_${i}); do
21197                         mdt_index=$($LFS getstripe -m $file)
21198                         # broken symlink getstripe will fail
21199                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21200                                 error "$file is not on MDT${MDTIDX}"
21201                 done
21202         done
21203
21204         # the multiple link file should still in MDT0
21205         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21206         [ $mdt_index == 0 ] ||
21207                 error "$file is not on MDT${MDTIDX}"
21208
21209         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21210         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21211                 error " expect $old_dir_flag get $new_dir_flag"
21212
21213         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21214         [ "$old_file_flag" = "$new_file_flag" ] ||
21215                 error " expect $old_file_flag get $new_file_flag"
21216
21217         local new_dir_mode=$(stat -c%f $migrate_dir)
21218         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21219                 error "expect mode $old_dir_mode get $new_dir_mode"
21220
21221         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21222         [ "$old_file_mode" = "$new_file_mode" ] ||
21223                 error "expect mode $old_file_mode get $new_file_mode"
21224
21225         diff /etc/passwd $migrate_dir/$tfile ||
21226                 error "$tfile different after migration"
21227
21228         diff /etc/passwd $other_dir/luna ||
21229                 error "luna different after migration"
21230
21231         diff /etc/passwd $migrate_dir/sofia ||
21232                 error "sofia different after migration"
21233
21234         diff /etc/passwd $migrate_dir/david ||
21235                 error "david different after migration"
21236
21237         diff /etc/passwd $other_dir/zachary ||
21238                 error "zachary different after migration"
21239
21240         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21241                 error "${tfile}_ln different after migration"
21242
21243         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21244                 error "${tfile}_ln_other different after migration"
21245
21246         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21247         [ $stripe_count = 2 ] ||
21248                 error "dir strpe_count $d != 2 after migration."
21249
21250         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21251         [ $stripe_count = 2 ] ||
21252                 error "file strpe_count $d != 2 after migration."
21253
21254         #migrate back to MDT0
21255         MDTIDX=0
21256
21257         $LFS migrate -m $MDTIDX $migrate_dir ||
21258                 error "fails on migrating remote dir to MDT0"
21259
21260         echo "migrate back to MDT0, checking.."
21261         for file in $(find $migrate_dir); do
21262                 mdt_index=$($LFS getstripe -m $file)
21263                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21264                         error "$file is not on MDT${MDTIDX}"
21265         done
21266
21267         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21268         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21269                 error " expect $old_dir_flag get $new_dir_flag"
21270
21271         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21272         [ "$old_file_flag" = "$new_file_flag" ] ||
21273                 error " expect $old_file_flag get $new_file_flag"
21274
21275         local new_dir_mode=$(stat -c%f $migrate_dir)
21276         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21277                 error "expect mode $old_dir_mode get $new_dir_mode"
21278
21279         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21280         [ "$old_file_mode" = "$new_file_mode" ] ||
21281                 error "expect mode $old_file_mode get $new_file_mode"
21282
21283         diff /etc/passwd ${migrate_dir}/$tfile ||
21284                 error "$tfile different after migration"
21285
21286         diff /etc/passwd ${other_dir}/luna ||
21287                 error "luna different after migration"
21288
21289         diff /etc/passwd ${migrate_dir}/sofia ||
21290                 error "sofia different after migration"
21291
21292         diff /etc/passwd ${other_dir}/zachary ||
21293                 error "zachary different after migration"
21294
21295         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21296                 error "${tfile}_ln different after migration"
21297
21298         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21299                 error "${tfile}_ln_other different after migration"
21300
21301         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21302         [ $stripe_count = 2 ] ||
21303                 error "dir strpe_count $d != 2 after migration."
21304
21305         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21306         [ $stripe_count = 2 ] ||
21307                 error "file strpe_count $d != 2 after migration."
21308
21309         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21310 }
21311 run_test 230b "migrate directory"
21312
21313 test_230c() {
21314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21315         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21316         remote_mds_nodsh && skip "remote MDS with nodsh"
21317         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21318                 skip "Need MDS version at least 2.11.52"
21319
21320         local MDTIDX=1
21321         local total=3
21322         local mdt_index
21323         local file
21324         local migrate_dir=$DIR/$tdir/migrate_dir
21325
21326         #If migrating directory fails in the middle, all entries of
21327         #the directory is still accessiable.
21328         test_mkdir $DIR/$tdir
21329         test_mkdir -i0 -c1 $migrate_dir
21330         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21331         stat $migrate_dir
21332         createmany -o $migrate_dir/f $total ||
21333                 error "create files under ${migrate_dir} failed"
21334
21335         # fail after migrating top dir, and this will fail only once, so the
21336         # first sub file migration will fail (currently f3), others succeed.
21337         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21338         do_facet mds1 lctl set_param fail_loc=0x1801
21339         local t=$(ls $migrate_dir | wc -l)
21340         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21341                 error "migrate should fail"
21342         local u=$(ls $migrate_dir | wc -l)
21343         [ "$u" == "$t" ] || error "$u != $t during migration"
21344
21345         # add new dir/file should succeed
21346         mkdir $migrate_dir/dir ||
21347                 error "mkdir failed under migrating directory"
21348         touch $migrate_dir/file ||
21349                 error "create file failed under migrating directory"
21350
21351         # add file with existing name should fail
21352         for file in $migrate_dir/f*; do
21353                 stat $file > /dev/null || error "stat $file failed"
21354                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21355                         error "open(O_CREAT|O_EXCL) $file should fail"
21356                 $MULTIOP $file m && error "create $file should fail"
21357                 touch $DIR/$tdir/remote_dir/$tfile ||
21358                         error "touch $tfile failed"
21359                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21360                         error "link $file should fail"
21361                 mdt_index=$($LFS getstripe -m $file)
21362                 if [ $mdt_index == 0 ]; then
21363                         # file failed to migrate is not allowed to rename to
21364                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21365                                 error "rename to $file should fail"
21366                 else
21367                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21368                                 error "rename to $file failed"
21369                 fi
21370                 echo hello >> $file || error "write $file failed"
21371         done
21372
21373         # resume migration with different options should fail
21374         $LFS migrate -m 0 $migrate_dir &&
21375                 error "migrate -m 0 $migrate_dir should fail"
21376
21377         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21378                 error "migrate -c 2 $migrate_dir should fail"
21379
21380         # resume migration should succeed
21381         $LFS migrate -m $MDTIDX $migrate_dir ||
21382                 error "migrate $migrate_dir failed"
21383
21384         echo "Finish migration, then checking.."
21385         for file in $(find $migrate_dir); do
21386                 mdt_index=$($LFS getstripe -m $file)
21387                 [ $mdt_index == $MDTIDX ] ||
21388                         error "$file is not on MDT${MDTIDX}"
21389         done
21390
21391         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21392 }
21393 run_test 230c "check directory accessiblity if migration failed"
21394
21395 test_230d() {
21396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21398         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21399                 skip "Need MDS version at least 2.11.52"
21400         # LU-11235
21401         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21402
21403         local migrate_dir=$DIR/$tdir/migrate_dir
21404         local old_index
21405         local new_index
21406         local old_count
21407         local new_count
21408         local new_hash
21409         local mdt_index
21410         local i
21411         local j
21412
21413         old_index=$((RANDOM % MDSCOUNT))
21414         old_count=$((MDSCOUNT - old_index))
21415         new_index=$((RANDOM % MDSCOUNT))
21416         new_count=$((MDSCOUNT - new_index))
21417         new_hash=1 # for all_char
21418
21419         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21420         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21421
21422         test_mkdir $DIR/$tdir
21423         test_mkdir -i $old_index -c $old_count $migrate_dir
21424
21425         for ((i=0; i<100; i++)); do
21426                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21427                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21428                         error "create files under remote dir failed $i"
21429         done
21430
21431         echo -n "Migrate from MDT$old_index "
21432         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21433         echo -n "to MDT$new_index"
21434         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21435         echo
21436
21437         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21438         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21439                 error "migrate remote dir error"
21440
21441         echo "Finish migration, then checking.."
21442         for file in $(find $migrate_dir -maxdepth 1); do
21443                 mdt_index=$($LFS getstripe -m $file)
21444                 if [ $mdt_index -lt $new_index ] ||
21445                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21446                         error "$file is on MDT$mdt_index"
21447                 fi
21448         done
21449
21450         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21451 }
21452 run_test 230d "check migrate big directory"
21453
21454 test_230e() {
21455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21456         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21457         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21458                 skip "Need MDS version at least 2.11.52"
21459
21460         local i
21461         local j
21462         local a_fid
21463         local b_fid
21464
21465         mkdir_on_mdt0 $DIR/$tdir
21466         mkdir $DIR/$tdir/migrate_dir
21467         mkdir $DIR/$tdir/other_dir
21468         touch $DIR/$tdir/migrate_dir/a
21469         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21470         ls $DIR/$tdir/other_dir
21471
21472         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21473                 error "migrate dir fails"
21474
21475         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21476         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21477
21478         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21479         [ $mdt_index == 0 ] || error "a is not on MDT0"
21480
21481         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21482                 error "migrate dir fails"
21483
21484         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21485         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21486
21487         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21488         [ $mdt_index == 1 ] || error "a is not on MDT1"
21489
21490         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21491         [ $mdt_index == 1 ] || error "b is not on MDT1"
21492
21493         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21494         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21495
21496         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21497
21498         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21499 }
21500 run_test 230e "migrate mulitple local link files"
21501
21502 test_230f() {
21503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21505         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21506                 skip "Need MDS version at least 2.11.52"
21507
21508         local a_fid
21509         local ln_fid
21510
21511         mkdir -p $DIR/$tdir
21512         mkdir $DIR/$tdir/migrate_dir
21513         $LFS mkdir -i1 $DIR/$tdir/other_dir
21514         touch $DIR/$tdir/migrate_dir/a
21515         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21516         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21517         ls $DIR/$tdir/other_dir
21518
21519         # a should be migrated to MDT1, since no other links on MDT0
21520         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21521                 error "#1 migrate dir fails"
21522         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21523         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21524         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21525         [ $mdt_index == 1 ] || error "a is not on MDT1"
21526
21527         # a should stay on MDT1, because it is a mulitple link file
21528         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21529                 error "#2 migrate dir fails"
21530         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21531         [ $mdt_index == 1 ] || error "a is not on MDT1"
21532
21533         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21534                 error "#3 migrate dir fails"
21535
21536         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21537         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21538         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21539
21540         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21541         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21542
21543         # a should be migrated to MDT0, since no other links on MDT1
21544         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21545                 error "#4 migrate dir fails"
21546         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21547         [ $mdt_index == 0 ] || error "a is not on MDT0"
21548
21549         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21550 }
21551 run_test 230f "migrate mulitple remote link files"
21552
21553 test_230g() {
21554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21555         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21556         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21557                 skip "Need MDS version at least 2.11.52"
21558
21559         mkdir -p $DIR/$tdir/migrate_dir
21560
21561         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21562                 error "migrating dir to non-exist MDT succeeds"
21563         true
21564 }
21565 run_test 230g "migrate dir to non-exist MDT"
21566
21567 test_230h() {
21568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21569         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21570         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21571                 skip "Need MDS version at least 2.11.52"
21572
21573         local mdt_index
21574
21575         mkdir -p $DIR/$tdir/migrate_dir
21576
21577         $LFS migrate -m1 $DIR &&
21578                 error "migrating mountpoint1 should fail"
21579
21580         $LFS migrate -m1 $DIR/$tdir/.. &&
21581                 error "migrating mountpoint2 should fail"
21582
21583         # same as mv
21584         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21585                 error "migrating $tdir/migrate_dir/.. should fail"
21586
21587         true
21588 }
21589 run_test 230h "migrate .. and root"
21590
21591 test_230i() {
21592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21594         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21595                 skip "Need MDS version at least 2.11.52"
21596
21597         mkdir -p $DIR/$tdir/migrate_dir
21598
21599         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21600                 error "migration fails with a tailing slash"
21601
21602         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21603                 error "migration fails with two tailing slashes"
21604 }
21605 run_test 230i "lfs migrate -m tolerates trailing slashes"
21606
21607 test_230j() {
21608         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21609         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21610                 skip "Need MDS version at least 2.11.52"
21611
21612         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21613         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21614                 error "create $tfile failed"
21615         cat /etc/passwd > $DIR/$tdir/$tfile
21616
21617         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21618
21619         cmp /etc/passwd $DIR/$tdir/$tfile ||
21620                 error "DoM file mismatch after migration"
21621 }
21622 run_test 230j "DoM file data not changed after dir migration"
21623
21624 test_230k() {
21625         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21626         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21627                 skip "Need MDS version at least 2.11.56"
21628
21629         local total=20
21630         local files_on_starting_mdt=0
21631
21632         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21633         $LFS getdirstripe $DIR/$tdir
21634         for i in $(seq $total); do
21635                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21636                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21637                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21638         done
21639
21640         echo "$files_on_starting_mdt files on MDT0"
21641
21642         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21643         $LFS getdirstripe $DIR/$tdir
21644
21645         files_on_starting_mdt=0
21646         for i in $(seq $total); do
21647                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21648                         error "file $tfile.$i mismatch after migration"
21649                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21650                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21651         done
21652
21653         echo "$files_on_starting_mdt files on MDT1 after migration"
21654         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21655
21656         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21657         $LFS getdirstripe $DIR/$tdir
21658
21659         files_on_starting_mdt=0
21660         for i in $(seq $total); do
21661                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21662                         error "file $tfile.$i mismatch after 2nd migration"
21663                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21664                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21665         done
21666
21667         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21668         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21669
21670         true
21671 }
21672 run_test 230k "file data not changed after dir migration"
21673
21674 test_230l() {
21675         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21676         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21677                 skip "Need MDS version at least 2.11.56"
21678
21679         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21680         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21681                 error "create files under remote dir failed $i"
21682         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21683 }
21684 run_test 230l "readdir between MDTs won't crash"
21685
21686 test_230m() {
21687         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21688         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21689                 skip "Need MDS version at least 2.11.56"
21690
21691         local MDTIDX=1
21692         local mig_dir=$DIR/$tdir/migrate_dir
21693         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21694         local shortstr="b"
21695         local val
21696
21697         echo "Creating files and dirs with xattrs"
21698         test_mkdir $DIR/$tdir
21699         test_mkdir -i0 -c1 $mig_dir
21700         mkdir $mig_dir/dir
21701         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21702                 error "cannot set xattr attr1 on dir"
21703         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21704                 error "cannot set xattr attr2 on dir"
21705         touch $mig_dir/dir/f0
21706         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21707                 error "cannot set xattr attr1 on file"
21708         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21709                 error "cannot set xattr attr2 on file"
21710         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21711         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21712         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21713         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21714         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21715         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21716         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21717         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21718         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21719
21720         echo "Migrating to MDT1"
21721         $LFS migrate -m $MDTIDX $mig_dir ||
21722                 error "fails on migrating dir to MDT1"
21723
21724         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21725         echo "Checking xattrs"
21726         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21727         [ "$val" = $longstr ] ||
21728                 error "expecting xattr1 $longstr on dir, found $val"
21729         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21730         [ "$val" = $shortstr ] ||
21731                 error "expecting xattr2 $shortstr on dir, found $val"
21732         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21733         [ "$val" = $longstr ] ||
21734                 error "expecting xattr1 $longstr on file, found $val"
21735         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21736         [ "$val" = $shortstr ] ||
21737                 error "expecting xattr2 $shortstr on file, found $val"
21738 }
21739 run_test 230m "xattrs not changed after dir migration"
21740
21741 test_230n() {
21742         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21743         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21744                 skip "Need MDS version at least 2.13.53"
21745
21746         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21747         cat /etc/hosts > $DIR/$tdir/$tfile
21748         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21749         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21750
21751         cmp /etc/hosts $DIR/$tdir/$tfile ||
21752                 error "File data mismatch after migration"
21753 }
21754 run_test 230n "Dir migration with mirrored file"
21755
21756 test_230o() {
21757         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21758         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21759                 skip "Need MDS version at least 2.13.52"
21760
21761         local mdts=$(comma_list $(mdts_nodes))
21762         local timeout=100
21763         local restripe_status
21764         local delta
21765         local i
21766
21767         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21768
21769         # in case "crush" hash type is not set
21770         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21771
21772         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21773                            mdt.*MDT0000.enable_dir_restripe)
21774         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21775         stack_trap "do_nodes $mdts $LCTL set_param \
21776                     mdt.*.enable_dir_restripe=$restripe_status"
21777
21778         mkdir $DIR/$tdir
21779         createmany -m $DIR/$tdir/f 100 ||
21780                 error "create files under remote dir failed $i"
21781         createmany -d $DIR/$tdir/d 100 ||
21782                 error "create dirs under remote dir failed $i"
21783
21784         for i in $(seq 2 $MDSCOUNT); do
21785                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21786                 $LFS setdirstripe -c $i $DIR/$tdir ||
21787                         error "split -c $i $tdir failed"
21788                 wait_update $HOSTNAME \
21789                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21790                         error "dir split not finished"
21791                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21792                         awk '/migrate/ {sum += $2} END { print sum }')
21793                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21794                 # delta is around total_files/stripe_count
21795                 (( $delta < 200 / (i - 1) + 4 )) ||
21796                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21797         done
21798 }
21799 run_test 230o "dir split"
21800
21801 test_230p() {
21802         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21803         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21804                 skip "Need MDS version at least 2.13.52"
21805
21806         local mdts=$(comma_list $(mdts_nodes))
21807         local timeout=100
21808         local restripe_status
21809         local delta
21810         local c
21811
21812         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21813
21814         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21815
21816         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21817                            mdt.*MDT0000.enable_dir_restripe)
21818         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21819         stack_trap "do_nodes $mdts $LCTL set_param \
21820                     mdt.*.enable_dir_restripe=$restripe_status"
21821
21822         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21823         createmany -m $DIR/$tdir/f 100 ||
21824                 error "create files under remote dir failed"
21825         createmany -d $DIR/$tdir/d 100 ||
21826                 error "create dirs under remote dir failed"
21827
21828         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21829                 local mdt_hash="crush"
21830
21831                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21832                 $LFS setdirstripe -c $c $DIR/$tdir ||
21833                         error "split -c $c $tdir failed"
21834                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21835                         mdt_hash="$mdt_hash,fixed"
21836                 elif [ $c -eq 1 ]; then
21837                         mdt_hash="none"
21838                 fi
21839                 wait_update $HOSTNAME \
21840                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21841                         error "dir merge not finished"
21842                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21843                         awk '/migrate/ {sum += $2} END { print sum }')
21844                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21845                 # delta is around total_files/stripe_count
21846                 (( delta < 200 / c + 4 )) ||
21847                         error "$delta files migrated >= $((200 / c + 4))"
21848         done
21849 }
21850 run_test 230p "dir merge"
21851
21852 test_230q() {
21853         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21854         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21855                 skip "Need MDS version at least 2.13.52"
21856
21857         local mdts=$(comma_list $(mdts_nodes))
21858         local saved_threshold=$(do_facet mds1 \
21859                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21860         local saved_delta=$(do_facet mds1 \
21861                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21862         local threshold=100
21863         local delta=2
21864         local total=0
21865         local stripe_count=0
21866         local stripe_index
21867         local nr_files
21868         local create
21869
21870         # test with fewer files on ZFS
21871         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21872
21873         stack_trap "do_nodes $mdts $LCTL set_param \
21874                     mdt.*.dir_split_count=$saved_threshold"
21875         stack_trap "do_nodes $mdts $LCTL set_param \
21876                     mdt.*.dir_split_delta=$saved_delta"
21877         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21878         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21879         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21880         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21881         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21882         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21883
21884         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21885         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21886
21887         create=$((threshold * 3 / 2))
21888         while [ $stripe_count -lt $MDSCOUNT ]; do
21889                 createmany -m $DIR/$tdir/f $total $create ||
21890                         error "create sub files failed"
21891                 stat $DIR/$tdir > /dev/null
21892                 total=$((total + create))
21893                 stripe_count=$((stripe_count + delta))
21894                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21895
21896                 wait_update $HOSTNAME \
21897                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21898                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21899
21900                 wait_update $HOSTNAME \
21901                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21902                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21903
21904                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21905                 echo "$nr_files/$total files on MDT$stripe_index after split"
21906                 # allow 10% margin of imbalance with crush hash
21907                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21908                         error "$nr_files files on MDT$stripe_index after split"
21909
21910                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21911                 [ $nr_files -eq $total ] ||
21912                         error "total sub files $nr_files != $total"
21913         done
21914
21915         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21916
21917         echo "fixed layout directory won't auto split"
21918         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21919         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21920                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21921         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21922                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21923 }
21924 run_test 230q "dir auto split"
21925
21926 test_230r() {
21927         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21928         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21929         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21930                 skip "Need MDS version at least 2.13.54"
21931
21932         # maximum amount of local locks:
21933         # parent striped dir - 2 locks
21934         # new stripe in parent to migrate to - 1 lock
21935         # source and target - 2 locks
21936         # Total 5 locks for regular file
21937         mkdir -p $DIR/$tdir
21938         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21939         touch $DIR/$tdir/dir1/eee
21940
21941         # create 4 hardlink for 4 more locks
21942         # Total: 9 locks > RS_MAX_LOCKS (8)
21943         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21944         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21945         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21946         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21947         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21948         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21949         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21950         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21951
21952         cancel_lru_locks mdc
21953
21954         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21955                 error "migrate dir fails"
21956
21957         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21958 }
21959 run_test 230r "migrate with too many local locks"
21960
21961 test_230s() {
21962         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21963                 skip "Need MDS version at least 2.14.52"
21964
21965         local mdts=$(comma_list $(mdts_nodes))
21966         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21967                                 mdt.*MDT0000.enable_dir_restripe)
21968
21969         stack_trap "do_nodes $mdts $LCTL set_param \
21970                     mdt.*.enable_dir_restripe=$restripe_status"
21971
21972         local st
21973         for st in 0 1; do
21974                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21975                 test_mkdir $DIR/$tdir
21976                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21977                         error "$LFS mkdir should return EEXIST if target exists"
21978                 rmdir $DIR/$tdir
21979         done
21980 }
21981 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21982
21983 test_230t()
21984 {
21985         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21986         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21987                 skip "Need MDS version at least 2.14.50"
21988
21989         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21990         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21991         $LFS project -p 1 -s $DIR/$tdir ||
21992                 error "set $tdir project id failed"
21993         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21994                 error "set subdir project id failed"
21995         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21996 }
21997 run_test 230t "migrate directory with project ID set"
21998
21999 test_230u()
22000 {
22001         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22002         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22003                 skip "Need MDS version at least 2.14.53"
22004
22005         local count
22006
22007         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22008         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22009         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22010         for i in $(seq 0 $((MDSCOUNT - 1))); do
22011                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22012                 echo "$count dirs migrated to MDT$i"
22013         done
22014         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22015         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22016 }
22017 run_test 230u "migrate directory by QOS"
22018
22019 test_230v()
22020 {
22021         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22022         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22023                 skip "Need MDS version at least 2.14.53"
22024
22025         local count
22026
22027         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22028         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22029         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22030         for i in $(seq 0 $((MDSCOUNT - 1))); do
22031                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22032                 echo "$count subdirs migrated to MDT$i"
22033                 (( i == 3 )) && (( count > 0 )) &&
22034                         error "subdir shouldn't be migrated to MDT3"
22035         done
22036         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22037         (( count == 3 )) || error "dirs migrated to $count MDTs"
22038 }
22039 run_test 230v "subdir migrated to the MDT where its parent is located"
22040
22041 test_230w() {
22042         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22043         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22044                 skip "Need MDS version at least 2.15.0"
22045
22046         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22047         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22048         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22049
22050         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22051                 error "migrate failed"
22052
22053         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22054                 error "$tdir stripe count mismatch"
22055
22056         for i in $(seq 0 9); do
22057                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22058                         error "d$i is striped"
22059         done
22060 }
22061 run_test 230w "non-recursive mode dir migration"
22062
22063 test_230x() {
22064         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22065         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22066                 skip "Need MDS version at least 2.15.0"
22067
22068         mkdir -p $DIR/$tdir || error "mkdir failed"
22069         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22070
22071         local mdt_name=$(mdtname_from_index 0)
22072         local low=$(do_facet mds2 $LCTL get_param -n \
22073                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22074         local high=$(do_facet mds2 $LCTL get_param -n \
22075                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22076         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22077         local maxage=$(do_facet mds2 $LCTL get_param -n \
22078                 osp.*$mdt_name-osp-MDT0001.maxage)
22079
22080         stack_trap "do_facet mds2 $LCTL set_param -n \
22081                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22082                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22083         stack_trap "do_facet mds2 $LCTL set_param -n \
22084                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22085
22086         do_facet mds2 $LCTL set_param -n \
22087                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22088         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22089         sleep 4
22090         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22091                 error "migrate $tdir should fail"
22092
22093         do_facet mds2 $LCTL set_param -n \
22094                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22095         do_facet mds2 $LCTL set_param -n \
22096                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22097         sleep 4
22098         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22099                 error "migrate failed"
22100         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22101                 error "$tdir stripe count mismatch"
22102 }
22103 run_test 230x "dir migration check space"
22104
22105 test_230y() {
22106         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22107         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22108                 skip "Need MDS version at least 2.15.55.45"
22109
22110         local pid
22111
22112         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22113         $LFS getdirstripe $DIR/$tdir
22114         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22115         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22116         pid=$!
22117         sleep 1
22118
22119         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22120         do_facet mds2 lctl set_param fail_loc=0x1802
22121
22122         wait $pid
22123         do_facet mds2 lctl set_param fail_loc=0
22124         $LFS getdirstripe $DIR/$tdir
22125         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22126         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22127 }
22128 run_test 230y "unlink dir with bad hash type"
22129
22130 test_230z() {
22131         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22132         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22133                 skip "Need MDS version at least 2.15.55.45"
22134
22135         local pid
22136
22137         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22138         $LFS getdirstripe $DIR/$tdir
22139         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22140         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22141         pid=$!
22142         sleep 1
22143
22144         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22145         do_facet mds2 lctl set_param fail_loc=0x1802
22146
22147         wait $pid
22148         do_facet mds2 lctl set_param fail_loc=0
22149         $LFS getdirstripe $DIR/$tdir
22150
22151         # resume migration
22152         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22153                 error "resume migration failed"
22154         $LFS getdirstripe $DIR/$tdir
22155         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22156                 error "migration is not finished"
22157 }
22158 run_test 230z "resume dir migration with bad hash type"
22159
22160 test_231a()
22161 {
22162         # For simplicity this test assumes that max_pages_per_rpc
22163         # is the same across all OSCs
22164         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22165         local bulk_size=$((max_pages * PAGE_SIZE))
22166         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22167                                        head -n 1)
22168
22169         mkdir -p $DIR/$tdir
22170         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22171                 error "failed to set stripe with -S ${brw_size}M option"
22172         stack_trap "rm -rf $DIR/$tdir"
22173
22174         # clear the OSC stats
22175         $LCTL set_param osc.*.stats=0 &>/dev/null
22176         stop_writeback
22177
22178         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22179         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22180                 oflag=direct &>/dev/null || error "dd failed"
22181
22182         sync; sleep 1; sync # just to be safe
22183         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22184         if [ x$nrpcs != "x1" ]; then
22185                 $LCTL get_param osc.*.stats
22186                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22187         fi
22188
22189         start_writeback
22190         # Drop the OSC cache, otherwise we will read from it
22191         cancel_lru_locks osc
22192
22193         # clear the OSC stats
22194         $LCTL set_param osc.*.stats=0 &>/dev/null
22195
22196         # Client reads $bulk_size.
22197         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22198                 iflag=direct &>/dev/null || error "dd failed"
22199
22200         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22201         if [ x$nrpcs != "x1" ]; then
22202                 $LCTL get_param osc.*.stats
22203                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22204         fi
22205 }
22206 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22207
22208 test_231b() {
22209         mkdir -p $DIR/$tdir
22210         stack_trap "rm -rf $DIR/$tdir"
22211         local i
22212         for i in {0..1023}; do
22213                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22214                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22215                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22216         done
22217         sync
22218 }
22219 run_test 231b "must not assert on fully utilized OST request buffer"
22220
22221 test_232a() {
22222         mkdir -p $DIR/$tdir
22223         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22224
22225         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22226         do_facet ost1 $LCTL set_param fail_loc=0x31c
22227
22228         # ignore dd failure
22229         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22230         stack_trap "rm -f $DIR/$tdir/$tfile"
22231
22232         do_facet ost1 $LCTL set_param fail_loc=0
22233         umount_client $MOUNT || error "umount failed"
22234         mount_client $MOUNT || error "mount failed"
22235         stop ost1 || error "cannot stop ost1"
22236         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22237 }
22238 run_test 232a "failed lock should not block umount"
22239
22240 test_232b() {
22241         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22242                 skip "Need MDS version at least 2.10.58"
22243
22244         mkdir -p $DIR/$tdir
22245         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22246         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22247         stack_trap "rm -f $DIR/$tdir/$tfile"
22248         sync
22249         cancel_lru_locks osc
22250
22251         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22252         do_facet ost1 $LCTL set_param fail_loc=0x31c
22253
22254         # ignore failure
22255         $LFS data_version $DIR/$tdir/$tfile || true
22256
22257         do_facet ost1 $LCTL set_param fail_loc=0
22258         umount_client $MOUNT || error "umount failed"
22259         mount_client $MOUNT || error "mount failed"
22260         stop ost1 || error "cannot stop ost1"
22261         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22262 }
22263 run_test 232b "failed data version lock should not block umount"
22264
22265 test_233a() {
22266         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22267                 skip "Need MDS version at least 2.3.64"
22268         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22269
22270         local fid=$($LFS path2fid $MOUNT)
22271
22272         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22273                 error "cannot access $MOUNT using its FID '$fid'"
22274 }
22275 run_test 233a "checking that OBF of the FS root succeeds"
22276
22277 test_233b() {
22278         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22279                 skip "Need MDS version at least 2.5.90"
22280         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22281
22282         local fid=$($LFS path2fid $MOUNT/.lustre)
22283
22284         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22285                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22286
22287         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22288         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22289                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22290 }
22291 run_test 233b "checking that OBF of the FS .lustre succeeds"
22292
22293 test_234() {
22294         local p="$TMP/sanityN-$TESTNAME.parameters"
22295         save_lustre_params client "llite.*.xattr_cache" > $p
22296         lctl set_param llite.*.xattr_cache 1 ||
22297                 skip_env "xattr cache is not supported"
22298
22299         mkdir -p $DIR/$tdir || error "mkdir failed"
22300         touch $DIR/$tdir/$tfile || error "touch failed"
22301         # OBD_FAIL_LLITE_XATTR_ENOMEM
22302         $LCTL set_param fail_loc=0x1405
22303         getfattr -n user.attr $DIR/$tdir/$tfile &&
22304                 error "getfattr should have failed with ENOMEM"
22305         $LCTL set_param fail_loc=0x0
22306         rm -rf $DIR/$tdir
22307
22308         restore_lustre_params < $p
22309         rm -f $p
22310 }
22311 run_test 234 "xattr cache should not crash on ENOMEM"
22312
22313 test_235() {
22314         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22315                 skip "Need MDS version at least 2.4.52"
22316
22317         flock_deadlock $DIR/$tfile
22318         local RC=$?
22319         case $RC in
22320                 0)
22321                 ;;
22322                 124) error "process hangs on a deadlock"
22323                 ;;
22324                 *) error "error executing flock_deadlock $DIR/$tfile"
22325                 ;;
22326         esac
22327 }
22328 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22329
22330 #LU-2935
22331 test_236() {
22332         check_swap_layouts_support
22333
22334         local ref1=/etc/passwd
22335         local ref2=/etc/group
22336         local file1=$DIR/$tdir/f1
22337         local file2=$DIR/$tdir/f2
22338
22339         test_mkdir -c1 $DIR/$tdir
22340         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22341         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22342         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22343         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22344         local fd=$(free_fd)
22345         local cmd="exec $fd<>$file2"
22346         eval $cmd
22347         rm $file2
22348         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22349                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22350         cmd="exec $fd>&-"
22351         eval $cmd
22352         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22353
22354         #cleanup
22355         rm -rf $DIR/$tdir
22356 }
22357 run_test 236 "Layout swap on open unlinked file"
22358
22359 # LU-4659 linkea consistency
22360 test_238() {
22361         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22362                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22363                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22364                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22365
22366         touch $DIR/$tfile
22367         ln $DIR/$tfile $DIR/$tfile.lnk
22368         touch $DIR/$tfile.new
22369         mv $DIR/$tfile.new $DIR/$tfile
22370         local fid1=$($LFS path2fid $DIR/$tfile)
22371         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22372         local path1=$($LFS fid2path $FSNAME "$fid1")
22373         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22374         local path2=$($LFS fid2path $FSNAME "$fid2")
22375         [ $tfile.lnk == $path2 ] ||
22376                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22377         rm -f $DIR/$tfile*
22378 }
22379 run_test 238 "Verify linkea consistency"
22380
22381 test_239A() { # was test_239
22382         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22383                 skip "Need MDS version at least 2.5.60"
22384
22385         local list=$(comma_list $(mdts_nodes))
22386
22387         mkdir -p $DIR/$tdir
22388         createmany -o $DIR/$tdir/f- 5000
22389         unlinkmany $DIR/$tdir/f- 5000
22390         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22391                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22392         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22393                         osp.*MDT*.sync_in_flight" | calc_sum)
22394         [ "$changes" -eq 0 ] || error "$changes not synced"
22395 }
22396 run_test 239A "osp_sync test"
22397
22398 test_239a() { #LU-5297
22399         remote_mds_nodsh && skip "remote MDS with nodsh"
22400
22401         touch $DIR/$tfile
22402         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22403         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22404         chgrp $RUNAS_GID $DIR/$tfile
22405         wait_delete_completed
22406 }
22407 run_test 239a "process invalid osp sync record correctly"
22408
22409 test_239b() { #LU-5297
22410         remote_mds_nodsh && skip "remote MDS with nodsh"
22411
22412         touch $DIR/$tfile1
22413         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22414         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22415         chgrp $RUNAS_GID $DIR/$tfile1
22416         wait_delete_completed
22417         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22418         touch $DIR/$tfile2
22419         chgrp $RUNAS_GID $DIR/$tfile2
22420         wait_delete_completed
22421 }
22422 run_test 239b "process osp sync record with ENOMEM error correctly"
22423
22424 test_240() {
22425         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22426         remote_mds_nodsh && skip "remote MDS with nodsh"
22427
22428         mkdir -p $DIR/$tdir
22429
22430         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22431                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22432         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22433                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22434
22435         umount_client $MOUNT || error "umount failed"
22436         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22437         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22438         mount_client $MOUNT || error "failed to mount client"
22439
22440         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22441         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22442 }
22443 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22444
22445 test_241_bio() {
22446         local count=$1
22447         local bsize=$2
22448
22449         for LOOP in $(seq $count); do
22450                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22451                 cancel_lru_locks $OSC || true
22452         done
22453 }
22454
22455 test_241_dio() {
22456         local count=$1
22457         local bsize=$2
22458
22459         for LOOP in $(seq $1); do
22460                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22461                         2>/dev/null
22462         done
22463 }
22464
22465 test_241a() { # was test_241
22466         local bsize=$PAGE_SIZE
22467
22468         (( bsize < 40960 )) && bsize=40960
22469         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22470         ls -la $DIR/$tfile
22471         cancel_lru_locks $OSC
22472         test_241_bio 1000 $bsize &
22473         PID=$!
22474         test_241_dio 1000 $bsize
22475         wait $PID
22476 }
22477 run_test 241a "bio vs dio"
22478
22479 test_241b() {
22480         local bsize=$PAGE_SIZE
22481
22482         (( bsize < 40960 )) && bsize=40960
22483         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22484         ls -la $DIR/$tfile
22485         test_241_dio 1000 $bsize &
22486         PID=$!
22487         test_241_dio 1000 $bsize
22488         wait $PID
22489 }
22490 run_test 241b "dio vs dio"
22491
22492 test_242() {
22493         remote_mds_nodsh && skip "remote MDS with nodsh"
22494
22495         mkdir_on_mdt0 $DIR/$tdir
22496         touch $DIR/$tdir/$tfile
22497
22498         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22499         do_facet mds1 lctl set_param fail_loc=0x105
22500         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22501
22502         do_facet mds1 lctl set_param fail_loc=0
22503         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22504 }
22505 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22506
22507 test_243()
22508 {
22509         test_mkdir $DIR/$tdir
22510         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22511 }
22512 run_test 243 "various group lock tests"
22513
22514 test_244a()
22515 {
22516         test_mkdir $DIR/$tdir
22517         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22518         sendfile_grouplock $DIR/$tdir/$tfile || \
22519                 error "sendfile+grouplock failed"
22520         rm -rf $DIR/$tdir
22521 }
22522 run_test 244a "sendfile with group lock tests"
22523
22524 test_244b()
22525 {
22526         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22527
22528         local threads=50
22529         local size=$((1024*1024))
22530
22531         test_mkdir $DIR/$tdir
22532         for i in $(seq 1 $threads); do
22533                 local file=$DIR/$tdir/file_$((i / 10))
22534                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22535                 local pids[$i]=$!
22536         done
22537         for i in $(seq 1 $threads); do
22538                 wait ${pids[$i]}
22539         done
22540 }
22541 run_test 244b "multi-threaded write with group lock"
22542
22543 test_245a() {
22544         local flagname="multi_mod_rpcs"
22545         local connect_data_name="max_mod_rpcs"
22546         local out
22547
22548         # check if multiple modify RPCs flag is set
22549         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22550                 grep "connect_flags:")
22551         echo "$out"
22552
22553         echo "$out" | grep -qw $flagname
22554         if [ $? -ne 0 ]; then
22555                 echo "connect flag $flagname is not set"
22556                 return
22557         fi
22558
22559         # check if multiple modify RPCs data is set
22560         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22561         echo "$out"
22562
22563         echo "$out" | grep -qw $connect_data_name ||
22564                 error "import should have connect data $connect_data_name"
22565 }
22566 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22567
22568 test_245b() {
22569         local flagname="multi_mod_rpcs"
22570         local connect_data_name="max_mod_rpcs"
22571         local out
22572
22573         remote_mds_nodsh && skip "remote MDS with nodsh"
22574         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22575
22576         # check if multiple modify RPCs flag is set
22577         out=$(do_facet mds1 \
22578               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22579               grep "connect_flags:")
22580         echo "$out"
22581
22582         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22583
22584         # check if multiple modify RPCs data is set
22585         out=$(do_facet mds1 \
22586               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22587
22588         [[ "$out" =~ $connect_data_name ]] ||
22589                 {
22590                         echo "$out"
22591                         error "missing connect data $connect_data_name"
22592                 }
22593 }
22594 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22595
22596 cleanup_247() {
22597         local submount=$1
22598
22599         trap 0
22600         umount_client $submount
22601         rmdir $submount
22602 }
22603
22604 test_247a() {
22605         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22606                 grep -q subtree ||
22607                 skip_env "Fileset feature is not supported"
22608
22609         local submount=${MOUNT}_$tdir
22610
22611         mkdir $MOUNT/$tdir
22612         mkdir -p $submount || error "mkdir $submount failed"
22613         FILESET="$FILESET/$tdir" mount_client $submount ||
22614                 error "mount $submount failed"
22615         trap "cleanup_247 $submount" EXIT
22616         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22617         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22618                 error "read $MOUNT/$tdir/$tfile failed"
22619         cleanup_247 $submount
22620 }
22621 run_test 247a "mount subdir as fileset"
22622
22623 test_247b() {
22624         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22625                 skip_env "Fileset feature is not supported"
22626
22627         local submount=${MOUNT}_$tdir
22628
22629         rm -rf $MOUNT/$tdir
22630         mkdir -p $submount || error "mkdir $submount failed"
22631         SKIP_FILESET=1
22632         FILESET="$FILESET/$tdir" mount_client $submount &&
22633                 error "mount $submount should fail"
22634         rmdir $submount
22635 }
22636 run_test 247b "mount subdir that dose not exist"
22637
22638 test_247c() {
22639         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22640                 skip_env "Fileset feature is not supported"
22641
22642         local submount=${MOUNT}_$tdir
22643
22644         mkdir -p $MOUNT/$tdir/dir1
22645         mkdir -p $submount || error "mkdir $submount failed"
22646         trap "cleanup_247 $submount" EXIT
22647         FILESET="$FILESET/$tdir" mount_client $submount ||
22648                 error "mount $submount failed"
22649         local fid=$($LFS path2fid $MOUNT/)
22650         $LFS fid2path $submount $fid && error "fid2path should fail"
22651         cleanup_247 $submount
22652 }
22653 run_test 247c "running fid2path outside subdirectory root"
22654
22655 test_247d() {
22656         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22657                 skip "Fileset feature is not supported"
22658
22659         local submount=${MOUNT}_$tdir
22660
22661         mkdir -p $MOUNT/$tdir/dir1
22662         mkdir -p $submount || error "mkdir $submount failed"
22663         FILESET="$FILESET/$tdir" mount_client $submount ||
22664                 error "mount $submount failed"
22665         trap "cleanup_247 $submount" EXIT
22666
22667         local td=$submount/dir1
22668         local fid=$($LFS path2fid $td)
22669         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22670
22671         # check that we get the same pathname back
22672         local rootpath
22673         local found
22674         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22675                 echo "$rootpath $fid"
22676                 found=$($LFS fid2path $rootpath "$fid")
22677                 [ -n "$found" ] || error "fid2path should succeed"
22678                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22679         done
22680         # check wrong root path format
22681         rootpath=$submount"_wrong"
22682         found=$($LFS fid2path $rootpath "$fid")
22683         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22684
22685         cleanup_247 $submount
22686 }
22687 run_test 247d "running fid2path inside subdirectory root"
22688
22689 # LU-8037
22690 test_247e() {
22691         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22692                 grep -q subtree ||
22693                 skip "Fileset feature is not supported"
22694
22695         local submount=${MOUNT}_$tdir
22696
22697         mkdir $MOUNT/$tdir
22698         mkdir -p $submount || error "mkdir $submount failed"
22699         FILESET="$FILESET/.." mount_client $submount &&
22700                 error "mount $submount should fail"
22701         rmdir $submount
22702 }
22703 run_test 247e "mount .. as fileset"
22704
22705 test_247f() {
22706         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22707         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22708                 skip "Need at least version 2.14.50.162"
22709         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22710                 skip "Fileset feature is not supported"
22711
22712         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22713         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22714                 error "mkdir remote failed"
22715         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22716                 error "mkdir remote/subdir failed"
22717         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22718                 error "mkdir striped failed"
22719         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22720
22721         local submount=${MOUNT}_$tdir
22722
22723         mkdir -p $submount || error "mkdir $submount failed"
22724         stack_trap "rmdir $submount"
22725
22726         local dir
22727         local fileset=$FILESET
22728         local mdts=$(comma_list $(mdts_nodes))
22729
22730         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22731         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22732                 $tdir/striped/subdir $tdir/striped/.; do
22733                 FILESET="$fileset/$dir" mount_client $submount ||
22734                         error "mount $dir failed"
22735                 umount_client $submount
22736         done
22737 }
22738 run_test 247f "mount striped or remote directory as fileset"
22739
22740 test_subdir_mount_lock()
22741 {
22742         local testdir=$1
22743         local submount=${MOUNT}_$(basename $testdir)
22744
22745         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22746
22747         mkdir -p $submount || error "mkdir $submount failed"
22748         stack_trap "rmdir $submount"
22749
22750         FILESET="$fileset/$testdir" mount_client $submount ||
22751                 error "mount $FILESET failed"
22752         stack_trap "umount $submount"
22753
22754         local mdts=$(comma_list $(mdts_nodes))
22755
22756         local nrpcs
22757
22758         stat $submount > /dev/null || error "stat $submount failed"
22759         cancel_lru_locks $MDC
22760         stat $submount > /dev/null || error "stat $submount failed"
22761         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22762         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22763         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22764         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22765                 awk '/getattr/ {sum += $2} END {print sum}')
22766
22767         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22768 }
22769
22770 test_247g() {
22771         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22772
22773         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22774                 error "mkdir $tdir failed"
22775         test_subdir_mount_lock $tdir
22776 }
22777 run_test 247g "striped directory submount revalidate ROOT from cache"
22778
22779 test_247h() {
22780         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22781         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22782                 skip "Need MDS version at least 2.15.51"
22783
22784         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22785         test_subdir_mount_lock $tdir
22786         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22787         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22788                 error "mkdir $tdir.1 failed"
22789         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22790 }
22791 run_test 247h "remote directory submount revalidate ROOT from cache"
22792
22793 test_248a() {
22794         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22795         [ -z "$fast_read_sav" ] && skip "no fast read support"
22796
22797         # create a large file for fast read verification
22798         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22799
22800         # make sure the file is created correctly
22801         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22802                 { rm -f $DIR/$tfile; skip "file creation error"; }
22803
22804         echo "Test 1: verify that fast read is 4 times faster on cache read"
22805
22806         # small read with fast read enabled
22807         $LCTL set_param -n llite.*.fast_read=1
22808         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22809                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22810                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22811         # small read with fast read disabled
22812         $LCTL set_param -n llite.*.fast_read=0
22813         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22814                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22815                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22816
22817         # verify that fast read is 4 times faster for cache read
22818         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22819                 error_not_in_vm "fast read was not 4 times faster: " \
22820                            "$t_fast vs $t_slow"
22821
22822         echo "Test 2: verify the performance between big and small read"
22823         $LCTL set_param -n llite.*.fast_read=1
22824
22825         # 1k non-cache read
22826         cancel_lru_locks osc
22827         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22828                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22829                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22830
22831         # 1M non-cache read
22832         cancel_lru_locks osc
22833         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22834                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22835                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22836
22837         # verify that big IO is not 4 times faster than small IO
22838         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22839                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22840
22841         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22842         rm -f $DIR/$tfile
22843 }
22844 run_test 248a "fast read verification"
22845
22846 test_248b() {
22847         # Default short_io_bytes=16384, try both smaller and larger sizes.
22848         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22849         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22850         echo "bs=53248 count=113 normal buffered write"
22851         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22852                 error "dd of initial data file failed"
22853         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22854
22855         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22856         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22857                 error "dd with sync normal writes failed"
22858         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22859
22860         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22861         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22862                 error "dd with sync small writes failed"
22863         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22864
22865         cancel_lru_locks osc
22866
22867         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22868         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22869         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22870         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22871                 iflag=direct || error "dd with O_DIRECT small read failed"
22872         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22873         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22874                 error "compare $TMP/$tfile.1 failed"
22875
22876         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22877         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22878
22879         # just to see what the maximum tunable value is, and test parsing
22880         echo "test invalid parameter 2MB"
22881         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22882                 error "too-large short_io_bytes allowed"
22883         echo "test maximum parameter 512KB"
22884         # if we can set a larger short_io_bytes, run test regardless of version
22885         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22886                 # older clients may not allow setting it this large, that's OK
22887                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22888                         skip "Need at least client version 2.13.50"
22889                 error "medium short_io_bytes failed"
22890         fi
22891         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22892         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22893
22894         echo "test large parameter 64KB"
22895         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22896         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22897
22898         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22899         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22900                 error "dd with sync large writes failed"
22901         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22902
22903         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22904         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22905         num=$((113 * 4096 / PAGE_SIZE))
22906         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22907         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22908                 error "dd with O_DIRECT large writes failed"
22909         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22910                 error "compare $DIR/$tfile.3 failed"
22911
22912         cancel_lru_locks osc
22913
22914         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22915         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22916                 error "dd with O_DIRECT large read failed"
22917         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22918                 error "compare $TMP/$tfile.2 failed"
22919
22920         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22921         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22922                 error "dd with O_DIRECT large read failed"
22923         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22924                 error "compare $TMP/$tfile.3 failed"
22925 }
22926 run_test 248b "test short_io read and write for both small and large sizes"
22927
22928 test_249() { # LU-7890
22929         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22930                 skip "Need at least version 2.8.54"
22931
22932         rm -f $DIR/$tfile
22933         $LFS setstripe -c 1 $DIR/$tfile
22934         # Offset 2T == 4k * 512M
22935         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22936                 error "dd to 2T offset failed"
22937 }
22938 run_test 249 "Write above 2T file size"
22939
22940 test_250() {
22941         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22942          && skip "no 16TB file size limit on ZFS"
22943
22944         $LFS setstripe -c 1 $DIR/$tfile
22945         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22946         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22947         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22948         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22949                 conv=notrunc,fsync && error "append succeeded"
22950         return 0
22951 }
22952 run_test 250 "Write above 16T limit"
22953
22954 test_251() {
22955         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22956
22957         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22958         #Skip once - writing the first stripe will succeed
22959         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22960         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22961                 error "short write happened"
22962
22963         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22964         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22965                 error "short read happened"
22966
22967         rm -f $DIR/$tfile
22968 }
22969 run_test 251 "Handling short read and write correctly"
22970
22971 test_252() {
22972         remote_mds_nodsh && skip "remote MDS with nodsh"
22973         remote_ost_nodsh && skip "remote OST with nodsh"
22974         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22975                 skip_env "ldiskfs only test"
22976         fi
22977
22978         local tgt
22979         local dev
22980         local out
22981         local uuid
22982         local num
22983         local gen
22984
22985         # check lr_reader on OST0000
22986         tgt=ost1
22987         dev=$(facet_device $tgt)
22988         out=$(do_facet $tgt $LR_READER $dev)
22989         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22990         echo "$out"
22991         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22992         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22993                 error "Invalid uuid returned by $LR_READER on target $tgt"
22994         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22995
22996         # check lr_reader -c on MDT0000
22997         tgt=mds1
22998         dev=$(facet_device $tgt)
22999         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23000                 skip "$LR_READER does not support additional options"
23001         fi
23002         out=$(do_facet $tgt $LR_READER -c $dev)
23003         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23004         echo "$out"
23005         num=$(echo "$out" | grep -c "mdtlov")
23006         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23007                 error "Invalid number of mdtlov clients returned by $LR_READER"
23008         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23009
23010         # check lr_reader -cr on MDT0000
23011         out=$(do_facet $tgt $LR_READER -cr $dev)
23012         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23013         echo "$out"
23014         echo "$out" | grep -q "^reply_data:$" ||
23015                 error "$LR_READER should have returned 'reply_data' section"
23016         num=$(echo "$out" | grep -c "client_generation")
23017         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23018 }
23019 run_test 252 "check lr_reader tool"
23020
23021 test_253() {
23022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23023         remote_mds_nodsh && skip "remote MDS with nodsh"
23024         remote_mgs_nodsh && skip "remote MGS with nodsh"
23025
23026         local ostidx=0
23027         local rc=0
23028         local ost_name=$(ostname_from_index $ostidx)
23029
23030         # on the mdt's osc
23031         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23032         do_facet $SINGLEMDS $LCTL get_param -n \
23033                 osp.$mdtosc_proc1.reserved_mb_high ||
23034                 skip  "remote MDS does not support reserved_mb_high"
23035
23036         rm -rf $DIR/$tdir
23037         wait_mds_ost_sync
23038         wait_delete_completed
23039         mkdir $DIR/$tdir
23040         stack_trap "rm -rf $DIR/$tdir"
23041
23042         pool_add $TESTNAME || error "Pool creation failed"
23043         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23044
23045         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23046                 error "Setstripe failed"
23047
23048         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23049
23050         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23051                     grep "watermarks")
23052         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23053
23054         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23055                         osp.$mdtosc_proc1.prealloc_status)
23056         echo "prealloc_status $oa_status"
23057
23058         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23059                 error "File creation should fail"
23060
23061         #object allocation was stopped, but we still able to append files
23062         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23063                 oflag=append || error "Append failed"
23064
23065         rm -f $DIR/$tdir/$tfile.0
23066
23067         # For this test, we want to delete the files we created to go out of
23068         # space but leave the watermark, so we remain nearly out of space
23069         ost_watermarks_enospc_delete_files $tfile $ostidx
23070
23071         wait_delete_completed
23072
23073         sleep_maxage
23074
23075         for i in $(seq 10 12); do
23076                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23077                         2>/dev/null || error "File creation failed after rm"
23078         done
23079
23080         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23081                         osp.$mdtosc_proc1.prealloc_status)
23082         echo "prealloc_status $oa_status"
23083
23084         if (( oa_status != 0 )); then
23085                 error "Object allocation still disable after rm"
23086         fi
23087 }
23088 run_test 253 "Check object allocation limit"
23089
23090 test_254() {
23091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23092         remote_mds_nodsh && skip "remote MDS with nodsh"
23093
23094         local mdt=$(facet_svc $SINGLEMDS)
23095
23096         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23097                 skip "MDS does not support changelog_size"
23098
23099         local cl_user
23100
23101         changelog_register || error "changelog_register failed"
23102
23103         changelog_clear 0 || error "changelog_clear failed"
23104
23105         local size1=$(do_facet $SINGLEMDS \
23106                       $LCTL get_param -n mdd.$mdt.changelog_size)
23107         echo "Changelog size $size1"
23108
23109         rm -rf $DIR/$tdir
23110         $LFS mkdir -i 0 $DIR/$tdir
23111         # change something
23112         mkdir -p $DIR/$tdir/pics/2008/zachy
23113         touch $DIR/$tdir/pics/2008/zachy/timestamp
23114         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23115         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23116         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23117         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23118         rm $DIR/$tdir/pics/desktop.jpg
23119
23120         local size2=$(do_facet $SINGLEMDS \
23121                       $LCTL get_param -n mdd.$mdt.changelog_size)
23122         echo "Changelog size after work $size2"
23123
23124         (( $size2 > $size1 )) ||
23125                 error "new Changelog size=$size2 less than old size=$size1"
23126 }
23127 run_test 254 "Check changelog size"
23128
23129 ladvise_no_type()
23130 {
23131         local type=$1
23132         local file=$2
23133
23134         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23135                 awk -F: '{print $2}' | grep $type > /dev/null
23136         if [ $? -ne 0 ]; then
23137                 return 0
23138         fi
23139         return 1
23140 }
23141
23142 ladvise_no_ioctl()
23143 {
23144         local file=$1
23145
23146         lfs ladvise -a willread $file > /dev/null 2>&1
23147         if [ $? -eq 0 ]; then
23148                 return 1
23149         fi
23150
23151         lfs ladvise -a willread $file 2>&1 |
23152                 grep "Inappropriate ioctl for device" > /dev/null
23153         if [ $? -eq 0 ]; then
23154                 return 0
23155         fi
23156         return 1
23157 }
23158
23159 percent() {
23160         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23161 }
23162
23163 # run a random read IO workload
23164 # usage: random_read_iops <filename> <filesize> <iosize>
23165 random_read_iops() {
23166         local file=$1
23167         local fsize=$2
23168         local iosize=${3:-4096}
23169
23170         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23171                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23172 }
23173
23174 drop_file_oss_cache() {
23175         local file="$1"
23176         local nodes="$2"
23177
23178         $LFS ladvise -a dontneed $file 2>/dev/null ||
23179                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23180 }
23181
23182 ladvise_willread_performance()
23183 {
23184         local repeat=10
23185         local average_origin=0
23186         local average_cache=0
23187         local average_ladvise=0
23188
23189         for ((i = 1; i <= $repeat; i++)); do
23190                 echo "Iter $i/$repeat: reading without willread hint"
23191                 cancel_lru_locks osc
23192                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23193                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23194                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23195                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23196
23197                 cancel_lru_locks osc
23198                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23199                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23200                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23201
23202                 cancel_lru_locks osc
23203                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23204                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23205                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23206                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23207                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23208         done
23209         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23210         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23211         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23212
23213         speedup_cache=$(percent $average_cache $average_origin)
23214         speedup_ladvise=$(percent $average_ladvise $average_origin)
23215
23216         echo "Average uncached read: $average_origin"
23217         echo "Average speedup with OSS cached read: " \
23218                 "$average_cache = +$speedup_cache%"
23219         echo "Average speedup with ladvise willread: " \
23220                 "$average_ladvise = +$speedup_ladvise%"
23221
23222         local lowest_speedup=20
23223         if (( ${average_cache%.*} < $lowest_speedup )); then
23224                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23225                      " got $average_cache%. Skipping ladvise willread check."
23226                 return 0
23227         fi
23228
23229         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23230         # it is still good to run until then to exercise 'ladvise willread'
23231         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23232                 [ "$ost1_FSTYPE" = "zfs" ] &&
23233                 echo "osd-zfs does not support dontneed or drop_caches" &&
23234                 return 0
23235
23236         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23237         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23238                 error_not_in_vm "Speedup with willread is less than " \
23239                         "$lowest_speedup%, got $average_ladvise%"
23240 }
23241
23242 test_255a() {
23243         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23244                 skip "lustre < 2.8.54 does not support ladvise "
23245         remote_ost_nodsh && skip "remote OST with nodsh"
23246
23247         stack_trap "rm -f $DIR/$tfile"
23248         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23249
23250         ladvise_no_type willread $DIR/$tfile &&
23251                 skip "willread ladvise is not supported"
23252
23253         ladvise_no_ioctl $DIR/$tfile &&
23254                 skip "ladvise ioctl is not supported"
23255
23256         local size_mb=100
23257         local size=$((size_mb * 1048576))
23258         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23259                 error "dd to $DIR/$tfile failed"
23260
23261         lfs ladvise -a willread $DIR/$tfile ||
23262                 error "Ladvise failed with no range argument"
23263
23264         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23265                 error "Ladvise failed with no -l or -e argument"
23266
23267         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23268                 error "Ladvise failed with only -e argument"
23269
23270         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23271                 error "Ladvise failed with only -l argument"
23272
23273         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23274                 error "End offset should not be smaller than start offset"
23275
23276         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23277                 error "End offset should not be equal to start offset"
23278
23279         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23280                 error "Ladvise failed with overflowing -s argument"
23281
23282         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23283                 error "Ladvise failed with overflowing -e argument"
23284
23285         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23286                 error "Ladvise failed with overflowing -l argument"
23287
23288         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23289                 error "Ladvise succeeded with conflicting -l and -e arguments"
23290
23291         echo "Synchronous ladvise should wait"
23292         local delay=8
23293 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23294         do_nodes $(comma_list $(osts_nodes)) \
23295                 $LCTL set_param fail_val=$delay fail_loc=0x237
23296         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23297                 $LCTL set_param fail_loc=0"
23298
23299         local start_ts=$SECONDS
23300         lfs ladvise -a willread $DIR/$tfile ||
23301                 error "Ladvise failed with no range argument"
23302         local end_ts=$SECONDS
23303         local inteval_ts=$((end_ts - start_ts))
23304
23305         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23306                 error "Synchronous advice didn't wait reply"
23307         fi
23308
23309         echo "Asynchronous ladvise shouldn't wait"
23310         local start_ts=$SECONDS
23311         lfs ladvise -a willread -b $DIR/$tfile ||
23312                 error "Ladvise failed with no range argument"
23313         local end_ts=$SECONDS
23314         local inteval_ts=$((end_ts - start_ts))
23315
23316         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23317                 error "Asynchronous advice blocked"
23318         fi
23319
23320         ladvise_willread_performance
23321 }
23322 run_test 255a "check 'lfs ladvise -a willread'"
23323
23324 facet_meminfo() {
23325         local facet=$1
23326         local info=$2
23327
23328         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23329 }
23330
23331 test_255b() {
23332         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23333                 skip "lustre < 2.8.54 does not support ladvise "
23334         remote_ost_nodsh && skip "remote OST with nodsh"
23335
23336         stack_trap "rm -f $DIR/$tfile"
23337         lfs setstripe -c 1 -i 0 $DIR/$tfile
23338
23339         ladvise_no_type dontneed $DIR/$tfile &&
23340                 skip "dontneed ladvise is not supported"
23341
23342         ladvise_no_ioctl $DIR/$tfile &&
23343                 skip "ladvise ioctl is not supported"
23344
23345         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23346                 [ "$ost1_FSTYPE" = "zfs" ] &&
23347                 skip "zfs-osd does not support 'ladvise dontneed'"
23348
23349         local size_mb=100
23350         local size=$((size_mb * 1048576))
23351         # In order to prevent disturbance of other processes, only check 3/4
23352         # of the memory usage
23353         local kibibytes=$((size_mb * 1024 * 3 / 4))
23354
23355         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23356                 error "dd to $DIR/$tfile failed"
23357
23358         #force write to complete before dropping OST cache & checking memory
23359         sync
23360
23361         local total=$(facet_meminfo ost1 MemTotal)
23362         echo "Total memory: $total KiB"
23363
23364         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23365         local before_read=$(facet_meminfo ost1 Cached)
23366         echo "Cache used before read: $before_read KiB"
23367
23368         lfs ladvise -a willread $DIR/$tfile ||
23369                 error "Ladvise willread failed"
23370         local after_read=$(facet_meminfo ost1 Cached)
23371         echo "Cache used after read: $after_read KiB"
23372
23373         lfs ladvise -a dontneed $DIR/$tfile ||
23374                 error "Ladvise dontneed again failed"
23375         local no_read=$(facet_meminfo ost1 Cached)
23376         echo "Cache used after dontneed ladvise: $no_read KiB"
23377
23378         if [ $total -lt $((before_read + kibibytes)) ]; then
23379                 echo "Memory is too small, abort checking"
23380                 return 0
23381         fi
23382
23383         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23384                 error "Ladvise willread should use more memory" \
23385                         "than $kibibytes KiB"
23386         fi
23387
23388         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23389                 error "Ladvise dontneed should release more memory" \
23390                         "than $kibibytes KiB"
23391         fi
23392 }
23393 run_test 255b "check 'lfs ladvise -a dontneed'"
23394
23395 test_255c() {
23396         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23397                 skip "lustre < 2.10.50 does not support lockahead"
23398
23399         local ost1_imp=$(get_osc_import_name client ost1)
23400         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23401                          cut -d'.' -f2)
23402         local count
23403         local new_count
23404         local difference
23405         local i
23406         local rc
23407
23408         test_mkdir -p $DIR/$tdir
23409         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23410
23411         #test 10 returns only success/failure
23412         i=10
23413         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23414         rc=$?
23415         if [ $rc -eq 255 ]; then
23416                 error "Ladvise test${i} failed, ${rc}"
23417         fi
23418
23419         #test 11 counts lock enqueue requests, all others count new locks
23420         i=11
23421         count=$(do_facet ost1 \
23422                 $LCTL get_param -n ost.OSS.ost.stats)
23423         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23424
23425         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23426         rc=$?
23427         if [ $rc -eq 255 ]; then
23428                 error "Ladvise test${i} failed, ${rc}"
23429         fi
23430
23431         new_count=$(do_facet ost1 \
23432                 $LCTL get_param -n ost.OSS.ost.stats)
23433         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23434                    awk '{ print $2 }')
23435
23436         difference="$((new_count - count))"
23437         if [ $difference -ne $rc ]; then
23438                 error "Ladvise test${i}, bad enqueue count, returned " \
23439                       "${rc}, actual ${difference}"
23440         fi
23441
23442         for i in $(seq 12 21); do
23443                 # If we do not do this, we run the risk of having too many
23444                 # locks and starting lock cancellation while we are checking
23445                 # lock counts.
23446                 cancel_lru_locks osc
23447
23448                 count=$($LCTL get_param -n \
23449                        ldlm.namespaces.$imp_name.lock_unused_count)
23450
23451                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23452                 rc=$?
23453                 if [ $rc -eq 255 ]; then
23454                         error "Ladvise test ${i} failed, ${rc}"
23455                 fi
23456
23457                 new_count=$($LCTL get_param -n \
23458                        ldlm.namespaces.$imp_name.lock_unused_count)
23459                 difference="$((new_count - count))"
23460
23461                 # Test 15 output is divided by 100 to map down to valid return
23462                 if [ $i -eq 15 ]; then
23463                         rc="$((rc * 100))"
23464                 fi
23465
23466                 if [ $difference -ne $rc ]; then
23467                         error "Ladvise test ${i}, bad lock count, returned " \
23468                               "${rc}, actual ${difference}"
23469                 fi
23470         done
23471
23472         #test 22 returns only success/failure
23473         i=22
23474         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23475         rc=$?
23476         if [ $rc -eq 255 ]; then
23477                 error "Ladvise test${i} failed, ${rc}"
23478         fi
23479 }
23480 run_test 255c "suite of ladvise lockahead tests"
23481
23482 test_256() {
23483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23484         remote_mds_nodsh && skip "remote MDS with nodsh"
23485         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23486         changelog_users $SINGLEMDS | grep "^cl" &&
23487                 skip "active changelog user"
23488
23489         local cl_user
23490         local cat_sl
23491         local mdt_dev
23492
23493         mdt_dev=$(facet_device $SINGLEMDS)
23494         echo $mdt_dev
23495
23496         changelog_register || error "changelog_register failed"
23497
23498         rm -rf $DIR/$tdir
23499         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23500
23501         changelog_clear 0 || error "changelog_clear failed"
23502
23503         # change something
23504         touch $DIR/$tdir/{1..10}
23505
23506         # stop the MDT
23507         stop $SINGLEMDS || error "Fail to stop MDT"
23508
23509         # remount the MDT
23510         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23511                 error "Fail to start MDT"
23512
23513         #after mount new plainllog is used
23514         touch $DIR/$tdir/{11..19}
23515         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23516         stack_trap "rm -f $tmpfile"
23517         cat_sl=$(do_facet $SINGLEMDS "sync; \
23518                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23519                  llog_reader $tmpfile | grep -c type=1064553b")
23520         do_facet $SINGLEMDS llog_reader $tmpfile
23521
23522         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23523
23524         changelog_clear 0 || error "changelog_clear failed"
23525
23526         cat_sl=$(do_facet $SINGLEMDS "sync; \
23527                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23528                  llog_reader $tmpfile | grep -c type=1064553b")
23529
23530         if (( cat_sl == 2 )); then
23531                 error "Empty plain llog was not deleted from changelog catalog"
23532         elif (( cat_sl != 1 )); then
23533                 error "Active plain llog shouldn't be deleted from catalog"
23534         fi
23535 }
23536 run_test 256 "Check llog delete for empty and not full state"
23537
23538 test_257() {
23539         remote_mds_nodsh && skip "remote MDS with nodsh"
23540         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23541                 skip "Need MDS version at least 2.8.55"
23542
23543         test_mkdir $DIR/$tdir
23544
23545         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23546                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23547         stat $DIR/$tdir
23548
23549 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23550         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23551         local facet=mds$((mdtidx + 1))
23552         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23553         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23554
23555         stop $facet || error "stop MDS failed"
23556         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23557                 error "start MDS fail"
23558         wait_recovery_complete $facet
23559 }
23560 run_test 257 "xattr locks are not lost"
23561
23562 # Verify we take the i_mutex when security requires it
23563 test_258a() {
23564 #define OBD_FAIL_IMUTEX_SEC 0x141c
23565         $LCTL set_param fail_loc=0x141c
23566         touch $DIR/$tfile
23567         chmod u+s $DIR/$tfile
23568         chmod a+rwx $DIR/$tfile
23569         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23570         RC=$?
23571         if [ $RC -ne 0 ]; then
23572                 error "error, failed to take i_mutex, rc=$?"
23573         fi
23574         rm -f $DIR/$tfile
23575 }
23576 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23577
23578 # Verify we do NOT take the i_mutex in the normal case
23579 test_258b() {
23580 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23581         $LCTL set_param fail_loc=0x141d
23582         touch $DIR/$tfile
23583         chmod a+rwx $DIR
23584         chmod a+rw $DIR/$tfile
23585         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23586         RC=$?
23587         if [ $RC -ne 0 ]; then
23588                 error "error, took i_mutex unnecessarily, rc=$?"
23589         fi
23590         rm -f $DIR/$tfile
23591
23592 }
23593 run_test 258b "verify i_mutex security behavior"
23594
23595 test_259() {
23596         local file=$DIR/$tfile
23597         local before
23598         local after
23599
23600         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23601
23602         stack_trap "rm -f $file" EXIT
23603
23604         wait_delete_completed
23605         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23606         echo "before: $before"
23607
23608         $LFS setstripe -i 0 -c 1 $file
23609         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23610         sync_all_data
23611         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23612         echo "after write: $after"
23613
23614 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23615         do_facet ost1 $LCTL set_param fail_loc=0x2301
23616         $TRUNCATE $file 0
23617         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23618         echo "after truncate: $after"
23619
23620         stop ost1
23621         do_facet ost1 $LCTL set_param fail_loc=0
23622         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23623         sleep 2
23624         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23625         echo "after restart: $after"
23626         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23627                 error "missing truncate?"
23628
23629         return 0
23630 }
23631 run_test 259 "crash at delayed truncate"
23632
23633 test_260() {
23634 #define OBD_FAIL_MDC_CLOSE               0x806
23635         $LCTL set_param fail_loc=0x80000806
23636         touch $DIR/$tfile
23637
23638 }
23639 run_test 260 "Check mdc_close fail"
23640
23641 ### Data-on-MDT sanity tests ###
23642 test_270a() {
23643         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23644                 skip "Need MDS version at least 2.10.55 for DoM"
23645
23646         # create DoM file
23647         local dom=$DIR/$tdir/dom_file
23648         local tmp=$DIR/$tdir/tmp_file
23649
23650         mkdir_on_mdt0 $DIR/$tdir
23651
23652         # basic checks for DoM component creation
23653         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23654                 error "Can set MDT layout to non-first entry"
23655
23656         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23657                 error "Can define multiple entries as MDT layout"
23658
23659         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23660
23661         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23662         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23663         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23664
23665         local mdtidx=$($LFS getstripe -m $dom)
23666         local mdtname=MDT$(printf %04x $mdtidx)
23667         local facet=mds$((mdtidx + 1))
23668         local space_check=1
23669
23670         # Skip free space checks with ZFS
23671         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23672
23673         # write
23674         sync
23675         local size_tmp=$((65536 * 3))
23676         local mdtfree1=$(do_facet $facet \
23677                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23678
23679         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23680         # check also direct IO along write
23681         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23682         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23683         sync
23684         cmp $tmp $dom || error "file data is different"
23685         [ $(stat -c%s $dom) == $size_tmp ] ||
23686                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23687         if [ $space_check == 1 ]; then
23688                 local mdtfree2=$(do_facet $facet \
23689                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23690
23691                 # increase in usage from by $size_tmp
23692                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23693                         error "MDT free space wrong after write: " \
23694                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23695         fi
23696
23697         # truncate
23698         local size_dom=10000
23699
23700         $TRUNCATE $dom $size_dom
23701         [ $(stat -c%s $dom) == $size_dom ] ||
23702                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23703         if [ $space_check == 1 ]; then
23704                 mdtfree1=$(do_facet $facet \
23705                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23706                 # decrease in usage from $size_tmp to new $size_dom
23707                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23708                   $(((size_tmp - size_dom) / 1024)) ] ||
23709                         error "MDT free space is wrong after truncate: " \
23710                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23711         fi
23712
23713         # append
23714         cat $tmp >> $dom
23715         sync
23716         size_dom=$((size_dom + size_tmp))
23717         [ $(stat -c%s $dom) == $size_dom ] ||
23718                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23719         if [ $space_check == 1 ]; then
23720                 mdtfree2=$(do_facet $facet \
23721                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23722                 # increase in usage by $size_tmp from previous
23723                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23724                         error "MDT free space is wrong after append: " \
23725                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23726         fi
23727
23728         # delete
23729         rm $dom
23730         if [ $space_check == 1 ]; then
23731                 mdtfree1=$(do_facet $facet \
23732                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23733                 # decrease in usage by $size_dom from previous
23734                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23735                         error "MDT free space is wrong after removal: " \
23736                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23737         fi
23738
23739         # combined striping
23740         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23741                 error "Can't create DoM + OST striping"
23742
23743         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23744         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23745         # check also direct IO along write
23746         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23747         sync
23748         cmp $tmp $dom || error "file data is different"
23749         [ $(stat -c%s $dom) == $size_tmp ] ||
23750                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23751         rm $dom $tmp
23752
23753         return 0
23754 }
23755 run_test 270a "DoM: basic functionality tests"
23756
23757 test_270b() {
23758         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23759                 skip "Need MDS version at least 2.10.55"
23760
23761         local dom=$DIR/$tdir/dom_file
23762         local max_size=1048576
23763
23764         mkdir -p $DIR/$tdir
23765         $LFS setstripe -E $max_size -L mdt $dom
23766
23767         # truncate over the limit
23768         $TRUNCATE $dom $(($max_size + 1)) &&
23769                 error "successful truncate over the maximum size"
23770         # write over the limit
23771         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23772                 error "successful write over the maximum size"
23773         # append over the limit
23774         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23775         echo "12345" >> $dom && error "successful append over the maximum size"
23776         rm $dom
23777
23778         return 0
23779 }
23780 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23781
23782 test_270c() {
23783         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23784                 skip "Need MDS version at least 2.10.55"
23785
23786         mkdir -p $DIR/$tdir
23787         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23788
23789         # check files inherit DoM EA
23790         touch $DIR/$tdir/first
23791         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23792                 error "bad pattern"
23793         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23794                 error "bad stripe count"
23795         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23796                 error "bad stripe size"
23797
23798         # check directory inherits DoM EA and uses it as default
23799         mkdir $DIR/$tdir/subdir
23800         touch $DIR/$tdir/subdir/second
23801         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23802                 error "bad pattern in sub-directory"
23803         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23804                 error "bad stripe count in sub-directory"
23805         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23806                 error "bad stripe size in sub-directory"
23807         return 0
23808 }
23809 run_test 270c "DoM: DoM EA inheritance tests"
23810
23811 test_270d() {
23812         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23813                 skip "Need MDS version at least 2.10.55"
23814
23815         mkdir -p $DIR/$tdir
23816         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23817
23818         # inherit default DoM striping
23819         mkdir $DIR/$tdir/subdir
23820         touch $DIR/$tdir/subdir/f1
23821
23822         # change default directory striping
23823         $LFS setstripe -c 1 $DIR/$tdir/subdir
23824         touch $DIR/$tdir/subdir/f2
23825         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23826                 error "wrong default striping in file 2"
23827         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23828                 error "bad pattern in file 2"
23829         return 0
23830 }
23831 run_test 270d "DoM: change striping from DoM to RAID0"
23832
23833 test_270e() {
23834         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23835                 skip "Need MDS version at least 2.10.55"
23836
23837         mkdir -p $DIR/$tdir/dom
23838         mkdir -p $DIR/$tdir/norm
23839         DOMFILES=20
23840         NORMFILES=10
23841         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23842         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23843
23844         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23845         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23846
23847         # find DoM files by layout
23848         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23849         [ $NUM -eq  $DOMFILES ] ||
23850                 error "lfs find -L: found $NUM, expected $DOMFILES"
23851         echo "Test 1: lfs find 20 DOM files by layout: OK"
23852
23853         # there should be 1 dir with default DOM striping
23854         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23855         [ $NUM -eq  1 ] ||
23856                 error "lfs find -L: found $NUM, expected 1 dir"
23857         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23858
23859         # find DoM files by stripe size
23860         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23861         [ $NUM -eq  $DOMFILES ] ||
23862                 error "lfs find -S: found $NUM, expected $DOMFILES"
23863         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23864
23865         # find files by stripe offset except DoM files
23866         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23867         [ $NUM -eq  $NORMFILES ] ||
23868                 error "lfs find -i: found $NUM, expected $NORMFILES"
23869         echo "Test 5: lfs find no DOM files by stripe index: OK"
23870         return 0
23871 }
23872 run_test 270e "DoM: lfs find with DoM files test"
23873
23874 test_270f() {
23875         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23876                 skip "Need MDS version at least 2.10.55"
23877
23878         local mdtname=${FSNAME}-MDT0000-mdtlov
23879         local dom=$DIR/$tdir/dom_file
23880         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23881                                                 lod.$mdtname.dom_stripesize)
23882         local dom_limit=131072
23883
23884         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23885         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23886                                                 lod.$mdtname.dom_stripesize)
23887         [ ${dom_limit} -eq ${dom_current} ] ||
23888                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23889
23890         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23891         $LFS setstripe -d $DIR/$tdir
23892         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23893                 error "Can't set directory default striping"
23894
23895         # exceed maximum stripe size
23896         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23897                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23898         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23899                 error "Able to create DoM component size more than LOD limit"
23900
23901         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23902         dom_current=$(do_facet mds1 $LCTL get_param -n \
23903                                                 lod.$mdtname.dom_stripesize)
23904         [ 0 -eq ${dom_current} ] ||
23905                 error "Can't set zero DoM stripe limit"
23906         rm $dom
23907
23908         # attempt to create DoM file on server with disabled DoM should
23909         # remove DoM entry from layout and be succeed
23910         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23911                 error "Can't create DoM file (DoM is disabled)"
23912         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23913                 error "File has DoM component while DoM is disabled"
23914         rm $dom
23915
23916         # attempt to create DoM file with only DoM stripe should return error
23917         $LFS setstripe -E $dom_limit -L mdt $dom &&
23918                 error "Able to create DoM-only file while DoM is disabled"
23919
23920         # too low values to be aligned with smallest stripe size 64K
23921         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23922         dom_current=$(do_facet mds1 $LCTL get_param -n \
23923                                                 lod.$mdtname.dom_stripesize)
23924         [ 30000 -eq ${dom_current} ] &&
23925                 error "Can set too small DoM stripe limit"
23926
23927         # 64K is a minimal stripe size in Lustre, expect limit of that size
23928         [ 65536 -eq ${dom_current} ] ||
23929                 error "Limit is not set to 64K but ${dom_current}"
23930
23931         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23932         dom_current=$(do_facet mds1 $LCTL get_param -n \
23933                                                 lod.$mdtname.dom_stripesize)
23934         echo $dom_current
23935         [ 2147483648 -eq ${dom_current} ] &&
23936                 error "Can set too large DoM stripe limit"
23937
23938         do_facet mds1 $LCTL set_param -n \
23939                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23940         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23941                 error "Can't create DoM component size after limit change"
23942         do_facet mds1 $LCTL set_param -n \
23943                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23944         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23945                 error "Can't create DoM file after limit decrease"
23946         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23947                 error "Can create big DoM component after limit decrease"
23948         touch ${dom}_def ||
23949                 error "Can't create file with old default layout"
23950
23951         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23952         return 0
23953 }
23954 run_test 270f "DoM: maximum DoM stripe size checks"
23955
23956 test_270g() {
23957         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23958                 skip "Need MDS version at least 2.13.52"
23959         local dom=$DIR/$tdir/$tfile
23960
23961         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23962         local lodname=${FSNAME}-MDT0000-mdtlov
23963
23964         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23965         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23966         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23967         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23968
23969         local dom_limit=1024
23970         local dom_threshold="50%"
23971
23972         $LFS setstripe -d $DIR/$tdir
23973         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23974                 error "Can't set directory default striping"
23975
23976         do_facet mds1 $LCTL set_param -n \
23977                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23978         # set 0 threshold and create DOM file to change tunable stripesize
23979         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23980         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23981                 error "Failed to create $dom file"
23982         # now tunable dom_cur_stripesize should reach maximum
23983         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23984                                         lod.${lodname}.dom_stripesize_cur_kb)
23985         [[ $dom_current == $dom_limit ]] ||
23986                 error "Current DOM stripesize is not maximum"
23987         rm $dom
23988
23989         # set threshold for further tests
23990         do_facet mds1 $LCTL set_param -n \
23991                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23992         echo "DOM threshold is $dom_threshold free space"
23993         local dom_def
23994         local dom_set
23995         # Spoof bfree to exceed threshold
23996         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23997         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23998         for spfree in 40 20 0 15 30 55; do
23999                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24000                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24001                         error "Failed to create $dom file"
24002                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24003                                         lod.${lodname}.dom_stripesize_cur_kb)
24004                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24005                 [[ $dom_def != $dom_current ]] ||
24006                         error "Default stripe size was not changed"
24007                 if (( spfree > 0 )) ; then
24008                         dom_set=$($LFS getstripe -S $dom)
24009                         (( dom_set == dom_def * 1024 )) ||
24010                                 error "DOM component size is still old"
24011                 else
24012                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24013                                 error "DoM component is set with no free space"
24014                 fi
24015                 rm $dom
24016                 dom_current=$dom_def
24017         done
24018 }
24019 run_test 270g "DoM: default DoM stripe size depends on free space"
24020
24021 test_270h() {
24022         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24023                 skip "Need MDS version at least 2.13.53"
24024
24025         local mdtname=${FSNAME}-MDT0000-mdtlov
24026         local dom=$DIR/$tdir/$tfile
24027         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24028
24029         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24030         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24031
24032         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24033         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24034                 error "can't create OST file"
24035         # mirrored file with DOM entry in the second mirror
24036         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24037                 error "can't create mirror with DoM component"
24038
24039         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24040
24041         # DOM component in the middle and has other enries in the same mirror,
24042         # should succeed but lost DoM component
24043         $LFS setstripe --copy=${dom}_1 $dom ||
24044                 error "Can't create file from OST|DOM mirror layout"
24045         # check new file has no DoM layout after all
24046         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24047                 error "File has DoM component while DoM is disabled"
24048 }
24049 run_test 270h "DoM: DoM stripe removal when disabled on server"
24050
24051 test_270i() {
24052         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24053                 skip "Need MDS version at least 2.14.54"
24054
24055         mkdir $DIR/$tdir
24056         # DoM with plain layout
24057         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24058                 error "default plain layout with DoM must fail"
24059         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24060                 error "setstripe plain file layout with DoM must fail"
24061         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24062                 error "default DoM layout with bad striping must fail"
24063         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24064                 error "setstripe to DoM layout with bad striping must fail"
24065         return 0
24066 }
24067 run_test 270i "DoM: setting invalid DoM striping should fail"
24068
24069 test_270j() {
24070         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24071                 skip "Need MDS version at least 2.15.55.203"
24072
24073         local dom=$DIR/$tdir/$tfile
24074         local odv
24075         local ndv
24076
24077         mkdir -p $DIR/$tdir
24078
24079         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24080
24081         odv=$($LFS data_version $dom)
24082         chmod 666 $dom
24083         mv $dom ${dom}_moved
24084         link ${dom}_moved $dom
24085         setfattr -n user.attrx -v "some_attr" $dom
24086         ndv=$($LFS data_version $dom)
24087         (( $ndv == $odv )) ||
24088                 error "data version was changed by metadata operations"
24089
24090         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24091                 error "failed to write data into $dom"
24092         cancel_lru_locks mdc
24093         ndv=$($LFS data_version $dom)
24094         (( $ndv != $odv )) ||
24095                 error "data version wasn't changed on write"
24096
24097         odv=$ndv
24098         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24099         ndv=$($LFS data_version $dom)
24100         (( $ndv != $odv )) ||
24101                 error "data version wasn't changed on truncate down"
24102
24103         odv=$ndv
24104         $TRUNCATE $dom 25000
24105         ndv=$($LFS data_version $dom)
24106         (( $ndv != $odv )) ||
24107                 error "data version wasn't changed on truncate up"
24108
24109         # check also fallocate for ldiskfs
24110         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24111                 odv=$ndv
24112                 fallocate -l 1048576 $dom
24113                 ndv=$($LFS data_version $dom)
24114                 (( $ndv != $odv )) ||
24115                         error "data version wasn't changed on fallocate"
24116
24117                 odv=$ndv
24118                 fallocate -p --offset 4096 -l 4096 $dom
24119                 ndv=$($LFS data_version $dom)
24120                 (( $ndv != $odv )) ||
24121                         error "data version wasn't changed on fallocate punch"
24122         fi
24123 }
24124 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24125
24126 test_271a() {
24127         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24128                 skip "Need MDS version at least 2.10.55"
24129
24130         local dom=$DIR/$tdir/dom
24131
24132         mkdir -p $DIR/$tdir
24133
24134         $LFS setstripe -E 1024K -L mdt $dom
24135
24136         lctl set_param -n mdc.*.stats=clear
24137         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24138         cat $dom > /dev/null
24139         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24140         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24141         ls $dom
24142         rm -f $dom
24143 }
24144 run_test 271a "DoM: data is cached for read after write"
24145
24146 test_271b() {
24147         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24148                 skip "Need MDS version at least 2.10.55"
24149
24150         local dom=$DIR/$tdir/dom
24151
24152         mkdir -p $DIR/$tdir
24153
24154         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24155
24156         lctl set_param -n mdc.*.stats=clear
24157         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24158         cancel_lru_locks mdc
24159         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24160         # second stat to check size is cached on client
24161         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24162         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24163         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24164         rm -f $dom
24165 }
24166 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24167
24168 test_271ba() {
24169         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24170                 skip "Need MDS version at least 2.10.55"
24171
24172         local dom=$DIR/$tdir/dom
24173
24174         mkdir -p $DIR/$tdir
24175
24176         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24177
24178         lctl set_param -n mdc.*.stats=clear
24179         lctl set_param -n osc.*.stats=clear
24180         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24181         cancel_lru_locks mdc
24182         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24183         # second stat to check size is cached on client
24184         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24185         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24186         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24187         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24188         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24189         rm -f $dom
24190 }
24191 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24192
24193
24194 get_mdc_stats() {
24195         local mdtidx=$1
24196         local param=$2
24197         local mdt=MDT$(printf %04x $mdtidx)
24198
24199         if [ -z $param ]; then
24200                 lctl get_param -n mdc.*$mdt*.stats
24201         else
24202                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24203         fi
24204 }
24205
24206 test_271c() {
24207         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24208                 skip "Need MDS version at least 2.10.55"
24209
24210         local dom=$DIR/$tdir/dom
24211
24212         mkdir -p $DIR/$tdir
24213
24214         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24215
24216         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24217         local facet=mds$((mdtidx + 1))
24218
24219         cancel_lru_locks mdc
24220         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24221         createmany -o $dom 1000
24222         lctl set_param -n mdc.*.stats=clear
24223         smalliomany -w $dom 1000 200
24224         get_mdc_stats $mdtidx
24225         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24226         # Each file has 1 open, 1 IO enqueues, total 2000
24227         # but now we have also +1 getxattr for security.capability, total 3000
24228         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24229         unlinkmany $dom 1000
24230
24231         cancel_lru_locks mdc
24232         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24233         createmany -o $dom 1000
24234         lctl set_param -n mdc.*.stats=clear
24235         smalliomany -w $dom 1000 200
24236         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24237         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24238         # for OPEN and IO lock.
24239         [ $((enq - enq_2)) -ge 1000 ] ||
24240                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24241         unlinkmany $dom 1000
24242         return 0
24243 }
24244 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24245
24246 cleanup_271def_tests() {
24247         trap 0
24248         rm -f $1
24249 }
24250
24251 test_271d() {
24252         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24253                 skip "Need MDS version at least 2.10.57"
24254
24255         local dom=$DIR/$tdir/dom
24256         local tmp=$TMP/$tfile
24257         trap "cleanup_271def_tests $tmp" EXIT
24258
24259         mkdir -p $DIR/$tdir
24260
24261         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24262
24263         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24264
24265         cancel_lru_locks mdc
24266         dd if=/dev/urandom of=$tmp bs=1000 count=1
24267         dd if=$tmp of=$dom bs=1000 count=1
24268         cancel_lru_locks mdc
24269
24270         cat /etc/hosts >> $tmp
24271         lctl set_param -n mdc.*.stats=clear
24272
24273         # append data to the same file it should update local page
24274         echo "Append to the same page"
24275         cat /etc/hosts >> $dom
24276         local num=$(get_mdc_stats $mdtidx ost_read)
24277         local ra=$(get_mdc_stats $mdtidx req_active)
24278         local rw=$(get_mdc_stats $mdtidx req_waittime)
24279
24280         [ -z $num ] || error "$num READ RPC occured"
24281         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24282         echo "... DONE"
24283
24284         # compare content
24285         cmp $tmp $dom || error "file miscompare"
24286
24287         cancel_lru_locks mdc
24288         lctl set_param -n mdc.*.stats=clear
24289
24290         echo "Open and read file"
24291         cat $dom > /dev/null
24292         local num=$(get_mdc_stats $mdtidx ost_read)
24293         local ra=$(get_mdc_stats $mdtidx req_active)
24294         local rw=$(get_mdc_stats $mdtidx req_waittime)
24295
24296         [ -z $num ] || error "$num READ RPC occured"
24297         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24298         echo "... DONE"
24299
24300         # compare content
24301         cmp $tmp $dom || error "file miscompare"
24302
24303         return 0
24304 }
24305 run_test 271d "DoM: read on open (1K file in reply buffer)"
24306
24307 test_271f() {
24308         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24309                 skip "Need MDS version at least 2.10.57"
24310
24311         local dom=$DIR/$tdir/dom
24312         local tmp=$TMP/$tfile
24313         trap "cleanup_271def_tests $tmp" EXIT
24314
24315         mkdir -p $DIR/$tdir
24316
24317         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24318
24319         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24320
24321         cancel_lru_locks mdc
24322         dd if=/dev/urandom of=$tmp bs=265000 count=1
24323         dd if=$tmp of=$dom bs=265000 count=1
24324         cancel_lru_locks mdc
24325         cat /etc/hosts >> $tmp
24326         lctl set_param -n mdc.*.stats=clear
24327
24328         echo "Append to the same page"
24329         cat /etc/hosts >> $dom
24330         local num=$(get_mdc_stats $mdtidx ost_read)
24331         local ra=$(get_mdc_stats $mdtidx req_active)
24332         local rw=$(get_mdc_stats $mdtidx req_waittime)
24333
24334         [ -z $num ] || error "$num READ RPC occured"
24335         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24336         echo "... DONE"
24337
24338         # compare content
24339         cmp $tmp $dom || error "file miscompare"
24340
24341         cancel_lru_locks mdc
24342         lctl set_param -n mdc.*.stats=clear
24343
24344         echo "Open and read file"
24345         cat $dom > /dev/null
24346         local num=$(get_mdc_stats $mdtidx ost_read)
24347         local ra=$(get_mdc_stats $mdtidx req_active)
24348         local rw=$(get_mdc_stats $mdtidx req_waittime)
24349
24350         [ -z $num ] && num=0
24351         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24352         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24353         echo "... DONE"
24354
24355         # compare content
24356         cmp $tmp $dom || error "file miscompare"
24357
24358         return 0
24359 }
24360 run_test 271f "DoM: read on open (200K file and read tail)"
24361
24362 test_271g() {
24363         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24364                 skip "Skipping due to old client or server version"
24365
24366         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24367         # to get layout
24368         $CHECKSTAT -t file $DIR1/$tfile
24369
24370         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24371         MULTIOP_PID=$!
24372         sleep 1
24373         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24374         $LCTL set_param fail_loc=0x80000314
24375         rm $DIR1/$tfile || error "Unlink fails"
24376         RC=$?
24377         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24378         [ $RC -eq 0 ] || error "Failed write to stale object"
24379 }
24380 run_test 271g "Discard DoM data vs client flush race"
24381
24382 test_272a() {
24383         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24384                 skip "Need MDS version at least 2.11.50"
24385
24386         local dom=$DIR/$tdir/dom
24387         mkdir -p $DIR/$tdir
24388
24389         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24390         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24391                 error "failed to write data into $dom"
24392         local old_md5=$(md5sum $dom)
24393
24394         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24395                 error "failed to migrate to the same DoM component"
24396
24397         local new_md5=$(md5sum $dom)
24398
24399         [ "$old_md5" == "$new_md5" ] ||
24400                 error "md5sum differ: $old_md5, $new_md5"
24401
24402         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24403                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24404 }
24405 run_test 272a "DoM migration: new layout with the same DOM component"
24406
24407 test_272b() {
24408         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24409                 skip "Need MDS version at least 2.11.50"
24410
24411         local dom=$DIR/$tdir/dom
24412         mkdir -p $DIR/$tdir
24413         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24414         stack_trap "rm -rf $DIR/$tdir"
24415
24416         local mdtidx=$($LFS getstripe -m $dom)
24417         local mdtname=MDT$(printf %04x $mdtidx)
24418         local facet=mds$((mdtidx + 1))
24419
24420         local mdtfree1=$(do_facet $facet \
24421                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24422         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24423                 error "failed to write data into $dom"
24424         local old_md5=$(md5sum $dom)
24425         cancel_lru_locks mdc
24426         local mdtfree1=$(do_facet $facet \
24427                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24428
24429         $LFS migrate -c2 $dom ||
24430                 error "failed to migrate to the new composite layout"
24431         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24432                 error "MDT stripe was not removed"
24433         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24434                 error "$dir1 shouldn't have DATAVER EA"
24435
24436         cancel_lru_locks mdc
24437         local new_md5=$(md5sum $dom)
24438         [ "$old_md5" == "$new_md5" ] ||
24439                 error "$old_md5 != $new_md5"
24440
24441         # Skip free space checks with ZFS
24442         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24443                 local mdtfree2=$(do_facet $facet \
24444                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24445                 [ $mdtfree2 -gt $mdtfree1 ] ||
24446                         error "MDT space is not freed after migration"
24447         fi
24448         return 0
24449 }
24450 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24451
24452 test_272c() {
24453         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24454                 skip "Need MDS version at least 2.11.50"
24455
24456         local dom=$DIR/$tdir/$tfile
24457         mkdir -p $DIR/$tdir
24458         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24459         stack_trap "rm -rf $DIR/$tdir"
24460
24461         local mdtidx=$($LFS getstripe -m $dom)
24462         local mdtname=MDT$(printf %04x $mdtidx)
24463         local facet=mds$((mdtidx + 1))
24464
24465         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24466                 error "failed to write data into $dom"
24467         local old_md5=$(md5sum $dom)
24468         cancel_lru_locks mdc
24469         local mdtfree1=$(do_facet $facet \
24470                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24471
24472         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24473                 error "failed to migrate to the new composite layout"
24474         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24475                 error "MDT stripe was not removed"
24476
24477         cancel_lru_locks mdc
24478         local new_md5=$(md5sum $dom)
24479         [ "$old_md5" == "$new_md5" ] ||
24480                 error "$old_md5 != $new_md5"
24481
24482         # Skip free space checks with ZFS
24483         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24484                 local mdtfree2=$(do_facet $facet \
24485                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24486                 [ $mdtfree2 -gt $mdtfree1 ] ||
24487                         error "MDS space is not freed after migration"
24488         fi
24489         return 0
24490 }
24491 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24492
24493 test_272d() {
24494         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24495                 skip "Need MDS version at least 2.12.55"
24496
24497         local dom=$DIR/$tdir/$tfile
24498         mkdir -p $DIR/$tdir
24499         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24500
24501         local mdtidx=$($LFS getstripe -m $dom)
24502         local mdtname=MDT$(printf %04x $mdtidx)
24503         local facet=mds$((mdtidx + 1))
24504
24505         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24506                 error "failed to write data into $dom"
24507         local old_md5=$(md5sum $dom)
24508         cancel_lru_locks mdc
24509         local mdtfree1=$(do_facet $facet \
24510                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24511
24512         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24513                 error "failed mirroring to the new composite layout"
24514         $LFS mirror resync $dom ||
24515                 error "failed mirror resync"
24516         $LFS mirror split --mirror-id 1 -d $dom ||
24517                 error "failed mirror split"
24518
24519         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24520                 error "MDT stripe was not removed"
24521
24522         cancel_lru_locks mdc
24523         local new_md5=$(md5sum $dom)
24524         [ "$old_md5" == "$new_md5" ] ||
24525                 error "$old_md5 != $new_md5"
24526
24527         # Skip free space checks with ZFS
24528         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24529                 local mdtfree2=$(do_facet $facet \
24530                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24531                 [ $mdtfree2 -gt $mdtfree1 ] ||
24532                         error "MDS space is not freed after DOM mirror deletion"
24533         fi
24534         return 0
24535 }
24536 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24537
24538 test_272e() {
24539         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24540                 skip "Need MDS version at least 2.12.55"
24541
24542         local dom=$DIR/$tdir/$tfile
24543         mkdir -p $DIR/$tdir
24544         $LFS setstripe -c 2 $dom
24545
24546         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24547                 error "failed to write data into $dom"
24548         local old_md5=$(md5sum $dom)
24549         cancel_lru_locks
24550
24551         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24552                 error "failed mirroring to the DOM layout"
24553         $LFS mirror resync $dom ||
24554                 error "failed mirror resync"
24555         $LFS mirror split --mirror-id 1 -d $dom ||
24556                 error "failed mirror split"
24557
24558         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24559                 error "MDT stripe wasn't set"
24560
24561         cancel_lru_locks
24562         local new_md5=$(md5sum $dom)
24563         [ "$old_md5" == "$new_md5" ] ||
24564                 error "$old_md5 != $new_md5"
24565
24566         return 0
24567 }
24568 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24569
24570 test_272f() {
24571         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24572                 skip "Need MDS version at least 2.12.55"
24573
24574         local dom=$DIR/$tdir/$tfile
24575         mkdir -p $DIR/$tdir
24576         $LFS setstripe -c 2 $dom
24577
24578         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24579                 error "failed to write data into $dom"
24580         local old_md5=$(md5sum $dom)
24581         cancel_lru_locks
24582
24583         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24584                 error "failed migrating to the DOM file"
24585
24586         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24587                 error "MDT stripe wasn't set"
24588
24589         cancel_lru_locks
24590         local new_md5=$(md5sum $dom)
24591         [ "$old_md5" != "$new_md5" ] &&
24592                 error "$old_md5 != $new_md5"
24593
24594         return 0
24595 }
24596 run_test 272f "DoM migration: OST-striped file to DOM file"
24597
24598 test_273a() {
24599         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24600                 skip "Need MDS version at least 2.11.50"
24601
24602         # Layout swap cannot be done if either file has DOM component,
24603         # this will never be supported, migration should be used instead
24604
24605         local dom=$DIR/$tdir/$tfile
24606         mkdir -p $DIR/$tdir
24607
24608         $LFS setstripe -c2 ${dom}_plain
24609         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24610         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24611                 error "can swap layout with DoM component"
24612         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24613                 error "can swap layout with DoM component"
24614
24615         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24616         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24617                 error "can swap layout with DoM component"
24618         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24619                 error "can swap layout with DoM component"
24620         return 0
24621 }
24622 run_test 273a "DoM: layout swapping should fail with DOM"
24623
24624 test_273b() {
24625         mkdir -p $DIR/$tdir
24626         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24627
24628 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24629         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24630
24631         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24632 }
24633 run_test 273b "DoM: race writeback and object destroy"
24634
24635 test_273c() {
24636         mkdir -p $DIR/$tdir
24637         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24638
24639         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24640         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24641
24642         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24643 }
24644 run_test 273c "race writeback and object destroy"
24645
24646 test_275() {
24647         remote_ost_nodsh && skip "remote OST with nodsh"
24648         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24649                 skip "Need OST version >= 2.10.57"
24650
24651         local file=$DIR/$tfile
24652         local oss
24653
24654         oss=$(comma_list $(osts_nodes))
24655
24656         dd if=/dev/urandom of=$file bs=1M count=2 ||
24657                 error "failed to create a file"
24658         stack_trap "rm -f $file"
24659         cancel_lru_locks osc
24660
24661         #lock 1
24662         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24663                 error "failed to read a file"
24664
24665 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24666         $LCTL set_param fail_loc=0x8000031f
24667
24668         cancel_lru_locks osc &
24669         sleep 1
24670
24671 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24672         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24673         #IO takes another lock, but matches the PENDING one
24674         #and places it to the IO RPC
24675         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24676                 error "failed to read a file with PENDING lock"
24677 }
24678 run_test 275 "Read on a canceled duplicate lock"
24679
24680 test_276() {
24681         remote_ost_nodsh && skip "remote OST with nodsh"
24682         local pid
24683
24684         do_facet ost1 "(while true; do \
24685                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24686                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24687         pid=$!
24688
24689         for LOOP in $(seq 20); do
24690                 stop ost1
24691                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24692         done
24693         kill -9 $pid
24694         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24695                 rm $TMP/sanity_276_pid"
24696 }
24697 run_test 276 "Race between mount and obd_statfs"
24698
24699 test_277() {
24700         $LCTL set_param ldlm.namespaces.*.lru_size=0
24701         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24702         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24703                         grep ^used_mb | awk '{print $2}')
24704         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24705         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24706                 oflag=direct conv=notrunc
24707         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24708                         grep ^used_mb | awk '{print $2}')
24709         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24710 }
24711 run_test 277 "Direct IO shall drop page cache"
24712
24713 test_278() {
24714         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24715         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24716         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24717                 skip "needs the same host for mdt1 mdt2" && return
24718
24719         local pid1
24720         local pid2
24721
24722 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24723         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24724         stop mds2 &
24725         pid2=$!
24726
24727         stop mds1
24728
24729         echo "Starting MDTs"
24730         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24731         wait $pid2
24732 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24733 #will return NULL
24734         do_facet mds2 $LCTL set_param fail_loc=0
24735
24736         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24737         wait_recovery_complete mds2
24738 }
24739 run_test 278 "Race starting MDS between MDTs stop/start"
24740
24741 test_280() {
24742         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24743                 skip "Need MGS version at least 2.13.52"
24744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24745         combined_mgs_mds || skip "needs combined MGS/MDT"
24746
24747         umount_client $MOUNT
24748 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24749         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24750
24751         mount_client $MOUNT &
24752         sleep 1
24753         stop mgs || error "stop mgs failed"
24754         #for a race mgs would crash
24755         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24756         # make sure we unmount client before remounting
24757         wait
24758         umount_client $MOUNT
24759         mount_client $MOUNT || error "mount client failed"
24760 }
24761 run_test 280 "Race between MGS umount and client llog processing"
24762
24763 cleanup_test_300() {
24764         trap 0
24765         umask $SAVE_UMASK
24766 }
24767 test_striped_dir() {
24768         local mdt_index=$1
24769         local stripe_count
24770         local stripe_index
24771
24772         mkdir -p $DIR/$tdir
24773
24774         SAVE_UMASK=$(umask)
24775         trap cleanup_test_300 RETURN EXIT
24776
24777         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24778                                                 $DIR/$tdir/striped_dir ||
24779                 error "set striped dir error"
24780
24781         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24782         [ "$mode" = "755" ] || error "expect 755 got $mode"
24783
24784         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24785                 error "getdirstripe failed"
24786         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24787         if [ "$stripe_count" != "2" ]; then
24788                 error "1:stripe_count is $stripe_count, expect 2"
24789         fi
24790         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24791         if [ "$stripe_count" != "2" ]; then
24792                 error "2:stripe_count is $stripe_count, expect 2"
24793         fi
24794
24795         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24796         if [ "$stripe_index" != "$mdt_index" ]; then
24797                 error "stripe_index is $stripe_index, expect $mdt_index"
24798         fi
24799
24800         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24801                 error "nlink error after create striped dir"
24802
24803         mkdir $DIR/$tdir/striped_dir/a
24804         mkdir $DIR/$tdir/striped_dir/b
24805
24806         stat $DIR/$tdir/striped_dir/a ||
24807                 error "create dir under striped dir failed"
24808         stat $DIR/$tdir/striped_dir/b ||
24809                 error "create dir under striped dir failed"
24810
24811         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24812                 error "nlink error after mkdir"
24813
24814         rmdir $DIR/$tdir/striped_dir/a
24815         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24816                 error "nlink error after rmdir"
24817
24818         rmdir $DIR/$tdir/striped_dir/b
24819         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24820                 error "nlink error after rmdir"
24821
24822         chattr +i $DIR/$tdir/striped_dir
24823         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24824                 error "immutable flags not working under striped dir!"
24825         chattr -i $DIR/$tdir/striped_dir
24826
24827         rmdir $DIR/$tdir/striped_dir ||
24828                 error "rmdir striped dir error"
24829
24830         cleanup_test_300
24831
24832         true
24833 }
24834
24835 test_300a() {
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         test_striped_dir 0 || error "failed on striped dir on MDT0"
24842         test_striped_dir 1 || error "failed on striped dir on MDT0"
24843 }
24844 run_test 300a "basic striped dir sanity test"
24845
24846 test_300b() {
24847         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24848                 skip "skipped for lustre < 2.7.0"
24849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24851
24852         local i
24853         local mtime1
24854         local mtime2
24855         local mtime3
24856
24857         test_mkdir $DIR/$tdir || error "mkdir fail"
24858         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24859                 error "set striped dir error"
24860         for i in {0..9}; do
24861                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24862                 sleep 1
24863                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24864                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24865                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24866                 sleep 1
24867                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24868                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24869                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24870         done
24871         true
24872 }
24873 run_test 300b "check ctime/mtime for striped dir"
24874
24875 test_300c() {
24876         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24877                 skip "skipped for lustre < 2.7.0"
24878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24880
24881         local file_count
24882
24883         mkdir_on_mdt0 $DIR/$tdir
24884         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24885                 error "set striped dir error"
24886
24887         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24888                 error "chown striped dir failed"
24889
24890         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24891                 error "create 5k files failed"
24892
24893         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24894
24895         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24896
24897         rm -rf $DIR/$tdir
24898 }
24899 run_test 300c "chown && check ls under striped directory"
24900
24901 test_300d() {
24902         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24903                 skip "skipped for lustre < 2.7.0"
24904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24905         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24906
24907         local stripe_count
24908         local file
24909
24910         mkdir -p $DIR/$tdir
24911         $LFS setstripe -c 2 $DIR/$tdir
24912
24913         #local striped directory
24914         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24915                 error "set striped dir error"
24916         #look at the directories for debug purposes
24917         ls -l $DIR/$tdir
24918         $LFS getdirstripe $DIR/$tdir
24919         ls -l $DIR/$tdir/striped_dir
24920         $LFS getdirstripe $DIR/$tdir/striped_dir
24921         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24922                 error "create 10 files failed"
24923
24924         #remote striped directory
24925         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24926                 error "set striped dir error"
24927         #look at the directories for debug purposes
24928         ls -l $DIR/$tdir
24929         $LFS getdirstripe $DIR/$tdir
24930         ls -l $DIR/$tdir/remote_striped_dir
24931         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24932         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24933                 error "create 10 files failed"
24934
24935         for file in $(find $DIR/$tdir); do
24936                 stripe_count=$($LFS getstripe -c $file)
24937                 [ $stripe_count -eq 2 ] ||
24938                         error "wrong stripe $stripe_count for $file"
24939         done
24940
24941         rm -rf $DIR/$tdir
24942 }
24943 run_test 300d "check default stripe under striped directory"
24944
24945 test_300e() {
24946         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24947                 skip "Need MDS version at least 2.7.55"
24948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24949         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24950
24951         local stripe_count
24952         local file
24953
24954         mkdir -p $DIR/$tdir
24955
24956         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24957                 error "set striped dir error"
24958
24959         touch $DIR/$tdir/striped_dir/a
24960         touch $DIR/$tdir/striped_dir/b
24961         touch $DIR/$tdir/striped_dir/c
24962
24963         mkdir $DIR/$tdir/striped_dir/dir_a
24964         mkdir $DIR/$tdir/striped_dir/dir_b
24965         mkdir $DIR/$tdir/striped_dir/dir_c
24966
24967         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24968                 error "set striped adir under striped dir error"
24969
24970         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24971                 error "set striped bdir under striped dir error"
24972
24973         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24974                 error "set striped cdir under striped dir error"
24975
24976         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24977                 error "rename dir under striped dir fails"
24978
24979         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24980                 error "rename dir under different stripes fails"
24981
24982         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24983                 error "rename file under striped dir should succeed"
24984
24985         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24986                 error "rename dir under striped dir should succeed"
24987
24988         rm -rf $DIR/$tdir
24989 }
24990 run_test 300e "check rename under striped directory"
24991
24992 test_300f() {
24993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24995         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24996                 skip "Need MDS version at least 2.7.55"
24997
24998         local stripe_count
24999         local file
25000
25001         rm -rf $DIR/$tdir
25002         mkdir -p $DIR/$tdir
25003
25004         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25005                 error "set striped dir error"
25006
25007         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25008                 error "set striped dir error"
25009
25010         touch $DIR/$tdir/striped_dir/a
25011         mkdir $DIR/$tdir/striped_dir/dir_a
25012         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25013                 error "create striped dir under striped dir fails"
25014
25015         touch $DIR/$tdir/striped_dir1/b
25016         mkdir $DIR/$tdir/striped_dir1/dir_b
25017         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25018                 error "create striped dir under striped dir fails"
25019
25020         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25021                 error "rename dir under different striped dir should fail"
25022
25023         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25024                 error "rename striped dir under diff striped dir should fail"
25025
25026         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25027                 error "rename file under diff striped dirs fails"
25028
25029         rm -rf $DIR/$tdir
25030 }
25031 run_test 300f "check rename cross striped directory"
25032
25033 test_300_check_default_striped_dir()
25034 {
25035         local dirname=$1
25036         local default_count=$2
25037         local default_index=$3
25038         local stripe_count
25039         local stripe_index
25040         local dir_stripe_index
25041         local dir
25042
25043         echo "checking $dirname $default_count $default_index"
25044         $LFS setdirstripe -D -c $default_count -i $default_index \
25045                                 -H all_char $DIR/$tdir/$dirname ||
25046                 error "set default stripe on striped dir error"
25047         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25048         [ $stripe_count -eq $default_count ] ||
25049                 error "expect $default_count get $stripe_count for $dirname"
25050
25051         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25052         [ $stripe_index -eq $default_index ] ||
25053                 error "expect $default_index get $stripe_index for $dirname"
25054
25055         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25056                                                 error "create dirs failed"
25057
25058         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25059         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25060         for dir in $(find $DIR/$tdir/$dirname/*); do
25061                 stripe_count=$($LFS getdirstripe -c $dir)
25062                 (( $stripe_count == $default_count )) ||
25063                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25064                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25065                 error "stripe count $default_count != $stripe_count for $dir"
25066
25067                 stripe_index=$($LFS getdirstripe -i $dir)
25068                 [ $default_index -eq -1 ] ||
25069                         [ $stripe_index -eq $default_index ] ||
25070                         error "$stripe_index != $default_index for $dir"
25071
25072                 #check default stripe
25073                 stripe_count=$($LFS getdirstripe -D -c $dir)
25074                 [ $stripe_count -eq $default_count ] ||
25075                 error "default count $default_count != $stripe_count for $dir"
25076
25077                 stripe_index=$($LFS getdirstripe -D -i $dir)
25078                 [ $stripe_index -eq $default_index ] ||
25079                 error "default index $default_index != $stripe_index for $dir"
25080         done
25081         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25082 }
25083
25084 test_300g() {
25085         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25086         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25087                 skip "Need MDS version at least 2.7.55"
25088
25089         local dir
25090         local stripe_count
25091         local stripe_index
25092
25093         mkdir_on_mdt0 $DIR/$tdir
25094         mkdir $DIR/$tdir/normal_dir
25095
25096         #Checking when client cache stripe index
25097         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25098         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25099                 error "create striped_dir failed"
25100
25101         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25102                 error "create dir0 fails"
25103         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25104         [ $stripe_index -eq 0 ] ||
25105                 error "dir0 expect index 0 got $stripe_index"
25106
25107         mkdir $DIR/$tdir/striped_dir/dir1 ||
25108                 error "create dir1 fails"
25109         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25110         [ $stripe_index -eq 1 ] ||
25111                 error "dir1 expect index 1 got $stripe_index"
25112
25113         #check default stripe count/stripe index
25114         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25115         test_300_check_default_striped_dir normal_dir 1 0
25116         test_300_check_default_striped_dir normal_dir -1 1
25117         test_300_check_default_striped_dir normal_dir 2 -1
25118
25119         #delete default stripe information
25120         echo "delete default stripeEA"
25121         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25122                 error "set default stripe on striped dir error"
25123
25124         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25125         for dir in $(find $DIR/$tdir/normal_dir/*); do
25126                 stripe_count=$($LFS getdirstripe -c $dir)
25127                 [ $stripe_count -eq 0 ] ||
25128                         error "expect 1 get $stripe_count for $dir"
25129         done
25130 }
25131 run_test 300g "check default striped directory for normal directory"
25132
25133 test_300h() {
25134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25135         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25136                 skip "Need MDS version at least 2.7.55"
25137
25138         local dir
25139         local stripe_count
25140
25141         mkdir $DIR/$tdir
25142         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25143                 error "set striped dir error"
25144
25145         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25146         test_300_check_default_striped_dir striped_dir 1 0
25147         test_300_check_default_striped_dir striped_dir -1 1
25148         test_300_check_default_striped_dir striped_dir 2 -1
25149
25150         #delete default stripe information
25151         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25152                 error "set default stripe on striped dir error"
25153
25154         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25155         for dir in $(find $DIR/$tdir/striped_dir/*); do
25156                 stripe_count=$($LFS getdirstripe -c $dir)
25157                 [ $stripe_count -eq 0 ] ||
25158                         error "expect 1 get $stripe_count for $dir"
25159         done
25160 }
25161 run_test 300h "check default striped directory for striped directory"
25162
25163 test_300i() {
25164         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25165         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25166         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25167                 skip "Need MDS version at least 2.7.55"
25168
25169         local stripe_count
25170         local file
25171
25172         mkdir $DIR/$tdir
25173
25174         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25175                 error "set striped dir error"
25176
25177         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25178                 error "create files under striped dir failed"
25179
25180         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25181                 error "set striped hashdir error"
25182
25183         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25184                 error "create dir0 under hash dir failed"
25185         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25186                 error "create dir1 under hash dir failed"
25187         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25188                 error "create dir2 under hash dir failed"
25189
25190         # unfortunately, we need to umount to clear dir layout cache for now
25191         # once we fully implement dir layout, we can drop this
25192         umount_client $MOUNT || error "umount failed"
25193         mount_client $MOUNT || error "mount failed"
25194
25195         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25196         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25197         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25198
25199         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25200                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25201                         error "create crush2 dir $tdir/hashdir/d3 failed"
25202                 $LFS find -H crush2 $DIR/$tdir/hashdir
25203                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25204                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25205
25206                 # mkdir with an invalid hash type (hash=fail_val) from client
25207                 # should be replaced on MDS with a valid (default) hash type
25208                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25209                 $LCTL set_param fail_loc=0x1901 fail_val=99
25210                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25211
25212                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25213                 local expect=$(do_facet mds1 \
25214                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25215                 [[ $hash == $expect ]] ||
25216                         error "d99 hash '$hash' != expected hash '$expect'"
25217         fi
25218
25219         #set the stripe to be unknown hash type on read
25220         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25221         $LCTL set_param fail_loc=0x1901 fail_val=99
25222         for ((i = 0; i < 10; i++)); do
25223                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25224                         error "stat f-$i failed"
25225                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25226         done
25227
25228         touch $DIR/$tdir/striped_dir/f0 &&
25229                 error "create under striped dir with unknown hash should fail"
25230
25231         $LCTL set_param fail_loc=0
25232
25233         umount_client $MOUNT || error "umount failed"
25234         mount_client $MOUNT || error "mount failed"
25235
25236         return 0
25237 }
25238 run_test 300i "client handle unknown hash type striped directory"
25239
25240 test_300j() {
25241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25243         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25244                 skip "Need MDS version at least 2.7.55"
25245
25246         local stripe_count
25247         local file
25248
25249         mkdir $DIR/$tdir
25250
25251         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25252         $LCTL set_param fail_loc=0x1702
25253         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25254                 error "set striped dir error"
25255
25256         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25257                 error "create files under striped dir failed"
25258
25259         $LCTL set_param fail_loc=0
25260
25261         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25262
25263         return 0
25264 }
25265 run_test 300j "test large update record"
25266
25267 test_300k() {
25268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25269         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25270         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25271                 skip "Need MDS version at least 2.7.55"
25272
25273         # this test needs a huge transaction
25274         local kb
25275         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25276              osd*.$FSNAME-MDT0000.kbytestotal")
25277         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25278
25279         local stripe_count
25280         local file
25281
25282         mkdir $DIR/$tdir
25283
25284         #define OBD_FAIL_LARGE_STRIPE   0x1703
25285         $LCTL set_param fail_loc=0x1703
25286         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25287                 error "set striped dir error"
25288         $LCTL set_param fail_loc=0
25289
25290         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25291                 error "getstripeddir fails"
25292         rm -rf $DIR/$tdir/striped_dir ||
25293                 error "unlink striped dir fails"
25294
25295         return 0
25296 }
25297 run_test 300k "test large striped directory"
25298
25299 test_300l() {
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
25305         local stripe_index
25306
25307         test_mkdir -p $DIR/$tdir/striped_dir
25308         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25309                         error "chown $RUNAS_ID failed"
25310         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25311                 error "set default striped dir failed"
25312
25313         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25314         $LCTL set_param fail_loc=0x80000158
25315         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25316
25317         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25318         [ $stripe_index -eq 1 ] ||
25319                 error "expect 1 get $stripe_index for $dir"
25320 }
25321 run_test 300l "non-root user to create dir under striped dir with stale layout"
25322
25323 test_300m() {
25324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25325         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25326         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25327                 skip "Need MDS version at least 2.7.55"
25328
25329         mkdir -p $DIR/$tdir/striped_dir
25330         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25331                 error "set default stripes dir error"
25332
25333         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25334
25335         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25336         [ $stripe_count -eq 0 ] ||
25337                         error "expect 0 get $stripe_count for a"
25338
25339         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25340                 error "set default stripes dir error"
25341
25342         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25343
25344         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25345         [ $stripe_count -eq 0 ] ||
25346                         error "expect 0 get $stripe_count for b"
25347
25348         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25349                 error "set default stripes dir error"
25350
25351         mkdir $DIR/$tdir/striped_dir/c &&
25352                 error "default stripe_index is invalid, mkdir c should fails"
25353
25354         rm -rf $DIR/$tdir || error "rmdir fails"
25355 }
25356 run_test 300m "setstriped directory on single MDT FS"
25357
25358 cleanup_300n() {
25359         local list=$(comma_list $(mdts_nodes))
25360
25361         trap 0
25362         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25363 }
25364
25365 test_300n() {
25366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25367         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25368         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25369                 skip "Need MDS version at least 2.7.55"
25370         remote_mds_nodsh && skip "remote MDS with nodsh"
25371
25372         local stripe_index
25373         local list=$(comma_list $(mdts_nodes))
25374
25375         trap cleanup_300n RETURN EXIT
25376         mkdir -p $DIR/$tdir
25377         chmod 777 $DIR/$tdir
25378         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25379                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25380                 error "create striped dir succeeds with gid=0"
25381
25382         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25383         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25384                 error "create striped dir fails with gid=-1"
25385
25386         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25387         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25388                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25389                 error "set default striped dir succeeds with gid=0"
25390
25391
25392         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25393         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25394                 error "set default striped dir fails with gid=-1"
25395
25396
25397         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25398         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25399                                         error "create test_dir fails"
25400         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25401                                         error "create test_dir1 fails"
25402         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25403                                         error "create test_dir2 fails"
25404         cleanup_300n
25405 }
25406 run_test 300n "non-root user to create dir under striped dir with default EA"
25407
25408 test_300o() {
25409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25411         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25412                 skip "Need MDS version at least 2.7.55"
25413
25414         local numfree1
25415         local numfree2
25416
25417         mkdir -p $DIR/$tdir
25418
25419         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25420         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25421         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25422                 skip "not enough free inodes $numfree1 $numfree2"
25423         fi
25424
25425         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25426         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25427         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25428                 skip "not enough free space $numfree1 $numfree2"
25429         fi
25430
25431         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25432                 error "setdirstripe fails"
25433
25434         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25435                 error "create dirs fails"
25436
25437         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25438         ls $DIR/$tdir/striped_dir > /dev/null ||
25439                 error "ls striped dir fails"
25440         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25441                 error "unlink big striped dir fails"
25442 }
25443 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25444
25445 test_300p() {
25446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25448         remote_mds_nodsh && skip "remote MDS with nodsh"
25449
25450         mkdir_on_mdt0 $DIR/$tdir
25451
25452         #define OBD_FAIL_OUT_ENOSPC     0x1704
25453         do_facet mds2 lctl set_param fail_loc=0x80001704
25454         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25455                  && error "create striped directory should fail"
25456
25457         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25458
25459         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25460         true
25461 }
25462 run_test 300p "create striped directory without space"
25463
25464 test_300q() {
25465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25466         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25467
25468         local fd=$(free_fd)
25469         local cmd="exec $fd<$tdir"
25470         cd $DIR
25471         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25472         eval $cmd
25473         cmd="exec $fd<&-"
25474         trap "eval $cmd" EXIT
25475         cd $tdir || error "cd $tdir fails"
25476         rmdir  ../$tdir || error "rmdir $tdir fails"
25477         mkdir local_dir && error "create dir succeeds"
25478         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25479         eval $cmd
25480         return 0
25481 }
25482 run_test 300q "create remote directory under orphan directory"
25483
25484 test_300r() {
25485         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25486                 skip "Need MDS version at least 2.7.55" && return
25487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25488
25489         mkdir $DIR/$tdir
25490
25491         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25492                 error "set striped dir error"
25493
25494         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25495                 error "getstripeddir fails"
25496
25497         local stripe_count
25498         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25499                       awk '/lmv_stripe_count:/ { print $2 }')
25500
25501         [ $MDSCOUNT -ne $stripe_count ] &&
25502                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25503
25504         rm -rf $DIR/$tdir/striped_dir ||
25505                 error "unlink striped dir fails"
25506 }
25507 run_test 300r "test -1 striped directory"
25508
25509 test_300s_helper() {
25510         local count=$1
25511
25512         local stripe_dir=$DIR/$tdir/striped_dir.$count
25513
25514         $LFS mkdir -c $count $stripe_dir ||
25515                 error "lfs mkdir -c error"
25516
25517         $LFS getdirstripe $stripe_dir ||
25518                 error "lfs getdirstripe fails"
25519
25520         local stripe_count
25521         stripe_count=$($LFS getdirstripe $stripe_dir |
25522                       awk '/lmv_stripe_count:/ { print $2 }')
25523
25524         [ $count -ne $stripe_count ] &&
25525                 error_noexit "bad stripe count $stripe_count expected $count"
25526
25527         local dupe_stripes
25528         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25529                 awk '/0x/ {count[$1] += 1}; END {
25530                         for (idx in count) {
25531                                 if (count[idx]>1) {
25532                                         print "index " idx " count " count[idx]
25533                                 }
25534                         }
25535                 }')
25536
25537         if [[ -n "$dupe_stripes" ]] ; then
25538                 lfs getdirstripe $stripe_dir
25539                 error_noexit "Dupe MDT above: $dupe_stripes "
25540         fi
25541
25542         rm -rf $stripe_dir ||
25543                 error_noexit "unlink $stripe_dir fails"
25544 }
25545
25546 test_300s() {
25547         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25548                 skip "Need MDS version at least 2.7.55" && return
25549         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25550
25551         mkdir $DIR/$tdir
25552         for count in $(seq 2 $MDSCOUNT); do
25553                 test_300s_helper $count
25554         done
25555 }
25556 run_test 300s "test lfs mkdir -c without -i"
25557
25558 test_300t() {
25559         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25560                 skip "need MDS 2.14.55 or later"
25561         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25562
25563         local testdir="$DIR/$tdir/striped_dir"
25564         local dir1=$testdir/dir1
25565         local dir2=$testdir/dir2
25566
25567         mkdir -p $testdir
25568
25569         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25570                 error "failed to set default stripe count for $testdir"
25571
25572         mkdir $dir1
25573         local stripe_count=$($LFS getdirstripe -c $dir1)
25574
25575         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25576
25577         local max_count=$((MDSCOUNT - 1))
25578         local mdts=$(comma_list $(mdts_nodes))
25579
25580         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25581         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25582
25583         mkdir $dir2
25584         stripe_count=$($LFS getdirstripe -c $dir2)
25585
25586         (( $stripe_count == $max_count )) || error "wrong stripe count"
25587 }
25588 run_test 300t "test max_mdt_stripecount"
25589
25590 prepare_remote_file() {
25591         mkdir $DIR/$tdir/src_dir ||
25592                 error "create remote source failed"
25593
25594         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25595                  error "cp to remote source failed"
25596         touch $DIR/$tdir/src_dir/a
25597
25598         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25599                 error "create remote target dir failed"
25600
25601         touch $DIR/$tdir/tgt_dir/b
25602
25603         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25604                 error "rename dir cross MDT failed!"
25605
25606         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25607                 error "src_child still exists after rename"
25608
25609         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25610                 error "missing file(a) after rename"
25611
25612         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25613                 error "diff after rename"
25614 }
25615
25616 test_310a() {
25617         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25619
25620         local remote_file=$DIR/$tdir/tgt_dir/b
25621
25622         mkdir -p $DIR/$tdir
25623
25624         prepare_remote_file || error "prepare remote file failed"
25625
25626         #open-unlink file
25627         $OPENUNLINK $remote_file $remote_file ||
25628                 error "openunlink $remote_file failed"
25629         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25630 }
25631 run_test 310a "open unlink remote file"
25632
25633 test_310b() {
25634         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25636
25637         local remote_file=$DIR/$tdir/tgt_dir/b
25638
25639         mkdir -p $DIR/$tdir
25640
25641         prepare_remote_file || error "prepare remote file failed"
25642
25643         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25644         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25645         $CHECKSTAT -t file $remote_file || error "check file failed"
25646 }
25647 run_test 310b "unlink remote file with multiple links while open"
25648
25649 test_310c() {
25650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25651         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25652
25653         local remote_file=$DIR/$tdir/tgt_dir/b
25654
25655         mkdir -p $DIR/$tdir
25656
25657         prepare_remote_file || error "prepare remote file failed"
25658
25659         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25660         multiop_bg_pause $remote_file O_uc ||
25661                         error "mulitop failed for remote file"
25662         MULTIPID=$!
25663         $MULTIOP $DIR/$tfile Ouc
25664         kill -USR1 $MULTIPID
25665         wait $MULTIPID
25666 }
25667 run_test 310c "open-unlink remote file with multiple links"
25668
25669 #LU-4825
25670 test_311() {
25671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25672         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25673         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25674                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25675         remote_mds_nodsh && skip "remote MDS with nodsh"
25676
25677         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25678         local mdts=$(comma_list $(mdts_nodes))
25679
25680         mkdir -p $DIR/$tdir
25681         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25682         createmany -o $DIR/$tdir/$tfile. 1000
25683
25684         # statfs data is not real time, let's just calculate it
25685         old_iused=$((old_iused + 1000))
25686
25687         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25688                         osp.*OST0000*MDT0000.create_count")
25689         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25690                                 osp.*OST0000*MDT0000.max_create_count")
25691         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25692
25693         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25694         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25695         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25696
25697         unlinkmany $DIR/$tdir/$tfile. 1000
25698
25699         do_nodes $mdts "$LCTL set_param -n \
25700                         osp.*OST0000*.max_create_count=$max_count"
25701         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25702                 do_nodes $mdts "$LCTL set_param -n \
25703                                 osp.*OST0000*.create_count=$count"
25704         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25705                         grep "=0" && error "create_count is zero"
25706
25707         local new_iused
25708         for i in $(seq 120); do
25709                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25710                 # system may be too busy to destroy all objs in time, use
25711                 # a somewhat small value to not fail autotest
25712                 [ $((old_iused - new_iused)) -gt 400 ] && break
25713                 sleep 1
25714         done
25715
25716         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25717         [ $((old_iused - new_iused)) -gt 400 ] ||
25718                 error "objs not destroyed after unlink"
25719 }
25720 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25721
25722 zfs_get_objid()
25723 {
25724         local ost=$1
25725         local tf=$2
25726         local fid=($($LFS getstripe $tf | grep 0x))
25727         local seq=${fid[3]#0x}
25728         local objid=${fid[1]}
25729
25730         local vdevdir=$(dirname $(facet_vdevice $ost))
25731         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25732         local zfs_zapid=$(do_facet $ost $cmd |
25733                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25734                           awk '/Object/{getline; print $1}')
25735         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25736                           awk "/$objid = /"'{printf $3}')
25737
25738         echo $zfs_objid
25739 }
25740
25741 zfs_object_blksz() {
25742         local ost=$1
25743         local objid=$2
25744
25745         local vdevdir=$(dirname $(facet_vdevice $ost))
25746         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25747         local blksz=$(do_facet $ost $cmd $objid |
25748                       awk '/dblk/{getline; printf $4}')
25749
25750         case "${blksz: -1}" in
25751                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25752                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25753                 *) ;;
25754         esac
25755
25756         echo $blksz
25757 }
25758
25759 test_312() { # LU-4856
25760         remote_ost_nodsh && skip "remote OST with nodsh"
25761         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25762
25763         local max_blksz=$(do_facet ost1 \
25764                           $ZFS get -p recordsize $(facet_device ost1) |
25765                           awk '!/VALUE/{print $3}')
25766         local tf=$DIR/$tfile
25767
25768         $LFS setstripe -c1 $tf
25769         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25770
25771         # Get ZFS object id
25772         local zfs_objid=$(zfs_get_objid $facet $tf)
25773         # block size change by sequential overwrite
25774         local bs
25775
25776         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25777                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25778
25779                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25780                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25781         done
25782         rm -f $tf
25783
25784         $LFS setstripe -c1 $tf
25785         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25786
25787         # block size change by sequential append write
25788         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25789         zfs_objid=$(zfs_get_objid $facet $tf)
25790         local count
25791
25792         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25793                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25794                         oflag=sync conv=notrunc
25795
25796                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25797                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25798                         error "blksz error, actual $blksz, " \
25799                                 "expected: 2 * $count * $PAGE_SIZE"
25800         done
25801         rm -f $tf
25802
25803         # random write
25804         $LFS setstripe -c1 $tf
25805         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25806         zfs_objid=$(zfs_get_objid $facet $tf)
25807
25808         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25809         blksz=$(zfs_object_blksz $facet $zfs_objid)
25810         (( blksz == PAGE_SIZE )) ||
25811                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25812
25813         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25814         blksz=$(zfs_object_blksz $facet $zfs_objid)
25815         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25816
25817         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25818         blksz=$(zfs_object_blksz $facet $zfs_objid)
25819         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25820 }
25821 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25822
25823 test_313() {
25824         remote_ost_nodsh && skip "remote OST with nodsh"
25825
25826         local file=$DIR/$tfile
25827
25828         rm -f $file
25829         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25830
25831         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25832         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25833         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25834                 error "write should failed"
25835         do_facet ost1 "$LCTL set_param fail_loc=0"
25836         rm -f $file
25837 }
25838 run_test 313 "io should fail after last_rcvd update fail"
25839
25840 test_314() {
25841         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25842
25843         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25844         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25845         rm -f $DIR/$tfile
25846         wait_delete_completed
25847         do_facet ost1 "$LCTL set_param fail_loc=0"
25848 }
25849 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25850
25851 test_315() { # LU-618
25852         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25853
25854         local file=$DIR/$tfile
25855         rm -f $file
25856
25857         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25858                 error "multiop file write failed"
25859         $MULTIOP $file oO_RDONLY:r4063232_c &
25860         PID=$!
25861
25862         sleep 2
25863
25864         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25865         kill -USR1 $PID
25866
25867         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25868         rm -f $file
25869 }
25870 run_test 315 "read should be accounted"
25871
25872 test_316() {
25873         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25874         large_xattr_enabled || skip "ea_inode feature disabled"
25875
25876         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25877         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25878         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25879         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25880
25881         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25882 }
25883 run_test 316 "lfs migrate of file with large_xattr enabled"
25884
25885 test_317() {
25886         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25887                 skip "Need MDS version at least 2.11.53"
25888         if [ "$ost1_FSTYPE" == "zfs" ]; then
25889                 skip "LU-10370: no implementation for ZFS"
25890         fi
25891
25892         local trunc_sz
25893         local grant_blk_size
25894
25895         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25896                         awk '/grant_block_size:/ { print $2; exit; }')
25897         #
25898         # Create File of size 5M. Truncate it to below size's and verify
25899         # blocks count.
25900         #
25901         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25902                 error "Create file $DIR/$tfile failed"
25903         stack_trap "rm -f $DIR/$tfile" EXIT
25904
25905         for trunc_sz in 2097152 4097 4000 509 0; do
25906                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25907                         error "truncate $tfile to $trunc_sz failed"
25908                 local sz=$(stat --format=%s $DIR/$tfile)
25909                 local blk=$(stat --format=%b $DIR/$tfile)
25910                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25911                                      grant_blk_size) * 8))
25912
25913                 if [[ $blk -ne $trunc_blk ]]; then
25914                         $(which stat) $DIR/$tfile
25915                         error "Expected Block $trunc_blk got $blk for $tfile"
25916                 fi
25917
25918                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25919                         error "Expected Size $trunc_sz got $sz for $tfile"
25920         done
25921
25922         #
25923         # sparse file test
25924         # Create file with a hole and write actual 65536 bytes which aligned
25925         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25926         #
25927         local bs=65536
25928         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25929                 error "Create file : $DIR/$tfile"
25930
25931         #
25932         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25933         # blocks. The block count must drop to 8.
25934         #
25935         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25936                 ((bs - grant_blk_size) + 1)))
25937         $TRUNCATE $DIR/$tfile $trunc_sz ||
25938                 error "truncate $tfile to $trunc_sz failed"
25939
25940         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25941         sz=$(stat --format=%s $DIR/$tfile)
25942         blk=$(stat --format=%b $DIR/$tfile)
25943
25944         if [[ $blk -ne $trunc_bsz ]]; then
25945                 $(which stat) $DIR/$tfile
25946                 error "Expected Block $trunc_bsz got $blk for $tfile"
25947         fi
25948
25949         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25950                 error "Expected Size $trunc_sz got $sz for $tfile"
25951 }
25952 run_test 317 "Verify blocks get correctly update after truncate"
25953
25954 test_318() {
25955         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25956         local old_max_active=$($LCTL get_param -n \
25957                             ${llite_name}.max_read_ahead_async_active \
25958                             2>/dev/null)
25959
25960         $LCTL set_param llite.*.max_read_ahead_async_active=256
25961         local max_active=$($LCTL get_param -n \
25962                            ${llite_name}.max_read_ahead_async_active \
25963                            2>/dev/null)
25964         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25965
25966         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25967                 error "set max_read_ahead_async_active should succeed"
25968
25969         $LCTL set_param llite.*.max_read_ahead_async_active=512
25970         max_active=$($LCTL get_param -n \
25971                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25972         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25973
25974         # restore @max_active
25975         [ $old_max_active -ne 0 ] && $LCTL set_param \
25976                 llite.*.max_read_ahead_async_active=$old_max_active
25977
25978         local old_threshold=$($LCTL get_param -n \
25979                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25980         local max_per_file_mb=$($LCTL get_param -n \
25981                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25982
25983         local invalid=$(($max_per_file_mb + 1))
25984         $LCTL set_param \
25985                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25986                         && error "set $invalid should fail"
25987
25988         local valid=$(($invalid - 1))
25989         $LCTL set_param \
25990                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25991                         error "set $valid should succeed"
25992         local threshold=$($LCTL get_param -n \
25993                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25994         [ $threshold -eq $valid ] || error \
25995                 "expect threshold $valid got $threshold"
25996         $LCTL set_param \
25997                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25998 }
25999 run_test 318 "Verify async readahead tunables"
26000
26001 test_319() {
26002         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26003
26004         local before=$(date +%s)
26005         local evict
26006         local mdir=$DIR/$tdir
26007         local file=$mdir/xxx
26008
26009         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26010         touch $file
26011
26012 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26013         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26014         $LFS migrate -m1 $mdir &
26015
26016         sleep 1
26017         dd if=$file of=/dev/null
26018         wait
26019         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26020           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26021
26022         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26023 }
26024 run_test 319 "lost lease lock on migrate error"
26025
26026 test_398a() { # LU-4198
26027         local ost1_imp=$(get_osc_import_name client ost1)
26028         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26029                          cut -d'.' -f2)
26030
26031         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26032         stack_trap "rm -f $DIR/$tfile"
26033         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26034
26035         # request a new lock on client
26036         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26037
26038         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26039         local lock_count=$($LCTL get_param -n \
26040                            ldlm.namespaces.$imp_name.lru_size)
26041         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26042
26043         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26044
26045         # no lock cached, should use lockless DIO and not enqueue new lock
26046         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26047         lock_count=$($LCTL get_param -n \
26048                      ldlm.namespaces.$imp_name.lru_size)
26049         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26050
26051         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26052
26053         # no lock cached, should use locked DIO append
26054         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26055                 conv=notrunc || error "DIO append failed"
26056         lock_count=$($LCTL get_param -n \
26057                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26058         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26059 }
26060 run_test 398a "direct IO should cancel lock otherwise lockless"
26061
26062 test_398b() { # LU-4198
26063         local before=$(date +%s)
26064         local njobs=4
26065         local size=48
26066
26067         which fio || skip_env "no fio installed"
26068         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26069         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26070
26071         # Single page, multiple pages, stripe size, 4*stripe size
26072         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26073                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26074                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26075                         --numjobs=$njobs --fallocate=none \
26076                         --iodepth=16 --allow_file_create=0 \
26077                         --size=$((size/njobs))M \
26078                         --filename=$DIR/$tfile &
26079                 bg_pid=$!
26080
26081                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26082                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26083                         --numjobs=$njobs --fallocate=none \
26084                         --iodepth=16 --allow_file_create=0 \
26085                         --size=$((size/njobs))M \
26086                         --filename=$DIR/$tfile || true
26087                 wait $bg_pid
26088         done
26089
26090         evict=$(do_facet client $LCTL get_param \
26091                 osc.$FSNAME-OST*-osc-*/state |
26092             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26093
26094         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26095                 (do_facet client $LCTL get_param \
26096                         osc.$FSNAME-OST*-osc-*/state;
26097                     error "eviction happened: $evict before:$before")
26098
26099         rm -f $DIR/$tfile
26100 }
26101 run_test 398b "DIO and buffer IO race"
26102
26103 test_398c() { # LU-4198
26104         local ost1_imp=$(get_osc_import_name client ost1)
26105         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26106                          cut -d'.' -f2)
26107
26108         which fio || skip_env "no fio installed"
26109
26110         saved_debug=$($LCTL get_param -n debug)
26111         $LCTL set_param debug=0
26112
26113         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26114         ((size /= 1024)) # by megabytes
26115         ((size /= 2)) # write half of the OST at most
26116         [ $size -gt 40 ] && size=40 #reduce test time anyway
26117
26118         $LFS setstripe -c 1 $DIR/$tfile
26119
26120         # it seems like ldiskfs reserves more space than necessary if the
26121         # writing blocks are not mapped, so it extends the file firstly
26122         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26123         cancel_lru_locks osc
26124
26125         # clear and verify rpc_stats later
26126         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26127
26128         local njobs=4
26129         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26130         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26131                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26132                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26133                 --filename=$DIR/$tfile
26134         [ $? -eq 0 ] || error "fio write error"
26135
26136         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26137                 error "Locks were requested while doing AIO"
26138
26139         # get the percentage of 1-page I/O
26140         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26141                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26142                 awk '{print $7}')
26143         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26144
26145         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26146         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26147                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26148                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26149                 --filename=$DIR/$tfile
26150         [ $? -eq 0 ] || error "fio mixed read write error"
26151
26152         echo "AIO with large block size ${size}M"
26153         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26154                 --numjobs=1 --fallocate=none --ioengine=libaio \
26155                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26156                 --filename=$DIR/$tfile
26157         [ $? -eq 0 ] || error "fio large block size failed"
26158
26159         rm -f $DIR/$tfile
26160         $LCTL set_param debug="$saved_debug"
26161 }
26162 run_test 398c "run fio to test AIO"
26163
26164 test_398d() { #  LU-13846
26165         which aiocp || skip_env "no aiocp installed"
26166         local aio_file=$DIR/$tfile.aio
26167
26168         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26169
26170         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26171         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26172         stack_trap "rm -f $DIR/$tfile $aio_file"
26173
26174         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26175
26176         # make sure we don't crash and fail properly
26177         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26178                 error "aio not aligned with PAGE SIZE should fail"
26179
26180         rm -f $DIR/$tfile $aio_file
26181 }
26182 run_test 398d "run aiocp to verify block size > stripe size"
26183
26184 test_398e() {
26185         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26186         touch $DIR/$tfile.new
26187         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26188 }
26189 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26190
26191 test_398f() { #  LU-14687
26192         which aiocp || skip_env "no aiocp installed"
26193         local aio_file=$DIR/$tfile.aio
26194
26195         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26196
26197         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26198         stack_trap "rm -f $DIR/$tfile $aio_file"
26199
26200         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26201         $LCTL set_param fail_loc=0x1418
26202         # make sure we don't crash and fail properly
26203         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26204                 error "aio with page allocation failure succeeded"
26205         $LCTL set_param fail_loc=0
26206         diff $DIR/$tfile $aio_file
26207         [[ $? != 0 ]] || error "no diff after failed aiocp"
26208 }
26209 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26210
26211 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26212 # stripe and i/o size must be > stripe size
26213 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26214 # single RPC in flight.  This test shows async DIO submission is working by
26215 # showing multiple RPCs in flight.
26216 test_398g() { #  LU-13798
26217         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26218
26219         # We need to do some i/o first to acquire enough grant to put our RPCs
26220         # in flight; otherwise a new connection may not have enough grant
26221         # available
26222         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26223                 error "parallel dio failed"
26224         stack_trap "rm -f $DIR/$tfile"
26225
26226         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26227         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26228         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26229         stack_trap "$LCTL set_param -n $pages_per_rpc"
26230
26231         # Recreate file so it's empty
26232         rm -f $DIR/$tfile
26233         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26234         #Pause rpc completion to guarantee we see multiple rpcs in flight
26235         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26236         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26237         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26238
26239         # Clear rpc stats
26240         $LCTL set_param osc.*.rpc_stats=c
26241
26242         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26243                 error "parallel dio failed"
26244         stack_trap "rm -f $DIR/$tfile"
26245
26246         $LCTL get_param osc.*-OST0000-*.rpc_stats
26247         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26248                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26249                 grep "8:" | awk '{print $8}')
26250         # We look at the "8 rpcs in flight" field, and verify A) it is present
26251         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26252         # as expected for an 8M DIO to a file with 1M stripes.
26253         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26254
26255         # Verify turning off parallel dio works as expected
26256         # Clear rpc stats
26257         $LCTL set_param osc.*.rpc_stats=c
26258         $LCTL set_param llite.*.parallel_dio=0
26259         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26260
26261         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26262                 error "dio with parallel dio disabled failed"
26263
26264         # Ideally, we would see only one RPC in flight here, but there is an
26265         # unavoidable race between i/o completion and RPC in flight counting,
26266         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26267         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26268         # So instead we just verify it's always < 8.
26269         $LCTL get_param osc.*-OST0000-*.rpc_stats
26270         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26271                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26272                 grep '^$' -B1 | grep . | awk '{print $1}')
26273         [ $ret != "8:" ] ||
26274                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26275 }
26276 run_test 398g "verify parallel dio async RPC submission"
26277
26278 test_398h() { #  LU-13798
26279         local dio_file=$DIR/$tfile.dio
26280
26281         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26282
26283         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26284         stack_trap "rm -f $DIR/$tfile $dio_file"
26285
26286         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26287                 error "parallel dio failed"
26288         diff $DIR/$tfile $dio_file
26289         [[ $? == 0 ]] || error "file diff after aiocp"
26290 }
26291 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26292
26293 test_398i() { #  LU-13798
26294         local dio_file=$DIR/$tfile.dio
26295
26296         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26297
26298         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26299         stack_trap "rm -f $DIR/$tfile $dio_file"
26300
26301         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26302         $LCTL set_param fail_loc=0x1418
26303         # make sure we don't crash and fail properly
26304         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26305                 error "parallel dio page allocation failure succeeded"
26306         diff $DIR/$tfile $dio_file
26307         [[ $? != 0 ]] || error "no diff after failed aiocp"
26308 }
26309 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26310
26311 test_398j() { #  LU-13798
26312         # Stripe size > RPC size but less than i/o size tests split across
26313         # stripes and RPCs for individual i/o op
26314         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26315
26316         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26317         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26318         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26319         stack_trap "$LCTL set_param -n $pages_per_rpc"
26320
26321         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26322                 error "parallel dio write failed"
26323         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26324
26325         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26326                 error "parallel dio read failed"
26327         diff $DIR/$tfile $DIR/$tfile.2
26328         [[ $? == 0 ]] || error "file diff after parallel dio read"
26329 }
26330 run_test 398j "test parallel dio where stripe size > rpc_size"
26331
26332 test_398k() { #  LU-13798
26333         wait_delete_completed
26334         wait_mds_ost_sync
26335
26336         # 4 stripe file; we will cause out of space on OST0
26337         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26338
26339         # Fill OST0 (if it's not too large)
26340         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26341                    head -n1)
26342         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26343                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26344         fi
26345         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26346         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26347                 error "dd should fill OST0"
26348         stack_trap "rm -f $DIR/$tfile.1"
26349
26350         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26351         err=$?
26352
26353         ls -la $DIR/$tfile
26354         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26355                 error "file is not 0 bytes in size"
26356
26357         # dd above should not succeed, but don't error until here so we can
26358         # get debug info above
26359         [[ $err != 0 ]] ||
26360                 error "parallel dio write with enospc succeeded"
26361         stack_trap "rm -f $DIR/$tfile"
26362 }
26363 run_test 398k "test enospc on first stripe"
26364
26365 test_398l() { #  LU-13798
26366         wait_delete_completed
26367         wait_mds_ost_sync
26368
26369         # 4 stripe file; we will cause out of space on OST0
26370         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26371         # happens on the second i/o chunk we issue
26372         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26373
26374         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26375         stack_trap "rm -f $DIR/$tfile"
26376
26377         # Fill OST0 (if it's not too large)
26378         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26379                    head -n1)
26380         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26381                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26382         fi
26383         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26384         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26385                 error "dd should fill OST0"
26386         stack_trap "rm -f $DIR/$tfile.1"
26387
26388         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26389         err=$?
26390         stack_trap "rm -f $DIR/$tfile.2"
26391
26392         # Check that short write completed as expected
26393         ls -la $DIR/$tfile.2
26394         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26395                 error "file is not 1M in size"
26396
26397         # dd above should not succeed, but don't error until here so we can
26398         # get debug info above
26399         [[ $err != 0 ]] ||
26400                 error "parallel dio write with enospc succeeded"
26401
26402         # Truncate source file to same length as output file and diff them
26403         $TRUNCATE $DIR/$tfile 1048576
26404         diff $DIR/$tfile $DIR/$tfile.2
26405         [[ $? == 0 ]] || error "data incorrect after short write"
26406 }
26407 run_test 398l "test enospc on intermediate stripe/RPC"
26408
26409 test_398m() { #  LU-13798
26410         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26411
26412         # Set up failure on OST0, the first stripe:
26413         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26414         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26415         # OST0 is on ost1, OST1 is on ost2.
26416         # So this fail_val specifies OST0
26417         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26418         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26419
26420         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26421                 error "parallel dio write with failure on first stripe succeeded"
26422         stack_trap "rm -f $DIR/$tfile"
26423         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26424
26425         # Place data in file for read
26426         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26427                 error "parallel dio write failed"
26428
26429         # Fail read on OST0, first stripe
26430         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26431         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26432         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26433                 error "parallel dio read with error on first stripe succeeded"
26434         rm -f $DIR/$tfile.2
26435         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26436
26437         # Switch to testing on OST1, second stripe
26438         # Clear file contents, maintain striping
26439         echo > $DIR/$tfile
26440         # Set up failure on OST1, second stripe:
26441         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26442         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26443
26444         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26445                 error "parallel dio write with failure on second stripe succeeded"
26446         stack_trap "rm -f $DIR/$tfile"
26447         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26448
26449         # Place data in file for read
26450         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26451                 error "parallel dio write failed"
26452
26453         # Fail read on OST1, second stripe
26454         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26455         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26456         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26457                 error "parallel dio read with error on second stripe succeeded"
26458         rm -f $DIR/$tfile.2
26459         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26460 }
26461 run_test 398m "test RPC failures with parallel dio"
26462
26463 # Parallel submission of DIO should not cause problems for append, but it's
26464 # important to verify.
26465 test_398n() { #  LU-13798
26466         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26467
26468         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26469                 error "dd to create source file failed"
26470         stack_trap "rm -f $DIR/$tfile"
26471
26472         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26473                 error "parallel dio write with failure on second stripe succeeded"
26474         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26475         diff $DIR/$tfile $DIR/$tfile.1
26476         [[ $? == 0 ]] || error "data incorrect after append"
26477
26478 }
26479 run_test 398n "test append with parallel DIO"
26480
26481 test_398o() {
26482         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26483 }
26484 run_test 398o "right kms with DIO"
26485
26486 test_398p()
26487 {
26488         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26489         which aiocp || skip_env "no aiocp installed"
26490
26491         local stripe_size=$((1024 * 1024)) #1 MiB
26492         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26493         local file_size=$((25 * stripe_size))
26494
26495         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26496         stack_trap "rm -f $DIR/$tfile*"
26497         # Just a bit bigger than the largest size in the test set below
26498         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26499                 error "buffered i/o to create file failed"
26500
26501         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26502                 $((stripe_size * 4)); do
26503
26504                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26505
26506                 echo "bs: $bs, file_size $file_size"
26507                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26508                         $DIR/$tfile.1 $DIR/$tfile.2 &
26509                 pid_dio1=$!
26510                 # Buffered I/O with similar but not the same block size
26511                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26512                         conv=notrunc &
26513                 pid_bio2=$!
26514                 wait $pid_dio1
26515                 rc1=$?
26516                 wait $pid_bio2
26517                 rc2=$?
26518                 if (( rc1 != 0 )); then
26519                         error "aio copy 1 w/bsize $bs failed: $rc1"
26520                 fi
26521                 if (( rc2 != 0 )); then
26522                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26523                 fi
26524
26525                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26526                         error "size incorrect"
26527                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26528                         error "files differ, bsize $bs"
26529                 rm -f $DIR/$tfile.2
26530         done
26531 }
26532 run_test 398p "race aio with buffered i/o"
26533
26534 test_fake_rw() {
26535         local read_write=$1
26536         if [ "$read_write" = "write" ]; then
26537                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26538         elif [ "$read_write" = "read" ]; then
26539                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26540         else
26541                 error "argument error"
26542         fi
26543
26544         # turn off debug for performance testing
26545         local saved_debug=$($LCTL get_param -n debug)
26546         $LCTL set_param debug=0
26547
26548         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26549
26550         # get ost1 size - $FSNAME-OST0000
26551         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26552         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26553         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26554
26555         if [ "$read_write" = "read" ]; then
26556                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26557         fi
26558
26559         local start_time=$(date +%s.%N)
26560         $dd_cmd bs=1M count=$blocks oflag=sync ||
26561                 error "real dd $read_write error"
26562         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26563
26564         if [ "$read_write" = "write" ]; then
26565                 rm -f $DIR/$tfile
26566         fi
26567
26568         # define OBD_FAIL_OST_FAKE_RW           0x238
26569         do_facet ost1 $LCTL set_param fail_loc=0x238
26570
26571         local start_time=$(date +%s.%N)
26572         $dd_cmd bs=1M count=$blocks oflag=sync ||
26573                 error "fake dd $read_write error"
26574         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26575
26576         if [ "$read_write" = "write" ]; then
26577                 # verify file size
26578                 cancel_lru_locks osc
26579                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26580                         error "$tfile size not $blocks MB"
26581         fi
26582         do_facet ost1 $LCTL set_param fail_loc=0
26583
26584         echo "fake $read_write $duration_fake vs. normal $read_write" \
26585                 "$duration in seconds"
26586         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26587                 error_not_in_vm "fake write is slower"
26588
26589         $LCTL set_param -n debug="$saved_debug"
26590         rm -f $DIR/$tfile
26591 }
26592 test_399a() { # LU-7655 for OST fake write
26593         remote_ost_nodsh && skip "remote OST with nodsh"
26594
26595         test_fake_rw write
26596 }
26597 run_test 399a "fake write should not be slower than normal write"
26598
26599 test_399b() { # LU-8726 for OST fake read
26600         remote_ost_nodsh && skip "remote OST with nodsh"
26601         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26602                 skip_env "ldiskfs only test"
26603         fi
26604
26605         test_fake_rw read
26606 }
26607 run_test 399b "fake read should not be slower than normal read"
26608
26609 test_400a() { # LU-1606, was conf-sanity test_74
26610         if ! which $CC > /dev/null 2>&1; then
26611                 skip_env "$CC is not installed"
26612         fi
26613
26614         local extra_flags=''
26615         local out=$TMP/$tfile
26616         local prefix=/usr/include/lustre
26617         local prog
26618
26619         # Oleg removes .c files in his test rig so test if any c files exist
26620         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26621                 skip_env "Needed .c test files are missing"
26622
26623         if ! [[ -d $prefix ]]; then
26624                 # Assume we're running in tree and fixup the include path.
26625                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26626                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26627                 extra_flags+=" -L$LUSTRE/utils/.libs"
26628         fi
26629
26630         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26631                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26632                         error "client api broken"
26633         done
26634         rm -f $out
26635 }
26636 run_test 400a "Lustre client api program can compile and link"
26637
26638 test_400b() { # LU-1606, LU-5011
26639         local header
26640         local out=$TMP/$tfile
26641         local prefix=/usr/include/linux/lustre
26642
26643         # We use a hard coded prefix so that this test will not fail
26644         # when run in tree. There are headers in lustre/include/lustre/
26645         # that are not packaged (like lustre_idl.h) and have more
26646         # complicated include dependencies (like config.h and lnet/types.h).
26647         # Since this test about correct packaging we just skip them when
26648         # they don't exist (see below) rather than try to fixup cppflags.
26649
26650         if ! which $CC > /dev/null 2>&1; then
26651                 skip_env "$CC is not installed"
26652         fi
26653
26654         for header in $prefix/*.h; do
26655                 if ! [[ -f "$header" ]]; then
26656                         continue
26657                 fi
26658
26659                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26660                         continue # lustre_ioctl.h is internal header
26661                 fi
26662
26663                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26664                         error "cannot compile '$header'"
26665         done
26666         rm -f $out
26667 }
26668 run_test 400b "packaged headers can be compiled"
26669
26670 test_401a() { #LU-7437
26671         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26672         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26673
26674         #count the number of parameters by "list_param -R"
26675         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26676         #count the number of parameters by listing proc files
26677         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26678         echo "proc_dirs='$proc_dirs'"
26679         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26680         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26681                       sort -u | wc -l)
26682
26683         [ $params -eq $procs ] ||
26684                 error "found $params parameters vs. $procs proc files"
26685
26686         # test the list_param -D option only returns directories
26687         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26688         #count the number of parameters by listing proc directories
26689         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26690                 sort -u | wc -l)
26691
26692         [ $params -eq $procs ] ||
26693                 error "found $params parameters vs. $procs proc files"
26694 }
26695 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26696
26697 test_401b() {
26698         # jobid_var may not allow arbitrary values, so use jobid_name
26699         # if available
26700         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26701                 local testname=jobid_name tmp='testing%p'
26702         else
26703                 local testname=jobid_var tmp=testing
26704         fi
26705
26706         local save=$($LCTL get_param -n $testname)
26707
26708         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26709                 error "no error returned when setting bad parameters"
26710
26711         local jobid_new=$($LCTL get_param -n foe $testname baz)
26712         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26713
26714         $LCTL set_param -n fog=bam $testname=$save bat=fog
26715         local jobid_old=$($LCTL get_param -n foe $testname bag)
26716         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26717 }
26718 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26719
26720 test_401c() {
26721         # jobid_var may not allow arbitrary values, so use jobid_name
26722         # if available
26723         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26724                 local testname=jobid_name
26725         else
26726                 local testname=jobid_var
26727         fi
26728
26729         local jobid_var_old=$($LCTL get_param -n $testname)
26730         local jobid_var_new
26731
26732         $LCTL set_param $testname= &&
26733                 error "no error returned for 'set_param a='"
26734
26735         jobid_var_new=$($LCTL get_param -n $testname)
26736         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26737                 error "$testname was changed by setting without value"
26738
26739         $LCTL set_param $testname &&
26740                 error "no error returned for 'set_param a'"
26741
26742         jobid_var_new=$($LCTL get_param -n $testname)
26743         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26744                 error "$testname was changed by setting without value"
26745 }
26746 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26747
26748 test_401d() {
26749         # jobid_var may not allow arbitrary values, so use jobid_name
26750         # if available
26751         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26752                 local testname=jobid_name new_value='foo=bar%p'
26753         else
26754                 local testname=jobid_var new_valuie=foo=bar
26755         fi
26756
26757         local jobid_var_old=$($LCTL get_param -n $testname)
26758         local jobid_var_new
26759
26760         $LCTL set_param $testname=$new_value ||
26761                 error "'set_param a=b' did not accept a value containing '='"
26762
26763         jobid_var_new=$($LCTL get_param -n $testname)
26764         [[ "$jobid_var_new" == "$new_value" ]] ||
26765                 error "'set_param a=b' failed on a value containing '='"
26766
26767         # Reset the $testname to test the other format
26768         $LCTL set_param $testname=$jobid_var_old
26769         jobid_var_new=$($LCTL get_param -n $testname)
26770         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26771                 error "failed to reset $testname"
26772
26773         $LCTL set_param $testname $new_value ||
26774                 error "'set_param a b' did not accept a value containing '='"
26775
26776         jobid_var_new=$($LCTL get_param -n $testname)
26777         [[ "$jobid_var_new" == "$new_value" ]] ||
26778                 error "'set_param a b' failed on a value containing '='"
26779
26780         $LCTL set_param $testname $jobid_var_old
26781         jobid_var_new=$($LCTL get_param -n $testname)
26782         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26783                 error "failed to reset $testname"
26784 }
26785 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26786
26787 test_401e() { # LU-14779
26788         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26789                 error "lctl list_param MGC* failed"
26790         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26791         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26792                 error "lctl get_param lru_size failed"
26793 }
26794 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26795
26796 test_402() {
26797         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26798         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26799                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26800         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26801                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26802                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26803         remote_mds_nodsh && skip "remote MDS with nodsh"
26804
26805         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26806 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26807         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26808         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26809                 echo "Touch failed - OK"
26810 }
26811 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26812
26813 test_403() {
26814         local file1=$DIR/$tfile.1
26815         local file2=$DIR/$tfile.2
26816         local tfile=$TMP/$tfile
26817
26818         rm -f $file1 $file2 $tfile
26819
26820         touch $file1
26821         ln $file1 $file2
26822
26823         # 30 sec OBD_TIMEOUT in ll_getattr()
26824         # right before populating st_nlink
26825         $LCTL set_param fail_loc=0x80001409
26826         stat -c %h $file1 > $tfile &
26827
26828         # create an alias, drop all locks and reclaim the dentry
26829         < $file2
26830         cancel_lru_locks mdc
26831         cancel_lru_locks osc
26832         sysctl -w vm.drop_caches=2
26833
26834         wait
26835
26836         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26837
26838         rm -f $tfile $file1 $file2
26839 }
26840 run_test 403 "i_nlink should not drop to zero due to aliasing"
26841
26842 test_404() { # LU-6601
26843         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26844                 skip "Need server version newer than 2.8.52"
26845         remote_mds_nodsh && skip "remote MDS with nodsh"
26846
26847         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26848                 awk '/osp .*-osc-MDT/ { print $4}')
26849
26850         local osp
26851         for osp in $mosps; do
26852                 echo "Deactivate: " $osp
26853                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26854                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26855                         awk -vp=$osp '$4 == p { print $2 }')
26856                 [ $stat = IN ] || {
26857                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26858                         error "deactivate error"
26859                 }
26860                 echo "Activate: " $osp
26861                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26862                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26863                         awk -vp=$osp '$4 == p { print $2 }')
26864                 [ $stat = UP ] || {
26865                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26866                         error "activate error"
26867                 }
26868         done
26869 }
26870 run_test 404 "validate manual {de}activated works properly for OSPs"
26871
26872 test_405() {
26873         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26874         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26875                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26876                         skip "Layout swap lock is not supported"
26877
26878         check_swap_layouts_support
26879         check_swap_layout_no_dom $DIR
26880
26881         test_mkdir $DIR/$tdir
26882         swap_lock_test -d $DIR/$tdir ||
26883                 error "One layout swap locked test failed"
26884 }
26885 run_test 405 "Various layout swap lock tests"
26886
26887 test_406() {
26888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26889         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26890         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26892         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26893                 skip "Need MDS version at least 2.8.50"
26894
26895         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26896         local test_pool=$TESTNAME
26897
26898         pool_add $test_pool || error "pool_add failed"
26899         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26900                 error "pool_add_targets failed"
26901
26902         save_layout_restore_at_exit $MOUNT
26903
26904         # parent set default stripe count only, child will stripe from both
26905         # parent and fs default
26906         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26907                 error "setstripe $MOUNT failed"
26908         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26909         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26910         for i in $(seq 10); do
26911                 local f=$DIR/$tdir/$tfile.$i
26912                 touch $f || error "touch failed"
26913                 local count=$($LFS getstripe -c $f)
26914                 [ $count -eq $OSTCOUNT ] ||
26915                         error "$f stripe count $count != $OSTCOUNT"
26916                 local offset=$($LFS getstripe -i $f)
26917                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26918                 local size=$($LFS getstripe -S $f)
26919                 [ $size -eq $((def_stripe_size * 2)) ] ||
26920                         error "$f stripe size $size != $((def_stripe_size * 2))"
26921                 local pool=$($LFS getstripe -p $f)
26922                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26923         done
26924
26925         # change fs default striping, delete parent default striping, now child
26926         # will stripe from new fs default striping only
26927         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26928                 error "change $MOUNT default stripe failed"
26929         $LFS setstripe -c 0 $DIR/$tdir ||
26930                 error "delete $tdir default stripe failed"
26931         for i in $(seq 11 20); do
26932                 local f=$DIR/$tdir/$tfile.$i
26933                 touch $f || error "touch $f failed"
26934                 local count=$($LFS getstripe -c $f)
26935                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26936                 local offset=$($LFS getstripe -i $f)
26937                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26938                 local size=$($LFS getstripe -S $f)
26939                 [ $size -eq $def_stripe_size ] ||
26940                         error "$f stripe size $size != $def_stripe_size"
26941                 local pool=$($LFS getstripe -p $f)
26942                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26943         done
26944
26945         unlinkmany $DIR/$tdir/$tfile. 1 20
26946
26947         local f=$DIR/$tdir/$tfile
26948         pool_remove_all_targets $test_pool $f
26949         pool_remove $test_pool $f
26950 }
26951 run_test 406 "DNE support fs default striping"
26952
26953 test_407() {
26954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26955         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26956                 skip "Need MDS version at least 2.8.55"
26957         remote_mds_nodsh && skip "remote MDS with nodsh"
26958
26959         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26960                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26961         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26962                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26963         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26964
26965         #define OBD_FAIL_DT_TXN_STOP    0x2019
26966         for idx in $(seq $MDSCOUNT); do
26967                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26968         done
26969         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26970         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26971                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26972         true
26973 }
26974 run_test 407 "transaction fail should cause operation fail"
26975
26976 test_408() {
26977         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26978
26979         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26980         lctl set_param fail_loc=0x8000040a
26981         # let ll_prepare_partial_page() fail
26982         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26983
26984         rm -f $DIR/$tfile
26985
26986         # create at least 100 unused inodes so that
26987         # shrink_icache_memory(0) should not return 0
26988         touch $DIR/$tfile-{0..100}
26989         rm -f $DIR/$tfile-{0..100}
26990         sync
26991
26992         echo 2 > /proc/sys/vm/drop_caches
26993 }
26994 run_test 408 "drop_caches should not hang due to page leaks"
26995
26996 test_409()
26997 {
26998         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26999
27000         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27001         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27002         touch $DIR/$tdir/guard || error "(2) Fail to create"
27003
27004         local PREFIX=$(str_repeat 'A' 128)
27005         echo "Create 1K hard links start at $(date)"
27006         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27007                 error "(3) Fail to hard link"
27008
27009         echo "Links count should be right although linkEA overflow"
27010         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27011         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27012         [ $linkcount -eq 1001 ] ||
27013                 error "(5) Unexpected hard links count: $linkcount"
27014
27015         echo "List all links start at $(date)"
27016         ls -l $DIR/$tdir/foo > /dev/null ||
27017                 error "(6) Fail to list $DIR/$tdir/foo"
27018
27019         echo "Unlink hard links start at $(date)"
27020         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27021                 error "(7) Fail to unlink"
27022         echo "Unlink hard links finished at $(date)"
27023 }
27024 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27025
27026 test_410()
27027 {
27028         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27029                 skip "Need client version at least 2.9.59"
27030         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27031                 skip "Need MODULES build"
27032
27033         # Create a file, and stat it from the kernel
27034         local testfile=$DIR/$tfile
27035         touch $testfile
27036
27037         local run_id=$RANDOM
27038         local my_ino=$(stat --format "%i" $testfile)
27039
27040         # Try to insert the module. This will always fail as the
27041         # module is designed to not be inserted.
27042         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27043             &> /dev/null
27044
27045         # Anything but success is a test failure
27046         dmesg | grep -q \
27047             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27048             error "no inode match"
27049 }
27050 run_test 410 "Test inode number returned from kernel thread"
27051
27052 cleanup_test411_cgroup() {
27053         trap 0
27054         rmdir "$1"
27055 }
27056
27057 test_411() {
27058         local cg_basedir=/sys/fs/cgroup/memory
27059         # LU-9966
27060         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27061                 skip "no setup for cgroup"
27062
27063         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27064                 error "test file creation failed"
27065         cancel_lru_locks osc
27066
27067         # Create a very small memory cgroup to force a slab allocation error
27068         local cgdir=$cg_basedir/osc_slab_alloc
27069         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27070         trap "cleanup_test411_cgroup $cgdir" EXIT
27071         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27072         echo 1M > $cgdir/memory.limit_in_bytes
27073
27074         # Should not LBUG, just be killed by oom-killer
27075         # dd will return 0 even allocation failure in some environment.
27076         # So don't check return value
27077         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27078         cleanup_test411_cgroup $cgdir
27079
27080         return 0
27081 }
27082 run_test 411 "Slab allocation error with cgroup does not LBUG"
27083
27084 test_412() {
27085         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27086         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27087                 skip "Need server version at least 2.10.55"
27088
27089         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27090                 error "mkdir failed"
27091         $LFS getdirstripe $DIR/$tdir
27092         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27093         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27094                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27095         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27096         [ $stripe_count -eq 2 ] ||
27097                 error "expect 2 get $stripe_count"
27098
27099         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27100
27101         local index
27102         local index2
27103
27104         # subdirs should be on the same MDT as parent
27105         for i in $(seq 0 $((MDSCOUNT - 1))); do
27106                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27107                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27108                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27109                 (( index == i )) || error "mdt$i/sub on MDT$index"
27110         done
27111
27112         # stripe offset -1, ditto
27113         for i in {1..10}; do
27114                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27115                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27116                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27117                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27118                 (( index == index2 )) ||
27119                         error "qos$i on MDT$index, sub on MDT$index2"
27120         done
27121
27122         local testdir=$DIR/$tdir/inherit
27123
27124         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27125         # inherit 2 levels
27126         for i in 1 2; do
27127                 testdir=$testdir/s$i
27128                 mkdir $testdir || error "mkdir $testdir failed"
27129                 index=$($LFS getstripe -m $testdir)
27130                 (( index == 1 )) ||
27131                         error "$testdir on MDT$index"
27132         done
27133
27134         # not inherit any more
27135         testdir=$testdir/s3
27136         mkdir $testdir || error "mkdir $testdir failed"
27137         getfattr -d -m dmv $testdir | grep dmv &&
27138                 error "default LMV set on $testdir" || true
27139 }
27140 run_test 412 "mkdir on specific MDTs"
27141
27142 TEST413_COUNT=${TEST413_COUNT:-200}
27143
27144 #
27145 # set_maxage() is used by test_413 only.
27146 # This is a helper function to set maxage. Does not return any value.
27147 # Input: maxage to set
27148 #
27149 set_maxage() {
27150         local lmv_qos_maxage
27151         local lod_qos_maxage
27152         local new_maxage=$1
27153
27154         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27155         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27156         stack_trap "$LCTL set_param \
27157                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27158         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27159                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27160         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27161                 lod.*.mdt_qos_maxage=$new_maxage
27162         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27163                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27164 }
27165
27166 generate_uneven_mdts() {
27167         local threshold=$1
27168         local ffree
27169         local bavail
27170         local max
27171         local min
27172         local max_index
27173         local min_index
27174         local tmp
27175         local i
27176
27177         echo
27178         echo "Check for uneven MDTs: "
27179
27180         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27181         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27182         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27183
27184         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27185         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27186         max_index=0
27187         min_index=0
27188         for ((i = 1; i < ${#ffree[@]}; i++)); do
27189                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27190                 if [ $tmp -gt $max ]; then
27191                         max=$tmp
27192                         max_index=$i
27193                 fi
27194                 if [ $tmp -lt $min ]; then
27195                         min=$tmp
27196                         min_index=$i
27197                 fi
27198         done
27199
27200         (( min > 0 )) || skip "low space on MDT$min_index"
27201         (( ${ffree[min_index]} > 0 )) ||
27202                 skip "no free files on MDT$min_index"
27203         (( ${ffree[min_index]} < 10000000 )) ||
27204                 skip "too many free files on MDT$min_index"
27205
27206         # Check if we need to generate uneven MDTs
27207         local diff=$(((max - min) * 100 / min))
27208         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27209         local testdir # individual folder within $testdirp
27210         local start
27211         local cmd
27212
27213         # fallocate is faster to consume space on MDT, if available
27214         if check_fallocate_supported mds$((min_index + 1)); then
27215                 cmd="fallocate -l 128K "
27216         else
27217                 cmd="dd if=/dev/zero bs=128K count=1 of="
27218         fi
27219
27220         echo "using cmd $cmd"
27221         for (( i = 0; diff < threshold; i++ )); do
27222                 testdir=${testdirp}/$i
27223                 [ -d $testdir ] && continue
27224
27225                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27226
27227                 mkdir -p $testdirp
27228                 # generate uneven MDTs, create till $threshold% diff
27229                 echo -n "weight diff=$diff% must be > $threshold% ..."
27230                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27231                 $LFS mkdir -i $min_index $testdir ||
27232                         error "mkdir $testdir failed"
27233                 $LFS setstripe -E 1M -L mdt $testdir ||
27234                         error "setstripe $testdir failed"
27235                 start=$SECONDS
27236                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27237                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27238                 done
27239                 sync; sleep 1; sync
27240
27241                 # wait for QOS to update
27242                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27243
27244                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27245                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27246                 max=$(((${ffree[max_index]} >> 8) *
27247                         (${bavail[max_index]} * bsize >> 16)))
27248                 min=$(((${ffree[min_index]} >> 8) *
27249                         (${bavail[min_index]} * bsize >> 16)))
27250                 (( min > 0 )) || skip "low space on MDT$min_index"
27251                 diff=$(((max - min) * 100 / min))
27252         done
27253
27254         echo "MDT filesfree available: ${ffree[*]}"
27255         echo "MDT blocks available: ${bavail[*]}"
27256         echo "weight diff=$diff%"
27257 }
27258
27259 test_qos_mkdir() {
27260         local mkdir_cmd=$1
27261         local stripe_count=$2
27262         local mdts=$(comma_list $(mdts_nodes))
27263
27264         local testdir
27265         local lmv_qos_prio_free
27266         local lmv_qos_threshold_rr
27267         local lod_qos_prio_free
27268         local lod_qos_threshold_rr
27269         local total
27270         local count
27271         local i
27272
27273         # @total is total directories created if it's testing plain
27274         # directories, otherwise it's total stripe object count for
27275         # striped directories test.
27276         # remote/striped directory unlinking is slow on zfs and may
27277         # timeout, test with fewer directories
27278         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27279
27280         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27281         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27282         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27283                 head -n1)
27284         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27285         stack_trap "$LCTL set_param \
27286                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27287         stack_trap "$LCTL set_param \
27288                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27289
27290         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27291                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27292         lod_qos_prio_free=${lod_qos_prio_free%%%}
27293         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27294                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27295         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27296         stack_trap "do_nodes $mdts $LCTL set_param \
27297                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27298         stack_trap "do_nodes $mdts $LCTL set_param \
27299                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27300
27301         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27302         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27303
27304         testdir=$DIR/$tdir-s$stripe_count/rr
27305
27306         local stripe_index=$($LFS getstripe -m $testdir)
27307         local test_mkdir_rr=true
27308
27309         getfattr -d -m dmv -e hex $testdir | grep dmv
27310         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27311                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27312                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27313                         test_mkdir_rr=false
27314         fi
27315
27316         echo
27317         $test_mkdir_rr &&
27318                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27319                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27320
27321         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27322         for (( i = 0; i < total / stripe_count; i++ )); do
27323                 eval $mkdir_cmd $testdir/subdir$i ||
27324                         error "$mkdir_cmd subdir$i failed"
27325         done
27326
27327         for (( i = 0; i < $MDSCOUNT; i++ )); do
27328                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27329                 echo "$count directories created on MDT$i"
27330                 if $test_mkdir_rr; then
27331                         (( count == total / stripe_count / MDSCOUNT )) ||
27332                                 error "subdirs are not evenly distributed"
27333                 elif (( i == stripe_index )); then
27334                         (( count == total / stripe_count )) ||
27335                                 error "$count subdirs created on MDT$i"
27336                 else
27337                         (( count == 0 )) ||
27338                                 error "$count subdirs created on MDT$i"
27339                 fi
27340
27341                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27342                         count=$($LFS getdirstripe $testdir/* |
27343                                 grep -c -P "^\s+$i\t")
27344                         echo "$count stripes created on MDT$i"
27345                         # deviation should < 5% of average
27346                         delta=$((count - total / MDSCOUNT))
27347                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27348                                 error "stripes are not evenly distributed"
27349                 fi
27350         done
27351
27352         echo
27353         echo "Check for uneven MDTs: "
27354
27355         local ffree
27356         local bavail
27357         local max
27358         local min
27359         local max_index
27360         local min_index
27361         local tmp
27362
27363         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27364         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27365         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27366
27367         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27368         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27369         max_index=0
27370         min_index=0
27371         for ((i = 1; i < ${#ffree[@]}; i++)); do
27372                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27373                 if [ $tmp -gt $max ]; then
27374                         max=$tmp
27375                         max_index=$i
27376                 fi
27377                 if [ $tmp -lt $min ]; then
27378                         min=$tmp
27379                         min_index=$i
27380                 fi
27381         done
27382         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27383
27384         (( min > 0 )) || skip "low space on MDT$min_index"
27385         (( ${ffree[min_index]} < 10000000 )) ||
27386                 skip "too many free files on MDT$min_index"
27387
27388         generate_uneven_mdts 120
27389
27390         echo "MDT filesfree available: ${ffree[*]}"
27391         echo "MDT blocks available: ${bavail[*]}"
27392         echo "weight diff=$(((max - min) * 100 / min))%"
27393         echo
27394         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27395
27396         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27397         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27398         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27399         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27400         # decrease statfs age, so that it can be updated in time
27401         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27402         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27403
27404         sleep 1
27405
27406         testdir=$DIR/$tdir-s$stripe_count/qos
27407
27408         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27409         for (( i = 0; i < total / stripe_count; i++ )); do
27410                 eval $mkdir_cmd $testdir/subdir$i ||
27411                         error "$mkdir_cmd subdir$i failed"
27412         done
27413
27414         max=0
27415         for (( i = 0; i < $MDSCOUNT; i++ )); do
27416                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27417                 (( count > max )) && max=$count
27418                 echo "$count directories created on MDT$i : curmax=$max"
27419         done
27420
27421         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27422
27423         # D-value should > 10% of average
27424         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27425                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27426
27427         # ditto for stripes
27428         if (( stripe_count > 1 )); then
27429                 max=0
27430                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27431                         count=$($LFS getdirstripe $testdir/* |
27432                                 grep -c -P "^\s+$i\t")
27433                         (( count > max )) && max=$count
27434                         echo "$count stripes created on MDT$i"
27435                 done
27436
27437                 min=$($LFS getdirstripe $testdir/* |
27438                         grep -c -P "^\s+$min_index\t")
27439                 (( max - min > total / MDSCOUNT / 10 )) ||
27440                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27441         fi
27442 }
27443
27444 most_full_mdt() {
27445         local ffree
27446         local bavail
27447         local bsize
27448         local min
27449         local min_index
27450         local tmp
27451
27452         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27453         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27454         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27455
27456         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27457         min_index=0
27458         for ((i = 1; i < ${#ffree[@]}; i++)); do
27459                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27460                 (( tmp < min )) && min=$tmp && min_index=$i
27461         done
27462
27463         echo -n $min_index
27464 }
27465
27466 test_413a() {
27467         [ $MDSCOUNT -lt 2 ] &&
27468                 skip "We need at least 2 MDTs for this test"
27469
27470         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27471                 skip "Need server version at least 2.12.52"
27472
27473         local stripe_max=$((MDSCOUNT - 1))
27474         local stripe_count
27475
27476         # let caller set maxage for latest result
27477         set_maxage 1
27478
27479         # fill MDT unevenly
27480         generate_uneven_mdts 120
27481
27482         # test 4-stripe directory at most, otherwise it's too slow
27483         # We are being very defensive. Although Autotest uses 4 MDTs.
27484         # We make sure stripe_max does not go over 4.
27485         (( stripe_max > 4 )) && stripe_max=4
27486         # unlinking striped directory is slow on zfs, and may timeout, only test
27487         # plain directory
27488         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27489         for stripe_count in $(seq 1 $stripe_max); do
27490                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27491                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27492                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27493                         error "mkdir failed"
27494                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27495         done
27496 }
27497 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27498
27499 test_413b() {
27500         [ $MDSCOUNT -lt 2 ] &&
27501                 skip "We need at least 2 MDTs for this test"
27502
27503         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27504                 skip "Need server version at least 2.12.52"
27505
27506         local stripe_max=$((MDSCOUNT - 1))
27507         local testdir
27508         local stripe_count
27509
27510         # let caller set maxage for latest result
27511         set_maxage 1
27512
27513         # fill MDT unevenly
27514         generate_uneven_mdts 120
27515
27516         # test 4-stripe directory at most, otherwise it's too slow
27517         # We are being very defensive. Although Autotest uses 4 MDTs.
27518         # We make sure stripe_max does not go over 4.
27519         (( stripe_max > 4 )) && stripe_max=4
27520         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27521         for stripe_count in $(seq 1 $stripe_max); do
27522                 testdir=$DIR/$tdir-s$stripe_count
27523                 mkdir $testdir || error "mkdir $testdir failed"
27524                 mkdir $testdir/rr || error "mkdir rr failed"
27525                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27526                         error "mkdir qos failed"
27527                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27528                         $testdir/rr || error "setdirstripe rr failed"
27529                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27530                         error "setdirstripe failed"
27531                 test_qos_mkdir "mkdir" $stripe_count
27532         done
27533 }
27534 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27535
27536 test_413c() {
27537         (( $MDSCOUNT >= 2 )) ||
27538                 skip "We need at least 2 MDTs for this test"
27539
27540         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27541                 skip "Need server version at least 2.14.51"
27542
27543         local testdir
27544         local inherit
27545         local inherit_rr
27546         local lmv_qos_maxage
27547         local lod_qos_maxage
27548
27549         # let caller set maxage for latest result
27550         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27551         $LCTL set_param lmv.*.qos_maxage=1
27552         stack_trap "$LCTL set_param \
27553                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27554         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27555                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27556         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27557                 lod.*.mdt_qos_maxage=1
27558         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27559                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27560
27561         # fill MDT unevenly
27562         generate_uneven_mdts 120
27563
27564         testdir=$DIR/${tdir}-s1
27565         mkdir $testdir || error "mkdir $testdir failed"
27566         mkdir $testdir/rr || error "mkdir rr failed"
27567         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27568         # default max_inherit is -1, default max_inherit_rr is 0
27569         $LFS setdirstripe -D -c 1 $testdir/rr ||
27570                 error "setdirstripe rr failed"
27571         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27572                 error "setdirstripe qos failed"
27573         test_qos_mkdir "mkdir" 1
27574
27575         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27576         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27577         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27578         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27579         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27580
27581         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27582         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27583         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27584         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27585         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27586         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27587         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27588                 error "level2 shouldn't have default LMV" || true
27589 }
27590 run_test 413c "mkdir with default LMV max inherit rr"
27591
27592 test_413d() {
27593         (( MDSCOUNT >= 2 )) ||
27594                 skip "We need at least 2 MDTs for this test"
27595
27596         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27597                 skip "Need server version at least 2.14.51"
27598
27599         local lmv_qos_threshold_rr
27600
27601         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27602                 head -n1)
27603         stack_trap "$LCTL set_param \
27604                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27605
27606         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27607         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27608         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27609                 error "$tdir shouldn't have default LMV"
27610         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27611                 error "mkdir sub failed"
27612
27613         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27614
27615         (( count == 100 )) || error "$count subdirs on MDT0"
27616 }
27617 run_test 413d "inherit ROOT default LMV"
27618
27619 test_413e() {
27620         (( MDSCOUNT >= 2 )) ||
27621                 skip "We need at least 2 MDTs for this test"
27622         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27623                 skip "Need server version at least 2.14.55"
27624
27625         local testdir=$DIR/$tdir
27626         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27627         local max_inherit
27628         local sub_max_inherit
27629
27630         mkdir -p $testdir || error "failed to create $testdir"
27631
27632         # set default max-inherit to -1 if stripe count is 0 or 1
27633         $LFS setdirstripe -D -c 1 $testdir ||
27634                 error "failed to set default LMV"
27635         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27636         (( max_inherit == -1 )) ||
27637                 error "wrong max_inherit value $max_inherit"
27638
27639         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27640         $LFS setdirstripe -D -c -1 $testdir ||
27641                 error "failed to set default LMV"
27642         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27643         (( max_inherit > 0 )) ||
27644                 error "wrong max_inherit value $max_inherit"
27645
27646         # and the subdir will decrease the max_inherit by 1
27647         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27648         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27649         (( sub_max_inherit == max_inherit - 1)) ||
27650                 error "wrong max-inherit of subdir $sub_max_inherit"
27651
27652         # check specified --max-inherit and warning message
27653         stack_trap "rm -f $tmpfile"
27654         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27655                 error "failed to set default LMV"
27656         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27657         (( max_inherit == -1 )) ||
27658                 error "wrong max_inherit value $max_inherit"
27659
27660         # check the warning messages
27661         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27662                 error "failed to detect warning string"
27663         fi
27664 }
27665 run_test 413e "check default max-inherit value"
27666
27667 test_fs_dmv_inherit()
27668 {
27669         local testdir=$DIR/$tdir
27670
27671         local count
27672         local inherit
27673         local inherit_rr
27674
27675         for i in 1 2; do
27676                 mkdir $testdir || error "mkdir $testdir failed"
27677                 count=$($LFS getdirstripe -D -c $testdir)
27678                 (( count == 1 )) ||
27679                         error "$testdir default LMV count mismatch $count != 1"
27680                 inherit=$($LFS getdirstripe -D -X $testdir)
27681                 (( inherit == 3 - i )) ||
27682                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27683                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27684                 (( inherit_rr == 3 - i )) ||
27685                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27686                 testdir=$testdir/sub
27687         done
27688
27689         mkdir $testdir || error "mkdir $testdir failed"
27690         count=$($LFS getdirstripe -D -c $testdir)
27691         (( count == 0 )) ||
27692                 error "$testdir default LMV count not zero: $count"
27693 }
27694
27695 test_413f() {
27696         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27697
27698         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27699                 skip "Need server version at least 2.14.55"
27700
27701         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27702                 error "dump $DIR default LMV failed"
27703         stack_trap "setfattr --restore=$TMP/dmv.ea"
27704
27705         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27706                 error "set $DIR default LMV failed"
27707
27708         test_fs_dmv_inherit
27709 }
27710 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27711
27712 test_413g() {
27713         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27714
27715         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27716         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27717                 error "dump $DIR default LMV failed"
27718         stack_trap "setfattr --restore=$TMP/dmv.ea"
27719
27720         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27721                 error "set $DIR default LMV failed"
27722
27723         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27724                 error "mount $MOUNT2 failed"
27725         stack_trap "umount_client $MOUNT2"
27726
27727         local saved_DIR=$DIR
27728
27729         export DIR=$MOUNT2
27730
27731         stack_trap "export DIR=$saved_DIR"
27732
27733         # first check filesystem-wide default LMV inheritance
27734         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27735
27736         # then check subdirs are spread to all MDTs
27737         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27738
27739         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27740
27741         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27742 }
27743 run_test 413g "enforce ROOT default LMV on subdir mount"
27744
27745 test_413h() {
27746         (( MDSCOUNT >= 2 )) ||
27747                 skip "We need at least 2 MDTs for this test"
27748
27749         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27750                 skip "Need server version at least 2.15.50.6"
27751
27752         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27753
27754         stack_trap "$LCTL set_param \
27755                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27756         $LCTL set_param lmv.*.qos_maxage=1
27757
27758         local depth=5
27759         local rr_depth=4
27760         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27761         local count=$((MDSCOUNT * 20))
27762
27763         generate_uneven_mdts 50
27764
27765         mkdir -p $dir || error "mkdir $dir failed"
27766         stack_trap "rm -rf $dir"
27767         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27768                 --max-inherit-rr=$rr_depth $dir
27769
27770         for ((d=0; d < depth + 2; d++)); do
27771                 log "dir=$dir:"
27772                 for ((sub=0; sub < count; sub++)); do
27773                         mkdir $dir/d$sub
27774                 done
27775                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27776                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27777                 # subdirs within $rr_depth should be created round-robin
27778                 if (( d < rr_depth )); then
27779                         (( ${num[0]} != count )) ||
27780                                 error "all objects created on MDT ${num[1]}"
27781                 fi
27782
27783                 dir=$dir/d0
27784         done
27785 }
27786 run_test 413h "don't stick to parent for round-robin dirs"
27787
27788 test_413i() {
27789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27790
27791         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27792                 skip "Need server version at least 2.14.55"
27793
27794         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27795                 error "dump $DIR default LMV failed"
27796         stack_trap "setfattr --restore=$TMP/dmv.ea"
27797
27798         local testdir=$DIR/$tdir
27799         local def_max_rr=1
27800         local def_max=3
27801         local count
27802
27803         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27804                 --max-inherit-rr=$def_max_rr $DIR ||
27805                 error "set $DIR default LMV failed"
27806
27807         for i in $(seq 2 3); do
27808                 def_max=$((def_max - 1))
27809                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27810
27811                 mkdir $testdir
27812                 # RR is decremented and keeps zeroed once exhausted
27813                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27814                 (( count == def_max_rr )) ||
27815                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27816
27817                 # max-inherit is decremented
27818                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27819                 (( count == def_max )) ||
27820                         error_noexit "$testdir: max-inherit $count != $def_max"
27821
27822                 testdir=$testdir/d$i
27823         done
27824
27825         # d3 is the last inherited from ROOT, no inheritance anymore
27826         # i.e. no the default layout anymore
27827         mkdir -p $testdir/d4/d5
27828         count=$($LFS getdirstripe -D --max-inherit $testdir)
27829         (( count == -1 )) ||
27830                 error_noexit "$testdir: max-inherit $count != -1"
27831
27832         local p_count=$($LFS getdirstripe -i $testdir)
27833
27834         for i in $(seq 4 5); do
27835                 testdir=$testdir/d$i
27836
27837                 # the root default layout is not applied once exhausted
27838                 count=$($LFS getdirstripe -i $testdir)
27839                 (( count == p_count )) ||
27840                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27841         done
27842
27843         $LFS setdirstripe -i 0 $DIR/d2
27844         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27845         (( count == -1 )) ||
27846                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27847 }
27848 run_test 413i "check default layout inheritance"
27849
27850 test_413z() {
27851         local pids=""
27852         local subdir
27853         local pid
27854
27855         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27856                 unlinkmany $subdir/f. $TEST413_COUNT &
27857                 pids="$pids $!"
27858         done
27859
27860         for pid in $pids; do
27861                 wait $pid
27862         done
27863
27864         true
27865 }
27866 run_test 413z "413 test cleanup"
27867
27868 test_414() {
27869 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27870         $LCTL set_param fail_loc=0x80000521
27871         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27872         rm -f $DIR/$tfile
27873 }
27874 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27875
27876 test_415() {
27877         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27878         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27879                 skip "Need server version at least 2.11.52"
27880
27881         # LU-11102
27882         local total=500
27883         local max=120
27884
27885         # this test may be slow on ZFS
27886         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27887
27888         # though this test is designed for striped directory, let's test normal
27889         # directory too since lock is always saved as CoS lock.
27890         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27891         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27892         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27893         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27894         wait_delete_completed_mds
27895
27896         # run a loop without concurrent touch to measure rename duration.
27897         # only for test debug/robustness, NOT part of COS functional test.
27898         local start_time=$SECONDS
27899         for ((i = 0; i < total; i++)); do
27900                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27901                         > /dev/null
27902         done
27903         local baseline=$((SECONDS - start_time))
27904         echo "rename $total files without 'touch' took $baseline sec"
27905
27906         (
27907                 while true; do
27908                         touch $DIR/$tdir
27909                 done
27910         ) &
27911         local setattr_pid=$!
27912
27913         # rename files back to original name so unlinkmany works
27914         start_time=$SECONDS
27915         for ((i = 0; i < total; i++)); do
27916                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27917                         > /dev/null
27918         done
27919         local duration=$((SECONDS - start_time))
27920
27921         kill -9 $setattr_pid
27922
27923         echo "rename $total files with 'touch' took $duration sec"
27924         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27925         (( duration <= max )) ||
27926                 error_not_in_vm "rename took $duration > $max sec"
27927 }
27928 run_test 415 "lock revoke is not missing"
27929
27930 test_416() {
27931         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27932                 skip "Need server version at least 2.11.55"
27933
27934         # define OBD_FAIL_OSD_TXN_START    0x19a
27935         do_facet mds1 lctl set_param fail_loc=0x19a
27936
27937         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27938
27939         true
27940 }
27941 run_test 416 "transaction start failure won't cause system hung"
27942
27943 cleanup_417() {
27944         trap 0
27945         do_nodes $(comma_list $(mdts_nodes)) \
27946                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27947         do_nodes $(comma_list $(mdts_nodes)) \
27948                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27949         do_nodes $(comma_list $(mdts_nodes)) \
27950                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27951 }
27952
27953 test_417() {
27954         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27955         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27956                 skip "Need MDS version at least 2.11.56"
27957
27958         trap cleanup_417 RETURN EXIT
27959
27960         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27961         do_nodes $(comma_list $(mdts_nodes)) \
27962                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27963         $LFS migrate -m 0 $DIR/$tdir.1 &&
27964                 error "migrate dir $tdir.1 should fail"
27965
27966         do_nodes $(comma_list $(mdts_nodes)) \
27967                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27968         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27969                 error "create remote dir $tdir.2 should fail"
27970
27971         do_nodes $(comma_list $(mdts_nodes)) \
27972                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27973         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27974                 error "create striped dir $tdir.3 should fail"
27975         true
27976 }
27977 run_test 417 "disable remote dir, striped dir and dir migration"
27978
27979 # Checks that the outputs of df [-i] and lfs df [-i] match
27980 #
27981 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27982 check_lfs_df() {
27983         local dir=$2
27984         local inodes
27985         local df_out
27986         local lfs_df_out
27987         local count
27988         local passed=false
27989
27990         # blocks or inodes
27991         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27992
27993         for count in {1..100}; do
27994                 do_nodes "$CLIENTS" \
27995                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27996                 sync; sleep 0.2
27997
27998                 # read the lines of interest
27999                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28000                         error "df $inodes $dir | tail -n +2 failed"
28001                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28002                         error "lfs df $inodes $dir | grep summary: failed"
28003
28004                 # skip first substrings of each output as they are different
28005                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28006                 # compare the two outputs
28007                 passed=true
28008                 #  skip "available" on MDT until LU-13997 is fixed.
28009                 #for i in {1..5}; do
28010                 for i in 1 2 4 5; do
28011                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28012                 done
28013                 $passed && break
28014         done
28015
28016         if ! $passed; then
28017                 df -P $inodes $dir
28018                 echo
28019                 lfs df $inodes $dir
28020                 error "df and lfs df $1 output mismatch: "      \
28021                       "df ${inodes}: ${df_out[*]}, "            \
28022                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28023         fi
28024 }
28025
28026 test_418() {
28027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28028
28029         local dir=$DIR/$tdir
28030         local numfiles=$((RANDOM % 4096 + 2))
28031         local numblocks=$((RANDOM % 256 + 1))
28032
28033         wait_delete_completed
28034         test_mkdir $dir
28035
28036         # check block output
28037         check_lfs_df blocks $dir
28038         # check inode output
28039         check_lfs_df inodes $dir
28040
28041         # create a single file and retest
28042         echo "Creating a single file and testing"
28043         createmany -o $dir/$tfile- 1 &>/dev/null ||
28044                 error "creating 1 file in $dir failed"
28045         check_lfs_df blocks $dir
28046         check_lfs_df inodes $dir
28047
28048         # create a random number of files
28049         echo "Creating $((numfiles - 1)) files and testing"
28050         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28051                 error "creating $((numfiles - 1)) files in $dir failed"
28052
28053         # write a random number of blocks to the first test file
28054         echo "Writing $numblocks 4K blocks and testing"
28055         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28056                 count=$numblocks &>/dev/null ||
28057                 error "dd to $dir/${tfile}-0 failed"
28058
28059         # retest
28060         check_lfs_df blocks $dir
28061         check_lfs_df inodes $dir
28062
28063         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28064                 error "unlinking $numfiles files in $dir failed"
28065 }
28066 run_test 418 "df and lfs df outputs match"
28067
28068 test_419()
28069 {
28070         local dir=$DIR/$tdir
28071
28072         mkdir -p $dir
28073         touch $dir/file
28074
28075         cancel_lru_locks mdc
28076
28077         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28078         $LCTL set_param fail_loc=0x1410
28079         cat $dir/file
28080         $LCTL set_param fail_loc=0
28081         rm -rf $dir
28082 }
28083 run_test 419 "Verify open file by name doesn't crash kernel"
28084
28085 test_420()
28086 {
28087         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28088                 skip "Need MDS version at least 2.12.53"
28089
28090         local SAVE_UMASK=$(umask)
28091         local dir=$DIR/$tdir
28092         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28093
28094         mkdir -p $dir
28095         umask 0000
28096         mkdir -m03777 $dir/testdir
28097         ls -dn $dir/testdir
28098         # Need to remove trailing '.' when SELinux is enabled
28099         local dirperms=$(ls -dn $dir/testdir |
28100                          awk '{ sub(/\.$/, "", $1); print $1}')
28101         [ $dirperms == "drwxrwsrwt" ] ||
28102                 error "incorrect perms on $dir/testdir"
28103
28104         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28105                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28106         ls -n $dir/testdir/testfile
28107         local fileperms=$(ls -n $dir/testdir/testfile |
28108                           awk '{ sub(/\.$/, "", $1); print $1}')
28109         [ $fileperms == "-rwxr-xr-x" ] ||
28110                 error "incorrect perms on $dir/testdir/testfile"
28111
28112         umask $SAVE_UMASK
28113 }
28114 run_test 420 "clear SGID bit on non-directories for non-members"
28115
28116 test_421a() {
28117         local cnt
28118         local fid1
28119         local fid2
28120
28121         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28122                 skip "Need MDS version at least 2.12.54"
28123
28124         test_mkdir $DIR/$tdir
28125         createmany -o $DIR/$tdir/f 3
28126         cnt=$(ls -1 $DIR/$tdir | wc -l)
28127         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28128
28129         fid1=$(lfs path2fid $DIR/$tdir/f1)
28130         fid2=$(lfs path2fid $DIR/$tdir/f2)
28131         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28132
28133         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28134         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28135
28136         cnt=$(ls -1 $DIR/$tdir | wc -l)
28137         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28138
28139         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28140         createmany -o $DIR/$tdir/f 3
28141         cnt=$(ls -1 $DIR/$tdir | wc -l)
28142         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28143
28144         fid1=$(lfs path2fid $DIR/$tdir/f1)
28145         fid2=$(lfs path2fid $DIR/$tdir/f2)
28146         echo "remove using fsname $FSNAME"
28147         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28148
28149         cnt=$(ls -1 $DIR/$tdir | wc -l)
28150         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28151 }
28152 run_test 421a "simple rm by fid"
28153
28154 test_421b() {
28155         local cnt
28156         local FID1
28157         local FID2
28158
28159         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28160                 skip "Need MDS version at least 2.12.54"
28161
28162         test_mkdir $DIR/$tdir
28163         createmany -o $DIR/$tdir/f 3
28164         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28165         MULTIPID=$!
28166
28167         FID1=$(lfs path2fid $DIR/$tdir/f1)
28168         FID2=$(lfs path2fid $DIR/$tdir/f2)
28169         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28170
28171         kill -USR1 $MULTIPID
28172         wait
28173
28174         cnt=$(ls $DIR/$tdir | wc -l)
28175         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28176 }
28177 run_test 421b "rm by fid on open file"
28178
28179 test_421c() {
28180         local cnt
28181         local FIDS
28182
28183         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28184                 skip "Need MDS version at least 2.12.54"
28185
28186         test_mkdir $DIR/$tdir
28187         createmany -o $DIR/$tdir/f 3
28188         touch $DIR/$tdir/$tfile
28189         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28190         cnt=$(ls -1 $DIR/$tdir | wc -l)
28191         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28192
28193         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28194         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28195
28196         cnt=$(ls $DIR/$tdir | wc -l)
28197         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28198 }
28199 run_test 421c "rm by fid against hardlinked files"
28200
28201 test_421d() {
28202         local cnt
28203         local FIDS
28204
28205         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28206                 skip "Need MDS version at least 2.12.54"
28207
28208         test_mkdir $DIR/$tdir
28209         createmany -o $DIR/$tdir/f 4097
28210         cnt=$(ls -1 $DIR/$tdir | wc -l)
28211         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28212
28213         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28214         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28215
28216         cnt=$(ls $DIR/$tdir | wc -l)
28217         rm -rf $DIR/$tdir
28218         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28219 }
28220 run_test 421d "rmfid en masse"
28221
28222 test_421e() {
28223         local cnt
28224         local FID
28225
28226         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28227         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28228                 skip "Need MDS version at least 2.12.54"
28229
28230         mkdir -p $DIR/$tdir
28231         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28232         createmany -o $DIR/$tdir/striped_dir/f 512
28233         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28234         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28235
28236         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28237                 sed "s/[/][^:]*://g")
28238         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28239
28240         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28241         rm -rf $DIR/$tdir
28242         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28243 }
28244 run_test 421e "rmfid in DNE"
28245
28246 test_421f() {
28247         local cnt
28248         local FID
28249
28250         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28251                 skip "Need MDS version at least 2.12.54"
28252
28253         test_mkdir $DIR/$tdir
28254         touch $DIR/$tdir/f
28255         cnt=$(ls -1 $DIR/$tdir | wc -l)
28256         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28257
28258         FID=$(lfs path2fid $DIR/$tdir/f)
28259         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28260         # rmfid should fail
28261         cnt=$(ls -1 $DIR/$tdir | wc -l)
28262         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28263
28264         chmod a+rw $DIR/$tdir
28265         ls -la $DIR/$tdir
28266         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28267         # rmfid should fail
28268         cnt=$(ls -1 $DIR/$tdir | wc -l)
28269         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28270
28271         rm -f $DIR/$tdir/f
28272         $RUNAS touch $DIR/$tdir/f
28273         FID=$(lfs path2fid $DIR/$tdir/f)
28274         echo "rmfid as root"
28275         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28276         cnt=$(ls -1 $DIR/$tdir | wc -l)
28277         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28278
28279         rm -f $DIR/$tdir/f
28280         $RUNAS touch $DIR/$tdir/f
28281         cnt=$(ls -1 $DIR/$tdir | wc -l)
28282         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28283         FID=$(lfs path2fid $DIR/$tdir/f)
28284         # rmfid w/o user_fid2path mount option should fail
28285         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28286         cnt=$(ls -1 $DIR/$tdir | wc -l)
28287         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28288
28289         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28290         stack_trap "rmdir $tmpdir"
28291         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28292                 error "failed to mount client'"
28293         stack_trap "umount_client $tmpdir"
28294
28295         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28296         # rmfid should succeed
28297         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28298         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28299
28300         # rmfid shouldn't allow to remove files due to dir's permission
28301         chmod a+rwx $tmpdir/$tdir
28302         touch $tmpdir/$tdir/f
28303         ls -la $tmpdir/$tdir
28304         FID=$(lfs path2fid $tmpdir/$tdir/f)
28305         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28306         return 0
28307 }
28308 run_test 421f "rmfid checks permissions"
28309
28310 test_421g() {
28311         local cnt
28312         local FIDS
28313
28314         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28315         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28316                 skip "Need MDS version at least 2.12.54"
28317
28318         mkdir -p $DIR/$tdir
28319         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28320         createmany -o $DIR/$tdir/striped_dir/f 512
28321         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28322         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28323
28324         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28325                 sed "s/[/][^:]*://g")
28326
28327         rm -f $DIR/$tdir/striped_dir/f1*
28328         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28329         removed=$((512 - cnt))
28330
28331         # few files have been just removed, so we expect
28332         # rmfid to fail on their fids
28333         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28334         [ $removed != $errors ] && error "$errors != $removed"
28335
28336         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28337         rm -rf $DIR/$tdir
28338         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28339 }
28340 run_test 421g "rmfid to return errors properly"
28341
28342 test_421h() {
28343         local mount_other
28344         local mount_ret
28345         local rmfid_ret
28346         local old_fid
28347         local fidA
28348         local fidB
28349         local fidC
28350         local fidD
28351
28352         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28353                 skip "Need MDS version at least 2.15.53"
28354
28355         test_mkdir $DIR/$tdir
28356         test_mkdir $DIR/$tdir/subdir
28357         touch $DIR/$tdir/subdir/file0
28358         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28359         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28360         rm -f $DIR/$tdir/subdir/file0
28361         touch $DIR/$tdir/subdir/fileA
28362         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28363         echo File $DIR/$tdir/subdir/fileA FID $fidA
28364         touch $DIR/$tdir/subdir/fileB
28365         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28366         echo File $DIR/$tdir/subdir/fileB FID $fidB
28367         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28368         touch $DIR/$tdir/subdir/fileC
28369         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28370         echo File $DIR/$tdir/subdir/fileC FID $fidC
28371         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28372         touch $DIR/$tdir/fileD
28373         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28374         echo File $DIR/$tdir/fileD FID $fidD
28375
28376         # mount another client mount point with subdirectory mount
28377         export FILESET=/$tdir/subdir
28378         mount_other=${MOUNT}_other
28379         mount_client $mount_other ${MOUNT_OPTS}
28380         mount_ret=$?
28381         export FILESET=""
28382         (( mount_ret == 0 )) || error "mount $mount_other failed"
28383
28384         echo Removing FIDs:
28385         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28386         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28387         rmfid_ret=$?
28388
28389         umount_client $mount_other || error "umount $mount_other failed"
28390
28391         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28392
28393         # fileA should have been deleted
28394         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28395
28396         # fileB should have been deleted
28397         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28398
28399         # fileC should not have been deleted, fid also exists outside of fileset
28400         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28401
28402         # fileD should not have been deleted, it exists outside of fileset
28403         stat $DIR/$tdir/fileD || error "fileD deleted"
28404 }
28405 run_test 421h "rmfid with fileset mount"
28406
28407 test_422() {
28408         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28409         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28410         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28411         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28412         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28413
28414         local amc=$(at_max_get client)
28415         local amo=$(at_max_get mds1)
28416         local timeout=`lctl get_param -n timeout`
28417
28418         at_max_set 0 client
28419         at_max_set 0 mds1
28420
28421 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28422         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28423                         fail_val=$(((2*timeout + 10)*1000))
28424         touch $DIR/$tdir/d3/file &
28425         sleep 2
28426 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28427         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28428                         fail_val=$((2*timeout + 5))
28429         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28430         local pid=$!
28431         sleep 1
28432         kill -9 $pid
28433         sleep $((2 * timeout))
28434         echo kill $pid
28435         kill -9 $pid
28436         lctl mark touch
28437         touch $DIR/$tdir/d2/file3
28438         touch $DIR/$tdir/d2/file4
28439         touch $DIR/$tdir/d2/file5
28440
28441         wait
28442         at_max_set $amc client
28443         at_max_set $amo mds1
28444
28445         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28446         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28447                 error "Watchdog is always throttled"
28448 }
28449 run_test 422 "kill a process with RPC in progress"
28450
28451 stat_test() {
28452     df -h $MOUNT &
28453     df -h $MOUNT &
28454     df -h $MOUNT &
28455     df -h $MOUNT &
28456     df -h $MOUNT &
28457     df -h $MOUNT &
28458 }
28459
28460 test_423() {
28461     local _stats
28462     # ensure statfs cache is expired
28463     sleep 2;
28464
28465     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28466     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28467
28468     return 0
28469 }
28470 run_test 423 "statfs should return a right data"
28471
28472 test_424() {
28473 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28474         $LCTL set_param fail_loc=0x80000522
28475         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28476         rm -f $DIR/$tfile
28477 }
28478 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28479
28480 test_425() {
28481         test_mkdir -c -1 $DIR/$tdir
28482         $LFS setstripe -c -1 $DIR/$tdir
28483
28484         lru_resize_disable "" 100
28485         stack_trap "lru_resize_enable" EXIT
28486
28487         sleep 5
28488
28489         for i in $(seq $((MDSCOUNT * 125))); do
28490                 local t=$DIR/$tdir/$tfile_$i
28491
28492                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28493                         error_noexit "Create file $t"
28494         done
28495         stack_trap "rm -rf $DIR/$tdir" EXIT
28496
28497         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28498                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28499                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28500
28501                 [ $lock_count -le $lru_size ] ||
28502                         error "osc lock count $lock_count > lru size $lru_size"
28503         done
28504
28505         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28506                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28507                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28508
28509                 [ $lock_count -le $lru_size ] ||
28510                         error "mdc lock count $lock_count > lru size $lru_size"
28511         done
28512 }
28513 run_test 425 "lock count should not exceed lru size"
28514
28515 test_426() {
28516         splice-test -r $DIR/$tfile
28517         splice-test -rd $DIR/$tfile
28518         splice-test $DIR/$tfile
28519         splice-test -d $DIR/$tfile
28520 }
28521 run_test 426 "splice test on Lustre"
28522
28523 test_427() {
28524         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28525         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28526                 skip "Need MDS version at least 2.12.4"
28527         local log
28528
28529         mkdir $DIR/$tdir
28530         mkdir $DIR/$tdir/1
28531         mkdir $DIR/$tdir/2
28532         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28533         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28534
28535         $LFS getdirstripe $DIR/$tdir/1/dir
28536
28537         #first setfattr for creating updatelog
28538         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28539
28540 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28541         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28542         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28543         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28544
28545         sleep 2
28546         fail mds2
28547         wait_recovery_complete mds2 $((2*TIMEOUT))
28548
28549         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28550         echo $log | grep "get update log failed" &&
28551                 error "update log corruption is detected" || true
28552 }
28553 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28554
28555 test_428() {
28556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28557         local cache_limit=$CACHE_MAX
28558
28559         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28560         $LCTL set_param -n llite.*.max_cached_mb=64
28561
28562         mkdir $DIR/$tdir
28563         $LFS setstripe -c 1 $DIR/$tdir
28564         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28565         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28566         #test write
28567         for f in $(seq 4); do
28568                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28569         done
28570         wait
28571
28572         cancel_lru_locks osc
28573         # Test read
28574         for f in $(seq 4); do
28575                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28576         done
28577         wait
28578 }
28579 run_test 428 "large block size IO should not hang"
28580
28581 test_429() { # LU-7915 / LU-10948
28582         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28583         local testfile=$DIR/$tfile
28584         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28585         local new_flag=1
28586         local first_rpc
28587         local second_rpc
28588         local third_rpc
28589
28590         $LCTL get_param $ll_opencache_threshold_count ||
28591                 skip "client does not have opencache parameter"
28592
28593         set_opencache $new_flag
28594         stack_trap "restore_opencache"
28595         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28596                 error "enable opencache failed"
28597         touch $testfile
28598         # drop MDC DLM locks
28599         cancel_lru_locks mdc
28600         # clear MDC RPC stats counters
28601         $LCTL set_param $mdc_rpcstats=clear
28602
28603         # According to the current implementation, we need to run 3 times
28604         # open & close file to verify if opencache is enabled correctly.
28605         # 1st, RPCs are sent for lookup/open and open handle is released on
28606         #      close finally.
28607         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28608         #      so open handle won't be released thereafter.
28609         # 3rd, No RPC is sent out.
28610         $MULTIOP $testfile oc || error "multiop failed"
28611         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28612         echo "1st: $first_rpc RPCs in flight"
28613
28614         $MULTIOP $testfile oc || error "multiop failed"
28615         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28616         echo "2nd: $second_rpc RPCs in flight"
28617
28618         $MULTIOP $testfile oc || error "multiop failed"
28619         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28620         echo "3rd: $third_rpc RPCs in flight"
28621
28622         #verify no MDC RPC is sent
28623         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28624 }
28625 run_test 429 "verify if opencache flag on client side does work"
28626
28627 lseek_test_430() {
28628         local offset
28629         local file=$1
28630
28631         # data at [200K, 400K)
28632         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28633                 error "256K->512K dd fails"
28634         # data at [2M, 3M)
28635         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28636                 error "2M->3M dd fails"
28637         # data at [4M, 5M)
28638         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28639                 error "4M->5M dd fails"
28640         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28641         # start at first component hole #1
28642         printf "Seeking hole from 1000 ... "
28643         offset=$(lseek_test -l 1000 $file)
28644         echo $offset
28645         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28646         printf "Seeking data from 1000 ... "
28647         offset=$(lseek_test -d 1000 $file)
28648         echo $offset
28649         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28650
28651         # start at first component data block
28652         printf "Seeking hole from 300000 ... "
28653         offset=$(lseek_test -l 300000 $file)
28654         echo $offset
28655         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28656         printf "Seeking data from 300000 ... "
28657         offset=$(lseek_test -d 300000 $file)
28658         echo $offset
28659         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28660
28661         # start at the first component but beyond end of object size
28662         printf "Seeking hole from 1000000 ... "
28663         offset=$(lseek_test -l 1000000 $file)
28664         echo $offset
28665         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28666         printf "Seeking data from 1000000 ... "
28667         offset=$(lseek_test -d 1000000 $file)
28668         echo $offset
28669         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28670
28671         # start at second component stripe 2 (empty file)
28672         printf "Seeking hole from 1500000 ... "
28673         offset=$(lseek_test -l 1500000 $file)
28674         echo $offset
28675         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28676         printf "Seeking data from 1500000 ... "
28677         offset=$(lseek_test -d 1500000 $file)
28678         echo $offset
28679         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28680
28681         # start at second component stripe 1 (all data)
28682         printf "Seeking hole from 3000000 ... "
28683         offset=$(lseek_test -l 3000000 $file)
28684         echo $offset
28685         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28686         printf "Seeking data from 3000000 ... "
28687         offset=$(lseek_test -d 3000000 $file)
28688         echo $offset
28689         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28690
28691         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28692                 error "2nd dd fails"
28693         echo "Add data block at 640K...1280K"
28694
28695         # start at before new data block, in hole
28696         printf "Seeking hole from 600000 ... "
28697         offset=$(lseek_test -l 600000 $file)
28698         echo $offset
28699         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28700         printf "Seeking data from 600000 ... "
28701         offset=$(lseek_test -d 600000 $file)
28702         echo $offset
28703         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28704
28705         # start at the first component new data block
28706         printf "Seeking hole from 1000000 ... "
28707         offset=$(lseek_test -l 1000000 $file)
28708         echo $offset
28709         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28710         printf "Seeking data from 1000000 ... "
28711         offset=$(lseek_test -d 1000000 $file)
28712         echo $offset
28713         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28714
28715         # start at second component stripe 2, new data
28716         printf "Seeking hole from 1200000 ... "
28717         offset=$(lseek_test -l 1200000 $file)
28718         echo $offset
28719         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28720         printf "Seeking data from 1200000 ... "
28721         offset=$(lseek_test -d 1200000 $file)
28722         echo $offset
28723         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28724
28725         # start beyond file end
28726         printf "Using offset > filesize ... "
28727         lseek_test -l 4000000 $file && error "lseek should fail"
28728         printf "Using offset > filesize ... "
28729         lseek_test -d 4000000 $file && error "lseek should fail"
28730
28731         printf "Done\n\n"
28732 }
28733
28734 test_430a() {
28735         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28736                 skip "MDT does not support SEEK_HOLE"
28737
28738         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28739                 skip "OST does not support SEEK_HOLE"
28740
28741         local file=$DIR/$tdir/$tfile
28742
28743         mkdir -p $DIR/$tdir
28744
28745         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28746         # OST stripe #1 will have continuous data at [1M, 3M)
28747         # OST stripe #2 is empty
28748         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28749         lseek_test_430 $file
28750         rm $file
28751         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28752         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28753         lseek_test_430 $file
28754         rm $file
28755         $LFS setstripe -c2 -S 512K $file
28756         echo "Two stripes, stripe size 512K"
28757         lseek_test_430 $file
28758         rm $file
28759         # FLR with stale mirror
28760         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28761                        -N -c2 -S 1M $file
28762         echo "Mirrored file:"
28763         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28764         echo "Plain 2 stripes 1M"
28765         lseek_test_430 $file
28766         rm $file
28767 }
28768 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28769
28770 test_430b() {
28771         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28772                 skip "OST does not support SEEK_HOLE"
28773
28774         local offset
28775         local file=$DIR/$tdir/$tfile
28776
28777         mkdir -p $DIR/$tdir
28778         # Empty layout lseek should fail
28779         $MCREATE $file
28780         # seek from 0
28781         printf "Seeking hole from 0 ... "
28782         lseek_test -l 0 $file && error "lseek should fail"
28783         printf "Seeking data from 0 ... "
28784         lseek_test -d 0 $file && error "lseek should fail"
28785         rm $file
28786
28787         # 1M-hole file
28788         $LFS setstripe -E 1M -c2 -E eof $file
28789         $TRUNCATE $file 1048576
28790         printf "Seeking hole from 1000000 ... "
28791         offset=$(lseek_test -l 1000000 $file)
28792         echo $offset
28793         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28794         printf "Seeking data from 1000000 ... "
28795         lseek_test -d 1000000 $file && error "lseek should fail"
28796         rm $file
28797
28798         # full component followed by non-inited one
28799         $LFS setstripe -E 1M -c2 -E eof $file
28800         dd if=/dev/urandom of=$file bs=1M count=1
28801         printf "Seeking hole from 1000000 ... "
28802         offset=$(lseek_test -l 1000000 $file)
28803         echo $offset
28804         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28805         printf "Seeking hole from 1048576 ... "
28806         lseek_test -l 1048576 $file && error "lseek should fail"
28807         # init second component and truncate back
28808         echo "123" >> $file
28809         $TRUNCATE $file 1048576
28810         printf "Seeking hole from 1000000 ... "
28811         offset=$(lseek_test -l 1000000 $file)
28812         echo $offset
28813         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28814         printf "Seeking hole from 1048576 ... "
28815         lseek_test -l 1048576 $file && error "lseek should fail"
28816         # boundary checks for big values
28817         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28818         offset=$(lseek_test -d 0 $file.10g)
28819         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28820         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28821         offset=$(lseek_test -d 0 $file.100g)
28822         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28823         return 0
28824 }
28825 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28826
28827 test_430c() {
28828         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28829                 skip "OST does not support SEEK_HOLE"
28830
28831         local file=$DIR/$tdir/$tfile
28832         local start
28833
28834         mkdir -p $DIR/$tdir
28835         stack_trap "rm -f $file $file.tmp"
28836         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28837
28838         # cp version 8.33+ prefers lseek over fiemap
28839         local ver=$(cp --version | awk '{ print $4; exit; }')
28840
28841         echo "cp $ver installed"
28842         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28843                 start=$SECONDS
28844                 time cp -v $file $file.tmp || error "cp $file failed"
28845                 (( SECONDS - start < 5 )) || {
28846                         strace cp $file $file.tmp |&
28847                                 grep -E "open|read|seek|FIEMAP" |
28848                                 grep -A 100 $file
28849                         error "cp: too long runtime $((SECONDS - start))"
28850                 }
28851         else
28852                 echo "cp test skipped due to $ver < 8.33"
28853         fi
28854
28855         # tar version 1.29+ supports SEEK_HOLE/DATA
28856         ver=$(tar --version | awk '{ print $4; exit; }')
28857         echo "tar $ver installed"
28858         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28859                 start=$SECONDS
28860                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28861                 (( SECONDS - start < 5 )) || {
28862                         strace tar cf $file.tmp --sparse $file |&
28863                                 grep -E "open|read|seek|FIEMAP" |
28864                                 grep -A 100 $file
28865                         error "tar: too long runtime $((SECONDS - start))"
28866                 }
28867         else
28868                 echo "tar test skipped due to $ver < 1.29"
28869         fi
28870 }
28871 run_test 430c "lseek: external tools check"
28872
28873 test_431() { # LU-14187
28874         local file=$DIR/$tdir/$tfile
28875
28876         mkdir -p $DIR/$tdir
28877         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28878         dd if=/dev/urandom of=$file bs=4k count=1
28879         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28880         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28881         #define OBD_FAIL_OST_RESTART_IO 0x251
28882         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28883         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28884         cp $file $file.0
28885         cancel_lru_locks
28886         sync_all_data
28887         echo 3 > /proc/sys/vm/drop_caches
28888         diff  $file $file.0 || error "data diff"
28889 }
28890 run_test 431 "Restart transaction for IO"
28891
28892 cleanup_test_432() {
28893         do_facet mgs $LCTL nodemap_activate 0
28894         wait_nm_sync active
28895 }
28896
28897 test_432() {
28898         local tmpdir=$TMP/dir432
28899
28900         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28901                 skip "Need MDS version at least 2.14.52"
28902
28903         stack_trap cleanup_test_432 EXIT
28904         mkdir $DIR/$tdir
28905         mkdir $tmpdir
28906
28907         do_facet mgs $LCTL nodemap_activate 1
28908         wait_nm_sync active
28909         do_facet mgs $LCTL nodemap_modify --name default \
28910                 --property admin --value 1
28911         do_facet mgs $LCTL nodemap_modify --name default \
28912                 --property trusted --value 1
28913         cancel_lru_locks mdc
28914         wait_nm_sync default admin_nodemap
28915         wait_nm_sync default trusted_nodemap
28916
28917         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28918                grep -ci "Operation not permitted") -ne 0 ]; then
28919                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28920         fi
28921 }
28922 run_test 432 "mv dir from outside Lustre"
28923
28924 test_433() {
28925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28926
28927         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28928                 skip "inode cache not supported"
28929
28930         $LCTL set_param llite.*.inode_cache=0
28931         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28932
28933         local count=256
28934         local before
28935         local after
28936
28937         cancel_lru_locks mdc
28938         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28939         createmany -m $DIR/$tdir/f $count
28940         createmany -d $DIR/$tdir/d $count
28941         ls -l $DIR/$tdir > /dev/null
28942         stack_trap "rm -rf $DIR/$tdir"
28943
28944         before=$(num_objects)
28945         cancel_lru_locks mdc
28946         after=$(num_objects)
28947
28948         # sometimes even @before is less than 2 * count
28949         while (( before - after < count )); do
28950                 sleep 1
28951                 after=$(num_objects)
28952                 wait=$((wait + 1))
28953                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28954                 if (( wait > 60 )); then
28955                         error "inode slab grew from $before to $after"
28956                 fi
28957         done
28958
28959         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28960 }
28961 run_test 433 "ldlm lock cancel releases dentries and inodes"
28962
28963 test_434() {
28964         local file
28965         local getxattr_count
28966         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28967         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28968
28969         [[ $(getenforce) == "Disabled" ]] ||
28970                 skip "lsm selinux module have to be disabled for this test"
28971
28972         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28973                 error "fail to create $DIR/$tdir/ on MDT0000"
28974
28975         touch $DIR/$tdir/$tfile-{001..100}
28976
28977         # disable the xattr cache
28978         save_lustre_params client "llite.*.xattr_cache" > $p
28979         lctl set_param llite.*.xattr_cache=0
28980         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28981
28982         # clear clients mdc stats
28983         clear_stats $mdc_stat_param ||
28984                 error "fail to clear stats on mdc MDT0000"
28985
28986         for file in $DIR/$tdir/$tfile-{001..100}; do
28987                 getfattr -n security.selinux $file |&
28988                         grep -q "Operation not supported" ||
28989                         error "getxattr on security.selinux should return EOPNOTSUPP"
28990         done
28991
28992         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28993         (( getxattr_count < 100 )) ||
28994                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28995 }
28996 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28997
28998 test_440() {
28999         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29000                 source $LUSTRE/scripts/bash-completion/lustre
29001         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29002                 source /usr/share/bash-completion/completions/lustre
29003         else
29004                 skip "bash completion scripts not found"
29005         fi
29006
29007         local lctl_completions
29008         local lfs_completions
29009
29010         lctl_completions=$(_lustre_cmds lctl)
29011         if [[ ! $lctl_completions =~ "get_param" ]]; then
29012                 error "lctl bash completion failed"
29013         fi
29014
29015         lfs_completions=$(_lustre_cmds lfs)
29016         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29017                 error "lfs bash completion failed"
29018         fi
29019 }
29020 run_test 440 "bash completion for lfs, lctl"
29021
29022 prep_801() {
29023         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29024         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29025                 skip "Need server version at least 2.9.55"
29026
29027         start_full_debug_logging
29028 }
29029
29030 post_801() {
29031         stop_full_debug_logging
29032 }
29033
29034 barrier_stat() {
29035         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29036                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29037                            awk '/The barrier for/ { print $7 }')
29038                 echo $st
29039         else
29040                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29041                 echo \'$st\'
29042         fi
29043 }
29044
29045 barrier_expired() {
29046         local expired
29047
29048         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29049                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29050                           awk '/will be expired/ { print $7 }')
29051         else
29052                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29053         fi
29054
29055         echo $expired
29056 }
29057
29058 test_801a() {
29059         prep_801
29060
29061         echo "Start barrier_freeze at: $(date)"
29062         #define OBD_FAIL_BARRIER_DELAY          0x2202
29063         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29064         # Do not reduce barrier time - See LU-11873
29065         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29066
29067         sleep 2
29068         local b_status=$(barrier_stat)
29069         echo "Got barrier status at: $(date)"
29070         [ "$b_status" = "'freezing_p1'" ] ||
29071                 error "(1) unexpected barrier status $b_status"
29072
29073         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29074         wait
29075         b_status=$(barrier_stat)
29076         [ "$b_status" = "'frozen'" ] ||
29077                 error "(2) unexpected barrier status $b_status"
29078
29079         local expired=$(barrier_expired)
29080         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29081         sleep $((expired + 3))
29082
29083         b_status=$(barrier_stat)
29084         [ "$b_status" = "'expired'" ] ||
29085                 error "(3) unexpected barrier status $b_status"
29086
29087         # Do not reduce barrier time - See LU-11873
29088         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29089                 error "(4) fail to freeze barrier"
29090
29091         b_status=$(barrier_stat)
29092         [ "$b_status" = "'frozen'" ] ||
29093                 error "(5) unexpected barrier status $b_status"
29094
29095         echo "Start barrier_thaw at: $(date)"
29096         #define OBD_FAIL_BARRIER_DELAY          0x2202
29097         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29098         do_facet mgs $LCTL barrier_thaw $FSNAME &
29099
29100         sleep 2
29101         b_status=$(barrier_stat)
29102         echo "Got barrier status at: $(date)"
29103         [ "$b_status" = "'thawing'" ] ||
29104                 error "(6) unexpected barrier status $b_status"
29105
29106         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29107         wait
29108         b_status=$(barrier_stat)
29109         [ "$b_status" = "'thawed'" ] ||
29110                 error "(7) unexpected barrier status $b_status"
29111
29112         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29113         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29114         do_facet mgs $LCTL barrier_freeze $FSNAME
29115
29116         b_status=$(barrier_stat)
29117         [ "$b_status" = "'failed'" ] ||
29118                 error "(8) unexpected barrier status $b_status"
29119
29120         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29121         do_facet mgs $LCTL barrier_thaw $FSNAME
29122
29123         post_801
29124 }
29125 run_test 801a "write barrier user interfaces and stat machine"
29126
29127 test_801b() {
29128         prep_801
29129
29130         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29131         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29132         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29133         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29134         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29135
29136         cancel_lru_locks mdc
29137
29138         # 180 seconds should be long enough
29139         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29140
29141         local b_status=$(barrier_stat)
29142         [ "$b_status" = "'frozen'" ] ||
29143                 error "(6) unexpected barrier status $b_status"
29144
29145         mkdir $DIR/$tdir/d0/d10 &
29146         mkdir_pid=$!
29147
29148         touch $DIR/$tdir/d1/f13 &
29149         touch_pid=$!
29150
29151         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29152         ln_pid=$!
29153
29154         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29155         mv_pid=$!
29156
29157         rm -f $DIR/$tdir/d4/f12 &
29158         rm_pid=$!
29159
29160         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29161
29162         # To guarantee taht the 'stat' is not blocked
29163         b_status=$(barrier_stat)
29164         [ "$b_status" = "'frozen'" ] ||
29165                 error "(8) unexpected barrier status $b_status"
29166
29167         # let above commands to run at background
29168         sleep 5
29169
29170         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29171         ps -p $touch_pid || error "(10) touch should be blocked"
29172         ps -p $ln_pid || error "(11) link should be blocked"
29173         ps -p $mv_pid || error "(12) rename should be blocked"
29174         ps -p $rm_pid || error "(13) unlink should be blocked"
29175
29176         b_status=$(barrier_stat)
29177         [ "$b_status" = "'frozen'" ] ||
29178                 error "(14) unexpected barrier status $b_status"
29179
29180         do_facet mgs $LCTL barrier_thaw $FSNAME
29181         b_status=$(barrier_stat)
29182         [ "$b_status" = "'thawed'" ] ||
29183                 error "(15) unexpected barrier status $b_status"
29184
29185         wait $mkdir_pid || error "(16) mkdir should succeed"
29186         wait $touch_pid || error "(17) touch should succeed"
29187         wait $ln_pid || error "(18) link should succeed"
29188         wait $mv_pid || error "(19) rename should succeed"
29189         wait $rm_pid || error "(20) unlink should succeed"
29190
29191         post_801
29192 }
29193 run_test 801b "modification will be blocked by write barrier"
29194
29195 test_801c() {
29196         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29197
29198         prep_801
29199
29200         stop mds2 || error "(1) Fail to stop mds2"
29201
29202         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29203
29204         local b_status=$(barrier_stat)
29205         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29206                 do_facet mgs $LCTL barrier_thaw $FSNAME
29207                 error "(2) unexpected barrier status $b_status"
29208         }
29209
29210         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29211                 error "(3) Fail to rescan barrier bitmap"
29212
29213         # Do not reduce barrier time - See LU-11873
29214         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29215
29216         b_status=$(barrier_stat)
29217         [ "$b_status" = "'frozen'" ] ||
29218                 error "(4) unexpected barrier status $b_status"
29219
29220         do_facet mgs $LCTL barrier_thaw $FSNAME
29221         b_status=$(barrier_stat)
29222         [ "$b_status" = "'thawed'" ] ||
29223                 error "(5) unexpected barrier status $b_status"
29224
29225         local devname=$(mdsdevname 2)
29226
29227         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29228
29229         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29230                 error "(7) Fail to rescan barrier bitmap"
29231
29232         post_801
29233 }
29234 run_test 801c "rescan barrier bitmap"
29235
29236 test_802b() {
29237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29238         remote_mds_nodsh && skip "remote MDS with nodsh"
29239
29240         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29241                 skip "readonly option not available"
29242
29243         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29244
29245         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29246                 error "(2) Fail to copy"
29247
29248         # write back all cached data before setting MDT to readonly
29249         cancel_lru_locks
29250         sync_all_data
29251
29252         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29253         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29254
29255         echo "Modify should be refused"
29256         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29257
29258         echo "Read should be allowed"
29259         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29260                 error "(7) Read should succeed under ro mode"
29261
29262         # disable readonly
29263         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29264 }
29265 run_test 802b "be able to set MDTs to readonly"
29266
29267 test_803a() {
29268         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29269         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29270                 skip "MDS needs to be newer than 2.10.54"
29271
29272         mkdir_on_mdt0 $DIR/$tdir
29273         # Create some objects on all MDTs to trigger related logs objects
29274         for idx in $(seq $MDSCOUNT); do
29275                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29276                         $DIR/$tdir/dir${idx} ||
29277                         error "Fail to create $DIR/$tdir/dir${idx}"
29278         done
29279
29280         wait_delete_completed # ensure old test cleanups are finished
29281         sleep 3
29282         echo "before create:"
29283         $LFS df -i $MOUNT
29284         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29285
29286         for i in {1..10}; do
29287                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29288                         error "Fail to create $DIR/$tdir/foo$i"
29289         done
29290
29291         # sync ZFS-on-MDS to refresh statfs data
29292         wait_zfs_commit mds1
29293         sleep 3
29294         echo "after create:"
29295         $LFS df -i $MOUNT
29296         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29297
29298         # allow for an llog to be cleaned up during the test
29299         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29300                 error "before ($before_used) + 10 > after ($after_used)"
29301
29302         for i in {1..10}; do
29303                 rm -rf $DIR/$tdir/foo$i ||
29304                         error "Fail to remove $DIR/$tdir/foo$i"
29305         done
29306
29307         # sync ZFS-on-MDS to refresh statfs data
29308         wait_zfs_commit mds1
29309         wait_delete_completed
29310         sleep 3 # avoid MDT return cached statfs
29311         echo "after unlink:"
29312         $LFS df -i $MOUNT
29313         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29314
29315         # allow for an llog to be created during the test
29316         [ $after_used -le $((before_used + 1)) ] ||
29317                 error "after ($after_used) > before ($before_used) + 1"
29318 }
29319 run_test 803a "verify agent object for remote object"
29320
29321 test_803b() {
29322         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29323         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29324                 skip "MDS needs to be newer than 2.13.56"
29325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29326
29327         for i in $(seq 0 $((MDSCOUNT - 1))); do
29328                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29329         done
29330
29331         local before=0
29332         local after=0
29333
29334         local tmp
29335
29336         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29337         for i in $(seq 0 $((MDSCOUNT - 1))); do
29338                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29339                         awk '/getattr/ { print $2 }')
29340                 before=$((before + tmp))
29341         done
29342         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29343         for i in $(seq 0 $((MDSCOUNT - 1))); do
29344                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29345                         awk '/getattr/ { print $2 }')
29346                 after=$((after + tmp))
29347         done
29348
29349         [ $before -eq $after ] || error "getattr count $before != $after"
29350 }
29351 run_test 803b "remote object can getattr from cache"
29352
29353 test_804() {
29354         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29355         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29356                 skip "MDS needs to be newer than 2.10.54"
29357         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29358
29359         mkdir -p $DIR/$tdir
29360         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29361                 error "Fail to create $DIR/$tdir/dir0"
29362
29363         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29364         local dev=$(mdsdevname 2)
29365
29366         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29367                 grep ${fid} || error "NOT found agent entry for dir0"
29368
29369         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29370                 error "Fail to create $DIR/$tdir/dir1"
29371
29372         touch $DIR/$tdir/dir1/foo0 ||
29373                 error "Fail to create $DIR/$tdir/dir1/foo0"
29374         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29375         local rc=0
29376
29377         for idx in $(seq $MDSCOUNT); do
29378                 dev=$(mdsdevname $idx)
29379                 do_facet mds${idx} \
29380                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29381                         grep ${fid} && rc=$idx
29382         done
29383
29384         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29385                 error "Fail to rename foo0 to foo1"
29386         if [ $rc -eq 0 ]; then
29387                 for idx in $(seq $MDSCOUNT); do
29388                         dev=$(mdsdevname $idx)
29389                         do_facet mds${idx} \
29390                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29391                         grep ${fid} && rc=$idx
29392                 done
29393         fi
29394
29395         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29396                 error "Fail to rename foo1 to foo2"
29397         if [ $rc -eq 0 ]; then
29398                 for idx in $(seq $MDSCOUNT); do
29399                         dev=$(mdsdevname $idx)
29400                         do_facet mds${idx} \
29401                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29402                         grep ${fid} && rc=$idx
29403                 done
29404         fi
29405
29406         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29407
29408         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29409                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29410         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29411                 error "Fail to rename foo2 to foo0"
29412         unlink $DIR/$tdir/dir1/foo0 ||
29413                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29414         rm -rf $DIR/$tdir/dir0 ||
29415                 error "Fail to rm $DIR/$tdir/dir0"
29416
29417         for idx in $(seq $MDSCOUNT); do
29418                 rc=0
29419
29420                 stop mds${idx}
29421                 dev=$(mdsdevname $idx)
29422                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29423                         rc=$?
29424                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29425                         error "mount mds$idx failed"
29426                 df $MOUNT > /dev/null 2>&1
29427
29428                 # e2fsck should not return error
29429                 [ $rc -eq 0 ] ||
29430                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29431         done
29432 }
29433 run_test 804 "verify agent entry for remote entry"
29434
29435 cleanup_805() {
29436         do_facet $SINGLEMDS zfs set quota=$old $fsset
29437         unlinkmany $DIR/$tdir/f- 1000000
29438         trap 0
29439 }
29440
29441 test_805() {
29442         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29443         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29444         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29445                 skip "netfree not implemented before 0.7"
29446         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29447                 skip "Need MDS version at least 2.10.57"
29448
29449         local fsset
29450         local freekb
29451         local usedkb
29452         local old
29453         local quota
29454         local pref="osd-zfs.$FSNAME-MDT0000."
29455
29456         # limit available space on MDS dataset to meet nospace issue
29457         # quickly. then ZFS 0.7.2 can use reserved space if asked
29458         # properly (using netfree flag in osd_declare_destroy()
29459         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29460         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29461                 gawk '{print $3}')
29462         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29463         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29464         let "usedkb=usedkb-freekb"
29465         let "freekb=freekb/2"
29466         if let "freekb > 5000"; then
29467                 let "freekb=5000"
29468         fi
29469         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29470         trap cleanup_805 EXIT
29471         mkdir_on_mdt0 $DIR/$tdir
29472         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29473                 error "Can't set PFL layout"
29474         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29475         rm -rf $DIR/$tdir || error "not able to remove"
29476         do_facet $SINGLEMDS zfs set quota=$old $fsset
29477         trap 0
29478 }
29479 run_test 805 "ZFS can remove from full fs"
29480
29481 # Size-on-MDS test
29482 check_lsom_data()
29483 {
29484         local file=$1
29485         local expect=$(stat -c %s $file)
29486
29487         check_lsom_size $1 $expect
29488
29489         local blocks=$($LFS getsom -b $file)
29490         expect=$(stat -c %b $file)
29491         [[ $blocks == $expect ]] ||
29492                 error "$file expected blocks: $expect, got: $blocks"
29493 }
29494
29495 check_lsom_size()
29496 {
29497         local size
29498         local expect=$2
29499
29500         cancel_lru_locks mdc
29501
29502         size=$($LFS getsom -s $1)
29503         [[ $size == $expect ]] ||
29504                 error "$file expected size: $expect, got: $size"
29505 }
29506
29507 test_806() {
29508         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29509                 skip "Need MDS version at least 2.11.52"
29510
29511         local bs=1048576
29512
29513         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29514
29515         disable_opencache
29516         stack_trap "restore_opencache"
29517
29518         # single-threaded write
29519         echo "Test SOM for single-threaded write"
29520         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29521                 error "write $tfile failed"
29522         check_lsom_size $DIR/$tfile $bs
29523
29524         local num=32
29525         local size=$(($num * $bs))
29526         local offset=0
29527         local i
29528
29529         echo "Test SOM for single client multi-threaded($num) write"
29530         $TRUNCATE $DIR/$tfile 0
29531         for ((i = 0; i < $num; i++)); do
29532                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29533                 local pids[$i]=$!
29534                 offset=$((offset + $bs))
29535         done
29536         for (( i=0; i < $num; i++ )); do
29537                 wait ${pids[$i]}
29538         done
29539         check_lsom_size $DIR/$tfile $size
29540
29541         $TRUNCATE $DIR/$tfile 0
29542         for ((i = 0; i < $num; i++)); do
29543                 offset=$((offset - $bs))
29544                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29545                 local pids[$i]=$!
29546         done
29547         for (( i=0; i < $num; i++ )); do
29548                 wait ${pids[$i]}
29549         done
29550         check_lsom_size $DIR/$tfile $size
29551
29552         # multi-client writes
29553         num=$(get_node_count ${CLIENTS//,/ })
29554         size=$(($num * $bs))
29555         offset=0
29556         i=0
29557
29558         echo "Test SOM for multi-client ($num) writes"
29559         $TRUNCATE $DIR/$tfile 0
29560         for client in ${CLIENTS//,/ }; do
29561                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29562                 local pids[$i]=$!
29563                 i=$((i + 1))
29564                 offset=$((offset + $bs))
29565         done
29566         for (( i=0; i < $num; i++ )); do
29567                 wait ${pids[$i]}
29568         done
29569         check_lsom_size $DIR/$tfile $offset
29570
29571         i=0
29572         $TRUNCATE $DIR/$tfile 0
29573         for client in ${CLIENTS//,/ }; do
29574                 offset=$((offset - $bs))
29575                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29576                 local pids[$i]=$!
29577                 i=$((i + 1))
29578         done
29579         for (( i=0; i < $num; i++ )); do
29580                 wait ${pids[$i]}
29581         done
29582         check_lsom_size $DIR/$tfile $size
29583
29584         # verify SOM blocks count
29585         echo "Verify SOM block count"
29586         $TRUNCATE $DIR/$tfile 0
29587         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29588                 error "failed to write file $tfile with fdatasync and fstat"
29589         check_lsom_data $DIR/$tfile
29590
29591         $TRUNCATE $DIR/$tfile 0
29592         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29593                 error "failed to write file $tfile with fdatasync"
29594         check_lsom_data $DIR/$tfile
29595
29596         $TRUNCATE $DIR/$tfile 0
29597         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29598                 error "failed to write file $tfile with sync IO"
29599         check_lsom_data $DIR/$tfile
29600
29601         # verify truncate
29602         echo "Test SOM for truncate"
29603         # use ftruncate to sync blocks on close request
29604         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29605         check_lsom_size $DIR/$tfile 16384
29606         check_lsom_data $DIR/$tfile
29607
29608         $TRUNCATE $DIR/$tfile 1234
29609         check_lsom_size $DIR/$tfile 1234
29610         # sync blocks on the MDT
29611         $MULTIOP $DIR/$tfile oc
29612         check_lsom_data $DIR/$tfile
29613 }
29614 run_test 806 "Verify Lazy Size on MDS"
29615
29616 test_807() {
29617         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29618         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29619                 skip "Need MDS version at least 2.11.52"
29620
29621         # Registration step
29622         changelog_register || error "changelog_register failed"
29623         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29624         changelog_users $SINGLEMDS | grep -q $cl_user ||
29625                 error "User $cl_user not found in changelog_users"
29626
29627         rm -rf $DIR/$tdir || error "rm $tdir failed"
29628         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29629         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29630         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29631         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29632                 error "truncate $tdir/trunc failed"
29633
29634         local bs=1048576
29635         echo "Test SOM for single-threaded write with fsync"
29636         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29637                 error "write $tfile failed"
29638         sync;sync;sync
29639
29640         # multi-client wirtes
29641         local num=$(get_node_count ${CLIENTS//,/ })
29642         local offset=0
29643         local i=0
29644
29645         echo "Test SOM for multi-client ($num) writes"
29646         touch $DIR/$tfile || error "touch $tfile failed"
29647         $TRUNCATE $DIR/$tfile 0
29648         for client in ${CLIENTS//,/ }; do
29649                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29650                 local pids[$i]=$!
29651                 i=$((i + 1))
29652                 offset=$((offset + $bs))
29653         done
29654         for (( i=0; i < $num; i++ )); do
29655                 wait ${pids[$i]}
29656         done
29657
29658         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29659         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29660         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29661         check_lsom_data $DIR/$tdir/trunc
29662         check_lsom_data $DIR/$tdir/single_dd
29663         check_lsom_data $DIR/$tfile
29664
29665         rm -rf $DIR/$tdir
29666         # Deregistration step
29667         changelog_deregister || error "changelog_deregister failed"
29668 }
29669 run_test 807 "verify LSOM syncing tool"
29670
29671 check_som_nologged()
29672 {
29673         local lines=$($LFS changelog $FSNAME-MDT0000 |
29674                 grep 'x=trusted.som' | wc -l)
29675         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29676 }
29677
29678 test_808() {
29679         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29680                 skip "Need MDS version at least 2.11.55"
29681
29682         # Registration step
29683         changelog_register || error "changelog_register failed"
29684
29685         touch $DIR/$tfile || error "touch $tfile failed"
29686         check_som_nologged
29687
29688         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29689                 error "write $tfile failed"
29690         check_som_nologged
29691
29692         $TRUNCATE $DIR/$tfile 1234
29693         check_som_nologged
29694
29695         $TRUNCATE $DIR/$tfile 1048576
29696         check_som_nologged
29697
29698         # Deregistration step
29699         changelog_deregister || error "changelog_deregister failed"
29700 }
29701 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29702
29703 check_som_nodata()
29704 {
29705         $LFS getsom $1
29706         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29707 }
29708
29709 test_809() {
29710         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29711                 skip "Need MDS version at least 2.11.56"
29712
29713         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29714                 error "failed to create DoM-only file $DIR/$tfile"
29715         touch $DIR/$tfile || error "touch $tfile failed"
29716         check_som_nodata $DIR/$tfile
29717
29718         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29719                 error "write $tfile failed"
29720         check_som_nodata $DIR/$tfile
29721
29722         $TRUNCATE $DIR/$tfile 1234
29723         check_som_nodata $DIR/$tfile
29724
29725         $TRUNCATE $DIR/$tfile 4097
29726         check_som_nodata $DIR/$file
29727 }
29728 run_test 809 "Verify no SOM xattr store for DoM-only files"
29729
29730 test_810() {
29731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29732         $GSS && skip_env "could not run with gss"
29733         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29734                 skip "OST < 2.12.58 doesn't align checksum"
29735
29736         set_checksums 1
29737         stack_trap "set_checksums $ORIG_CSUM" EXIT
29738         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29739
29740         local csum
29741         local before
29742         local after
29743         for csum in $CKSUM_TYPES; do
29744                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29745                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29746                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29747                         eval set -- $i
29748                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29749                         before=$(md5sum $DIR/$tfile)
29750                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29751                         after=$(md5sum $DIR/$tfile)
29752                         [ "$before" == "$after" ] ||
29753                                 error "$csum: $before != $after bs=$1 seek=$2"
29754                 done
29755         done
29756 }
29757 run_test 810 "partial page writes on ZFS (LU-11663)"
29758
29759 test_812a() {
29760         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29761                 skip "OST < 2.12.51 doesn't support this fail_loc"
29762
29763         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29764         # ensure ost1 is connected
29765         stat $DIR/$tfile >/dev/null || error "can't stat"
29766         wait_osc_import_state client ost1 FULL
29767         # no locks, no reqs to let the connection idle
29768         cancel_lru_locks osc
29769
29770         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29771 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29772         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29773         wait_osc_import_state client ost1 CONNECTING
29774         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29775
29776         stat $DIR/$tfile >/dev/null || error "can't stat file"
29777 }
29778 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29779
29780 test_812b() { # LU-12378
29781         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29782                 skip "OST < 2.12.51 doesn't support this fail_loc"
29783
29784         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29785         # ensure ost1 is connected
29786         stat $DIR/$tfile >/dev/null || error "can't stat"
29787         wait_osc_import_state client ost1 FULL
29788         # no locks, no reqs to let the connection idle
29789         cancel_lru_locks osc
29790
29791         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29792 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29793         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29794         wait_osc_import_state client ost1 CONNECTING
29795         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29796
29797         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29798         wait_osc_import_state client ost1 IDLE
29799 }
29800 run_test 812b "do not drop no resend request for idle connect"
29801
29802 test_812c() {
29803         local old
29804
29805         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29806
29807         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29808         $LFS getstripe $DIR/$tfile
29809         $LCTL set_param osc.*.idle_timeout=10
29810         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29811         # ensure ost1 is connected
29812         stat $DIR/$tfile >/dev/null || error "can't stat"
29813         wait_osc_import_state client ost1 FULL
29814         # no locks, no reqs to let the connection idle
29815         cancel_lru_locks osc
29816
29817 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29818         $LCTL set_param fail_loc=0x80000533
29819         sleep 15
29820         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29821 }
29822 run_test 812c "idle import vs lock enqueue race"
29823
29824 test_813() {
29825         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29826         [ -z "$file_heat_sav" ] && skip "no file heat support"
29827
29828         local readsample
29829         local writesample
29830         local readbyte
29831         local writebyte
29832         local readsample1
29833         local writesample1
29834         local readbyte1
29835         local writebyte1
29836
29837         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29838         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29839
29840         $LCTL set_param -n llite.*.file_heat=1
29841         echo "Turn on file heat"
29842         echo "Period second: $period_second, Decay percentage: $decay_pct"
29843
29844         echo "QQQQ" > $DIR/$tfile
29845         echo "QQQQ" > $DIR/$tfile
29846         echo "QQQQ" > $DIR/$tfile
29847         cat $DIR/$tfile > /dev/null
29848         cat $DIR/$tfile > /dev/null
29849         cat $DIR/$tfile > /dev/null
29850         cat $DIR/$tfile > /dev/null
29851
29852         local out=$($LFS heat_get $DIR/$tfile)
29853
29854         $LFS heat_get $DIR/$tfile
29855         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29856         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29857         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29858         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29859
29860         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29861         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29862         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29863         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29864
29865         sleep $((period_second + 3))
29866         echo "Sleep $((period_second + 3)) seconds..."
29867         # The recursion formula to calculate the heat of the file f is as
29868         # follow:
29869         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29870         # Where Hi is the heat value in the period between time points i*I and
29871         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29872         # to the weight of Ci.
29873         out=$($LFS heat_get $DIR/$tfile)
29874         $LFS heat_get $DIR/$tfile
29875         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29876         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29877         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29878         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29879
29880         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29881                 error "read sample ($readsample) is wrong"
29882         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29883                 error "write sample ($writesample) is wrong"
29884         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29885                 error "read bytes ($readbyte) is wrong"
29886         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29887                 error "write bytes ($writebyte) is wrong"
29888
29889         echo "QQQQ" > $DIR/$tfile
29890         echo "QQQQ" > $DIR/$tfile
29891         echo "QQQQ" > $DIR/$tfile
29892         cat $DIR/$tfile > /dev/null
29893         cat $DIR/$tfile > /dev/null
29894         cat $DIR/$tfile > /dev/null
29895         cat $DIR/$tfile > /dev/null
29896
29897         sleep $((period_second + 3))
29898         echo "Sleep $((period_second + 3)) seconds..."
29899
29900         out=$($LFS heat_get $DIR/$tfile)
29901         $LFS heat_get $DIR/$tfile
29902         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29903         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29904         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29905         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29906
29907         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29908                 4 * $decay_pct) / 100") -eq 1 ] ||
29909                 error "read sample ($readsample1) is wrong"
29910         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29911                 3 * $decay_pct) / 100") -eq 1 ] ||
29912                 error "write sample ($writesample1) is wrong"
29913         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29914                 20 * $decay_pct) / 100") -eq 1 ] ||
29915                 error "read bytes ($readbyte1) is wrong"
29916         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29917                 15 * $decay_pct) / 100") -eq 1 ] ||
29918                 error "write bytes ($writebyte1) is wrong"
29919
29920         echo "Turn off file heat for the file $DIR/$tfile"
29921         $LFS heat_set -o $DIR/$tfile
29922
29923         echo "QQQQ" > $DIR/$tfile
29924         echo "QQQQ" > $DIR/$tfile
29925         echo "QQQQ" > $DIR/$tfile
29926         cat $DIR/$tfile > /dev/null
29927         cat $DIR/$tfile > /dev/null
29928         cat $DIR/$tfile > /dev/null
29929         cat $DIR/$tfile > /dev/null
29930
29931         out=$($LFS heat_get $DIR/$tfile)
29932         $LFS heat_get $DIR/$tfile
29933         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29934         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29935         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29936         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29937
29938         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29939         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29940         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29941         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29942
29943         echo "Trun on file heat for the file $DIR/$tfile"
29944         $LFS heat_set -O $DIR/$tfile
29945
29946         echo "QQQQ" > $DIR/$tfile
29947         echo "QQQQ" > $DIR/$tfile
29948         echo "QQQQ" > $DIR/$tfile
29949         cat $DIR/$tfile > /dev/null
29950         cat $DIR/$tfile > /dev/null
29951         cat $DIR/$tfile > /dev/null
29952         cat $DIR/$tfile > /dev/null
29953
29954         out=$($LFS heat_get $DIR/$tfile)
29955         $LFS heat_get $DIR/$tfile
29956         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29957         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29958         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29959         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29960
29961         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29962         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29963         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29964         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29965
29966         $LFS heat_set -c $DIR/$tfile
29967         $LCTL set_param -n llite.*.file_heat=0
29968         echo "Turn off file heat support for the Lustre filesystem"
29969
29970         echo "QQQQ" > $DIR/$tfile
29971         echo "QQQQ" > $DIR/$tfile
29972         echo "QQQQ" > $DIR/$tfile
29973         cat $DIR/$tfile > /dev/null
29974         cat $DIR/$tfile > /dev/null
29975         cat $DIR/$tfile > /dev/null
29976         cat $DIR/$tfile > /dev/null
29977
29978         out=$($LFS heat_get $DIR/$tfile)
29979         $LFS heat_get $DIR/$tfile
29980         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29981         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29982         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29983         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29984
29985         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29986         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29987         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29988         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29989
29990         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29991         rm -f $DIR/$tfile
29992 }
29993 run_test 813 "File heat verfication"
29994
29995 test_814()
29996 {
29997         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29998         echo -n y >> $DIR/$tfile
29999         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30000         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30001 }
30002 run_test 814 "sparse cp works as expected (LU-12361)"
30003
30004 test_815()
30005 {
30006         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30007         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30008 }
30009 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30010
30011 test_816() {
30012         local ost1_imp=$(get_osc_import_name client ost1)
30013         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30014                          cut -d'.' -f2)
30015
30016         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30017         # ensure ost1 is connected
30018
30019         stat $DIR/$tfile >/dev/null || error "can't stat"
30020         wait_osc_import_state client ost1 FULL
30021         # no locks, no reqs to let the connection idle
30022         cancel_lru_locks osc
30023         lru_resize_disable osc
30024         local before
30025         local now
30026         before=$($LCTL get_param -n \
30027                  ldlm.namespaces.$imp_name.lru_size)
30028
30029         wait_osc_import_state client ost1 IDLE
30030         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30031         now=$($LCTL get_param -n \
30032               ldlm.namespaces.$imp_name.lru_size)
30033         [ $before == $now ] || error "lru_size changed $before != $now"
30034 }
30035 run_test 816 "do not reset lru_resize on idle reconnect"
30036
30037 cleanup_817() {
30038         umount $tmpdir
30039         exportfs -u localhost:$DIR/nfsexp
30040         rm -rf $DIR/nfsexp
30041 }
30042
30043 test_817() {
30044         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30045
30046         mkdir -p $DIR/nfsexp
30047         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30048                 error "failed to export nfs"
30049
30050         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30051         stack_trap cleanup_817 EXIT
30052
30053         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30054                 error "failed to mount nfs to $tmpdir"
30055
30056         cp /bin/true $tmpdir
30057         $DIR/nfsexp/true || error "failed to execute 'true' command"
30058 }
30059 run_test 817 "nfsd won't cache write lock for exec file"
30060
30061 test_818() {
30062         test_mkdir -i0 -c1 $DIR/$tdir
30063         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30064         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30065         stop $SINGLEMDS
30066
30067         # restore osp-syn threads
30068         stack_trap "fail $SINGLEMDS"
30069
30070         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30071         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30072         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30073                 error "start $SINGLEMDS failed"
30074         rm -rf $DIR/$tdir
30075
30076         local testid=$(echo $TESTNAME | tr '_' ' ')
30077
30078         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30079                 grep "run LFSCK" || error "run LFSCK is not suggested"
30080 }
30081 run_test 818 "unlink with failed llog"
30082
30083 test_819a() {
30084         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30085         cancel_lru_locks osc
30086         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30087         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30088         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30089         rm -f $TDIR/$tfile
30090 }
30091 run_test 819a "too big niobuf in read"
30092
30093 test_819b() {
30094         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30095         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30096         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30097         cancel_lru_locks osc
30098         sleep 1
30099         rm -f $TDIR/$tfile
30100 }
30101 run_test 819b "too big niobuf in write"
30102
30103
30104 function test_820_start_ost() {
30105         sleep 5
30106
30107         for num in $(seq $OSTCOUNT); do
30108                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30109         done
30110 }
30111
30112 test_820() {
30113         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30114
30115         mkdir $DIR/$tdir
30116         umount_client $MOUNT || error "umount failed"
30117         for num in $(seq $OSTCOUNT); do
30118                 stop ost$num
30119         done
30120
30121         # mount client with no active OSTs
30122         # so that the client can't initialize max LOV EA size
30123         # from OSC notifications
30124         mount_client $MOUNT || error "mount failed"
30125         # delay OST starting to keep this 0 max EA size for a while
30126         test_820_start_ost &
30127
30128         # create a directory on MDS2
30129         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30130                 error "Failed to create directory"
30131         # open intent should update default EA size
30132         # see mdc_update_max_ea_from_body()
30133         # notice this is the very first RPC to MDS2
30134         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30135         ret=$?
30136         echo $out
30137         # With SSK, this situation can lead to -EPERM being returned.
30138         # In that case, simply retry.
30139         if [ $ret -ne 0 ] && $SHARED_KEY; then
30140                 if echo "$out" | grep -q "not permitted"; then
30141                         cp /etc/services $DIR/$tdir/mds2
30142                         ret=$?
30143                 fi
30144         fi
30145         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30146 }
30147 run_test 820 "update max EA from open intent"
30148
30149 test_823() {
30150         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30151         local OST_MAX_PRECREATE=20000
30152
30153         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30154                 skip "Need MDS version at least 2.14.56"
30155
30156         save_lustre_params mds1 \
30157                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30158         do_facet $SINGLEMDS "$LCTL set_param -n \
30159                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30160         do_facet $SINGLEMDS "$LCTL set_param -n \
30161                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30162
30163         stack_trap "restore_lustre_params < $p; rm $p"
30164
30165         do_facet $SINGLEMDS "$LCTL set_param -n \
30166                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30167
30168         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30169                       osp.$FSNAME-OST0000*MDT0000.create_count")
30170         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30171                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30172         local expect_count=$(((($max/2)/256) * 256))
30173
30174         log "setting create_count to 100200:"
30175         log " -result- count: $count with max: $max, expecting: $expect_count"
30176
30177         [[ $count -eq expect_count ]] ||
30178                 error "Create count not set to max precreate."
30179 }
30180 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30181
30182 test_831() {
30183         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30184                 skip "Need MDS version 2.14.56"
30185
30186         local sync_changes=$(do_facet $SINGLEMDS \
30187                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30188
30189         [ "$sync_changes" -gt 100 ] &&
30190                 skip "Sync changes $sync_changes > 100 already"
30191
30192         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30193
30194         $LFS mkdir -i 0 $DIR/$tdir
30195         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30196
30197         save_lustre_params mds1 \
30198                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30199         save_lustre_params mds1 \
30200                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30201
30202         do_facet mds1 "$LCTL set_param -n \
30203                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30204                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30205         stack_trap "restore_lustre_params < $p" EXIT
30206
30207         createmany -o $DIR/$tdir/f- 1000
30208         unlinkmany $DIR/$tdir/f- 1000 &
30209         local UNLINK_PID=$!
30210
30211         while sleep 1; do
30212                 sync_changes=$(do_facet mds1 \
30213                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30214                 # the check in the code is racy, fail the test
30215                 # if the value above the limit by 10.
30216                 [ $sync_changes -gt 110 ] && {
30217                         kill -2 $UNLINK_PID
30218                         wait
30219                         error "osp changes throttling failed, $sync_changes>110"
30220                 }
30221                 kill -0 $UNLINK_PID 2> /dev/null || break
30222         done
30223         wait
30224 }
30225 run_test 831 "throttling unlink/setattr queuing on OSP"
30226
30227 test_832() {
30228         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30229         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30230                 skip "Need MDS version 2.15.52+"
30231         is_rmentry_supported || skip "rm_entry not supported"
30232
30233         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30234         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30235         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30236                 error "mkdir remote_dir failed"
30237         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30238                 error "mkdir striped_dir failed"
30239         touch $DIR/$tdir/file || error "touch file failed"
30240         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30241         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30242 }
30243 run_test 832 "lfs rm_entry"
30244
30245 test_833() {
30246         local file=$DIR/$tfile
30247
30248         stack_trap "rm -f $file" EXIT
30249         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30250
30251         local wpid
30252         local rpid
30253         local rpid2
30254
30255         # Buffered I/O write
30256         (
30257                 while [ ! -e $DIR/sanity.833.lck ]; do
30258                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30259                                 error "failed to write $file"
30260                         sleep 0.$((RANDOM % 4 + 1))
30261                 done
30262         )&
30263         wpid=$!
30264
30265         # Buffered I/O read
30266         (
30267                 while [ ! -e $DIR/sanity.833.lck ]; do
30268                         dd if=$file of=/dev/null bs=1M count=50 ||
30269                                 error "failed to read $file"
30270                         sleep 0.$((RANDOM % 4 + 1))
30271                 done
30272         )&
30273         rpid=$!
30274
30275         # Direct I/O read
30276         (
30277                 while [ ! -e $DIR/sanity.833.lck ]; do
30278                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30279                                 error "failed to read $file in direct I/O mode"
30280                         sleep 0.$((RANDOM % 4 + 1))
30281                 done
30282         )&
30283         rpid2=$!
30284
30285         sleep 30
30286         touch $DIR/sanity.833.lck
30287         wait $wpid || error "$?: buffered write failed"
30288         wait $rpid || error "$?: buffered read failed"
30289         wait $rpid2 || error "$?: direct read failed"
30290 }
30291 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30292
30293 #
30294 # tests that do cleanup/setup should be run at the end
30295 #
30296
30297 test_900() {
30298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30299         local ls
30300
30301         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30302         $LCTL set_param fail_loc=0x903
30303
30304         cancel_lru_locks MGC
30305
30306         FAIL_ON_ERROR=true cleanup
30307         FAIL_ON_ERROR=true setup
30308 }
30309 run_test 900 "umount should not race with any mgc requeue thread"
30310
30311 # LUS-6253/LU-11185
30312 test_901() {
30313         local old
30314         local count
30315         local oldc
30316         local newc
30317         local olds
30318         local news
30319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30320
30321         # some get_param have a bug to handle dot in param name
30322         cancel_lru_locks MGC
30323         old=$(mount -t lustre | wc -l)
30324         # 1 config+sptlrpc
30325         # 2 params
30326         # 3 nodemap
30327         # 4 IR
30328         old=$((old * 4))
30329         oldc=0
30330         count=0
30331         while [ $old -ne $oldc ]; do
30332                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30333                 sleep 1
30334                 ((count++))
30335                 if [ $count -ge $TIMEOUT ]; then
30336                         error "too large timeout"
30337                 fi
30338         done
30339         umount_client $MOUNT || error "umount failed"
30340         mount_client $MOUNT || error "mount failed"
30341         cancel_lru_locks MGC
30342         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30343
30344         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30345
30346         return 0
30347 }
30348 run_test 901 "don't leak a mgc lock on client umount"
30349
30350 # LU-13377
30351 test_902() {
30352         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30353                 skip "client does not have LU-13377 fix"
30354         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30355         $LCTL set_param fail_loc=0x1415
30356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30357         cancel_lru_locks osc
30358         rm -f $DIR/$tfile
30359 }
30360 run_test 902 "test short write doesn't hang lustre"
30361
30362 # LU-14711
30363 test_903() {
30364         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30365         echo "blah" > $DIR/${tfile}-2
30366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30367         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30368         $LCTL set_param fail_loc=0x417 fail_val=20
30369
30370         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30371         sleep 1 # To start the destroy
30372         wait_destroy_complete 150 || error "Destroy taking too long"
30373         cat $DIR/$tfile > /dev/null || error "Evicted"
30374 }
30375 run_test 903 "Test long page discard does not cause evictions"
30376
30377 test_904() {
30378         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30379         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30380                 grep -q project || skip "skip project quota not supported"
30381
30382         local testfile="$DIR/$tdir/$tfile"
30383         local xattr="trusted.projid"
30384         local projid
30385         local mdts=$(comma_list $(mdts_nodes))
30386         local saved=$(do_facet mds1 $LCTL get_param -n \
30387                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30388
30389         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30390         stack_trap "do_nodes $mdts $LCTL set_param \
30391                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30392
30393         mkdir -p $DIR/$tdir
30394         touch $testfile
30395         #hide projid xattr on server
30396         $LFS project -p 1 $testfile ||
30397                 error "set $testfile project id failed"
30398         getfattr -m - $testfile | grep $xattr &&
30399                 error "do not show trusted.projid when disabled on server"
30400         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30401         #should be hidden when projid is 0
30402         $LFS project -p 0 $testfile ||
30403                 error "set $testfile project id failed"
30404         getfattr -m - $testfile | grep $xattr &&
30405                 error "do not show trusted.projid with project ID 0"
30406
30407         #still can getxattr explicitly
30408         projid=$(getfattr -n $xattr $testfile |
30409                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30410         [ $projid == "0" ] ||
30411                 error "projid expected 0 not $projid"
30412
30413         #set the projid via setxattr
30414         setfattr -n $xattr -v "1000" $testfile ||
30415                 error "setattr failed with $?"
30416         projid=($($LFS project $testfile))
30417         [ ${projid[0]} == "1000" ] ||
30418                 error "projid expected 1000 not $projid"
30419
30420         #check the new projid via getxattr
30421         $LFS project -p 1001 $testfile ||
30422                 error "set $testfile project id failed"
30423         getfattr -m - $testfile | grep $xattr ||
30424                 error "should show trusted.projid when project ID != 0"
30425         projid=$(getfattr -n $xattr $testfile |
30426                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30427         [ $projid == "1001" ] ||
30428                 error "projid expected 1001 not $projid"
30429
30430         #try to set invalid projid
30431         setfattr -n $xattr -v "4294967295" $testfile &&
30432                 error "set invalid projid should fail"
30433
30434         #remove the xattr means setting projid to 0
30435         setfattr -x $xattr $testfile ||
30436                 error "setfattr failed with $?"
30437         projid=($($LFS project $testfile))
30438         [ ${projid[0]} == "0" ] ||
30439                 error "projid expected 0 not $projid"
30440
30441         #should be hidden when parent has inherit flag and same projid
30442         $LFS project -srp 1002 $DIR/$tdir ||
30443                 error "set $tdir project id failed"
30444         getfattr -m - $testfile | grep $xattr &&
30445                 error "do not show trusted.projid with inherit flag"
30446
30447         #still can getxattr explicitly
30448         projid=$(getfattr -n $xattr $testfile |
30449                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30450         [ $projid == "1002" ] ||
30451                 error "projid expected 1002 not $projid"
30452 }
30453 run_test 904 "virtual project ID xattr"
30454
30455 # LU-8582
30456 test_905() {
30457         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30458                 skip "need OST version >= 2.15.50.220 for fail_loc"
30459
30460         remote_ost_nodsh && skip "remote OST with nodsh"
30461         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30462
30463         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30464
30465         #define OBD_FAIL_OST_OPCODE 0x253
30466         # OST_LADVISE = 21
30467         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30468         $LFS ladvise -a willread $DIR/$tfile &&
30469                 error "unexpected success of ladvise with fault injection"
30470         $LFS ladvise -a willread $DIR/$tfile |&
30471                 grep -q "Operation not supported"
30472         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30473 }
30474 run_test 905 "bad or new opcode should not stuck client"
30475
30476 test_906() {
30477         grep -q io_uring_setup /proc/kallsyms ||
30478                 skip "Client OS does not support io_uring I/O engine"
30479         io_uring_probe || skip "kernel does not support io_uring fully"
30480         which fio || skip_env "no fio installed"
30481         fio --enghelp | grep -q io_uring ||
30482                 skip_env "fio does not support io_uring I/O engine"
30483
30484         local file=$DIR/$tfile
30485         local ioengine="io_uring"
30486         local numjobs=2
30487         local size=50M
30488
30489         fio --name=seqwrite --ioengine=$ioengine        \
30490                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30491                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30492                 error "fio seqwrite $file failed"
30493
30494         fio --name=seqread --ioengine=$ioengine \
30495                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30496                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30497                 error "fio seqread $file failed"
30498
30499         rm -f $file || error "rm -f $file failed"
30500 }
30501 run_test 906 "Simple test for io_uring I/O engine via fio"
30502
30503 complete_test $SECONDS
30504 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30505 check_and_cleanup_lustre
30506 if [ "$I_MOUNTED" != "yes" ]; then
30507         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30508 fi
30509 exit_status