Whamcloud - gitweb
3c73faf7813e7b0084ef2ce840a83d1e4fd7dca8
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-16515 118c 118d
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 #                                  5              12     8   12  15   (min)"
66 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
67
68 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
69         #                                               13    (min)"
70         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
71 fi
72
73 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
74         always_except LU-1941 130b 130c 130d 130e 130f 130g
75         always_except LU-9054 312
76 fi
77
78 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
79
80 # Get the SLES distro version
81 #
82 # Returns a version string that should only be used in comparing
83 # strings returned by version_code()
84 sles_version_code()
85 {
86         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
87
88         # All SuSE Linux versions have one decimal. version_code expects two
89         local sles_version=$version.0
90         version_code $sles_version
91 }
92
93 # Check if we are running on Ubuntu or SLES so we can make decisions on
94 # what tests to run
95 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
96         sles_version=$(sles_version_code)
97         [ $sles_version -lt $(version_code 11.4.0) ] &&
98                 always_except LU-4341 170
99
100         [ $sles_version -lt $(version_code 12.0.0) ] &&
101                 always_except LU-3703 234
102 elif [ -r /etc/os-release ]; then
103         if grep -qi ubuntu /etc/os-release; then
104                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
105                                                 -e 's/^VERSION=//p' \
106                                                 /etc/os-release |
107                                                 awk '{ print $1 }'))
108
109                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
110                         always_except LU-10366 410
111                 fi
112         fi
113 fi
114
115 build_test_filter
116 FAIL_ON_ERROR=false
117
118 cleanup() {
119         echo -n "cln.."
120         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
121         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
122 }
123 setup() {
124         echo -n "mnt.."
125         load_modules
126         setupall || exit 10
127         echo "done"
128 }
129
130 check_swap_layouts_support()
131 {
132         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
133                 skip "Does not support layout lock."
134 }
135
136 check_swap_layout_no_dom()
137 {
138         local FOLDER=$1
139         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
140         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
141 }
142
143 check_and_setup_lustre
144 DIR=${DIR:-$MOUNT}
145 assert_DIR
146
147 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
148
149 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
150 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
151 rm -rf $DIR/[Rdfs][0-9]*
152
153 # $RUNAS_ID may get set incorrectly somewhere else
154 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
155         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
156
157 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
158
159 if [ "${ONLY}" = "MOUNT" ] ; then
160         echo "Lustre is up, please go on"
161         exit
162 fi
163
164 echo "preparing for tests involving mounts"
165 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
166 touch $EXT2_DEV
167 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
168 echo # add a newline after mke2fs.
169
170 umask 077
171
172 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
173
174 # ensure all internal functions know we want full debug
175 export PTLDEBUG=all
176 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
177
178 test_0a() {
179         touch $DIR/$tfile
180         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
181         rm $DIR/$tfile
182         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
183 }
184 run_test 0a "touch; rm ====================="
185
186 test_0b() {
187         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
188         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
189 }
190 run_test 0b "chmod 0755 $DIR ============================="
191
192 test_0c() {
193         $LCTL get_param mdc.*.import | grep "state: FULL" ||
194                 error "import not FULL"
195         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
196                 error "bad target"
197 }
198 run_test 0c "check import proc"
199
200 test_0d() { # LU-3397
201         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
202                 skip "proc exports not supported before 2.10.57"
203
204         local mgs_exp="mgs.MGS.exports"
205         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
206         local exp_client_nid
207         local exp_client_version
208         local exp_val
209         local imp_val
210         local temp_imp=$DIR/$tfile.import
211         local temp_exp=$DIR/$tfile.export
212
213         # save mgc import file to $temp_imp
214         $LCTL get_param mgc.*.import | tee $temp_imp
215         # Check if client uuid is found in MGS export
216         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
217                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
218                         $client_uuid ] &&
219                         break;
220         done
221         # save mgs export file to $temp_exp
222         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
223
224         # Compare the value of field "connect_flags"
225         imp_val=$(grep "connect_flags" $temp_imp)
226         exp_val=$(grep "connect_flags" $temp_exp)
227         [ "$exp_val" == "$imp_val" ] ||
228                 error "export flags '$exp_val' != import flags '$imp_val'"
229
230         # Compare client versions.  Only compare top-3 fields for compatibility
231         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
232         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
233         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "exp version '$exp_client_version'($exp_val) != " \
236                         "'$(lustre_build_version client)'($imp_val)"
237 }
238 run_test 0d "check export proc ============================="
239
240 test_0e() { # LU-13417
241         (( $MDSCOUNT > 1 )) ||
242                 skip "We need at least 2 MDTs for this test"
243
244         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
245                 skip "Need server version at least 2.14.51"
246
247         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
248         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
249
250         [ $default_lmv_count -eq 1 ] ||
251                 error "$MOUNT default stripe count $default_lmv_count"
252
253         [ $default_lmv_index -eq -1 ] ||
254                 error "$MOUNT default stripe index $default_lmv_index"
255
256         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
257         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
258
259         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
260         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
261
262         [ $mdt_index1 -eq $mdt_index2 ] &&
263                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
264
265         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
266 }
267 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
268
269 test_1() {
270         test_mkdir $DIR/$tdir
271         test_mkdir $DIR/$tdir/d2
272         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
273         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
274         rmdir $DIR/$tdir/d2
275         rmdir $DIR/$tdir
276         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
277 }
278 run_test 1 "mkdir; remkdir; rmdir"
279
280 test_2() {
281         test_mkdir $DIR/$tdir
282         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
283         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
284         rm -r $DIR/$tdir
285         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
286 }
287 run_test 2 "mkdir; touch; rmdir; check file"
288
289 test_3() {
290         test_mkdir $DIR/$tdir
291         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
292         touch $DIR/$tdir/$tfile
293         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
294         rm -r $DIR/$tdir
295         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
296 }
297 run_test 3 "mkdir; touch; rmdir; check dir"
298
299 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
300 test_4() {
301         test_mkdir -i 1 $DIR/$tdir
302
303         touch $DIR/$tdir/$tfile ||
304                 error "Create file under remote directory failed"
305
306         rmdir $DIR/$tdir &&
307                 error "Expect error removing in-use dir $DIR/$tdir"
308
309         test -d $DIR/$tdir || error "Remote directory disappeared"
310
311         rm -rf $DIR/$tdir || error "remove remote dir error"
312 }
313 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
314
315 test_5() {
316         test_mkdir $DIR/$tdir
317         test_mkdir $DIR/$tdir/d2
318         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
319         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
320         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
321 }
322 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
323
324 test_6a() {
325         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
326         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
327         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
328                 error "$tfile does not have perm 0666 or UID $UID"
329         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
330         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
331                 error "$tfile should be 0666 and owned by UID $UID"
332 }
333 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
334
335 test_6c() {
336         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
337
338         touch $DIR/$tfile
339         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
340         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
341                 error "$tfile should be owned by UID $RUNAS_ID"
342         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
343         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
344                 error "$tfile should be owned by UID $RUNAS_ID"
345 }
346 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
347
348 test_6e() {
349         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
350
351         touch $DIR/$tfile
352         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
353         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
354                 error "$tfile should be owned by GID $UID"
355         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
356         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
358 }
359 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
360
361 test_6g() {
362         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
363
364         test_mkdir $DIR/$tdir
365         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
366         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
367         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
368         test_mkdir $DIR/$tdir/d/subdir
369         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
370                 error "$tdir/d/subdir should be GID $RUNAS_GID"
371         if [[ $MDSCOUNT -gt 1 ]]; then
372                 # check remote dir sgid inherite
373                 $LFS mkdir -i 0 $DIR/$tdir.local ||
374                         error "mkdir $tdir.local failed"
375                 chmod g+s $DIR/$tdir.local ||
376                         error "chmod $tdir.local failed"
377                 chgrp $RUNAS_GID $DIR/$tdir.local ||
378                         error "chgrp $tdir.local failed"
379                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
380                         error "mkdir $tdir.remote failed"
381                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
382                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
383                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
384                         error "$tdir.remote should be mode 02755"
385         fi
386 }
387 run_test 6g "verify new dir in sgid dir inherits group"
388
389 test_6h() { # bug 7331
390         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
391
392         touch $DIR/$tfile || error "touch failed"
393         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
394         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
395                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
396         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
397                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
398 }
399 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
400
401 test_7a() {
402         test_mkdir $DIR/$tdir
403         $MCREATE $DIR/$tdir/$tfile
404         chmod 0666 $DIR/$tdir/$tfile
405         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
406                 error "$tdir/$tfile should be mode 0666"
407 }
408 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
409
410 test_7b() {
411         if [ ! -d $DIR/$tdir ]; then
412                 test_mkdir $DIR/$tdir
413         fi
414         $MCREATE $DIR/$tdir/$tfile
415         echo -n foo > $DIR/$tdir/$tfile
416         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
417         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
418 }
419 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
420
421 test_8() {
422         test_mkdir $DIR/$tdir
423         touch $DIR/$tdir/$tfile
424         chmod 0666 $DIR/$tdir/$tfile
425         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
426                 error "$tfile mode not 0666"
427 }
428 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
429
430 test_9() {
431         test_mkdir $DIR/$tdir
432         test_mkdir $DIR/$tdir/d2
433         test_mkdir $DIR/$tdir/d2/d3
434         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
435 }
436 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
437
438 test_10() {
439         test_mkdir $DIR/$tdir
440         test_mkdir $DIR/$tdir/d2
441         touch $DIR/$tdir/d2/$tfile
442         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
443                 error "$tdir/d2/$tfile not a file"
444 }
445 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
446
447 test_11() {
448         test_mkdir $DIR/$tdir
449         test_mkdir $DIR/$tdir/d2
450         chmod 0666 $DIR/$tdir/d2
451         chmod 0705 $DIR/$tdir/d2
452         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
453                 error "$tdir/d2 mode not 0705"
454 }
455 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
456
457 test_12() {
458         test_mkdir $DIR/$tdir
459         touch $DIR/$tdir/$tfile
460         chmod 0666 $DIR/$tdir/$tfile
461         chmod 0654 $DIR/$tdir/$tfile
462         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
463                 error "$tdir/d2 mode not 0654"
464 }
465 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
466
467 test_13() {
468         test_mkdir $DIR/$tdir
469         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
470         >  $DIR/$tdir/$tfile
471         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
472                 error "$tdir/$tfile size not 0 after truncate"
473 }
474 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
475
476 test_14() {
477         test_mkdir $DIR/$tdir
478         touch $DIR/$tdir/$tfile
479         rm $DIR/$tdir/$tfile
480         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
481 }
482 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
483
484 test_15() {
485         test_mkdir $DIR/$tdir
486         touch $DIR/$tdir/$tfile
487         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
488         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
489                 error "$tdir/${tfile_2} not a file after rename"
490         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
491 }
492 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
493
494 test_16() {
495         test_mkdir $DIR/$tdir
496         touch $DIR/$tdir/$tfile
497         rm -rf $DIR/$tdir/$tfile
498         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
499 }
500 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
501
502 test_17a() {
503         test_mkdir $DIR/$tdir
504         touch $DIR/$tdir/$tfile
505         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
506         ls -l $DIR/$tdir
507         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
508                 error "$tdir/l-exist not a symlink"
509         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
510                 error "$tdir/l-exist not referencing a file"
511         rm -f $DIR/$tdir/l-exist
512         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
513 }
514 run_test 17a "symlinks: create, remove (real)"
515
516 test_17b() {
517         test_mkdir $DIR/$tdir
518         ln -s no-such-file $DIR/$tdir/l-dangle
519         ls -l $DIR/$tdir
520         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
521                 error "$tdir/l-dangle not referencing no-such-file"
522         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
523                 error "$tdir/l-dangle not referencing non-existent file"
524         rm -f $DIR/$tdir/l-dangle
525         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
526 }
527 run_test 17b "symlinks: create, remove (dangling)"
528
529 test_17c() { # bug 3440 - don't save failed open RPC for replay
530         test_mkdir $DIR/$tdir
531         ln -s foo $DIR/$tdir/$tfile
532         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
533 }
534 run_test 17c "symlinks: open dangling (should return error)"
535
536 test_17d() {
537         test_mkdir $DIR/$tdir
538         ln -s foo $DIR/$tdir/$tfile
539         touch $DIR/$tdir/$tfile || error "creating to new symlink"
540 }
541 run_test 17d "symlinks: create dangling"
542
543 test_17e() {
544         test_mkdir $DIR/$tdir
545         local foo=$DIR/$tdir/$tfile
546         ln -s $foo $foo || error "create symlink failed"
547         ls -l $foo || error "ls -l failed"
548         ls $foo && error "ls not failed" || true
549 }
550 run_test 17e "symlinks: create recursive symlink (should return error)"
551
552 test_17f() {
553         test_mkdir $DIR/$tdir
554         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
555         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
556         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
557         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
558         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
559         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
560         ls -l  $DIR/$tdir
561 }
562 run_test 17f "symlinks: long and very long symlink name"
563
564 # str_repeat(S, N) generate a string that is string S repeated N times
565 str_repeat() {
566         local s=$1
567         local n=$2
568         local ret=''
569         while [ $((n -= 1)) -ge 0 ]; do
570                 ret=$ret$s
571         done
572         echo $ret
573 }
574
575 # Long symlinks and LU-2241
576 test_17g() {
577         test_mkdir $DIR/$tdir
578         local TESTS="59 60 61 4094 4095"
579
580         # Fix for inode size boundary in 2.1.4
581         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
582                 TESTS="4094 4095"
583
584         # Patch not applied to 2.2 or 2.3 branches
585         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
586         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
587                 TESTS="4094 4095"
588
589         for i in $TESTS; do
590                 local SYMNAME=$(str_repeat 'x' $i)
591                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
592                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
593         done
594 }
595 run_test 17g "symlinks: really long symlink name and inode boundaries"
596
597 test_17h() { #bug 17378
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local mdt_idx
602
603         test_mkdir $DIR/$tdir
604         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
605         $LFS setstripe -c -1 $DIR/$tdir
606         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
607         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
608         touch $DIR/$tdir/$tfile || true
609 }
610 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
611
612 test_17i() { #bug 20018
613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
614         remote_mds_nodsh && skip "remote MDS with nodsh"
615
616         local foo=$DIR/$tdir/$tfile
617         local mdt_idx
618
619         test_mkdir -c1 $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         ln -s $foo $foo || error "create symlink failed"
622 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
624         ls -l $foo && error "error not detected"
625         return 0
626 }
627 run_test 17i "don't panic on short symlink (should return error)"
628
629 test_17k() { #bug 22301
630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
631         [[ -z "$(which rsync 2>/dev/null)" ]] &&
632                 skip "no rsync command"
633         rsync --help | grep -q xattr ||
634                 skip_env "$(rsync --version | head -n1) does not support xattrs"
635         test_mkdir $DIR/$tdir
636         test_mkdir $DIR/$tdir.new
637         touch $DIR/$tdir/$tfile
638         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
639         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
640                 error "rsync failed with xattrs enabled"
641 }
642 run_test 17k "symlinks: rsync with xattrs enabled"
643
644 test_17l() { # LU-279
645         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
646                 skip "no getfattr command"
647
648         test_mkdir $DIR/$tdir
649         touch $DIR/$tdir/$tfile
650         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
651         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
652                 # -h to not follow symlinks. -m '' to list all the xattrs.
653                 # grep to remove first line: '# file: $path'.
654                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
655                 do
656                         lgetxattr_size_check $path $xattr ||
657                                 error "lgetxattr_size_check $path $xattr failed"
658                 done
659         done
660 }
661 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
662
663 # LU-1540
664 test_17m() {
665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
666         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
667         remote_mds_nodsh && skip "remote MDS with nodsh"
668         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
669         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
670                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
671
672         local short_sym="0123456789"
673         local wdir=$DIR/$tdir
674         local i
675
676         test_mkdir $wdir
677         long_sym=$short_sym
678         # create a long symlink file
679         for ((i = 0; i < 4; ++i)); do
680                 long_sym=${long_sym}${long_sym}
681         done
682
683         echo "create 512 short and long symlink files under $wdir"
684         for ((i = 0; i < 256; ++i)); do
685                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
686                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
687         done
688
689         echo "erase them"
690         rm -f $wdir/*
691         sync
692         wait_delete_completed
693
694         echo "recreate the 512 symlink files with a shorter string"
695         for ((i = 0; i < 512; ++i)); do
696                 # rewrite the symlink file with a shorter string
697                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
698                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
699         done
700
701         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
702
703         echo "stop and checking mds${mds_index}:"
704         # e2fsck should not return error
705         stop mds${mds_index}
706         local devname=$(mdsdevname $mds_index)
707         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
708         rc=$?
709
710         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
711                 error "start mds${mds_index} failed"
712         df $MOUNT > /dev/null 2>&1
713         [ $rc -eq 0 ] ||
714                 error "e2fsck detected error for short/long symlink: rc=$rc"
715         rm -f $wdir/*
716 }
717 run_test 17m "run e2fsck against MDT which contains short/long symlink"
718
719 check_fs_consistency_17n() {
720         local mdt_index
721         local rc=0
722
723         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
724         # so it only check MDT1/MDT2 instead of all of MDTs.
725         for mdt_index in 1 2; do
726                 # e2fsck should not return error
727                 stop mds${mdt_index}
728                 local devname=$(mdsdevname $mdt_index)
729                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
730                         rc=$((rc + $?))
731
732                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
733                         error "mount mds$mdt_index failed"
734                 df $MOUNT > /dev/null 2>&1
735         done
736         return $rc
737 }
738
739 test_17n() {
740         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
742         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
743         remote_mds_nodsh && skip "remote MDS with nodsh"
744         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
745         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
746                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
747
748         local i
749
750         test_mkdir $DIR/$tdir
751         for ((i=0; i<10; i++)); do
752                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
753                         error "create remote dir error $i"
754                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
755                         error "create files under remote dir failed $i"
756         done
757
758         check_fs_consistency_17n ||
759                 error "e2fsck report error after create files under remote dir"
760
761         for ((i = 0; i < 10; i++)); do
762                 rm -rf $DIR/$tdir/remote_dir_${i} ||
763                         error "destroy remote dir error $i"
764         done
765
766         check_fs_consistency_17n ||
767                 error "e2fsck report error after unlink files under remote dir"
768
769         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
770                 skip "lustre < 2.4.50 does not support migrate mv"
771
772         for ((i = 0; i < 10; i++)); do
773                 mkdir -p $DIR/$tdir/remote_dir_${i}
774                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
775                         error "create files under remote dir failed $i"
776                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
777                         error "migrate remote dir error $i"
778         done
779         check_fs_consistency_17n || error "e2fsck report error after migration"
780
781         for ((i = 0; i < 10; i++)); do
782                 rm -rf $DIR/$tdir/remote_dir_${i} ||
783                         error "destroy remote dir error $i"
784         done
785
786         check_fs_consistency_17n || error "e2fsck report error after unlink"
787 }
788 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
789
790 test_17o() {
791         remote_mds_nodsh && skip "remote MDS with nodsh"
792         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
793                 skip "Need MDS version at least 2.3.64"
794
795         local wdir=$DIR/${tdir}o
796         local mdt_index
797         local rc=0
798
799         test_mkdir $wdir
800         touch $wdir/$tfile
801         mdt_index=$($LFS getstripe -m $wdir/$tfile)
802         mdt_index=$((mdt_index + 1))
803
804         cancel_lru_locks mdc
805         #fail mds will wait the failover finish then set
806         #following fail_loc to avoid interfer the recovery process.
807         fail mds${mdt_index}
808
809         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
810         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
811         ls -l $wdir/$tfile && rc=1
812         do_facet mds${mdt_index} lctl set_param fail_loc=0
813         [[ $rc -eq 0 ]] || error "stat file should fail"
814 }
815 run_test 17o "stat file with incompat LMA feature"
816
817 test_18() {
818         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
819         ls $DIR || error "Failed to ls $DIR: $?"
820 }
821 run_test 18 "touch .../f ; ls ... =============================="
822
823 test_19a() {
824         touch $DIR/$tfile
825         ls -l $DIR
826         rm $DIR/$tfile
827         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
828 }
829 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
830
831 test_19b() {
832         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
833 }
834 run_test 19b "ls -l .../f19 (should return error) =============="
835
836 test_19c() {
837         [ $RUNAS_ID -eq $UID ] &&
838                 skip_env "RUNAS_ID = UID = $UID -- skipping"
839
840         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
841 }
842 run_test 19c "$RUNAS touch .../f19 (should return error) =="
843
844 test_19d() {
845         cat $DIR/f19 && error || true
846 }
847 run_test 19d "cat .../f19 (should return error) =============="
848
849 test_20() {
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         touch $DIR/$tfile
853         rm $DIR/$tfile
854         touch $DIR/$tfile
855         rm $DIR/$tfile
856         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
857 }
858 run_test 20 "touch .../f ; ls -l ..."
859
860 test_21() {
861         test_mkdir $DIR/$tdir
862         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
863         ln -s dangle $DIR/$tdir/link
864         echo foo >> $DIR/$tdir/link
865         cat $DIR/$tdir/dangle
866         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
867         $CHECKSTAT -f -t file $DIR/$tdir/link ||
868                 error "$tdir/link not linked to a file"
869 }
870 run_test 21 "write to dangling link"
871
872 test_22() {
873         local wdir=$DIR/$tdir
874         test_mkdir $wdir
875         chown $RUNAS_ID:$RUNAS_GID $wdir
876         (cd $wdir || error "cd $wdir failed";
877                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
878                 $RUNAS tar xf -)
879         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
880         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
881         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
882                 error "checkstat -u failed"
883 }
884 run_test 22 "unpack tar archive as non-root user"
885
886 # was test_23
887 test_23a() {
888         test_mkdir $DIR/$tdir
889         local file=$DIR/$tdir/$tfile
890
891         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
892         openfile -f O_CREAT:O_EXCL $file &&
893                 error "$file recreate succeeded" || true
894 }
895 run_test 23a "O_CREAT|O_EXCL in subdir"
896
897 test_23b() { # bug 18988
898         test_mkdir $DIR/$tdir
899         local file=$DIR/$tdir/$tfile
900
901         rm -f $file
902         echo foo > $file || error "write filed"
903         echo bar >> $file || error "append filed"
904         $CHECKSTAT -s 8 $file || error "wrong size"
905         rm $file
906 }
907 run_test 23b "O_APPEND check"
908
909 # LU-9409, size with O_APPEND and tiny writes
910 test_23c() {
911         local file=$DIR/$tfile
912
913         # single dd
914         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
915         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
916         rm -f $file
917
918         # racing tiny writes
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
920         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
921         wait
922         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
923         rm -f $file
924
925         #racing tiny & normal writes
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
927         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
928         wait
929         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
930         rm -f $file
931
932         #racing tiny & normal writes 2, ugly numbers
933         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
934         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
935         wait
936         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
937         rm -f $file
938 }
939 run_test 23c "O_APPEND size checks for tiny writes"
940
941 # LU-11069 file offset is correct after appending writes
942 test_23d() {
943         local file=$DIR/$tfile
944         local offset
945
946         echo CentaurHauls > $file
947         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
948         if ((offset != 26)); then
949                 error "wrong offset, expected 26, got '$offset'"
950         fi
951 }
952 run_test 23d "file offset is correct after appending writes"
953
954 # rename sanity
955 test_24a() {
956         echo '-- same directory rename'
957         test_mkdir $DIR/$tdir
958         touch $DIR/$tdir/$tfile.1
959         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
960         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
961 }
962 run_test 24a "rename file to non-existent target"
963
964 test_24b() {
965         test_mkdir $DIR/$tdir
966         touch $DIR/$tdir/$tfile.{1,2}
967         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
968         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
969         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
970 }
971 run_test 24b "rename file to existing target"
972
973 test_24c() {
974         test_mkdir $DIR/$tdir
975         test_mkdir $DIR/$tdir/d$testnum.1
976         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
977         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
978         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
979 }
980 run_test 24c "rename directory to non-existent target"
981
982 test_24d() {
983         test_mkdir -c1 $DIR/$tdir
984         test_mkdir -c1 $DIR/$tdir/d$testnum.1
985         test_mkdir -c1 $DIR/$tdir/d$testnum.2
986         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
987         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
988         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
989 }
990 run_test 24d "rename directory to existing target"
991
992 test_24e() {
993         echo '-- cross directory renames --'
994         test_mkdir $DIR/R5a
995         test_mkdir $DIR/R5b
996         touch $DIR/R5a/f
997         mv $DIR/R5a/f $DIR/R5b/g
998         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
999         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1000 }
1001 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1002
1003 test_24f() {
1004         test_mkdir $DIR/R6a
1005         test_mkdir $DIR/R6b
1006         touch $DIR/R6a/f $DIR/R6b/g
1007         mv $DIR/R6a/f $DIR/R6b/g
1008         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1009         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1010 }
1011 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1012
1013 test_24g() {
1014         test_mkdir $DIR/R7a
1015         test_mkdir $DIR/R7b
1016         test_mkdir $DIR/R7a/d
1017         mv $DIR/R7a/d $DIR/R7b/e
1018         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1019         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1020 }
1021 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1022
1023 test_24h() {
1024         test_mkdir -c1 $DIR/R8a
1025         test_mkdir -c1 $DIR/R8b
1026         test_mkdir -c1 $DIR/R8a/d
1027         test_mkdir -c1 $DIR/R8b/e
1028         mrename $DIR/R8a/d $DIR/R8b/e
1029         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1030         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1031 }
1032 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1033
1034 test_24i() {
1035         echo "-- rename error cases"
1036         test_mkdir $DIR/R9
1037         test_mkdir $DIR/R9/a
1038         touch $DIR/R9/f
1039         mrename $DIR/R9/f $DIR/R9/a
1040         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1041         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1042         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1043 }
1044 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1045
1046 test_24j() {
1047         test_mkdir $DIR/R10
1048         mrename $DIR/R10/f $DIR/R10/g
1049         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1050         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1051         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1052 }
1053 run_test 24j "source does not exist ============================"
1054
1055 test_24k() {
1056         test_mkdir $DIR/R11a
1057         test_mkdir $DIR/R11a/d
1058         touch $DIR/R11a/f
1059         mv $DIR/R11a/f $DIR/R11a/d
1060         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1061         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1062 }
1063 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1064
1065 # bug 2429 - rename foo foo foo creates invalid file
1066 test_24l() {
1067         f="$DIR/f24l"
1068         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1069 }
1070 run_test 24l "Renaming a file to itself ========================"
1071
1072 test_24m() {
1073         f="$DIR/f24m"
1074         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1075         # on ext3 this does not remove either the source or target files
1076         # though the "expected" operation would be to remove the source
1077         $CHECKSTAT -t file ${f} || error "${f} missing"
1078         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1079 }
1080 run_test 24m "Renaming a file to a hard link to itself ========="
1081
1082 test_24n() {
1083     f="$DIR/f24n"
1084     # this stats the old file after it was renamed, so it should fail
1085     touch ${f}
1086     $CHECKSTAT ${f} || error "${f} missing"
1087     mv ${f} ${f}.rename
1088     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1089     $CHECKSTAT -a ${f} || error "${f} exists"
1090 }
1091 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1092
1093 test_24o() {
1094         test_mkdir $DIR/$tdir
1095         rename_many -s random -v -n 10 $DIR/$tdir
1096 }
1097 run_test 24o "rename of files during htree split"
1098
1099 test_24p() {
1100         test_mkdir $DIR/R12a
1101         test_mkdir $DIR/R12b
1102         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1103         mrename $DIR/R12a $DIR/R12b
1104         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1105         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1106         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1108 }
1109 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1110
1111 cleanup_multiop_pause() {
1112         trap 0
1113         kill -USR1 $MULTIPID
1114 }
1115
1116 test_24q() {
1117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1118
1119         test_mkdir $DIR/R13a
1120         test_mkdir $DIR/R13b
1121         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1122         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1123         MULTIPID=$!
1124
1125         trap cleanup_multiop_pause EXIT
1126         mrename $DIR/R13a $DIR/R13b
1127         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1128         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1129         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1130         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1131         cleanup_multiop_pause
1132         wait $MULTIPID || error "multiop close failed"
1133 }
1134 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1135
1136 test_24r() { #bug 3789
1137         test_mkdir $DIR/R14a
1138         test_mkdir $DIR/R14a/b
1139         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1140         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1141         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1142 }
1143 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1144
1145 test_24s() {
1146         test_mkdir $DIR/R15a
1147         test_mkdir $DIR/R15a/b
1148         test_mkdir $DIR/R15a/b/c
1149         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1150         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1151         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1152 }
1153 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1154
1155 test_24t() {
1156         test_mkdir $DIR/R16a
1157         test_mkdir $DIR/R16a/b
1158         test_mkdir $DIR/R16a/b/c
1159         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1161         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1162 }
1163 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1164
1165 test_24u() { # bug12192
1166         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1167         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1168 }
1169 run_test 24u "create stripe file"
1170
1171 simple_cleanup_common() {
1172         local createmany=$1
1173         local rc=0
1174
1175         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1176
1177         local start=$SECONDS
1178
1179         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1180         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1181         rc=$?
1182         wait_delete_completed
1183         echo "cleanup time $((SECONDS - start))"
1184         return $rc
1185 }
1186
1187 max_pages_per_rpc() {
1188         local mdtname="$(printf "MDT%04x" ${1:-0})"
1189         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1190 }
1191
1192 test_24v() {
1193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1194
1195         local nrfiles=${COUNT:-100000}
1196         local fname="$DIR/$tdir/$tfile"
1197
1198         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1199         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1200
1201         test_mkdir "$(dirname $fname)"
1202         # assume MDT0000 has the fewest inodes
1203         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1204         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1205         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1206
1207         stack_trap "simple_cleanup_common $nrfiles"
1208
1209         createmany -m "$fname" $nrfiles
1210
1211         cancel_lru_locks mdc
1212         lctl set_param mdc.*.stats clear
1213
1214         # was previously test_24D: LU-6101
1215         # readdir() returns correct number of entries after cursor reload
1216         local num_ls=$(ls $DIR/$tdir | wc -l)
1217         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1218         local num_all=$(ls -a $DIR/$tdir | wc -l)
1219         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1220                 [ $num_all -ne $((nrfiles + 2)) ]; then
1221                         error "Expected $nrfiles files, got $num_ls " \
1222                                 "($num_uniq unique $num_all .&..)"
1223         fi
1224         # LU-5 large readdir
1225         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1226         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1227         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1228         # take into account of overhead in lu_dirpage header and end mark in
1229         # each page, plus one in rpc_num calculation.
1230         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1231         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1232         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1233         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1234         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1235         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1236         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1237         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1238                 error "large readdir doesn't take effect: " \
1239                       "$mds_readpage should be about $rpc_max"
1240 }
1241 run_test 24v "list large directory (test hash collision, b=17560)"
1242
1243 test_24w() { # bug21506
1244         SZ1=234852
1245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1246         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1247         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1248         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1249         [[ "$SZ1" -eq "$SZ2" ]] ||
1250                 error "Error reading at the end of the file $tfile"
1251 }
1252 run_test 24w "Reading a file larger than 4Gb"
1253
1254 test_24x() {
1255         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1257         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1258                 skip "Need MDS version at least 2.7.56"
1259
1260         local MDTIDX=1
1261         local remote_dir=$DIR/$tdir/remote_dir
1262
1263         test_mkdir $DIR/$tdir
1264         $LFS mkdir -i $MDTIDX $remote_dir ||
1265                 error "create remote directory failed"
1266
1267         test_mkdir $DIR/$tdir/src_dir
1268         touch $DIR/$tdir/src_file
1269         test_mkdir $remote_dir/tgt_dir
1270         touch $remote_dir/tgt_file
1271
1272         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1273                 error "rename dir cross MDT failed!"
1274
1275         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1276                 error "rename file cross MDT failed!"
1277
1278         touch $DIR/$tdir/ln_file
1279         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1280                 error "ln file cross MDT failed"
1281
1282         rm -rf $DIR/$tdir || error "Can not delete directories"
1283 }
1284 run_test 24x "cross MDT rename/link"
1285
1286 test_24y() {
1287         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1289
1290         local remote_dir=$DIR/$tdir/remote_dir
1291         local mdtidx=1
1292
1293         test_mkdir $DIR/$tdir
1294         $LFS mkdir -i $mdtidx $remote_dir ||
1295                 error "create remote directory failed"
1296
1297         test_mkdir $remote_dir/src_dir
1298         touch $remote_dir/src_file
1299         test_mkdir $remote_dir/tgt_dir
1300         touch $remote_dir/tgt_file
1301
1302         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1303                 error "rename subdir in the same remote dir failed!"
1304
1305         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1306                 error "rename files in the same remote dir failed!"
1307
1308         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1309                 error "link files in the same remote dir failed!"
1310
1311         rm -rf $DIR/$tdir || error "Can not delete directories"
1312 }
1313 run_test 24y "rename/link on the same dir should succeed"
1314
1315 test_24z() {
1316         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1317         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1318                 skip "Need MDS version at least 2.12.51"
1319
1320         local index
1321
1322         for index in 0 1; do
1323                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1324                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1325         done
1326
1327         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1328
1329         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1330         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1331
1332         local mdts=$(comma_list $(mdts_nodes))
1333
1334         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1335         stack_trap "do_nodes $mdts $LCTL \
1336                 set_param mdt.*.enable_remote_rename=1" EXIT
1337
1338         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1339
1340         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1341         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1342 }
1343 run_test 24z "cross-MDT rename is done as cp"
1344
1345 test_24A() { # LU-3182
1346         local NFILES=5000
1347
1348         test_mkdir $DIR/$tdir
1349         stack_trap "simple_cleanup_common $NFILES"
1350         createmany -m $DIR/$tdir/$tfile $NFILES
1351         local t=$(ls $DIR/$tdir | wc -l)
1352         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1353         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1354
1355         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1356                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1357 }
1358 run_test 24A "readdir() returns correct number of entries."
1359
1360 test_24B() { # LU-4805
1361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1362
1363         local count
1364
1365         test_mkdir $DIR/$tdir
1366         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1367                 error "create striped dir failed"
1368
1369         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1370         [ $count -eq 2 ] || error "Expected 2, got $count"
1371
1372         touch $DIR/$tdir/striped_dir/a
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 3 ] || error "Expected 3, got $count"
1376
1377         touch $DIR/$tdir/striped_dir/.f
1378
1379         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1380         [ $count -eq 4 ] || error "Expected 4, got $count"
1381
1382         rm -rf $DIR/$tdir || error "Can not delete directories"
1383 }
1384 run_test 24B "readdir for striped dir return correct number of entries"
1385
1386 test_24C() {
1387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1388
1389         mkdir $DIR/$tdir
1390         mkdir $DIR/$tdir/d0
1391         mkdir $DIR/$tdir/d1
1392
1393         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1394                 error "create striped dir failed"
1395
1396         cd $DIR/$tdir/d0/striped_dir
1397
1398         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1399         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1400         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1401
1402         [ "$d0_ino" = "$parent_ino" ] ||
1403                 error ".. wrong, expect $d0_ino, get $parent_ino"
1404
1405         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1406                 error "mv striped dir failed"
1407
1408         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1409
1410         [ "$d1_ino" = "$parent_ino" ] ||
1411                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1412 }
1413 run_test 24C "check .. in striped dir"
1414
1415 test_24E() {
1416         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1418
1419         mkdir -p $DIR/$tdir
1420         mkdir $DIR/$tdir/src_dir
1421         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1422                 error "create remote source failed"
1423
1424         touch $DIR/$tdir/src_dir/src_child/a
1425
1426         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1427                 error "create remote target dir failed"
1428
1429         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1430                 error "create remote target child failed"
1431
1432         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1433                 error "rename dir cross MDT failed!"
1434
1435         find $DIR/$tdir
1436
1437         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1438                 error "src_child still exists after rename"
1439
1440         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1441                 error "missing file(a) after rename"
1442
1443         rm -rf $DIR/$tdir || error "Can not delete directories"
1444 }
1445 run_test 24E "cross MDT rename/link"
1446
1447 test_24F () {
1448         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1449
1450         local repeats=1000
1451         [ "$SLOW" = "no" ] && repeats=100
1452
1453         mkdir -p $DIR/$tdir
1454
1455         echo "$repeats repeats"
1456         for ((i = 0; i < repeats; i++)); do
1457                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1458                 touch $DIR/$tdir/test/a || error "touch fails"
1459                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1460                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1461         done
1462
1463         true
1464 }
1465 run_test 24F "hash order vs readdir (LU-11330)"
1466
1467 test_24G () {
1468         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1469
1470         local ino1
1471         local ino2
1472
1473         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1474         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1475         touch $DIR/$tdir-0/f1 || error "touch f1"
1476         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1477         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1478         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1479         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1480         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1481 }
1482 run_test 24G "migrate symlink in rename"
1483
1484 test_24H() {
1485         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1486         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1487                 skip "MDT1 should be on another node"
1488
1489         test_mkdir -i 1 -c 1 $DIR/$tdir
1490 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1491         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1492         touch $DIR/$tdir/$tfile || error "touch failed"
1493 }
1494 run_test 24H "repeat FLD_QUERY rpc"
1495
1496 test_25a() {
1497         echo '== symlink sanity ============================================='
1498
1499         test_mkdir $DIR/d25
1500         ln -s d25 $DIR/s25
1501         touch $DIR/s25/foo ||
1502                 error "File creation in symlinked directory failed"
1503 }
1504 run_test 25a "create file in symlinked directory ==============="
1505
1506 test_25b() {
1507         [ ! -d $DIR/d25 ] && test_25a
1508         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1509 }
1510 run_test 25b "lookup file in symlinked directory ==============="
1511
1512 test_26a() {
1513         test_mkdir $DIR/d26
1514         test_mkdir $DIR/d26/d26-2
1515         ln -s d26/d26-2 $DIR/s26
1516         touch $DIR/s26/foo || error "File creation failed"
1517 }
1518 run_test 26a "multiple component symlink ======================="
1519
1520 test_26b() {
1521         test_mkdir -p $DIR/$tdir/d26-2
1522         ln -s $tdir/d26-2/foo $DIR/s26-2
1523         touch $DIR/s26-2 || error "File creation failed"
1524 }
1525 run_test 26b "multiple component symlink at end of lookup ======"
1526
1527 test_26c() {
1528         test_mkdir $DIR/d26.2
1529         touch $DIR/d26.2/foo
1530         ln -s d26.2 $DIR/s26.2-1
1531         ln -s s26.2-1 $DIR/s26.2-2
1532         ln -s s26.2-2 $DIR/s26.2-3
1533         chmod 0666 $DIR/s26.2-3/foo
1534 }
1535 run_test 26c "chain of symlinks"
1536
1537 # recursive symlinks (bug 439)
1538 test_26d() {
1539         ln -s d26-3/foo $DIR/d26-3
1540 }
1541 run_test 26d "create multiple component recursive symlink"
1542
1543 test_26e() {
1544         [ ! -h $DIR/d26-3 ] && test_26d
1545         rm $DIR/d26-3
1546 }
1547 run_test 26e "unlink multiple component recursive symlink"
1548
1549 # recursive symlinks (bug 7022)
1550 test_26f() {
1551         test_mkdir $DIR/$tdir
1552         test_mkdir $DIR/$tdir/$tfile
1553         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1554         test_mkdir -p lndir/bar1
1555         test_mkdir $DIR/$tdir/$tfile/$tfile
1556         cd $tfile                || error "cd $tfile failed"
1557         ln -s .. dotdot          || error "ln dotdot failed"
1558         ln -s dotdot/lndir lndir || error "ln lndir failed"
1559         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1560         output=`ls $tfile/$tfile/lndir/bar1`
1561         [ "$output" = bar1 ] && error "unexpected output"
1562         rm -r $tfile             || error "rm $tfile failed"
1563         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1564 }
1565 run_test 26f "rm -r of a directory which has recursive symlink"
1566
1567 test_27a() {
1568         test_mkdir $DIR/$tdir
1569         $LFS getstripe $DIR/$tdir
1570         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1571         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1572         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1573 }
1574 run_test 27a "one stripe file"
1575
1576 test_27b() {
1577         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1578
1579         test_mkdir $DIR/$tdir
1580         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1581         $LFS getstripe -c $DIR/$tdir/$tfile
1582         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1583                 error "two-stripe file doesn't have two stripes"
1584
1585         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1586 }
1587 run_test 27b "create and write to two stripe file"
1588
1589 # 27c family tests specific striping, setstripe -o
1590 test_27ca() {
1591         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1592         test_mkdir -p $DIR/$tdir
1593         local osts="1"
1594
1595         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1596         $LFS getstripe -i $DIR/$tdir/$tfile
1597         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1598                 error "stripe not on specified OST"
1599
1600         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1601 }
1602 run_test 27ca "one stripe on specified OST"
1603
1604 test_27cb() {
1605         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1606         test_mkdir -p $DIR/$tdir
1607         local osts="1,0"
1608         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1609         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1610         echo "$getstripe"
1611
1612         # Strip getstripe output to a space separated list of OSTs
1613         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1614                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1615         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1616                 error "stripes not on specified OSTs"
1617
1618         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1619 }
1620 run_test 27cb "two stripes on specified OSTs"
1621
1622 test_27cc() {
1623         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1624         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1625                 skip "server does not support overstriping"
1626
1627         test_mkdir -p $DIR/$tdir
1628         local osts="0,0"
1629         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1630         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1631         echo "$getstripe"
1632
1633         # Strip getstripe output to a space separated list of OSTs
1634         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1635                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1636         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1637                 error "stripes not on specified OSTs"
1638
1639         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1640 }
1641 run_test 27cc "two stripes on the same OST"
1642
1643 test_27cd() {
1644         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1645         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1646                 skip "server does not support overstriping"
1647         test_mkdir -p $DIR/$tdir
1648         local osts="0,1,1,0"
1649         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1650         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1651         echo "$getstripe"
1652
1653         # Strip getstripe output to a space separated list of OSTs
1654         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1655                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1656         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1657                 error "stripes not on specified OSTs"
1658
1659         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1660 }
1661 run_test 27cd "four stripes on two OSTs"
1662
1663 test_27ce() {
1664         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1665                 skip_env "too many osts, skipping"
1666         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1667                 skip "server does not support overstriping"
1668         # We do one more stripe than we have OSTs
1669         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1670                 skip_env "ea_inode feature disabled"
1671
1672         test_mkdir -p $DIR/$tdir
1673         local osts=""
1674         for i in $(seq 0 $OSTCOUNT);
1675         do
1676                 osts=$osts"0"
1677                 if [ $i -ne $OSTCOUNT ]; then
1678                         osts=$osts","
1679                 fi
1680         done
1681         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1682         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1683         echo "$getstripe"
1684
1685         # Strip getstripe output to a space separated list of OSTs
1686         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1687                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1688         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1689                 error "stripes not on specified OSTs"
1690
1691         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1692 }
1693 run_test 27ce "more stripes than OSTs with -o"
1694
1695 test_27cf() {
1696         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1697         local pid=0
1698
1699         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1700         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1701         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1702         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1703                 error "failed to set $osp_proc=0"
1704
1705         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1706         pid=$!
1707         sleep 1
1708         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1709         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1710                 error "failed to set $osp_proc=1"
1711         wait $pid
1712         [[ $pid -ne 0 ]] ||
1713                 error "should return error due to $osp_proc=0"
1714 }
1715 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1716
1717 test_27cg() {
1718         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1719                 skip "server does not support overstriping"
1720         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1721         large_xattr_enabled || skip_env "ea_inode feature disabled"
1722
1723         local osts="0"
1724
1725         for ((i=1;i<1000;i++)); do
1726                 osts+=",$((i % OSTCOUNT))"
1727         done
1728
1729         local mdts=$(comma_list $(mdts_nodes))
1730         local before=$(do_nodes $mdts \
1731                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1732                 awk '/many credits/{print $3}' |
1733                 calc_sum)
1734
1735         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1736         $LFS getstripe $DIR/$tfile | grep stripe
1737
1738         rm -f $DIR/$tfile || error "can't unlink"
1739
1740         after=$(do_nodes $mdts \
1741                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1742                 awk '/many credits/{print $3}' |
1743                 calc_sum)
1744
1745         (( before == after )) ||
1746                 error "too many credits happened: $after > $before"
1747 }
1748 run_test 27cg "1000 shouldn't cause too many credits"
1749
1750 test_27d() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1753                 error "setstripe failed"
1754         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1755         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1756 }
1757 run_test 27d "create file with default settings"
1758
1759 test_27e() {
1760         # LU-5839 adds check for existed layout before setting it
1761         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1762                 skip "Need MDS version at least 2.7.56"
1763
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1766         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1767         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1768 }
1769 run_test 27e "setstripe existing file (should return error)"
1770
1771 test_27f() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1774                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1775         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1776                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1777         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1778         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1779 }
1780 run_test 27f "setstripe with bad stripe size (should return error)"
1781
1782 test_27g() {
1783         test_mkdir $DIR/$tdir
1784         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1785         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1786                 error "$DIR/$tdir/$tfile has object"
1787 }
1788 run_test 27g "$LFS getstripe with no objects"
1789
1790 test_27ga() {
1791         test_mkdir $DIR/$tdir
1792         touch $DIR/$tdir/$tfile || error "touch failed"
1793         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1794         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1795         local rc=$?
1796         (( rc == 2 )) || error "getstripe did not return ENOENT"
1797 }
1798 run_test 27ga "$LFS getstripe with missing file (should return error)"
1799
1800 test_27i() {
1801         test_mkdir $DIR/$tdir
1802         touch $DIR/$tdir/$tfile || error "touch failed"
1803         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1804                 error "missing objects"
1805 }
1806 run_test 27i "$LFS getstripe with some objects"
1807
1808 test_27j() {
1809         test_mkdir $DIR/$tdir
1810         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1811                 error "setstripe failed" || true
1812 }
1813 run_test 27j "setstripe with bad stripe offset (should return error)"
1814
1815 test_27k() { # bug 2844
1816         test_mkdir $DIR/$tdir
1817         local file=$DIR/$tdir/$tfile
1818         local ll_max_blksize=$((4 * 1024 * 1024))
1819         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1820         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1821         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1822         dd if=/dev/zero of=$file bs=4k count=1
1823         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1824         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1825 }
1826 run_test 27k "limit i_blksize for broken user apps"
1827
1828 test_27l() {
1829         mcreate $DIR/$tfile || error "creating file"
1830         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1831                 error "setstripe should have failed" || true
1832 }
1833 run_test 27l "check setstripe permissions (should return error)"
1834
1835 test_27m() {
1836         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1837
1838         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1839                 skip_env "multiple clients -- skipping"
1840
1841         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1842                    head -n1)
1843         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1844                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1845         fi
1846         stack_trap simple_cleanup_common
1847         test_mkdir $DIR/$tdir
1848         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1849         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1850                 error "dd should fill OST0"
1851         i=2
1852         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1853                 i=$((i + 1))
1854                 [ $i -gt 256 ] && break
1855         done
1856         i=$((i + 1))
1857         touch $DIR/$tdir/$tfile.$i
1858         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1859             awk '{print $1}'| grep -w "0") ] &&
1860                 error "OST0 was full but new created file still use it"
1861         i=$((i + 1))
1862         touch $DIR/$tdir/$tfile.$i
1863         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1864             awk '{print $1}'| grep -w "0") ] &&
1865                 error "OST0 was full but new created file still use it" || true
1866 }
1867 run_test 27m "create file while OST0 was full"
1868
1869 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1870 # if the OST isn't full anymore.
1871 reset_enospc() {
1872         local ostidx=${1:-""}
1873         local delay
1874         local ready
1875         local get_prealloc
1876
1877         local list=$(comma_list $(osts_nodes))
1878         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1879
1880         do_nodes $list lctl set_param fail_loc=0
1881         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1882         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1883                 awk '{print $1 * 2;exit;}')
1884         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1885                         grep -v \"^0$\""
1886         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1887 }
1888
1889 test_27n() {
1890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1892         remote_mds_nodsh && skip "remote MDS with nodsh"
1893         remote_ost_nodsh && skip "remote OST with nodsh"
1894
1895         reset_enospc
1896         rm -f $DIR/$tdir/$tfile
1897         exhaust_precreations 0 0x80000215
1898         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1899         touch $DIR/$tdir/$tfile || error "touch failed"
1900         $LFS getstripe $DIR/$tdir/$tfile
1901         reset_enospc
1902 }
1903 run_test 27n "create file with some full OSTs"
1904
1905 test_27o() {
1906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1908         remote_mds_nodsh && skip "remote MDS with nodsh"
1909         remote_ost_nodsh && skip "remote OST with nodsh"
1910
1911         reset_enospc
1912         rm -f $DIR/$tdir/$tfile
1913         exhaust_all_precreations 0x215
1914
1915         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1916
1917         reset_enospc
1918         rm -rf $DIR/$tdir/*
1919 }
1920 run_test 27o "create file with all full OSTs (should error)"
1921
1922 function create_and_checktime() {
1923         local fname=$1
1924         local loops=$2
1925         local i
1926
1927         for ((i=0; i < $loops; i++)); do
1928                 local start=$SECONDS
1929                 multiop $fname-$i Oc
1930                 ((SECONDS-start < TIMEOUT)) ||
1931                         error "creation took " $((SECONDS-$start)) && return 1
1932         done
1933 }
1934
1935 test_27oo() {
1936         local mdts=$(comma_list $(mdts_nodes))
1937
1938         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1939                 skip "Need MDS version at least 2.13.57"
1940
1941         local f0=$DIR/${tfile}-0
1942         local f1=$DIR/${tfile}-1
1943
1944         wait_delete_completed
1945
1946         # refill precreated objects
1947         $LFS setstripe -i0 -c1 $f0
1948
1949         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1950         # force QoS allocation policy
1951         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1952         stack_trap "do_nodes $mdts $LCTL set_param \
1953                 lov.*.qos_threshold_rr=$saved" EXIT
1954         sleep_maxage
1955
1956         # one OST is unavailable, but still have few objects preallocated
1957         stop ost1
1958         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1959                 rm -rf $f1 $DIR/$tdir*" EXIT
1960
1961         for ((i=0; i < 7; i++)); do
1962                 mkdir $DIR/$tdir$i || error "can't create dir"
1963                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1964                         error "can't set striping"
1965         done
1966         for ((i=0; i < 7; i++)); do
1967                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1968         done
1969         wait
1970 }
1971 run_test 27oo "don't let few threads to reserve too many objects"
1972
1973 test_27p() {
1974         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1976         remote_mds_nodsh && skip "remote MDS with nodsh"
1977         remote_ost_nodsh && skip "remote OST with nodsh"
1978
1979         reset_enospc
1980         rm -f $DIR/$tdir/$tfile
1981         test_mkdir $DIR/$tdir
1982
1983         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1984         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1985         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1986
1987         exhaust_precreations 0 0x80000215
1988         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1989         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1990         $LFS getstripe $DIR/$tdir/$tfile
1991
1992         reset_enospc
1993 }
1994 run_test 27p "append to a truncated file with some full OSTs"
1995
1996 test_27q() {
1997         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1999         remote_mds_nodsh && skip "remote MDS with nodsh"
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001
2002         reset_enospc
2003         rm -f $DIR/$tdir/$tfile
2004
2005         mkdir_on_mdt0 $DIR/$tdir
2006         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2007         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2008                 error "truncate $DIR/$tdir/$tfile failed"
2009         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2010
2011         exhaust_all_precreations 0x215
2012
2013         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2014         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2015
2016         reset_enospc
2017 }
2018 run_test 27q "append to truncated file with all OSTs full (should error)"
2019
2020 test_27r() {
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2023         remote_mds_nodsh && skip "remote MDS with nodsh"
2024         remote_ost_nodsh && skip "remote OST with nodsh"
2025
2026         reset_enospc
2027         rm -f $DIR/$tdir/$tfile
2028         exhaust_precreations 0 0x80000215
2029
2030         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2031
2032         reset_enospc
2033 }
2034 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2035
2036 test_27s() { # bug 10725
2037         test_mkdir $DIR/$tdir
2038         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2039         local stripe_count=0
2040         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2041         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2042                 error "stripe width >= 2^32 succeeded" || true
2043
2044 }
2045 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2046
2047 test_27t() { # bug 10864
2048         WDIR=$(pwd)
2049         WLFS=$(which lfs)
2050         cd $DIR
2051         touch $tfile
2052         $WLFS getstripe $tfile
2053         cd $WDIR
2054 }
2055 run_test 27t "check that utils parse path correctly"
2056
2057 test_27u() { # bug 4900
2058         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060
2061         local index
2062         local list=$(comma_list $(mdts_nodes))
2063
2064 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2065         do_nodes $list $LCTL set_param fail_loc=0x139
2066         test_mkdir -p $DIR/$tdir
2067         stack_trap "simple_cleanup_common 1000"
2068         createmany -o $DIR/$tdir/$tfile 1000
2069         do_nodes $list $LCTL set_param fail_loc=0
2070
2071         TLOG=$TMP/$tfile.getstripe
2072         $LFS getstripe $DIR/$tdir > $TLOG
2073         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2074         [[ $OBJS -gt 0 ]] &&
2075                 error "$OBJS objects created on OST-0. See $TLOG" ||
2076                 rm -f $TLOG
2077 }
2078 run_test 27u "skip object creation on OSC w/o objects"
2079
2080 test_27v() { # bug 4900
2081         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2083         remote_mds_nodsh && skip "remote MDS with nodsh"
2084         remote_ost_nodsh && skip "remote OST with nodsh"
2085
2086         exhaust_all_precreations 0x215
2087         reset_enospc
2088
2089         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2090
2091         touch $DIR/$tdir/$tfile
2092         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2093         # all except ost1
2094         for (( i=1; i < OSTCOUNT; i++ )); do
2095                 do_facet ost$i lctl set_param fail_loc=0x705
2096         done
2097         local START=`date +%s`
2098         createmany -o $DIR/$tdir/$tfile 32
2099
2100         local FINISH=`date +%s`
2101         local TIMEOUT=`lctl get_param -n timeout`
2102         local PROCESS=$((FINISH - START))
2103         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2104                error "$FINISH - $START >= $TIMEOUT / 2"
2105         sleep $((TIMEOUT / 2 - PROCESS))
2106         reset_enospc
2107 }
2108 run_test 27v "skip object creation on slow OST"
2109
2110 test_27w() { # bug 10997
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2113         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2114                 error "stripe size $size != 65536" || true
2115         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2116                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2117 }
2118 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2119
2120 test_27wa() {
2121         [[ $OSTCOUNT -lt 2 ]] &&
2122                 skip_env "skipping multiple stripe count/offset test"
2123
2124         test_mkdir $DIR/$tdir
2125         for i in $(seq 1 $OSTCOUNT); do
2126                 offset=$((i - 1))
2127                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2128                         error "setstripe -c $i -i $offset failed"
2129                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2130                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2131                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2132                 [ $index -ne $offset ] &&
2133                         error "stripe offset $index != $offset" || true
2134         done
2135 }
2136 run_test 27wa "check $LFS setstripe -c -i options"
2137
2138 test_27x() {
2139         remote_ost_nodsh && skip "remote OST with nodsh"
2140         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2142
2143         OFFSET=$(($OSTCOUNT - 1))
2144         OSTIDX=0
2145         local OST=$(ostname_from_index $OSTIDX)
2146
2147         test_mkdir $DIR/$tdir
2148         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2149         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2150         sleep_maxage
2151         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2152         for i in $(seq 0 $OFFSET); do
2153                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2154                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2155                 error "OST0 was degraded but new created file still use it"
2156         done
2157         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2158 }
2159 run_test 27x "create files while OST0 is degraded"
2160
2161 test_27y() {
2162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2163         remote_mds_nodsh && skip "remote MDS with nodsh"
2164         remote_ost_nodsh && skip "remote OST with nodsh"
2165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2166
2167         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2168         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2169                 osp.$mdtosc.prealloc_last_id)
2170         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2171                 osp.$mdtosc.prealloc_next_id)
2172         local fcount=$((last_id - next_id))
2173         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2174         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2175
2176         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2177                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2178         local OST_DEACTIVE_IDX=-1
2179         local OSC
2180         local OSTIDX
2181         local OST
2182
2183         for OSC in $MDS_OSCS; do
2184                 OST=$(osc_to_ost $OSC)
2185                 OSTIDX=$(index_from_ostuuid $OST)
2186                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2187                         OST_DEACTIVE_IDX=$OSTIDX
2188                 fi
2189                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2190                         echo $OSC "is Deactivated:"
2191                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2192                 fi
2193         done
2194
2195         OSTIDX=$(index_from_ostuuid $OST)
2196         test_mkdir $DIR/$tdir
2197         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2198
2199         for OSC in $MDS_OSCS; do
2200                 OST=$(osc_to_ost $OSC)
2201                 OSTIDX=$(index_from_ostuuid $OST)
2202                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2203                         echo $OST "is degraded:"
2204                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2205                                                 obdfilter.$OST.degraded=1
2206                 fi
2207         done
2208
2209         sleep_maxage
2210         createmany -o $DIR/$tdir/$tfile $fcount
2211
2212         for OSC in $MDS_OSCS; do
2213                 OST=$(osc_to_ost $OSC)
2214                 OSTIDX=$(index_from_ostuuid $OST)
2215                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2216                         echo $OST "is recovered from degraded:"
2217                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2218                                                 obdfilter.$OST.degraded=0
2219                 else
2220                         do_facet $SINGLEMDS lctl --device %$OSC activate
2221                 fi
2222         done
2223
2224         # all osp devices get activated, hence -1 stripe count restored
2225         local stripe_count=0
2226
2227         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2228         # devices get activated.
2229         sleep_maxage
2230         $LFS setstripe -c -1 $DIR/$tfile
2231         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2232         rm -f $DIR/$tfile
2233         [ $stripe_count -ne $OSTCOUNT ] &&
2234                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2235         return 0
2236 }
2237 run_test 27y "create files while OST0 is degraded and the rest inactive"
2238
2239 check_seq_oid()
2240 {
2241         log "check file $1"
2242
2243         lmm_count=$($LFS getstripe -c $1)
2244         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2245         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2246
2247         local old_ifs="$IFS"
2248         IFS=$'[:]'
2249         fid=($($LFS path2fid $1))
2250         IFS="$old_ifs"
2251
2252         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2253         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2254
2255         # compare lmm_seq and lu_fid->f_seq
2256         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2257         # compare lmm_object_id and lu_fid->oid
2258         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2259
2260         # check the trusted.fid attribute of the OST objects of the file
2261         local have_obdidx=false
2262         local stripe_nr=0
2263         $LFS getstripe $1 | while read obdidx oid hex seq; do
2264                 # skip lines up to and including "obdidx"
2265                 [ -z "$obdidx" ] && break
2266                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2267                 $have_obdidx || continue
2268
2269                 local ost=$((obdidx + 1))
2270                 local dev=$(ostdevname $ost)
2271                 local oid_hex
2272
2273                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2274
2275                 seq=$(echo $seq | sed -e "s/^0x//g")
2276                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2277                         oid_hex=$(echo $oid)
2278                 else
2279                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2280                 fi
2281                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2282
2283                 local ff=""
2284                 #
2285                 # Don't unmount/remount the OSTs if we don't need to do that.
2286                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2287                 # update too, until that use mount/ll_decode_filter_fid/mount.
2288                 # Re-enable when debugfs will understand new filter_fid.
2289                 #
2290                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2291                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2292                                 $dev 2>/dev/null" | grep "parent=")
2293                 fi
2294                 if [ -z "$ff" ]; then
2295                         stop ost$ost
2296                         mount_fstype ost$ost
2297                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2298                                 $(facet_mntpt ost$ost)/$obj_file)
2299                         unmount_fstype ost$ost
2300                         start ost$ost $dev $OST_MOUNT_OPTS
2301                         clients_up
2302                 fi
2303
2304                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2305
2306                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2307
2308                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2309                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2310                 #
2311                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2312                 #       stripe_size=1048576 component_id=1 component_start=0 \
2313                 #       component_end=33554432
2314                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2315                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2316                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2317                 local ff_pstripe
2318                 if grep -q 'stripe=' <<<$ff; then
2319                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2320                 else
2321                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2322                         # into f_ver in this case.  See comment on ff_parent.
2323                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2324                 fi
2325
2326                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2327                 [ $ff_pseq = $lmm_seq ] ||
2328                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2329                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2330                 [ $ff_poid = $lmm_oid ] ||
2331                         error "FF parent OID $ff_poid != $lmm_oid"
2332                 (($ff_pstripe == $stripe_nr)) ||
2333                         error "FF stripe $ff_pstripe != $stripe_nr"
2334
2335                 stripe_nr=$((stripe_nr + 1))
2336                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2337                         continue
2338                 if grep -q 'stripe_count=' <<<$ff; then
2339                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2340                                             -e 's/ .*//' <<<$ff)
2341                         [ $lmm_count = $ff_scnt ] ||
2342                                 error "FF stripe count $lmm_count != $ff_scnt"
2343                 fi
2344         done
2345 }
2346
2347 test_27z() {
2348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2349         remote_ost_nodsh && skip "remote OST with nodsh"
2350
2351         test_mkdir $DIR/$tdir
2352         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2353                 { error "setstripe -c -1 failed"; return 1; }
2354         # We need to send a write to every object to get parent FID info set.
2355         # This _should_ also work for setattr, but does not currently.
2356         # touch $DIR/$tdir/$tfile-1 ||
2357         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2358                 { error "dd $tfile-1 failed"; return 2; }
2359         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2360                 { error "setstripe -c -1 failed"; return 3; }
2361         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2362                 { error "dd $tfile-2 failed"; return 4; }
2363
2364         # make sure write RPCs have been sent to OSTs
2365         sync; sleep 5; sync
2366
2367         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2368         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2369 }
2370 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2371
2372 test_27A() { # b=19102
2373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2374
2375         save_layout_restore_at_exit $MOUNT
2376         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2377         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2378                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2379         local default_size=$($LFS getstripe -S $MOUNT)
2380         local default_offset=$($LFS getstripe -i $MOUNT)
2381         local dsize=$(do_facet $SINGLEMDS \
2382                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2383         [ $default_size -eq $dsize ] ||
2384                 error "stripe size $default_size != $dsize"
2385         [ $default_offset -eq -1 ] ||
2386                 error "stripe offset $default_offset != -1"
2387 }
2388 run_test 27A "check filesystem-wide default LOV EA values"
2389
2390 test_27B() { # LU-2523
2391         test_mkdir $DIR/$tdir
2392         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2393         touch $DIR/$tdir/f0
2394         # open f1 with O_LOV_DELAY_CREATE
2395         # rename f0 onto f1
2396         # call setstripe ioctl on open file descriptor for f1
2397         # close
2398         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2399                 $DIR/$tdir/f0
2400
2401         rm -f $DIR/$tdir/f1
2402         # open f1 with O_LOV_DELAY_CREATE
2403         # unlink f1
2404         # call setstripe ioctl on open file descriptor for f1
2405         # close
2406         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2407
2408         # Allow multiop to fail in imitation of NFS's busted semantics.
2409         true
2410 }
2411 run_test 27B "call setstripe on open unlinked file/rename victim"
2412
2413 # 27C family tests full striping and overstriping
2414 test_27Ca() { #LU-2871
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2416
2417         declare -a ost_idx
2418         local index
2419         local found
2420         local i
2421         local j
2422
2423         test_mkdir $DIR/$tdir
2424         cd $DIR/$tdir
2425         for i in $(seq 0 $((OSTCOUNT - 1))); do
2426                 # set stripe across all OSTs starting from OST$i
2427                 $LFS setstripe -i $i -c -1 $tfile$i
2428                 # get striping information
2429                 ost_idx=($($LFS getstripe $tfile$i |
2430                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2431                 echo "OST Index: ${ost_idx[*]}"
2432
2433                 # check the layout
2434                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2435                         error "${#ost_idx[@]} != $OSTCOUNT"
2436
2437                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2438                         found=0
2439                         for j in "${ost_idx[@]}"; do
2440                                 if [ $index -eq $j ]; then
2441                                         found=1
2442                                         break
2443                                 fi
2444                         done
2445                         [ $found = 1 ] ||
2446                                 error "Can not find $index in ${ost_idx[*]}"
2447                 done
2448         done
2449 }
2450 run_test 27Ca "check full striping across all OSTs"
2451
2452 test_27Cb() {
2453         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2454                 skip "server does not support overstriping"
2455         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2456                 skip_env "too many osts, skipping"
2457
2458         test_mkdir -p $DIR/$tdir
2459         local setcount=$(($OSTCOUNT * 2))
2460         [ $setcount -lt 160 ] || large_xattr_enabled ||
2461                 skip_env "ea_inode feature disabled"
2462
2463         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2464                 error "setstripe failed"
2465
2466         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2467         [ $count -eq $setcount ] ||
2468                 error "stripe count $count, should be $setcount"
2469
2470         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2471                 error "overstriped should be set in pattern"
2472
2473         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2474                 error "dd failed"
2475 }
2476 run_test 27Cb "more stripes than OSTs with -C"
2477
2478 test_27Cc() {
2479         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2480                 skip "server does not support overstriping"
2481         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2482
2483         test_mkdir -p $DIR/$tdir
2484         local setcount=$(($OSTCOUNT - 1))
2485
2486         [ $setcount -lt 160 ] || large_xattr_enabled ||
2487                 skip_env "ea_inode feature disabled"
2488
2489         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2490                 error "setstripe failed"
2491
2492         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2493         [ $count -eq $setcount ] ||
2494                 error "stripe count $count, should be $setcount"
2495
2496         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2497                 error "overstriped should not be set in pattern"
2498
2499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2500                 error "dd failed"
2501 }
2502 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2503
2504 test_27Cd() {
2505         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2506                 skip "server does not support overstriping"
2507         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2508         large_xattr_enabled || skip_env "ea_inode feature disabled"
2509
2510         force_new_seq_all
2511
2512         test_mkdir -p $DIR/$tdir
2513         local setcount=$LOV_MAX_STRIPE_COUNT
2514
2515         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2516                 error "setstripe failed"
2517
2518         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2519         [ $count -eq $setcount ] ||
2520                 error "stripe count $count, should be $setcount"
2521
2522         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2523                 error "overstriped should be set in pattern"
2524
2525         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2526                 error "dd failed"
2527
2528         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2529 }
2530 run_test 27Cd "test maximum stripe count"
2531
2532 test_27Ce() {
2533         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2534                 skip "server does not support overstriping"
2535         test_mkdir -p $DIR/$tdir
2536
2537         pool_add $TESTNAME || error "Pool creation failed"
2538         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2539
2540         local setcount=8
2541
2542         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2543                 error "setstripe failed"
2544
2545         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2546         [ $count -eq $setcount ] ||
2547                 error "stripe count $count, should be $setcount"
2548
2549         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2550                 error "overstriped should be set in pattern"
2551
2552         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2553                 error "dd failed"
2554
2555         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2556 }
2557 run_test 27Ce "test pool with overstriping"
2558
2559 test_27Cf() {
2560         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2561                 skip "server does not support overstriping"
2562         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2563                 skip_env "too many osts, skipping"
2564
2565         test_mkdir -p $DIR/$tdir
2566
2567         local setcount=$(($OSTCOUNT * 2))
2568         [ $setcount -lt 160 ] || large_xattr_enabled ||
2569                 skip_env "ea_inode feature disabled"
2570
2571         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2572                 error "setstripe failed"
2573
2574         echo 1 > $DIR/$tdir/$tfile
2575
2576         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2577         [ $count -eq $setcount ] ||
2578                 error "stripe count $count, should be $setcount"
2579
2580         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2581                 error "overstriped should be set in pattern"
2582
2583         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2584                 error "dd failed"
2585
2586         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2587 }
2588 run_test 27Cf "test default inheritance with overstriping"
2589
2590 test_27Cg() {
2591         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2592                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2593
2594         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2595         (( $? != 0 )) || error "must be an error for not existent OST#"
2596 }
2597 run_test 27Cg "test setstripe with wrong OST idx"
2598
2599 test_27D() {
2600         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2601         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2602         remote_mds_nodsh && skip "remote MDS with nodsh"
2603
2604         local POOL=${POOL:-testpool}
2605         local first_ost=0
2606         local last_ost=$(($OSTCOUNT - 1))
2607         local ost_step=1
2608         local ost_list=$(seq $first_ost $ost_step $last_ost)
2609         local ost_range="$first_ost $last_ost $ost_step"
2610
2611         test_mkdir $DIR/$tdir
2612         pool_add $POOL || error "pool_add failed"
2613         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2614
2615         local skip27D
2616         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2617                 skip27D+="-s 29"
2618         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2619                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2620                         skip27D+=" -s 30,31"
2621         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2622           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2623                 skip27D+=" -s 32,33"
2624         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2625                 skip27D+=" -s 34"
2626         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2627                 error "llapi_layout_test failed"
2628
2629         destroy_test_pools || error "destroy test pools failed"
2630 }
2631 run_test 27D "validate llapi_layout API"
2632
2633 # Verify that default_easize is increased from its initial value after
2634 # accessing a widely striped file.
2635 test_27E() {
2636         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2637         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2638                 skip "client does not have LU-3338 fix"
2639
2640         # 72 bytes is the minimum space required to store striping
2641         # information for a file striped across one OST:
2642         # (sizeof(struct lov_user_md_v3) +
2643         #  sizeof(struct lov_user_ost_data_v1))
2644         local min_easize=72
2645         $LCTL set_param -n llite.*.default_easize $min_easize ||
2646                 error "lctl set_param failed"
2647         local easize=$($LCTL get_param -n llite.*.default_easize)
2648
2649         [ $easize -eq $min_easize ] ||
2650                 error "failed to set default_easize"
2651
2652         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2653                 error "setstripe failed"
2654         # In order to ensure stat() call actually talks to MDS we need to
2655         # do something drastic to this file to shake off all lock, e.g.
2656         # rename it (kills lookup lock forcing cache cleaning)
2657         mv $DIR/$tfile $DIR/${tfile}-1
2658         ls -l $DIR/${tfile}-1
2659         rm $DIR/${tfile}-1
2660
2661         easize=$($LCTL get_param -n llite.*.default_easize)
2662
2663         [ $easize -gt $min_easize ] ||
2664                 error "default_easize not updated"
2665 }
2666 run_test 27E "check that default extended attribute size properly increases"
2667
2668 test_27F() { # LU-5346/LU-7975
2669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2670         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2671         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2672                 skip "Need MDS version at least 2.8.51"
2673         remote_ost_nodsh && skip "remote OST with nodsh"
2674
2675         test_mkdir $DIR/$tdir
2676         rm -f $DIR/$tdir/f0
2677         $LFS setstripe -c 2 $DIR/$tdir
2678
2679         # stop all OSTs to reproduce situation for LU-7975 ticket
2680         for num in $(seq $OSTCOUNT); do
2681                 stop ost$num
2682         done
2683
2684         # open/create f0 with O_LOV_DELAY_CREATE
2685         # truncate f0 to a non-0 size
2686         # close
2687         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2688
2689         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2690         # open/write it again to force delayed layout creation
2691         cat /etc/hosts > $DIR/$tdir/f0 &
2692         catpid=$!
2693
2694         # restart OSTs
2695         for num in $(seq $OSTCOUNT); do
2696                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2697                         error "ost$num failed to start"
2698         done
2699
2700         wait $catpid || error "cat failed"
2701
2702         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2703         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2704                 error "wrong stripecount"
2705
2706 }
2707 run_test 27F "Client resend delayed layout creation with non-zero size"
2708
2709 test_27G() { #LU-10629
2710         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2711                 skip "Need MDS version at least 2.11.51"
2712         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2713         remote_mds_nodsh && skip "remote MDS with nodsh"
2714         local POOL=${POOL:-testpool}
2715         local ostrange="0 0 1"
2716
2717         test_mkdir $DIR/$tdir
2718         touch $DIR/$tdir/$tfile.nopool
2719         pool_add $POOL || error "pool_add failed"
2720         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2721         $LFS setstripe -p $POOL $DIR/$tdir
2722
2723         local pool=$($LFS getstripe -p $DIR/$tdir)
2724
2725         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2726         touch $DIR/$tdir/$tfile.default
2727         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2728         $LFS find $DIR/$tdir -type f --pool $POOL
2729         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2730         [[ "$found" == "2" ]] ||
2731                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2732
2733         $LFS setstripe -d $DIR/$tdir
2734
2735         pool=$($LFS getstripe -p -d $DIR/$tdir)
2736
2737         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2738 }
2739 run_test 27G "Clear OST pool from stripe"
2740
2741 test_27H() {
2742         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2743                 skip "Need MDS version newer than 2.11.54"
2744         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2745         test_mkdir $DIR/$tdir
2746         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2747         touch $DIR/$tdir/$tfile
2748         $LFS getstripe -c $DIR/$tdir/$tfile
2749         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2750                 error "two-stripe file doesn't have two stripes"
2751
2752         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2753         $LFS getstripe -y $DIR/$tdir/$tfile
2754         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2755              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2756                 error "expected l_ost_idx: [02]$ not matched"
2757
2758         # make sure ost list has been cleared
2759         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2760         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2761                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2762         touch $DIR/$tdir/f3
2763         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2764 }
2765 run_test 27H "Set specific OSTs stripe"
2766
2767 test_27I() {
2768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2770         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2771                 skip "Need MDS version newer than 2.12.52"
2772         local pool=$TESTNAME
2773         local ostrange="1 1 1"
2774
2775         save_layout_restore_at_exit $MOUNT
2776         $LFS setstripe -c 2 -i 0 $MOUNT
2777         pool_add $pool || error "pool_add failed"
2778         pool_add_targets $pool $ostrange ||
2779                 error "pool_add_targets failed"
2780         test_mkdir $DIR/$tdir
2781         $LFS setstripe -p $pool $DIR/$tdir
2782         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2783         $LFS getstripe $DIR/$tdir/$tfile
2784 }
2785 run_test 27I "check that root dir striping does not break parent dir one"
2786
2787 test_27J() {
2788         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2789                 skip "Need MDS version newer than 2.12.51"
2790
2791         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2792         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2793         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2794            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2795                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2796
2797         test_mkdir $DIR/$tdir
2798         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2799         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2800
2801         # create foreign file (raw way)
2802         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2803                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2804
2805         ! $LFS setstripe --foreign --flags foo \
2806                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2807                         error "creating $tfile with '--flags foo' should fail"
2808
2809         ! $LFS setstripe --foreign --flags 0xffffffff \
2810                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2811                         error "creating $tfile w/ 0xffffffff flags should fail"
2812
2813         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2814                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2815
2816         # verify foreign file (raw way)
2817         parse_foreign_file -f $DIR/$tdir/$tfile |
2818                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2819                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2820         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2821                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_size: 73" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2825         parse_foreign_file -f $DIR/$tdir/$tfile |
2826                 grep "lov_foreign_type: 1" ||
2827                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2828         parse_foreign_file -f $DIR/$tdir/$tfile |
2829                 grep "lov_foreign_flags: 0x0000DA08" ||
2830                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2831         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2832                 grep "lov_foreign_value: 0x" |
2833                 sed -e 's/lov_foreign_value: 0x//')
2834         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2835         [[ $lov = ${lov2// /} ]] ||
2836                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2837
2838         # create foreign file (lfs + API)
2839         $LFS setstripe --foreign=none --flags 0xda08 \
2840                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2841                 error "$DIR/$tdir/${tfile}2: create failed"
2842
2843         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2844                 grep "lfm_magic:.*0x0BD70BD0" ||
2845                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2846         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2847         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2848                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2849         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2851         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2852                 grep "lfm_flags:.*0x0000DA08" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2854         $LFS getstripe $DIR/$tdir/${tfile}2 |
2855                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2856                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2857
2858         # modify striping should fail
2859         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2860                 error "$DIR/$tdir/$tfile: setstripe should fail"
2861         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2862                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2863
2864         # R/W should fail
2865         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2866         cat $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: read should fail"
2868         cat /etc/passwd > $DIR/$tdir/$tfile &&
2869                 error "$DIR/$tdir/$tfile: write should fail"
2870         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2871                 error "$DIR/$tdir/${tfile}2: write should fail"
2872
2873         # chmod should work
2874         chmod 222 $DIR/$tdir/$tfile ||
2875                 error "$DIR/$tdir/$tfile: chmod failed"
2876         chmod 222 $DIR/$tdir/${tfile}2 ||
2877                 error "$DIR/$tdir/${tfile}2: chmod failed"
2878
2879         # chown should work
2880         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2881                 error "$DIR/$tdir/$tfile: chown failed"
2882         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2883                 error "$DIR/$tdir/${tfile}2: chown failed"
2884
2885         # rename should work
2886         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2887                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2888         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2889                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2890
2891         #remove foreign file
2892         rm $DIR/$tdir/${tfile}.new ||
2893                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2894         rm $DIR/$tdir/${tfile}2.new ||
2895                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2896 }
2897 run_test 27J "basic ops on file with foreign LOV"
2898
2899 test_27K() {
2900         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2901                 skip "Need MDS version newer than 2.12.49"
2902
2903         test_mkdir $DIR/$tdir
2904         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2905         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2906
2907         # create foreign dir (raw way)
2908         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2909                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2910
2911         ! $LFS setdirstripe --foreign --flags foo \
2912                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2913                         error "creating $tdir with '--flags foo' should fail"
2914
2915         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2916                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2917                         error "creating $tdir w/ 0xffffffff flags should fail"
2918
2919         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2920                 error "create_foreign_dir FAILED"
2921
2922         # verify foreign dir (raw way)
2923         parse_foreign_dir -d $DIR/$tdir/$tdir |
2924                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2925                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2926         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2927                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2928         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2929                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2930         parse_foreign_dir -d $DIR/$tdir/$tdir |
2931                 grep "lmv_foreign_flags: 55813$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2933         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2934                 grep "lmv_foreign_value: 0x" |
2935                 sed 's/lmv_foreign_value: 0x//')
2936         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2937                 sed 's/ //g')
2938         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2939
2940         # create foreign dir (lfs + API)
2941         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2942                 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/$tdir/${tdir}2: create failed"
2944
2945         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2946
2947         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_magic:.*0x0CD50CD0" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2950         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2951         # - sizeof(lfm_type) - sizeof(lfm_flags)
2952         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2954         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2955                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2956         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2957                 grep "lfm_flags:.*0x0000DA05" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2959         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2962
2963         # file create in dir should fail
2964         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2965         touch $DIR/$tdir/${tdir}2/$tfile &&
2966                 error "$DIR/${tdir}2: file create should fail"
2967
2968         # chmod should work
2969         chmod 777 $DIR/$tdir/$tdir ||
2970                 error "$DIR/$tdir: chmod failed"
2971         chmod 777 $DIR/$tdir/${tdir}2 ||
2972                 error "$DIR/${tdir}2: chmod failed"
2973
2974         # chown should work
2975         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2976                 error "$DIR/$tdir: chown failed"
2977         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2978                 error "$DIR/${tdir}2: chown failed"
2979
2980         # rename should work
2981         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2982                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2983         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2984                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2985
2986         #remove foreign dir
2987         rmdir $DIR/$tdir/${tdir}.new ||
2988                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2989         rmdir $DIR/$tdir/${tdir}2.new ||
2990                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2991 }
2992 run_test 27K "basic ops on dir with foreign LMV"
2993
2994 test_27L() {
2995         remote_mds_nodsh && skip "remote MDS with nodsh"
2996
2997         local POOL=${POOL:-$TESTNAME}
2998
2999         pool_add $POOL || error "pool_add failed"
3000
3001         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3002                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3003                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3004 }
3005 run_test 27L "lfs pool_list gives correct pool name"
3006
3007 test_27M() {
3008         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3009                 skip "Need MDS version >= than 2.12.57"
3010         remote_mds_nodsh && skip "remote MDS with nodsh"
3011         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3012
3013         # Set default striping on directory
3014         local setcount=4
3015         local stripe_opt
3016         local mdts=$(comma_list $(mdts_nodes))
3017
3018         # if we run against a 2.12 server which lacks overstring support
3019         # then the connect_flag will not report overstriping, even if client
3020         # is 2.14+
3021         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3022                 stripe_opt="-C $setcount"
3023         elif (( $OSTCOUNT >= $setcount )); then
3024                 stripe_opt="-c $setcount"
3025         else
3026                 skip "server does not support overstriping"
3027         fi
3028
3029         test_mkdir $DIR/$tdir
3030
3031         # Validate existing append_* params and ensure restore
3032         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3033         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3034         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3035
3036         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3037         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3038         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3039
3040         $LFS setstripe $stripe_opt $DIR/$tdir
3041
3042         echo 1 > $DIR/$tdir/${tfile}.1
3043         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3044         (( $count == $setcount )) ||
3045                 error "(1) stripe count $count, should be $setcount"
3046
3047         local appendcount=$orig_count
3048         echo 1 >> $DIR/$tdir/${tfile}.2_append
3049         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3050         (( $count == $appendcount )) ||
3051                 error "(2)stripe count $count, should be $appendcount for append"
3052
3053         # Disable O_APPEND striping, verify it works
3054         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3055
3056         # Should now get the default striping, which is 4
3057         setcount=4
3058         echo 1 >> $DIR/$tdir/${tfile}.3_append
3059         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3060         (( $count == $setcount )) ||
3061                 error "(3) stripe count $count, should be $setcount"
3062
3063         # Try changing the stripe count for append files
3064         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3065
3066         # Append striping is now 2 (directory default is still 4)
3067         appendcount=2
3068         echo 1 >> $DIR/$tdir/${tfile}.4_append
3069         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3070         (( $count == $appendcount )) ||
3071                 error "(4) stripe count $count, should be $appendcount for append"
3072
3073         # Test append stripe count of -1
3074         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3075         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3076                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3077                 touch $DIR/$tdir/$tfile.specific.{1..128}
3078         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3079
3080         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3081         appendcount=$OSTCOUNT
3082         echo 1 >> $DIR/$tdir/${tfile}.5
3083         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3084         (( $count == $appendcount )) ||
3085                 error "(5) stripe count $count, should be $appendcount for append"
3086
3087         # Set append striping back to default of 1
3088         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3089
3090         # Try a new default striping, PFL + DOM
3091         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3092
3093         # Create normal DOM file, DOM returns stripe count == 0
3094         setcount=0
3095         touch $DIR/$tdir/${tfile}.6
3096         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3097         (( $count == $setcount )) ||
3098                 error "(6) stripe count $count, should be $setcount"
3099
3100         # Show
3101         appendcount=1
3102         echo 1 >> $DIR/$tdir/${tfile}.7_append
3103         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3104         (( $count == $appendcount )) ||
3105                 error "(7) stripe count $count, should be $appendcount for append"
3106
3107         # Clean up DOM layout
3108         $LFS setstripe -d $DIR/$tdir
3109
3110         save_layout_restore_at_exit $MOUNT
3111         # Now test that append striping works when layout is from root
3112         $LFS setstripe -c 2 $MOUNT
3113         # Make a special directory for this
3114         mkdir $DIR/${tdir}/${tdir}.2
3115
3116         # Verify for normal file
3117         setcount=2
3118         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3119         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3120         (( $count == $setcount )) ||
3121                 error "(8) stripe count $count, should be $setcount"
3122
3123         appendcount=1
3124         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3125         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3126         (( $count == $appendcount )) ||
3127                 error "(9) stripe count $count, should be $appendcount for append"
3128
3129         # Now test O_APPEND striping with pools
3130         pool_add $TESTNAME || error "pool creation failed"
3131         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3132         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3133
3134         echo 1 >> $DIR/$tdir/${tfile}.10_append
3135
3136         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3137         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3138
3139         # Check that count is still correct
3140         appendcount=1
3141         echo 1 >> $DIR/$tdir/${tfile}.11_append
3142         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3143         (( $count == $appendcount )) ||
3144                 error "(11) stripe count $count, should be $appendcount for append"
3145
3146         # Disable O_APPEND stripe count, verify pool works separately
3147         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3148
3149         echo 1 >> $DIR/$tdir/${tfile}.12_append
3150
3151         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3152         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3153
3154         # Remove pool setting, verify it's not applied
3155         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3156
3157         echo 1 >> $DIR/$tdir/${tfile}.13_append
3158
3159         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3160         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3161 }
3162 run_test 27M "test O_APPEND striping"
3163
3164 test_27N() {
3165         combined_mgs_mds && skip "needs separate MGS/MDT"
3166
3167         pool_add $TESTNAME || error "pool_add failed"
3168         do_facet mgs "$LCTL pool_list $FSNAME" |
3169                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3170                 error "lctl pool_list on MGS failed"
3171 }
3172 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3173
3174 clean_foreign_symlink() {
3175         trap 0
3176         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3177         for i in $DIR/$tdir/* ; do
3178                 $LFS unlink_foreign $i || true
3179         done
3180 }
3181
3182 test_27O() {
3183         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3184                 skip "Need MDS version newer than 2.12.51"
3185
3186         test_mkdir $DIR/$tdir
3187         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3188         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3189
3190         trap clean_foreign_symlink EXIT
3191
3192         # enable foreign_symlink behaviour
3193         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3194
3195         # foreign symlink LOV format is a partial path by default
3196
3197         # create foreign file (lfs + API)
3198         $LFS setstripe --foreign=symlink --flags 0xda05 \
3199                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3200                 error "$DIR/$tdir/${tfile}: create failed"
3201
3202         $LFS getstripe -v $DIR/$tdir/${tfile} |
3203                 grep "lfm_magic:.*0x0BD70BD0" ||
3204                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3205         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3207         $LFS getstripe -v $DIR/$tdir/${tfile} |
3208                 grep "lfm_flags:.*0x0000DA05" ||
3209                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3210         $LFS getstripe $DIR/$tdir/${tfile} |
3211                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3212                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3213
3214         # modify striping should fail
3215         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3216                 error "$DIR/$tdir/$tfile: setstripe should fail"
3217
3218         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3219         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3220         cat /etc/passwd > $DIR/$tdir/$tfile &&
3221                 error "$DIR/$tdir/$tfile: write should fail"
3222
3223         # rename should succeed
3224         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3225                 error "$DIR/$tdir/$tfile: rename has failed"
3226
3227         #remove foreign_symlink file should fail
3228         rm $DIR/$tdir/${tfile}.new &&
3229                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3230
3231         #test fake symlink
3232         mkdir /tmp/${uuid1} ||
3233                 error "/tmp/${uuid1}: mkdir has failed"
3234         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3235                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3236         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3237         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3239         #read should succeed now
3240         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3241                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3242         #write should succeed now
3243         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3244                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3245         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3247         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3248                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3249
3250         #check that getstripe still works
3251         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3252                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3253
3254         # chmod should still succeed
3255         chmod 644 $DIR/$tdir/${tfile}.new ||
3256                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3257
3258         # chown should still succeed
3259         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3260                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3261
3262         # rename should still succeed
3263         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3264                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3265
3266         #remove foreign_symlink file should still fail
3267         rm $DIR/$tdir/${tfile} &&
3268                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3269
3270         #use special ioctl() to unlink foreign_symlink file
3271         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3272                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3273
3274 }
3275 run_test 27O "basic ops on foreign file of symlink type"
3276
3277 test_27P() {
3278         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3279                 skip "Need MDS version newer than 2.12.49"
3280
3281         test_mkdir $DIR/$tdir
3282         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3283         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3284
3285         trap clean_foreign_symlink EXIT
3286
3287         # enable foreign_symlink behaviour
3288         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3289
3290         # foreign symlink LMV format is a partial path by default
3291
3292         # create foreign dir (lfs + API)
3293         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3294                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3295                 error "$DIR/$tdir/${tdir}: create failed"
3296
3297         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3298
3299         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3300                 grep "lfm_magic:.*0x0CD50CD0" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3302         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3303                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3304         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3305                 grep "lfm_flags:.*0x0000DA05" ||
3306                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3307         $LFS getdirstripe $DIR/$tdir/${tdir} |
3308                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3309                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3310
3311         # file create in dir should fail
3312         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3313         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3314
3315         # rename should succeed
3316         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3317                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3318
3319         #remove foreign_symlink dir should fail
3320         rmdir $DIR/$tdir/${tdir}.new &&
3321                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3322
3323         #test fake symlink
3324         mkdir -p /tmp/${uuid1}/${uuid2} ||
3325                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3326         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3327                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3328         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3329         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3330                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3331         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3332                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3333
3334         #check that getstripe fails now that foreign_symlink enabled
3335         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3336                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3337
3338         # file create in dir should work now
3339         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3340                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3341         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3342                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3343         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3344                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3345
3346         # chmod should still succeed
3347         chmod 755 $DIR/$tdir/${tdir}.new ||
3348                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3349
3350         # chown should still succeed
3351         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3352                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3353
3354         # rename should still succeed
3355         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3356                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3357
3358         #remove foreign_symlink dir should still fail
3359         rmdir $DIR/$tdir/${tdir} &&
3360                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3361
3362         #use special ioctl() to unlink foreign_symlink file
3363         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3364                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3365
3366         #created file should still exist
3367         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3368                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3369         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3370                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3371 }
3372 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3373
3374 test_27Q() {
3375         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3376         stack_trap "rm -f $TMP/$tfile*"
3377
3378         test_mkdir $DIR/$tdir-1
3379         test_mkdir $DIR/$tdir-2
3380
3381         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3382         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3383
3384         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3385         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3386
3387         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3388         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3389
3390         # Create some bad symlinks and ensure that we don't loop
3391         # forever or something. These should return ELOOP (40) and
3392         # ENOENT (2) but I don't want to test for that because there's
3393         # always some weirdo architecture that needs to ruin
3394         # everything by defining these error numbers differently.
3395
3396         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3397         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3398
3399         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3400         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3401
3402         return 0
3403 }
3404 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3405
3406 test_27R() {
3407         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3408                 skip "need MDS 2.14.55 or later"
3409         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3410
3411         local testdir="$DIR/$tdir"
3412         test_mkdir -p $testdir
3413         stack_trap "rm -rf $testdir"
3414         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3415
3416         local f1="$testdir/f1"
3417         touch $f1 || error "failed to touch $f1"
3418         local count=$($LFS getstripe -c $f1)
3419         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3420
3421         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3422         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3423
3424         local maxcount=$(($OSTCOUNT - 1))
3425         local mdts=$(comma_list $(mdts_nodes))
3426         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3427         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3428
3429         local f2="$testdir/f2"
3430         touch $f2 || error "failed to touch $f2"
3431         local count=$($LFS getstripe -c $f2)
3432         (( $count == $maxcount )) || error "wrong stripe count"
3433 }
3434 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3435
3436 test_27T() {
3437         [ $(facet_host client) == $(facet_host ost1) ] &&
3438                 skip "need ost1 and client on different nodes"
3439
3440 #define OBD_FAIL_OSC_NO_GRANT            0x411
3441         $LCTL set_param fail_loc=0x20000411 fail_val=1
3442 #define OBD_FAIL_OST_ENOSPC              0x215
3443         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3444         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3445         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3446                 error "multiop failed"
3447 }
3448 run_test 27T "no eio on close on partial write due to enosp"
3449
3450 test_27U() {
3451         local dir=$DIR/$tdir
3452         local file=$dir/$tfile
3453         local append_pool=${TESTNAME}-append
3454         local normal_pool=${TESTNAME}-normal
3455         local pool
3456         local stripe_count
3457         local stripe_count2
3458         local mdts=$(comma_list $(mdts_nodes))
3459
3460         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3461                 skip "Need MDS version at least 2.15.51 for append pool feature"
3462
3463         # Validate existing append_* params and ensure restore
3464         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3465         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3466         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3467
3468         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3469         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3470         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3471
3472         pool_add $append_pool || error "pool creation failed"
3473         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3474
3475         pool_add $normal_pool || error "pool creation failed"
3476         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3477
3478         test_mkdir $dir
3479         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3480
3481         echo XXX >> $file.1
3482         $LFS getstripe $file.1
3483
3484         pool=$($LFS getstripe -p $file.1)
3485         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3486
3487         stripe_count2=$($LFS getstripe -c $file.1)
3488         ((stripe_count2 == stripe_count)) ||
3489                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3490
3491         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3492
3493         echo XXX >> $file.2
3494         $LFS getstripe $file.2
3495
3496         pool=$($LFS getstripe -p $file.2)
3497         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3498
3499         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3500
3501         echo XXX >> $file.3
3502         $LFS getstripe $file.3
3503
3504         stripe_count2=$($LFS getstripe -c $file.3)
3505         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3506 }
3507 run_test 27U "append pool and stripe count work with composite default layout"
3508
3509 # createtest also checks that device nodes are created and
3510 # then visible correctly (#2091)
3511 test_28() { # bug 2091
3512         test_mkdir $DIR/d28
3513         $CREATETEST $DIR/d28/ct || error "createtest failed"
3514 }
3515 run_test 28 "create/mknod/mkdir with bad file types ============"
3516
3517 test_29() {
3518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3519
3520         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3521                 disable_opencache
3522                 stack_trap "restore_opencache"
3523         }
3524
3525         sync; sleep 1; sync # flush out any dirty pages from previous tests
3526         cancel_lru_locks
3527         test_mkdir $DIR/d29
3528         touch $DIR/d29/foo
3529         log 'first d29'
3530         ls -l $DIR/d29
3531
3532         declare -i LOCKCOUNTORIG=0
3533         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3534                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3535         done
3536         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3537
3538         declare -i LOCKUNUSEDCOUNTORIG=0
3539         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3540                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3541         done
3542
3543         log 'second d29'
3544         ls -l $DIR/d29
3545         log 'done'
3546
3547         declare -i LOCKCOUNTCURRENT=0
3548         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3549                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3550         done
3551
3552         declare -i LOCKUNUSEDCOUNTCURRENT=0
3553         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3554                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3555         done
3556
3557         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3558                 $LCTL set_param -n ldlm.dump_namespaces ""
3559                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3560                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3561                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3562                 return 2
3563         fi
3564         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3565                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3566                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3567                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3568                 return 3
3569         fi
3570 }
3571 run_test 29 "IT_GETATTR regression  ============================"
3572
3573 test_30a() { # was test_30
3574         cp $(which ls) $DIR || cp /bin/ls $DIR
3575         $DIR/ls / || error "Can't execute binary from lustre"
3576         rm $DIR/ls
3577 }
3578 run_test 30a "execute binary from Lustre (execve) =============="
3579
3580 test_30b() {
3581         cp `which ls` $DIR || cp /bin/ls $DIR
3582         chmod go+rx $DIR/ls
3583         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3584         rm $DIR/ls
3585 }
3586 run_test 30b "execute binary from Lustre as non-root ==========="
3587
3588 test_30c() { # b=22376
3589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3590
3591         cp $(which ls) $DIR || cp /bin/ls $DIR
3592         chmod a-rw $DIR/ls
3593         cancel_lru_locks mdc
3594         cancel_lru_locks osc
3595         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3596         rm -f $DIR/ls
3597 }
3598 run_test 30c "execute binary from Lustre without read perms ===="
3599
3600 test_30d() {
3601         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3602
3603         for i in {1..10}; do
3604                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3605                 local PID=$!
3606                 sleep 1
3607                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3608                 wait $PID || error "executing dd from Lustre failed"
3609                 rm -f $DIR/$tfile
3610         done
3611
3612         rm -f $DIR/dd
3613 }
3614 run_test 30d "execute binary from Lustre while clear locks"
3615
3616 test_31a() {
3617         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3618         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3619 }
3620 run_test 31a "open-unlink file =================================="
3621
3622 test_31b() {
3623         touch $DIR/f31 || error "touch $DIR/f31 failed"
3624         ln $DIR/f31 $DIR/f31b || error "ln failed"
3625         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3626         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3627 }
3628 run_test 31b "unlink file with multiple links while open ======="
3629
3630 test_31c() {
3631         touch $DIR/f31 || error "touch $DIR/f31 failed"
3632         ln $DIR/f31 $DIR/f31c || error "ln failed"
3633         multiop_bg_pause $DIR/f31 O_uc ||
3634                 error "multiop_bg_pause for $DIR/f31 failed"
3635         MULTIPID=$!
3636         $MULTIOP $DIR/f31c Ouc
3637         kill -USR1 $MULTIPID
3638         wait $MULTIPID
3639 }
3640 run_test 31c "open-unlink file with multiple links ============="
3641
3642 test_31d() {
3643         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3644         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3645 }
3646 run_test 31d "remove of open directory ========================="
3647
3648 test_31e() { # bug 2904
3649         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3650 }
3651 run_test 31e "remove of open non-empty directory ==============="
3652
3653 test_31f() { # bug 4554
3654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3655
3656         set -vx
3657         test_mkdir $DIR/d31f
3658         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3659         cp /etc/hosts $DIR/d31f
3660         ls -l $DIR/d31f
3661         $LFS getstripe $DIR/d31f/hosts
3662         multiop_bg_pause $DIR/d31f D_c || return 1
3663         MULTIPID=$!
3664
3665         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3666         test_mkdir $DIR/d31f
3667         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3668         cp /etc/hosts $DIR/d31f
3669         ls -l $DIR/d31f
3670         $LFS getstripe $DIR/d31f/hosts
3671         multiop_bg_pause $DIR/d31f D_c || return 1
3672         MULTIPID2=$!
3673
3674         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3675         wait $MULTIPID || error "first opendir $MULTIPID failed"
3676
3677         sleep 6
3678
3679         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3680         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3681         set +vx
3682 }
3683 run_test 31f "remove of open directory with open-unlink file ==="
3684
3685 test_31g() {
3686         echo "-- cross directory link --"
3687         test_mkdir -c1 $DIR/${tdir}ga
3688         test_mkdir -c1 $DIR/${tdir}gb
3689         touch $DIR/${tdir}ga/f
3690         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3691         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3692         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3693         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3694         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3695 }
3696 run_test 31g "cross directory link==============="
3697
3698 test_31h() {
3699         echo "-- cross directory link --"
3700         test_mkdir -c1 $DIR/${tdir}
3701         test_mkdir -c1 $DIR/${tdir}/dir
3702         touch $DIR/${tdir}/f
3703         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3704         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3705         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3706         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3707         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3708 }
3709 run_test 31h "cross directory link under child==============="
3710
3711 test_31i() {
3712         echo "-- cross directory link --"
3713         test_mkdir -c1 $DIR/$tdir
3714         test_mkdir -c1 $DIR/$tdir/dir
3715         touch $DIR/$tdir/dir/f
3716         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3717         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3718         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3719         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3720         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3721 }
3722 run_test 31i "cross directory link under parent==============="
3723
3724 test_31j() {
3725         test_mkdir -c1 -p $DIR/$tdir
3726         test_mkdir -c1 -p $DIR/$tdir/dir1
3727         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3728         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3729         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3730         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3731         return 0
3732 }
3733 run_test 31j "link for directory==============="
3734
3735 test_31k() {
3736         test_mkdir -c1 -p $DIR/$tdir
3737         touch $DIR/$tdir/s
3738         touch $DIR/$tdir/exist
3739         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3740         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3741         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3742         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3743         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3744         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3745         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3746         return 0
3747 }
3748 run_test 31k "link to file: the same, non-existing, dir==============="
3749
3750 test_31l() {
3751         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3752
3753         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3754         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3755                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3756
3757         touch $DIR/$tfile || error "create failed"
3758         mkdir $DIR/$tdir || error "mkdir failed"
3759         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3760 }
3761 run_test 31l "link to file: target dir has trailing slash"
3762
3763 test_31m() {
3764         mkdir $DIR/d31m
3765         touch $DIR/d31m/s
3766         mkdir $DIR/d31m2
3767         touch $DIR/d31m2/exist
3768         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3769         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3770         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3771         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3772         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3773         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3774         return 0
3775 }
3776 run_test 31m "link to file: the same, non-existing, dir==============="
3777
3778 test_31n() {
3779         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3780         nlink=$(stat --format=%h $DIR/$tfile)
3781         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3782         local fd=$(free_fd)
3783         local cmd="exec $fd<$DIR/$tfile"
3784         eval $cmd
3785         cmd="exec $fd<&-"
3786         trap "eval $cmd" EXIT
3787         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3788         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3789         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3790         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3791         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3792         eval $cmd
3793 }
3794 run_test 31n "check link count of unlinked file"
3795
3796 link_one() {
3797         local tempfile=$(mktemp $1_XXXXXX)
3798         mlink $tempfile $1 2> /dev/null &&
3799                 echo "$BASHPID: link $tempfile to $1 succeeded"
3800         munlink $tempfile
3801 }
3802
3803 test_31o() { # LU-2901
3804         test_mkdir $DIR/$tdir
3805         for LOOP in $(seq 100); do
3806                 rm -f $DIR/$tdir/$tfile*
3807                 for THREAD in $(seq 8); do
3808                         link_one $DIR/$tdir/$tfile.$LOOP &
3809                 done
3810                 wait
3811                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3812                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3813                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3814                         break || true
3815         done
3816 }
3817 run_test 31o "duplicate hard links with same filename"
3818
3819 test_31p() {
3820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3821
3822         test_mkdir $DIR/$tdir
3823         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3824         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3825
3826         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3827                 error "open unlink test1 failed"
3828         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3829                 error "open unlink test2 failed"
3830
3831         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3832                 error "test1 still exists"
3833         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3834                 error "test2 still exists"
3835 }
3836 run_test 31p "remove of open striped directory"
3837
3838 test_31q() {
3839         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3840
3841         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3842         index=$($LFS getdirstripe -i $DIR/$tdir)
3843         [ $index -eq 3 ] || error "first stripe index $index != 3"
3844         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3845         [ $index -eq 1 ] || error "second stripe index $index != 1"
3846
3847         # when "-c <stripe_count>" is set, the number of MDTs specified after
3848         # "-i" should equal to the stripe count
3849         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3850 }
3851 run_test 31q "create striped directory on specific MDTs"
3852
3853 #LU-14949
3854 test_31r() {
3855         touch $DIR/$tfile.target
3856         touch $DIR/$tfile.source
3857
3858         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3859         $LCTL set_param fail_loc=0x1419 fail_val=3
3860         cat $DIR/$tfile.target &
3861         CATPID=$!
3862
3863         # Guarantee open is waiting before we get here
3864         sleep 1
3865         mv $DIR/$tfile.source $DIR/$tfile.target
3866
3867         wait $CATPID
3868         RC=$?
3869         if [[ $RC -ne 0 ]]; then
3870                 error "open with cat failed, rc=$RC"
3871         fi
3872 }
3873 run_test 31r "open-rename(replace) race"
3874
3875 cleanup_test32_mount() {
3876         local rc=0
3877         trap 0
3878         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3879         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3880         losetup -d $loopdev || true
3881         rm -rf $DIR/$tdir
3882         return $rc
3883 }
3884
3885 test_32a() {
3886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3887
3888         echo "== more mountpoints and symlinks ================="
3889         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3890         trap cleanup_test32_mount EXIT
3891         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3892         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3893                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3894         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3895                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3896         cleanup_test32_mount
3897 }
3898 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3899
3900 test_32b() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3909                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3910         cleanup_test32_mount
3911 }
3912 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3913
3914 test_32c() {
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3918         trap cleanup_test32_mount EXIT
3919         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3920         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3921                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3922         test_mkdir -p $DIR/$tdir/d2/test_dir
3923         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3924                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3925         cleanup_test32_mount
3926 }
3927 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3928
3929 test_32d() {
3930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3931
3932         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3933         trap cleanup_test32_mount EXIT
3934         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3935         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3936                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3937         test_mkdir -p $DIR/$tdir/d2/test_dir
3938         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3939                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3940         cleanup_test32_mount
3941 }
3942 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3943
3944 test_32e() {
3945         rm -fr $DIR/$tdir
3946         test_mkdir -p $DIR/$tdir/tmp
3947         local tmp_dir=$DIR/$tdir/tmp
3948         ln -s $DIR/$tdir $tmp_dir/symlink11
3949         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3950         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3951         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3952 }
3953 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3954
3955 test_32f() {
3956         rm -fr $DIR/$tdir
3957         test_mkdir -p $DIR/$tdir/tmp
3958         local tmp_dir=$DIR/$tdir/tmp
3959         ln -s $DIR/$tdir $tmp_dir/symlink11
3960         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3961         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3962         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3963 }
3964 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3965
3966 test_32g() {
3967         local tmp_dir=$DIR/$tdir/tmp
3968         test_mkdir -p $tmp_dir
3969         test_mkdir $DIR/${tdir}2
3970         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3971         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3972         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3973         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3974         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3975         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3976 }
3977 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3978
3979 test_32h() {
3980         rm -fr $DIR/$tdir $DIR/${tdir}2
3981         tmp_dir=$DIR/$tdir/tmp
3982         test_mkdir -p $tmp_dir
3983         test_mkdir $DIR/${tdir}2
3984         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3985         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3986         ls $tmp_dir/symlink12 || error "listing symlink12"
3987         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3988 }
3989 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3990
3991 test_32i() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3995         trap cleanup_test32_mount EXIT
3996         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3997         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3998                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3999         touch $DIR/$tdir/test_file
4000         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4001                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4002         cleanup_test32_mount
4003 }
4004 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4005
4006 test_32j() {
4007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4008
4009         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4010         trap cleanup_test32_mount EXIT
4011         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4012         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4013                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4014         touch $DIR/$tdir/test_file
4015         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4016                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4017         cleanup_test32_mount
4018 }
4019 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4020
4021 test_32k() {
4022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4023
4024         rm -fr $DIR/$tdir
4025         trap cleanup_test32_mount EXIT
4026         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4027         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4028                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4029         test_mkdir -p $DIR/$tdir/d2
4030         touch $DIR/$tdir/d2/test_file || error "touch failed"
4031         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4032                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4033         cleanup_test32_mount
4034 }
4035 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4036
4037 test_32l() {
4038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4039
4040         rm -fr $DIR/$tdir
4041         trap cleanup_test32_mount EXIT
4042         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4043         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4044                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4045         test_mkdir -p $DIR/$tdir/d2
4046         touch $DIR/$tdir/d2/test_file || error "touch failed"
4047         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4048                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4049         cleanup_test32_mount
4050 }
4051 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4052
4053 test_32m() {
4054         rm -fr $DIR/d32m
4055         test_mkdir -p $DIR/d32m/tmp
4056         TMP_DIR=$DIR/d32m/tmp
4057         ln -s $DIR $TMP_DIR/symlink11
4058         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4059         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4060                 error "symlink11 not a link"
4061         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4062                 error "symlink01 not a link"
4063 }
4064 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4065
4066 test_32n() {
4067         rm -fr $DIR/d32n
4068         test_mkdir -p $DIR/d32n/tmp
4069         TMP_DIR=$DIR/d32n/tmp
4070         ln -s $DIR $TMP_DIR/symlink11
4071         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4072         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4073         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4074 }
4075 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4076
4077 test_32o() {
4078         touch $DIR/$tfile
4079         test_mkdir -p $DIR/d32o/tmp
4080         TMP_DIR=$DIR/d32o/tmp
4081         ln -s $DIR/$tfile $TMP_DIR/symlink12
4082         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4083         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4084                 error "symlink12 not a link"
4085         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4086         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4087                 error "$DIR/d32o/tmp/symlink12 not file type"
4088         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4089                 error "$DIR/d32o/symlink02 not file type"
4090 }
4091 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4092
4093 test_32p() {
4094         log 32p_1
4095         rm -fr $DIR/d32p
4096         log 32p_2
4097         rm -f $DIR/$tfile
4098         log 32p_3
4099         touch $DIR/$tfile
4100         log 32p_4
4101         test_mkdir -p $DIR/d32p/tmp
4102         log 32p_5
4103         TMP_DIR=$DIR/d32p/tmp
4104         log 32p_6
4105         ln -s $DIR/$tfile $TMP_DIR/symlink12
4106         log 32p_7
4107         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4108         log 32p_8
4109         cat $DIR/d32p/tmp/symlink12 ||
4110                 error "Can't open $DIR/d32p/tmp/symlink12"
4111         log 32p_9
4112         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4113         log 32p_10
4114 }
4115 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4116
4117 test_32q() {
4118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4119
4120         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4121         trap cleanup_test32_mount EXIT
4122         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4123         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4124         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4125                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4126         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4127         cleanup_test32_mount
4128 }
4129 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4130
4131 test_32r() {
4132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4133
4134         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4135         trap cleanup_test32_mount EXIT
4136         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4137         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4138         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4139                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4140         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4141         cleanup_test32_mount
4142 }
4143 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4144
4145 test_33aa() {
4146         rm -f $DIR/$tfile
4147         touch $DIR/$tfile
4148         chmod 444 $DIR/$tfile
4149         chown $RUNAS_ID $DIR/$tfile
4150         log 33_1
4151         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4152         log 33_2
4153 }
4154 run_test 33aa "write file with mode 444 (should return error)"
4155
4156 test_33a() {
4157         rm -fr $DIR/$tdir
4158         test_mkdir $DIR/$tdir
4159         chown $RUNAS_ID $DIR/$tdir
4160         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4161                 error "$RUNAS create $tdir/$tfile failed"
4162         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4163                 error "open RDWR" || true
4164 }
4165 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4166
4167 test_33b() {
4168         rm -fr $DIR/$tdir
4169         test_mkdir $DIR/$tdir
4170         chown $RUNAS_ID $DIR/$tdir
4171         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4172 }
4173 run_test 33b "test open file with malformed flags (No panic)"
4174
4175 test_33c() {
4176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4177         remote_ost_nodsh && skip "remote OST with nodsh"
4178
4179         local ostnum
4180         local ostname
4181         local write_bytes
4182         local all_zeros
4183
4184         all_zeros=true
4185         test_mkdir $DIR/$tdir
4186         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4187
4188         sync
4189         for ostnum in $(seq $OSTCOUNT); do
4190                 # test-framework's OST numbering is one-based, while Lustre's
4191                 # is zero-based
4192                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4193                 # check if at least some write_bytes stats are counted
4194                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4195                               obdfilter.$ostname.stats |
4196                               awk '/^write_bytes/ {print $7}' )
4197                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4198                 if (( ${write_bytes:-0} > 0 )); then
4199                         all_zeros=false
4200                         break
4201                 fi
4202         done
4203
4204         $all_zeros || return 0
4205
4206         # Write four bytes
4207         echo foo > $DIR/$tdir/bar
4208         # Really write them
4209         sync
4210
4211         # Total up write_bytes after writing.  We'd better find non-zeros.
4212         for ostnum in $(seq $OSTCOUNT); do
4213                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4214                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4215                               obdfilter/$ostname/stats |
4216                               awk '/^write_bytes/ {print $7}' )
4217                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4218                 if (( ${write_bytes:-0} > 0 )); then
4219                         all_zeros=false
4220                         break
4221                 fi
4222         done
4223
4224         if $all_zeros; then
4225                 for ostnum in $(seq $OSTCOUNT); do
4226                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4227                         echo "Check write_bytes is in obdfilter.*.stats:"
4228                         do_facet ost$ostnum lctl get_param -n \
4229                                 obdfilter.$ostname.stats
4230                 done
4231                 error "OST not keeping write_bytes stats (b=22312)"
4232         fi
4233 }
4234 run_test 33c "test write_bytes stats"
4235
4236 test_33d() {
4237         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4239
4240         local MDTIDX=1
4241         local remote_dir=$DIR/$tdir/remote_dir
4242
4243         test_mkdir $DIR/$tdir
4244         $LFS mkdir -i $MDTIDX $remote_dir ||
4245                 error "create remote directory failed"
4246
4247         touch $remote_dir/$tfile
4248         chmod 444 $remote_dir/$tfile
4249         chown $RUNAS_ID $remote_dir/$tfile
4250
4251         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4252
4253         chown $RUNAS_ID $remote_dir
4254         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4255                                         error "create" || true
4256         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4257                                     error "open RDWR" || true
4258         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4259 }
4260 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4261
4262 test_33e() {
4263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4264
4265         mkdir $DIR/$tdir
4266
4267         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4268         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4269         mkdir $DIR/$tdir/local_dir
4270
4271         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4272         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4273         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4274
4275         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4276                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4277
4278         rmdir $DIR/$tdir/* || error "rmdir failed"
4279
4280         umask 777
4281         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4282         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4283         mkdir $DIR/$tdir/local_dir
4284
4285         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4286         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4287         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4288
4289         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4290                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4291
4292         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4293
4294         umask 000
4295         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4296         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4297         mkdir $DIR/$tdir/local_dir
4298
4299         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4300         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4301         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4302
4303         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4304                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4305 }
4306 run_test 33e "mkdir and striped directory should have same mode"
4307
4308 cleanup_33f() {
4309         trap 0
4310         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4311 }
4312
4313 test_33f() {
4314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4315         remote_mds_nodsh && skip "remote MDS with nodsh"
4316
4317         mkdir $DIR/$tdir
4318         chmod go+rwx $DIR/$tdir
4319         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4320         trap cleanup_33f EXIT
4321
4322         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4323                 error "cannot create striped directory"
4324
4325         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4326                 error "cannot create files in striped directory"
4327
4328         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4329                 error "cannot remove files in striped directory"
4330
4331         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4332                 error "cannot remove striped directory"
4333
4334         cleanup_33f
4335 }
4336 run_test 33f "nonroot user can create, access, and remove a striped directory"
4337
4338 test_33g() {
4339         mkdir -p $DIR/$tdir/dir2
4340
4341         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4342         echo $err
4343         [[ $err =~ "exists" ]] || error "Not exists error"
4344 }
4345 run_test 33g "nonroot user create already existing root created file"
4346
4347 sub_33h() {
4348         local hash_type=$1
4349         local count=250
4350
4351         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4352                 error "lfs mkdir -H $hash_type $tdir failed"
4353         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4354
4355         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4356         local index2
4357         local fname
4358
4359         for fname in $DIR/$tdir/$tfile.bak \
4360                      $DIR/$tdir/$tfile.SAV \
4361                      $DIR/$tdir/$tfile.orig \
4362                      $DIR/$tdir/$tfile~; do
4363                 touch $fname || error "touch $fname failed"
4364                 index2=$($LFS getstripe -m $fname)
4365                 (( $index == $index2 )) ||
4366                         error "$fname MDT index mismatch $index != $index2"
4367         done
4368
4369         local failed=0
4370         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4371         local pattern
4372
4373         for pattern in ${patterns[*]}; do
4374                 echo "pattern $pattern"
4375                 fname=$DIR/$tdir/$pattern
4376                 for (( i = 0; i < $count; i++ )); do
4377                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4378                                 error "mktemp $DIR/$tdir/$pattern failed"
4379                         index2=$($LFS getstripe -m $fname)
4380                         (( $index == $index2 )) && continue
4381
4382                         failed=$((failed + 1))
4383                         echo "$fname MDT index mismatch $index != $index2"
4384                 done
4385         done
4386
4387         echo "$failed/$count MDT index mismatches, expect ~2-4"
4388         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4389
4390         local same=0
4391         local expect
4392
4393         # verify that "crush" is still broken with all files on same MDT,
4394         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4395         [[ "$hash_type" == "crush" ]] && expect=$count ||
4396                 expect=$((count / MDSCOUNT))
4397
4398         # crush2 doesn't put all-numeric suffixes on the same MDT,
4399         # filename like $tfile.12345678 should *not* be considered temp
4400         for pattern in ${patterns[*]}; do
4401                 local base=${pattern%%X*}
4402                 local suff=${pattern#$base}
4403
4404                 echo "pattern $pattern"
4405                 for (( i = 0; i < $count; i++ )); do
4406                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4407                         touch $fname || error "touch $fname failed"
4408                         index2=$($LFS getstripe -m $fname)
4409                         (( $index != $index2 )) && continue
4410
4411                         same=$((same + 1))
4412                 done
4413         done
4414
4415         # the number of "bad" hashes is random, as it depends on the random
4416         # filenames generated by "mktemp".  Allow some margin in the results.
4417         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4418         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4419            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4420                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4421         same=0
4422
4423         # crush2 doesn't put suffixes with special characters on the same MDT
4424         # filename like $tfile.txt.1234 should *not* be considered temp
4425         for pattern in ${patterns[*]}; do
4426                 local base=${pattern%%X*}
4427                 local suff=${pattern#$base}
4428
4429                 pattern=$base...${suff/XXX}
4430                 echo "pattern=$pattern"
4431                 for (( i = 0; i < $count; i++ )); do
4432                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4433                                 error "touch $fname failed"
4434                         index2=$($LFS getstripe -m $fname)
4435                         (( $index != $index2 )) && continue
4436
4437                         same=$((same + 1))
4438                 done
4439         done
4440
4441         # the number of "bad" hashes is random, as it depends on the random
4442         # filenames generated by "mktemp".  Allow some margin in the results.
4443         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4444         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4445            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4446                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4447 }
4448
4449 test_33h() {
4450         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4451         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4452                 skip "Need MDS version at least 2.13.50"
4453
4454         sub_33h crush
4455 }
4456 run_test 33h "temp file is located on the same MDT as target (crush)"
4457
4458 test_33hh() {
4459         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4460         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4461         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4462                 skip "Need MDS version at least 2.15.0 for crush2"
4463
4464         sub_33h crush2
4465 }
4466 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4467
4468 test_33i()
4469 {
4470         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4471
4472         local FNAME=$(str_repeat 'f' 250)
4473
4474         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4475         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4476
4477         local count
4478         local total
4479
4480         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4481
4482         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4483
4484         lctl --device %$MDC deactivate
4485         stack_trap "lctl --device %$MDC activate"
4486         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4487         total=$(\ls -l $DIR/$tdir | wc -l)
4488         # "ls -l" will list total in the first line
4489         total=$((total - 1))
4490         (( total + count == 1000 )) ||
4491                 error "ls list $total files, $count files on MDT1"
4492 }
4493 run_test 33i "striped directory can be accessed when one MDT is down"
4494
4495 test_33j() {
4496         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4497
4498         mkdir -p $DIR/$tdir/
4499
4500         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4501                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4502
4503         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4504                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4505
4506         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4507                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4508
4509         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4510                 error "-D was not specified, but still failed"
4511 }
4512 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4513
4514 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4515 test_34a() {
4516         rm -f $DIR/f34
4517         $MCREATE $DIR/f34 || error "mcreate failed"
4518         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4519                 error "getstripe failed"
4520         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4521         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4522                 error "getstripe failed"
4523         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4524                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4525 }
4526 run_test 34a "truncate file that has not been opened ==========="
4527
4528 test_34b() {
4529         [ ! -f $DIR/f34 ] && test_34a
4530         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4531                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4532         $OPENFILE -f O_RDONLY $DIR/f34
4533         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4534                 error "getstripe failed"
4535         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4536                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4537 }
4538 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4539
4540 test_34c() {
4541         [ ! -f $DIR/f34 ] && test_34a
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4543                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4544         $OPENFILE -f O_RDWR $DIR/f34
4545         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4546                 error "$LFS getstripe failed"
4547         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4548                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4549 }
4550 run_test 34c "O_RDWR opening file-with-size works =============="
4551
4552 test_34d() {
4553         [ ! -f $DIR/f34 ] && test_34a
4554         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4555                 error "dd failed"
4556         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4557                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4558         rm $DIR/f34
4559 }
4560 run_test 34d "write to sparse file ============================="
4561
4562 test_34e() {
4563         rm -f $DIR/f34e
4564         $MCREATE $DIR/f34e || error "mcreate failed"
4565         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4566         $CHECKSTAT -s 1000 $DIR/f34e ||
4567                 error "Size of $DIR/f34e not equal to 1000 bytes"
4568         $OPENFILE -f O_RDWR $DIR/f34e
4569         $CHECKSTAT -s 1000 $DIR/f34e ||
4570                 error "Size of $DIR/f34e not equal to 1000 bytes"
4571 }
4572 run_test 34e "create objects, some with size and some without =="
4573
4574 test_34f() { # bug 6242, 6243
4575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4576
4577         SIZE34F=48000
4578         rm -f $DIR/f34f
4579         $MCREATE $DIR/f34f || error "mcreate failed"
4580         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4581         dd if=$DIR/f34f of=$TMP/f34f
4582         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4583         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4584         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4585         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4586         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4587 }
4588 run_test 34f "read from a file with no objects until EOF ======="
4589
4590 test_34g() {
4591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4592
4593         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4594                 error "dd failed"
4595         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4596         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4597                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4598         cancel_lru_locks osc
4599         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4600                 error "wrong size after lock cancel"
4601
4602         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4603         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4604                 error "expanding truncate failed"
4605         cancel_lru_locks osc
4606         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4607                 error "wrong expanded size after lock cancel"
4608 }
4609 run_test 34g "truncate long file ==============================="
4610
4611 test_34h() {
4612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4613
4614         local gid=10
4615         local sz=1000
4616
4617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4618         sync # Flush the cache so that multiop below does not block on cache
4619              # flush when getting the group lock
4620         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4621         MULTIPID=$!
4622
4623         # Since just timed wait is not good enough, let's do a sync write
4624         # that way we are sure enough time for a roundtrip + processing
4625         # passed + 2 seconds of extra margin.
4626         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4627         rm $DIR/${tfile}-1
4628         sleep 2
4629
4630         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4631                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4632                 kill -9 $MULTIPID
4633         fi
4634         wait $MULTIPID
4635         local nsz=`stat -c %s $DIR/$tfile`
4636         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4637 }
4638 run_test 34h "ftruncate file under grouplock should not block"
4639
4640 test_35a() {
4641         cp /bin/sh $DIR/f35a
4642         chmod 444 $DIR/f35a
4643         chown $RUNAS_ID $DIR/f35a
4644         $RUNAS $DIR/f35a && error || true
4645         rm $DIR/f35a
4646 }
4647 run_test 35a "exec file with mode 444 (should return and not leak)"
4648
4649 test_36a() {
4650         rm -f $DIR/f36
4651         utime $DIR/f36 || error "utime failed for MDS"
4652 }
4653 run_test 36a "MDS utime check (mknod, utime)"
4654
4655 test_36b() {
4656         echo "" > $DIR/f36
4657         utime $DIR/f36 || error "utime failed for OST"
4658 }
4659 run_test 36b "OST utime check (open, utime)"
4660
4661 test_36c() {
4662         rm -f $DIR/d36/f36
4663         test_mkdir $DIR/d36
4664         chown $RUNAS_ID $DIR/d36
4665         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4666 }
4667 run_test 36c "non-root MDS utime check (mknod, utime)"
4668
4669 test_36d() {
4670         [ ! -d $DIR/d36 ] && test_36c
4671         echo "" > $DIR/d36/f36
4672         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4673 }
4674 run_test 36d "non-root OST utime check (open, utime)"
4675
4676 test_36e() {
4677         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4678
4679         test_mkdir $DIR/$tdir
4680         touch $DIR/$tdir/$tfile
4681         $RUNAS utime $DIR/$tdir/$tfile &&
4682                 error "utime worked, expected failure" || true
4683 }
4684 run_test 36e "utime on non-owned file (should return error)"
4685
4686 subr_36fh() {
4687         local fl="$1"
4688         local LANG_SAVE=$LANG
4689         local LC_LANG_SAVE=$LC_LANG
4690         export LANG=C LC_LANG=C # for date language
4691
4692         DATESTR="Dec 20  2000"
4693         test_mkdir $DIR/$tdir
4694         lctl set_param fail_loc=$fl
4695         date; date +%s
4696         cp /etc/hosts $DIR/$tdir/$tfile
4697         sync & # write RPC generated with "current" inode timestamp, but delayed
4698         sleep 1
4699         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4700         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4701         cancel_lru_locks $OSC
4702         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4703         date; date +%s
4704         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4705                 echo "BEFORE: $LS_BEFORE" && \
4706                 echo "AFTER : $LS_AFTER" && \
4707                 echo "WANT  : $DATESTR" && \
4708                 error "$DIR/$tdir/$tfile timestamps changed" || true
4709
4710         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4711 }
4712
4713 test_36f() {
4714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4715
4716         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4717         subr_36fh "0x80000214"
4718 }
4719 run_test 36f "utime on file racing with OST BRW write =========="
4720
4721 test_36g() {
4722         remote_ost_nodsh && skip "remote OST with nodsh"
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4725                 skip "Need MDS version at least 2.12.51"
4726
4727         local fmd_max_age
4728         local fmd
4729         local facet="ost1"
4730         local tgt="obdfilter"
4731
4732         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4733
4734         test_mkdir $DIR/$tdir
4735         fmd_max_age=$(do_facet $facet \
4736                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4737                 head -n 1")
4738
4739         echo "FMD max age: ${fmd_max_age}s"
4740         touch $DIR/$tdir/$tfile
4741         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4742                 gawk '{cnt=cnt+$1}  END{print cnt}')
4743         echo "FMD before: $fmd"
4744         [[ $fmd == 0 ]] &&
4745                 error "FMD wasn't create by touch"
4746         sleep $((fmd_max_age + 12))
4747         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4748                 gawk '{cnt=cnt+$1}  END{print cnt}')
4749         echo "FMD after: $fmd"
4750         [[ $fmd == 0 ]] ||
4751                 error "FMD wasn't expired by ping"
4752 }
4753 run_test 36g "FMD cache expiry ====================="
4754
4755 test_36h() {
4756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4757
4758         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4759         subr_36fh "0x80000227"
4760 }
4761 run_test 36h "utime on file racing with OST BRW write =========="
4762
4763 test_36i() {
4764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4765
4766         test_mkdir $DIR/$tdir
4767         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4768
4769         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4770         local new_mtime=$((mtime + 200))
4771
4772         #change Modify time of striped dir
4773         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4774                         error "change mtime failed"
4775
4776         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4777
4778         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4779 }
4780 run_test 36i "change mtime on striped directory"
4781
4782 # test_37 - duplicate with tests 32q 32r
4783
4784 test_38() {
4785         local file=$DIR/$tfile
4786         touch $file
4787         openfile -f O_DIRECTORY $file
4788         local RC=$?
4789         local ENOTDIR=20
4790         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4791         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4792 }
4793 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4794
4795 test_39a() { # was test_39
4796         touch $DIR/$tfile
4797         touch $DIR/${tfile}2
4798 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4799 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4800 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4801         sleep 2
4802         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4803         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4804                 echo "mtime"
4805                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4806                 echo "atime"
4807                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4808                 echo "ctime"
4809                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4810                 error "O_TRUNC didn't change timestamps"
4811         fi
4812 }
4813 run_test 39a "mtime changed on create"
4814
4815 test_39b() {
4816         test_mkdir -c1 $DIR/$tdir
4817         cp -p /etc/passwd $DIR/$tdir/fopen
4818         cp -p /etc/passwd $DIR/$tdir/flink
4819         cp -p /etc/passwd $DIR/$tdir/funlink
4820         cp -p /etc/passwd $DIR/$tdir/frename
4821         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4822
4823         sleep 1
4824         echo "aaaaaa" >> $DIR/$tdir/fopen
4825         echo "aaaaaa" >> $DIR/$tdir/flink
4826         echo "aaaaaa" >> $DIR/$tdir/funlink
4827         echo "aaaaaa" >> $DIR/$tdir/frename
4828
4829         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4830         local link_new=`stat -c %Y $DIR/$tdir/flink`
4831         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4832         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4833
4834         cat $DIR/$tdir/fopen > /dev/null
4835         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4836         rm -f $DIR/$tdir/funlink2
4837         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4838
4839         for (( i=0; i < 2; i++ )) ; do
4840                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4841                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4842                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4843                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4844
4845                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4846                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4847                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4848                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4849
4850                 cancel_lru_locks $OSC
4851                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4852         done
4853 }
4854 run_test 39b "mtime change on open, link, unlink, rename  ======"
4855
4856 # this should be set to past
4857 TEST_39_MTIME=`date -d "1 year ago" +%s`
4858
4859 # bug 11063
4860 test_39c() {
4861         touch $DIR1/$tfile
4862         sleep 2
4863         local mtime0=`stat -c %Y $DIR1/$tfile`
4864
4865         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4866         local mtime1=`stat -c %Y $DIR1/$tfile`
4867         [ "$mtime1" = $TEST_39_MTIME ] || \
4868                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4869
4870         local d1=`date +%s`
4871         echo hello >> $DIR1/$tfile
4872         local d2=`date +%s`
4873         local mtime2=`stat -c %Y $DIR1/$tfile`
4874         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4875                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4876
4877         mv $DIR1/$tfile $DIR1/$tfile-1
4878
4879         for (( i=0; i < 2; i++ )) ; do
4880                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4881                 [ "$mtime2" = "$mtime3" ] || \
4882                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4883
4884                 cancel_lru_locks $OSC
4885                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4886         done
4887 }
4888 run_test 39c "mtime change on rename ==========================="
4889
4890 # bug 21114
4891 test_39d() {
4892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4893
4894         touch $DIR1/$tfile
4895         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4896
4897         for (( i=0; i < 2; i++ )) ; do
4898                 local mtime=`stat -c %Y $DIR1/$tfile`
4899                 [ $mtime = $TEST_39_MTIME ] || \
4900                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4901
4902                 cancel_lru_locks $OSC
4903                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4904         done
4905 }
4906 run_test 39d "create, utime, stat =============================="
4907
4908 # bug 21114
4909 test_39e() {
4910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4911
4912         touch $DIR1/$tfile
4913         local mtime1=`stat -c %Y $DIR1/$tfile`
4914
4915         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4916
4917         for (( i=0; i < 2; i++ )) ; do
4918                 local mtime2=`stat -c %Y $DIR1/$tfile`
4919                 [ $mtime2 = $TEST_39_MTIME ] || \
4920                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4921
4922                 cancel_lru_locks $OSC
4923                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4924         done
4925 }
4926 run_test 39e "create, stat, utime, stat ========================"
4927
4928 # bug 21114
4929 test_39f() {
4930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4931
4932         touch $DIR1/$tfile
4933         mtime1=`stat -c %Y $DIR1/$tfile`
4934
4935         sleep 2
4936         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4937
4938         for (( i=0; i < 2; i++ )) ; do
4939                 local mtime2=`stat -c %Y $DIR1/$tfile`
4940                 [ $mtime2 = $TEST_39_MTIME ] || \
4941                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39f "create, stat, sleep, utime, stat ================="
4948
4949 # bug 11063
4950 test_39g() {
4951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4952
4953         echo hello >> $DIR1/$tfile
4954         local mtime1=`stat -c %Y $DIR1/$tfile`
4955
4956         sleep 2
4957         chmod o+r $DIR1/$tfile
4958
4959         for (( i=0; i < 2; i++ )) ; do
4960                 local mtime2=`stat -c %Y $DIR1/$tfile`
4961                 [ "$mtime1" = "$mtime2" ] || \
4962                         error "lost mtime: $mtime2, should be $mtime1"
4963
4964                 cancel_lru_locks $OSC
4965                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4966         done
4967 }
4968 run_test 39g "write, chmod, stat ==============================="
4969
4970 # bug 11063
4971 test_39h() {
4972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4973
4974         touch $DIR1/$tfile
4975         sleep 1
4976
4977         local d1=`date`
4978         echo hello >> $DIR1/$tfile
4979         local mtime1=`stat -c %Y $DIR1/$tfile`
4980
4981         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4982         local d2=`date`
4983         if [ "$d1" != "$d2" ]; then
4984                 echo "write and touch not within one second"
4985         else
4986                 for (( i=0; i < 2; i++ )) ; do
4987                         local mtime2=`stat -c %Y $DIR1/$tfile`
4988                         [ "$mtime2" = $TEST_39_MTIME ] || \
4989                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4990
4991                         cancel_lru_locks $OSC
4992                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4993                 done
4994         fi
4995 }
4996 run_test 39h "write, utime within one second, stat ============="
4997
4998 test_39i() {
4999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5000
5001         touch $DIR1/$tfile
5002         sleep 1
5003
5004         echo hello >> $DIR1/$tfile
5005         local mtime1=`stat -c %Y $DIR1/$tfile`
5006
5007         mv $DIR1/$tfile $DIR1/$tfile-1
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5011
5012                 [ "$mtime1" = "$mtime2" ] || \
5013                         error "lost mtime: $mtime2, should be $mtime1"
5014
5015                 cancel_lru_locks $OSC
5016                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5017         done
5018 }
5019 run_test 39i "write, rename, stat =============================="
5020
5021 test_39j() {
5022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5023
5024         start_full_debug_logging
5025         touch $DIR1/$tfile
5026         sleep 1
5027
5028         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5029         lctl set_param fail_loc=0x80000412
5030         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5031                 error "multiop failed"
5032         local multipid=$!
5033         local mtime1=`stat -c %Y $DIR1/$tfile`
5034
5035         mv $DIR1/$tfile $DIR1/$tfile-1
5036
5037         kill -USR1 $multipid
5038         wait $multipid || error "multiop close failed"
5039
5040         for (( i=0; i < 2; i++ )) ; do
5041                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5042                 [ "$mtime1" = "$mtime2" ] ||
5043                         error "mtime is lost on close: $mtime2, " \
5044                               "should be $mtime1"
5045
5046                 cancel_lru_locks
5047                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5048         done
5049         lctl set_param fail_loc=0
5050         stop_full_debug_logging
5051 }
5052 run_test 39j "write, rename, close, stat ======================="
5053
5054 test_39k() {
5055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5056
5057         touch $DIR1/$tfile
5058         sleep 1
5059
5060         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5061         local multipid=$!
5062         local mtime1=`stat -c %Y $DIR1/$tfile`
5063
5064         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5065
5066         kill -USR1 $multipid
5067         wait $multipid || error "multiop close failed"
5068
5069         for (( i=0; i < 2; i++ )) ; do
5070                 local mtime2=`stat -c %Y $DIR1/$tfile`
5071
5072                 [ "$mtime2" = $TEST_39_MTIME ] || \
5073                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5074
5075                 cancel_lru_locks
5076                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5077         done
5078 }
5079 run_test 39k "write, utime, close, stat ========================"
5080
5081 # this should be set to future
5082 TEST_39_ATIME=`date -d "1 year" +%s`
5083
5084 test_39l() {
5085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5086         remote_mds_nodsh && skip "remote MDS with nodsh"
5087
5088         local atime_diff=$(do_facet $SINGLEMDS \
5089                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5090         rm -rf $DIR/$tdir
5091         mkdir_on_mdt0 $DIR/$tdir
5092
5093         # test setting directory atime to future
5094         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5095         local atime=$(stat -c %X $DIR/$tdir)
5096         [ "$atime" = $TEST_39_ATIME ] ||
5097                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5098
5099         # test setting directory atime from future to now
5100         local now=$(date +%s)
5101         touch -a -d @$now $DIR/$tdir
5102
5103         atime=$(stat -c %X $DIR/$tdir)
5104         [ "$atime" -eq "$now"  ] ||
5105                 error "atime is not updated from future: $atime, $now"
5106
5107         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5108         sleep 3
5109
5110         # test setting directory atime when now > dir atime + atime_diff
5111         local d1=$(date +%s)
5112         ls $DIR/$tdir
5113         local d2=$(date +%s)
5114         cancel_lru_locks mdc
5115         atime=$(stat -c %X $DIR/$tdir)
5116         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5117                 error "atime is not updated  : $atime, should be $d2"
5118
5119         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5120         sleep 3
5121
5122         # test not setting directory atime when now < dir atime + atime_diff
5123         ls $DIR/$tdir
5124         cancel_lru_locks mdc
5125         atime=$(stat -c %X $DIR/$tdir)
5126         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5127                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5128
5129         do_facet $SINGLEMDS \
5130                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5131 }
5132 run_test 39l "directory atime update ==========================="
5133
5134 test_39m() {
5135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5136
5137         touch $DIR1/$tfile
5138         sleep 2
5139         local far_past_mtime=$(date -d "May 29 1953" +%s)
5140         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5141
5142         touch -m -d @$far_past_mtime $DIR1/$tfile
5143         touch -a -d @$far_past_atime $DIR1/$tfile
5144
5145         for (( i=0; i < 2; i++ )) ; do
5146                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5147                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5148                         error "atime or mtime set incorrectly"
5149
5150                 cancel_lru_locks $OSC
5151                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5152         done
5153 }
5154 run_test 39m "test atime and mtime before 1970"
5155
5156 test_39n() { # LU-3832
5157         remote_mds_nodsh && skip "remote MDS with nodsh"
5158
5159         local atime_diff=$(do_facet $SINGLEMDS \
5160                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5161         local atime0
5162         local atime1
5163         local atime2
5164
5165         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5166
5167         rm -rf $DIR/$tfile
5168         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5169         atime0=$(stat -c %X $DIR/$tfile)
5170
5171         sleep 5
5172         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5173         atime1=$(stat -c %X $DIR/$tfile)
5174
5175         sleep 5
5176         cancel_lru_locks mdc
5177         cancel_lru_locks osc
5178         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5179         atime2=$(stat -c %X $DIR/$tfile)
5180
5181         do_facet $SINGLEMDS \
5182                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5183
5184         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5185         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5186 }
5187 run_test 39n "check that O_NOATIME is honored"
5188
5189 test_39o() {
5190         TESTDIR=$DIR/$tdir/$tfile
5191         [ -e $TESTDIR ] && rm -rf $TESTDIR
5192         mkdir -p $TESTDIR
5193         cd $TESTDIR
5194         links1=2
5195         ls
5196         mkdir a b
5197         ls
5198         links2=$(stat -c %h .)
5199         [ $(($links1 + 2)) != $links2 ] &&
5200                 error "wrong links count $(($links1 + 2)) != $links2"
5201         rmdir b
5202         links3=$(stat -c %h .)
5203         [ $(($links1 + 1)) != $links3 ] &&
5204                 error "wrong links count $links1 != $links3"
5205         return 0
5206 }
5207 run_test 39o "directory cached attributes updated after create"
5208
5209 test_39p() {
5210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5211
5212         local MDTIDX=1
5213         TESTDIR=$DIR/$tdir/$tdir
5214         [ -e $TESTDIR ] && rm -rf $TESTDIR
5215         test_mkdir -p $TESTDIR
5216         cd $TESTDIR
5217         links1=2
5218         ls
5219         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5220         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5221         ls
5222         links2=$(stat -c %h .)
5223         [ $(($links1 + 2)) != $links2 ] &&
5224                 error "wrong links count $(($links1 + 2)) != $links2"
5225         rmdir remote_dir2
5226         links3=$(stat -c %h .)
5227         [ $(($links1 + 1)) != $links3 ] &&
5228                 error "wrong links count $links1 != $links3"
5229         return 0
5230 }
5231 run_test 39p "remote directory cached attributes updated after create ========"
5232
5233 test_39r() {
5234         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5235                 skip "no atime update on old OST"
5236         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5237                 skip_env "ldiskfs only test"
5238         fi
5239
5240         local saved_adiff
5241         saved_adiff=$(do_facet ost1 \
5242                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5243         stack_trap "do_facet ost1 \
5244                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5245
5246         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5247
5248         $LFS setstripe -i 0 $DIR/$tfile
5249         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5250                 error "can't write initial file"
5251         cancel_lru_locks osc
5252
5253         # exceed atime_diff and access file
5254         sleep 10
5255         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5256                 error "can't udpate atime"
5257
5258         local atime_cli=$(stat -c %X $DIR/$tfile)
5259         echo "client atime: $atime_cli"
5260         # allow atime update to be written to device
5261         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5262         sleep 5
5263
5264         local ostdev=$(ostdevname 1)
5265         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5266         local seq=${fid[3]#0x}
5267         local oid=${fid[1]}
5268         local oid_hex
5269
5270         if [ $seq == 0 ]; then
5271                 oid_hex=${fid[1]}
5272         else
5273                 oid_hex=${fid[2]#0x}
5274         fi
5275         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5276         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5277
5278         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5279         local atime_ost=$(do_facet ost1 "$cmd" |&
5280                           awk -F'[: ]' '/atime:/ { print $4 }')
5281         (( atime_cli == atime_ost )) ||
5282                 error "atime on client $atime_cli != ost $atime_ost"
5283 }
5284 run_test 39r "lazy atime update on OST"
5285
5286 test_39q() { # LU-8041
5287         local testdir=$DIR/$tdir
5288         mkdir -p $testdir
5289         multiop_bg_pause $testdir D_c || error "multiop failed"
5290         local multipid=$!
5291         cancel_lru_locks mdc
5292         kill -USR1 $multipid
5293         local atime=$(stat -c %X $testdir)
5294         [ "$atime" -ne 0 ] || error "atime is zero"
5295 }
5296 run_test 39q "close won't zero out atime"
5297
5298 test_39s() {
5299         local atime0
5300         local atime1
5301         local atime2
5302         local atime3
5303         local atime4
5304
5305         umount_client $MOUNT
5306         mount_client $MOUNT relatime
5307
5308         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5309         atime0=$(stat -c %X $DIR/$tfile)
5310
5311         # First read updates atime
5312         sleep 1
5313         cat $DIR/$tfile >/dev/null
5314         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5315
5316         # Next reads do not update atime
5317         sleep 1
5318         cat $DIR/$tfile >/dev/null
5319         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5320
5321         # If mtime is greater than atime, atime is updated
5322         sleep 1
5323         touch -m $DIR/$tfile # (mtime = now)
5324         sleep 1
5325         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5326         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5327
5328         # Next reads do not update atime
5329         sleep 1
5330         cat $DIR/$tfile >/dev/null
5331         atime4=$(stat -c %X $DIR/$tfile)
5332
5333         # Remount the client to clear 'relatime' option
5334         remount_client $MOUNT
5335
5336         (( atime0 < atime1 )) ||
5337                 error "atime $atime0 should be smaller than $atime1"
5338         (( atime1 == atime2 )) ||
5339                 error "atime $atime1 was updated to $atime2"
5340         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5341         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5342 }
5343 run_test 39s "relatime is supported"
5344
5345 test_40() {
5346         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5347         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5348                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5349         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5350                 error "$tfile is not 4096 bytes in size"
5351 }
5352 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5353
5354 test_41() {
5355         # bug 1553
5356         small_write $DIR/f41 18
5357 }
5358 run_test 41 "test small file write + fstat ====================="
5359
5360 count_ost_writes() {
5361         lctl get_param -n ${OSC}.*.stats |
5362                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5363                         END { printf("%0.0f", writes) }'
5364 }
5365
5366 # decent default
5367 WRITEBACK_SAVE=500
5368 DIRTY_RATIO_SAVE=40
5369 MAX_DIRTY_RATIO=50
5370 BG_DIRTY_RATIO_SAVE=10
5371 MAX_BG_DIRTY_RATIO=25
5372
5373 start_writeback() {
5374         trap 0
5375         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5376         # dirty_ratio, dirty_background_ratio
5377         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5378                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5379                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5380                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5381         else
5382                 # if file not here, we are a 2.4 kernel
5383                 kill -CONT `pidof kupdated`
5384         fi
5385 }
5386
5387 stop_writeback() {
5388         # setup the trap first, so someone cannot exit the test at the
5389         # exact wrong time and mess up a machine
5390         trap start_writeback EXIT
5391         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5392         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5393                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5394                 sysctl -w vm.dirty_writeback_centisecs=0
5395                 sysctl -w vm.dirty_writeback_centisecs=0
5396                 # save and increase /proc/sys/vm/dirty_ratio
5397                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5398                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5399                 # save and increase /proc/sys/vm/dirty_background_ratio
5400                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5401                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5402         else
5403                 # if file not here, we are a 2.4 kernel
5404                 kill -STOP `pidof kupdated`
5405         fi
5406 }
5407
5408 # ensure that all stripes have some grant before we test client-side cache
5409 setup_test42() {
5410         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5411                 dd if=/dev/zero of=$i bs=4k count=1
5412                 rm $i
5413         done
5414 }
5415
5416 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5417 # file truncation, and file removal.
5418 test_42a() {
5419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5420
5421         setup_test42
5422         cancel_lru_locks $OSC
5423         stop_writeback
5424         sync; sleep 1; sync # just to be safe
5425         BEFOREWRITES=`count_ost_writes`
5426         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5427         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5428         AFTERWRITES=`count_ost_writes`
5429         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5430                 error "$BEFOREWRITES < $AFTERWRITES"
5431         start_writeback
5432 }
5433 run_test 42a "ensure that we don't flush on close"
5434
5435 test_42b() {
5436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5437
5438         setup_test42
5439         cancel_lru_locks $OSC
5440         stop_writeback
5441         sync
5442         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5443         BEFOREWRITES=$(count_ost_writes)
5444         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5445         AFTERWRITES=$(count_ost_writes)
5446         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5447                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5448         fi
5449         BEFOREWRITES=$(count_ost_writes)
5450         sync || error "sync: $?"
5451         AFTERWRITES=$(count_ost_writes)
5452         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5453                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5454         fi
5455         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5456         start_writeback
5457         return 0
5458 }
5459 run_test 42b "test destroy of file with cached dirty data ======"
5460
5461 # if these tests just want to test the effect of truncation,
5462 # they have to be very careful.  consider:
5463 # - the first open gets a {0,EOF}PR lock
5464 # - the first write conflicts and gets a {0, count-1}PW
5465 # - the rest of the writes are under {count,EOF}PW
5466 # - the open for truncate tries to match a {0,EOF}PR
5467 #   for the filesize and cancels the PWs.
5468 # any number of fixes (don't get {0,EOF} on open, match
5469 # composite locks, do smarter file size management) fix
5470 # this, but for now we want these tests to verify that
5471 # the cancellation with truncate intent works, so we
5472 # start the file with a full-file pw lock to match against
5473 # until the truncate.
5474 trunc_test() {
5475         test=$1
5476         file=$DIR/$test
5477         offset=$2
5478         cancel_lru_locks $OSC
5479         stop_writeback
5480         # prime the file with 0,EOF PW to match
5481         touch $file
5482         $TRUNCATE $file 0
5483         sync; sync
5484         # now the real test..
5485         dd if=/dev/zero of=$file bs=1024 count=100
5486         BEFOREWRITES=`count_ost_writes`
5487         $TRUNCATE $file $offset
5488         cancel_lru_locks $OSC
5489         AFTERWRITES=`count_ost_writes`
5490         start_writeback
5491 }
5492
5493 test_42c() {
5494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5495
5496         trunc_test 42c 1024
5497         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5498                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5499         rm $file
5500 }
5501 run_test 42c "test partial truncate of file with cached dirty data"
5502
5503 test_42d() {
5504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5505
5506         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5507         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5508         $LCTL set_param debug=+cache
5509
5510         trunc_test 42d 0
5511         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5512                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5513         rm $file
5514 }
5515 run_test 42d "test complete truncate of file with cached dirty data"
5516
5517 test_42e() { # bug22074
5518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5519
5520         local TDIR=$DIR/${tdir}e
5521         local pages=16 # hardcoded 16 pages, don't change it.
5522         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5523         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5524         local max_dirty_mb
5525         local warmup_files
5526
5527         test_mkdir $DIR/${tdir}e
5528         $LFS setstripe -c 1 $TDIR
5529         createmany -o $TDIR/f $files
5530
5531         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5532
5533         # we assume that with $OSTCOUNT files, at least one of them will
5534         # be allocated on OST0.
5535         warmup_files=$((OSTCOUNT * max_dirty_mb))
5536         createmany -o $TDIR/w $warmup_files
5537
5538         # write a large amount of data into one file and sync, to get good
5539         # avail_grant number from OST.
5540         for ((i=0; i<$warmup_files; i++)); do
5541                 idx=$($LFS getstripe -i $TDIR/w$i)
5542                 [ $idx -ne 0 ] && continue
5543                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5544                 break
5545         done
5546         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5547         sync
5548         $LCTL get_param $proc_osc0/cur_dirty_bytes
5549         $LCTL get_param $proc_osc0/cur_grant_bytes
5550
5551         # create as much dirty pages as we can while not to trigger the actual
5552         # RPCs directly. but depends on the env, VFS may trigger flush during this
5553         # period, hopefully we are good.
5554         for ((i=0; i<$warmup_files; i++)); do
5555                 idx=$($LFS getstripe -i $TDIR/w$i)
5556                 [ $idx -ne 0 ] && continue
5557                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5558         done
5559         $LCTL get_param $proc_osc0/cur_dirty_bytes
5560         $LCTL get_param $proc_osc0/cur_grant_bytes
5561
5562         # perform the real test
5563         $LCTL set_param $proc_osc0/rpc_stats 0
5564         for ((;i<$files; i++)); do
5565                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5566                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5567         done
5568         sync
5569         $LCTL get_param $proc_osc0/rpc_stats
5570
5571         local percent=0
5572         local have_ppr=false
5573         $LCTL get_param $proc_osc0/rpc_stats |
5574                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5575                         # skip lines until we are at the RPC histogram data
5576                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5577                         $have_ppr || continue
5578
5579                         # we only want the percent stat for < 16 pages
5580                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5581
5582                         percent=$((percent + WPCT))
5583                         if [[ $percent -gt 15 ]]; then
5584                                 error "less than 16-pages write RPCs" \
5585                                       "$percent% > 15%"
5586                                 break
5587                         fi
5588                 done
5589         rm -rf $TDIR
5590 }
5591 run_test 42e "verify sub-RPC writes are not done synchronously"
5592
5593 test_43A() { # was test_43
5594         test_mkdir $DIR/$tdir
5595         cp -p /bin/ls $DIR/$tdir/$tfile
5596         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5597         pid=$!
5598         # give multiop a chance to open
5599         sleep 1
5600
5601         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5602         kill -USR1 $pid
5603         # Wait for multiop to exit
5604         wait $pid
5605 }
5606 run_test 43A "execution of file opened for write should return -ETXTBSY"
5607
5608 test_43a() {
5609         test_mkdir $DIR/$tdir
5610         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5611         $DIR/$tdir/sleep 60 &
5612         SLEEP_PID=$!
5613         # Make sure exec of $tdir/sleep wins race with truncate
5614         sleep 1
5615         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5616         kill $SLEEP_PID
5617 }
5618 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5619
5620 test_43b() {
5621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5622
5623         test_mkdir $DIR/$tdir
5624         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5625         $DIR/$tdir/sleep 60 &
5626         SLEEP_PID=$!
5627         # Make sure exec of $tdir/sleep wins race with truncate
5628         sleep 1
5629         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5630         kill $SLEEP_PID
5631 }
5632 run_test 43b "truncate of file being executed should return -ETXTBSY"
5633
5634 test_43c() {
5635         local testdir="$DIR/$tdir"
5636         test_mkdir $testdir
5637         cp $SHELL $testdir/
5638         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5639                 ( cd $testdir && md5sum -c )
5640 }
5641 run_test 43c "md5sum of copy into lustre"
5642
5643 test_44A() { # was test_44
5644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5645
5646         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5647         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5648 }
5649 run_test 44A "zero length read from a sparse stripe"
5650
5651 test_44a() {
5652         local nstripe=$($LFS getstripe -c -d $DIR)
5653         [ -z "$nstripe" ] && skip "can't get stripe info"
5654         [[ $nstripe -gt $OSTCOUNT ]] &&
5655                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5656
5657         local stride=$($LFS getstripe -S -d $DIR)
5658         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5659                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5660         fi
5661
5662         OFFSETS="0 $((stride/2)) $((stride-1))"
5663         for offset in $OFFSETS; do
5664                 for i in $(seq 0 $((nstripe-1))); do
5665                         local GLOBALOFFSETS=""
5666                         # size in Bytes
5667                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5668                         local myfn=$DIR/d44a-$size
5669                         echo "--------writing $myfn at $size"
5670                         ll_sparseness_write $myfn $size ||
5671                                 error "ll_sparseness_write"
5672                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5673                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5674                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5675
5676                         for j in $(seq 0 $((nstripe-1))); do
5677                                 # size in Bytes
5678                                 size=$((((j + $nstripe )*$stride + $offset)))
5679                                 ll_sparseness_write $myfn $size ||
5680                                         error "ll_sparseness_write"
5681                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5682                         done
5683                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5684                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5685                         rm -f $myfn
5686                 done
5687         done
5688 }
5689 run_test 44a "test sparse pwrite ==============================="
5690
5691 dirty_osc_total() {
5692         tot=0
5693         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5694                 tot=$(($tot + $d))
5695         done
5696         echo $tot
5697 }
5698 do_dirty_record() {
5699         before=`dirty_osc_total`
5700         echo executing "\"$*\""
5701         eval $*
5702         after=`dirty_osc_total`
5703         echo before $before, after $after
5704 }
5705 test_45() {
5706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5707
5708         f="$DIR/f45"
5709         # Obtain grants from OST if it supports it
5710         echo blah > ${f}_grant
5711         stop_writeback
5712         sync
5713         do_dirty_record "echo blah > $f"
5714         [[ $before -eq $after ]] && error "write wasn't cached"
5715         do_dirty_record "> $f"
5716         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5717         do_dirty_record "echo blah > $f"
5718         [[ $before -eq $after ]] && error "write wasn't cached"
5719         do_dirty_record "sync"
5720         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5721         do_dirty_record "echo blah > $f"
5722         [[ $before -eq $after ]] && error "write wasn't cached"
5723         do_dirty_record "cancel_lru_locks osc"
5724         [[ $before -gt $after ]] ||
5725                 error "lock cancellation didn't lower dirty count"
5726         start_writeback
5727 }
5728 run_test 45 "osc io page accounting ============================"
5729
5730 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5731 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5732 # objects offset and an assert hit when an rpc was built with 1023's mapped
5733 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5734 test_46() {
5735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5736
5737         f="$DIR/f46"
5738         stop_writeback
5739         sync
5740         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5741         sync
5742         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5743         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5744         sync
5745         start_writeback
5746 }
5747 run_test 46 "dirtying a previously written page ================"
5748
5749 # test_47 is removed "Device nodes check" is moved to test_28
5750
5751 test_48a() { # bug 2399
5752         [ "$mds1_FSTYPE" = "zfs" ] &&
5753         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5754                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5755
5756         test_mkdir $DIR/$tdir
5757         cd $DIR/$tdir
5758         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5759         test_mkdir $DIR/$tdir
5760         touch foo || error "'touch foo' failed after recreating cwd"
5761         test_mkdir bar
5762         touch .foo || error "'touch .foo' failed after recreating cwd"
5763         test_mkdir .bar
5764         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5765         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5766         cd . || error "'cd .' failed after recreating cwd"
5767         mkdir . && error "'mkdir .' worked after recreating cwd"
5768         rmdir . && error "'rmdir .' worked after recreating cwd"
5769         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5770         cd .. || error "'cd ..' failed after recreating cwd"
5771 }
5772 run_test 48a "Access renamed working dir (should return errors)="
5773
5774 test_48b() { # bug 2399
5775         rm -rf $DIR/$tdir
5776         test_mkdir $DIR/$tdir
5777         cd $DIR/$tdir
5778         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5779         touch foo && error "'touch foo' worked after removing cwd"
5780         mkdir foo && error "'mkdir foo' worked after removing cwd"
5781         touch .foo && error "'touch .foo' worked after removing cwd"
5782         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5783         ls . > /dev/null && error "'ls .' worked after removing cwd"
5784         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5785         mkdir . && error "'mkdir .' worked after removing cwd"
5786         rmdir . && error "'rmdir .' worked after removing cwd"
5787         ln -s . foo && error "'ln -s .' worked after removing cwd"
5788         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5789 }
5790 run_test 48b "Access removed working dir (should return errors)="
5791
5792 test_48c() { # bug 2350
5793         #lctl set_param debug=-1
5794         #set -vx
5795         rm -rf $DIR/$tdir
5796         test_mkdir -p $DIR/$tdir/dir
5797         cd $DIR/$tdir/dir
5798         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5799         $TRACE touch foo && error "touch foo worked after removing cwd"
5800         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5801         touch .foo && error "touch .foo worked after removing cwd"
5802         mkdir .foo && error "mkdir .foo worked after removing cwd"
5803         $TRACE ls . && error "'ls .' worked after removing cwd"
5804         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5805         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5806         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5807         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5808         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5809 }
5810 run_test 48c "Access removed working subdir (should return errors)"
5811
5812 test_48d() { # bug 2350
5813         #lctl set_param debug=-1
5814         #set -vx
5815         rm -rf $DIR/$tdir
5816         test_mkdir -p $DIR/$tdir/dir
5817         cd $DIR/$tdir/dir
5818         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5819         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5820         $TRACE touch foo && error "'touch foo' worked after removing parent"
5821         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5822         touch .foo && error "'touch .foo' worked after removing parent"
5823         mkdir .foo && error "mkdir .foo worked after removing parent"
5824         $TRACE ls . && error "'ls .' worked after removing parent"
5825         $TRACE ls .. && error "'ls ..' worked after removing parent"
5826         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5827         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5828         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5829         true
5830 }
5831 run_test 48d "Access removed parent subdir (should return errors)"
5832
5833 test_48e() { # bug 4134
5834         #lctl set_param debug=-1
5835         #set -vx
5836         rm -rf $DIR/$tdir
5837         test_mkdir -p $DIR/$tdir/dir
5838         cd $DIR/$tdir/dir
5839         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5840         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5841         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5842         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5843         # On a buggy kernel addition of "touch foo" after cd .. will
5844         # produce kernel oops in lookup_hash_it
5845         touch ../foo && error "'cd ..' worked after recreate parent"
5846         cd $DIR
5847         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5848 }
5849 run_test 48e "Access to recreated parent subdir (should return errors)"
5850
5851 test_48f() {
5852         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5853                 skip "need MDS >= 2.13.55"
5854         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5855         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5856                 skip "needs different host for mdt1 mdt2"
5857         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5858
5859         $LFS mkdir -i0 $DIR/$tdir
5860         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5861
5862         for d in sub1 sub2 sub3; do
5863                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5864                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5865                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5866         done
5867
5868         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5869 }
5870 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5871
5872 test_49() { # LU-1030
5873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5874         remote_ost_nodsh && skip "remote OST with nodsh"
5875
5876         # get ost1 size - $FSNAME-OST0000
5877         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5878                 awk '{ print $4 }')
5879         # write 800M at maximum
5880         [[ $ost1_size -lt 2 ]] && ost1_size=2
5881         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5882
5883         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5884         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5885         local dd_pid=$!
5886
5887         # change max_pages_per_rpc while writing the file
5888         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5889         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5890         # loop until dd process exits
5891         while ps ax -opid | grep -wq $dd_pid; do
5892                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5893                 sleep $((RANDOM % 5 + 1))
5894         done
5895         # restore original max_pages_per_rpc
5896         $LCTL set_param $osc1_mppc=$orig_mppc
5897         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5898 }
5899 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5900
5901 test_50() {
5902         # bug 1485
5903         test_mkdir $DIR/$tdir
5904         cd $DIR/$tdir
5905         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5906 }
5907 run_test 50 "special situations: /proc symlinks  ==============="
5908
5909 test_51a() {    # was test_51
5910         # bug 1516 - create an empty entry right after ".." then split dir
5911         test_mkdir -c1 $DIR/$tdir
5912         touch $DIR/$tdir/foo
5913         $MCREATE $DIR/$tdir/bar
5914         rm $DIR/$tdir/foo
5915         createmany -m $DIR/$tdir/longfile 201
5916         FNUM=202
5917         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5918                 $MCREATE $DIR/$tdir/longfile$FNUM
5919                 FNUM=$(($FNUM + 1))
5920                 echo -n "+"
5921         done
5922         echo
5923         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5924 }
5925 run_test 51a "special situations: split htree with empty entry =="
5926
5927 cleanup_print_lfs_df () {
5928         trap 0
5929         $LFS df
5930         $LFS df -i
5931 }
5932
5933 test_51b() {
5934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5935
5936         local dir=$DIR/$tdir
5937         local nrdirs=$((65536 + 100))
5938
5939         # cleanup the directory
5940         rm -fr $dir
5941
5942         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5943
5944         $LFS df
5945         $LFS df -i
5946         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5947         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5948         [[ $numfree -lt $nrdirs ]] &&
5949                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5950
5951         # need to check free space for the directories as well
5952         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5953         numfree=$(( blkfree / $(fs_inode_ksize) ))
5954         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5955
5956         trap cleanup_print_lfs_df EXIT
5957
5958         # create files
5959         createmany -d $dir/d $nrdirs || {
5960                 unlinkmany $dir/d $nrdirs
5961                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5962         }
5963
5964         # really created :
5965         nrdirs=$(ls -U $dir | wc -l)
5966
5967         # unlink all but 100 subdirectories, then check it still works
5968         local left=100
5969         local delete=$((nrdirs - left))
5970
5971         $LFS df
5972         $LFS df -i
5973
5974         # for ldiskfs the nlink count should be 1, but this is OSD specific
5975         # and so this is listed for informational purposes only
5976         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5977         unlinkmany -d $dir/d $delete ||
5978                 error "unlink of first $delete subdirs failed"
5979
5980         echo "nlink between: $(stat -c %h $dir)"
5981         local found=$(ls -U $dir | wc -l)
5982         [ $found -ne $left ] &&
5983                 error "can't find subdirs: found only $found, expected $left"
5984
5985         unlinkmany -d $dir/d $delete $left ||
5986                 error "unlink of second $left subdirs failed"
5987         # regardless of whether the backing filesystem tracks nlink accurately
5988         # or not, the nlink count shouldn't be more than "." and ".." here
5989         local after=$(stat -c %h $dir)
5990         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5991                 echo "nlink after: $after"
5992
5993         cleanup_print_lfs_df
5994 }
5995 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5996
5997 test_51d_sub() {
5998         local stripecount=$1
5999         local nfiles=$2
6000
6001         log "create files with stripecount=$stripecount"
6002         $LFS setstripe -C $stripecount $DIR/$tdir
6003         createmany -o $DIR/$tdir/t- $nfiles
6004         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6005         for ((n = 0; n < $OSTCOUNT; n++)); do
6006                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6007                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6008                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6009                             '($1 == '$n') { objs += 1 } \
6010                             END { printf("%0.0f", objs) }')
6011                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6012         done
6013         unlinkmany $DIR/$tdir/t- $nfiles
6014         rm  -f $TMP/$tfile
6015
6016         local nlast
6017         local min=4
6018         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6019
6020         # For some combinations of stripecount and OSTCOUNT current code
6021         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6022         # than others. Rather than skipping this test entirely, check that
6023         # and keep testing to ensure imbalance does not get worse. LU-15282
6024         (( (OSTCOUNT == 6 && stripecount == 4) ||
6025            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6026            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6027         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6028                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6029                         { $LFS df && $LFS df -i &&
6030                         error "stripecount=$stripecount: " \
6031                               "OST $n has fewer objects vs. OST $nlast " \
6032                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6033                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6034                         { $LFS df && $LFS df -i &&
6035                         error "stripecount=$stripecount: " \
6036                               "OST $n has more objects vs. OST $nlast " \
6037                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6038
6039                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6040                         { $LFS df && $LFS df -i &&
6041                         error "stripecount=$stripecount: " \
6042                               "OST $n has fewer #0 objects vs. OST $nlast " \
6043                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6044                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6045                         { $LFS df && $LFS df -i &&
6046                         error "stripecount=$stripecount: " \
6047                               "OST $n has more #0 objects vs. OST $nlast " \
6048                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6049         done
6050 }
6051
6052 test_51d() {
6053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6054         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6055
6056         local stripecount
6057         local per_ost=100
6058         local nfiles=$((per_ost * OSTCOUNT))
6059         local mdts=$(comma_list $(mdts_nodes))
6060         local param="osp.*.create_count"
6061         local qos_old=$(do_facet mds1 \
6062                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6063
6064         do_nodes $mdts \
6065                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6066         stack_trap "do_nodes $mdts \
6067                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6068
6069         test_mkdir $DIR/$tdir
6070         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6071         (( dirstripes > 0 )) || dirstripes=1
6072
6073         # Ensure enough OST objects precreated for tests to pass without
6074         # running out of objects.  This is an LOV r-r OST algorithm test,
6075         # not an OST object precreation test.
6076         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6077         (( old >= nfiles )) ||
6078         {
6079                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6080
6081                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6082                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6083
6084                 # trigger precreation from all MDTs for all OSTs
6085                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6086                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6087                 done
6088         }
6089
6090         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6091                 sleep 8  # allow object precreation to catch up
6092                 test_51d_sub $stripecount $nfiles
6093         done
6094 }
6095 run_test 51d "check LOV round-robin OST object distribution"
6096
6097 test_51e() {
6098         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6099                 skip_env "ldiskfs only test"
6100         fi
6101
6102         test_mkdir -c1 $DIR/$tdir
6103         test_mkdir -c1 $DIR/$tdir/d0
6104
6105         touch $DIR/$tdir/d0/foo
6106         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6107                 error "file exceed 65000 nlink limit!"
6108         unlinkmany $DIR/$tdir/d0/f- 65001
6109         return 0
6110 }
6111 run_test 51e "check file nlink limit"
6112
6113 test_51f() {
6114         test_mkdir $DIR/$tdir
6115
6116         local max=100000
6117         local ulimit_old=$(ulimit -n)
6118         local spare=20 # number of spare fd's for scripts/libraries, etc.
6119         local mdt=$($LFS getstripe -m $DIR/$tdir)
6120         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6121
6122         echo "MDT$mdt numfree=$numfree, max=$max"
6123         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6124         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6125                 while ! ulimit -n $((numfree + spare)); do
6126                         numfree=$((numfree * 3 / 4))
6127                 done
6128                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6129         else
6130                 echo "left ulimit at $ulimit_old"
6131         fi
6132
6133         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6134                 unlinkmany $DIR/$tdir/f $numfree
6135                 error "create+open $numfree files in $DIR/$tdir failed"
6136         }
6137         ulimit -n $ulimit_old
6138
6139         # if createmany exits at 120s there will be fewer than $numfree files
6140         unlinkmany $DIR/$tdir/f $numfree || true
6141 }
6142 run_test 51f "check many open files limit"
6143
6144 test_52a() {
6145         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6146         test_mkdir $DIR/$tdir
6147         touch $DIR/$tdir/foo
6148         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6149         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6150         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6151         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6152         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6153                                         error "link worked"
6154         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6155         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6156         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6157                                                      error "lsattr"
6158         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6159         cp -r $DIR/$tdir $TMP/
6160         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6161 }
6162 run_test 52a "append-only flag test (should return errors)"
6163
6164 test_52b() {
6165         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6166         test_mkdir $DIR/$tdir
6167         touch $DIR/$tdir/foo
6168         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6169         cat test > $DIR/$tdir/foo && error "cat test worked"
6170         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6171         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6172         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6173                                         error "link worked"
6174         echo foo >> $DIR/$tdir/foo && error "echo worked"
6175         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6176         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6177         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6178         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6179                                                         error "lsattr"
6180         chattr -i $DIR/$tdir/foo || error "chattr failed"
6181
6182         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6183 }
6184 run_test 52b "immutable flag test (should return errors) ======="
6185
6186 test_53() {
6187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6188         remote_mds_nodsh && skip "remote MDS with nodsh"
6189         remote_ost_nodsh && skip "remote OST with nodsh"
6190
6191         local param
6192         local param_seq
6193         local ostname
6194         local mds_last
6195         local mds_last_seq
6196         local ost_last
6197         local ost_last_seq
6198         local ost_last_id
6199         local ostnum
6200         local node
6201         local found=false
6202         local support_last_seq=true
6203
6204         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6205                 support_last_seq=false
6206
6207         # only test MDT0000
6208         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6209         local value
6210         for value in $(do_facet $SINGLEMDS \
6211                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6212                 param=$(echo ${value[0]} | cut -d "=" -f1)
6213                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6214
6215                 if $support_last_seq; then
6216                         param_seq=$(echo $param |
6217                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6218                         mds_last_seq=$(do_facet $SINGLEMDS \
6219                                        $LCTL get_param -n $param_seq)
6220                 fi
6221                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6222
6223                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6224                 node=$(facet_active_host ost$((ostnum+1)))
6225                 param="obdfilter.$ostname.last_id"
6226                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6227                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6228                         ost_last_id=$ost_last
6229
6230                         if $support_last_seq; then
6231                                 ost_last_id=$(echo $ost_last |
6232                                               awk -F':' '{print $2}' |
6233                                               sed -e "s/^0x//g")
6234                                 ost_last_seq=$(echo $ost_last |
6235                                                awk -F':' '{print $1}')
6236                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6237                         fi
6238
6239                         if [[ $ost_last_id != $mds_last ]]; then
6240                                 error "$ost_last_id != $mds_last"
6241                         else
6242                                 found=true
6243                                 break
6244                         fi
6245                 done
6246         done
6247         $found || error "can not match last_seq/last_id for $mdtosc"
6248         return 0
6249 }
6250 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6251
6252 test_54a() {
6253         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6254
6255         LANG=C $SOCKETSERVER $DIR/socket ||
6256                 error "$SOCKETSERVER $DIR/socket failed: $?"
6257         LANG=C $SOCKETCLIENT $DIR/socket ||
6258                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6259         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6260 }
6261 run_test 54a "unix domain socket test =========================="
6262
6263 test_54b() {
6264         f="$DIR/f54b"
6265         mknod $f c 1 3
6266         chmod 0666 $f
6267         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6268 }
6269 run_test 54b "char device works in lustre ======================"
6270
6271 find_loop_dev() {
6272         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6273         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6274         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6275
6276         for i in $(seq 3 7); do
6277                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6278                 LOOPDEV=$LOOPBASE$i
6279                 LOOPNUM=$i
6280                 break
6281         done
6282 }
6283
6284 cleanup_54c() {
6285         local rc=0
6286         loopdev="$DIR/loop54c"
6287
6288         trap 0
6289         $UMOUNT $DIR/$tdir || rc=$?
6290         losetup -d $loopdev || true
6291         losetup -d $LOOPDEV || true
6292         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6293         return $rc
6294 }
6295
6296 test_54c() {
6297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6298
6299         loopdev="$DIR/loop54c"
6300
6301         find_loop_dev
6302         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6303         trap cleanup_54c EXIT
6304         mknod $loopdev b 7 $LOOPNUM
6305         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6306         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6307         losetup $loopdev $DIR/$tfile ||
6308                 error "can't set up $loopdev for $DIR/$tfile"
6309         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6310         test_mkdir $DIR/$tdir
6311         mount -t ext2 $loopdev $DIR/$tdir ||
6312                 error "error mounting $loopdev on $DIR/$tdir"
6313         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6314                 error "dd write"
6315         df $DIR/$tdir
6316         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6317                 error "dd read"
6318         cleanup_54c
6319 }
6320 run_test 54c "block device works in lustre ====================="
6321
6322 test_54d() {
6323         local pipe="$DIR/$tfile.pipe"
6324         local string="aaaaaa"
6325
6326         mknod $pipe p
6327         echo -n "$string" > $pipe &
6328         local result=$(cat $pipe)
6329         [[ "$result" == "$string" ]] || error "$result != $string"
6330 }
6331 run_test 54d "fifo device works in lustre ======================"
6332
6333 test_54e() {
6334         f="$DIR/f54e"
6335         string="aaaaaa"
6336         cp -aL /dev/console $f
6337         echo $string > $f || error "echo $string to $f failed"
6338 }
6339 run_test 54e "console/tty device works in lustre ======================"
6340
6341 test_56a() {
6342         local numfiles=3
6343         local numdirs=2
6344         local dir=$DIR/$tdir
6345
6346         rm -rf $dir
6347         test_mkdir -p $dir/dir
6348         for i in $(seq $numfiles); do
6349                 touch $dir/file$i
6350                 touch $dir/dir/file$i
6351         done
6352
6353         local numcomp=$($LFS getstripe --component-count $dir)
6354
6355         [[ $numcomp == 0 ]] && numcomp=1
6356
6357         # test lfs getstripe with --recursive
6358         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6359
6360         [[ $filenum -eq $((numfiles * 2)) ]] ||
6361                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6362         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6363         [[ $filenum -eq $numfiles ]] ||
6364                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6365         echo "$LFS getstripe showed obdidx or l_ost_idx"
6366
6367         # test lfs getstripe with file instead of dir
6368         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6369         [[ $filenum -eq 1 ]] ||
6370                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6371         echo "$LFS getstripe file1 passed"
6372
6373         #test lfs getstripe with --verbose
6374         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6375         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6376                 error "$LFS getstripe --verbose $dir: "\
6377                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6378         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6379                 error "$LFS getstripe $dir: showed lmm_magic"
6380
6381         #test lfs getstripe with -v prints lmm_fid
6382         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6383         local countfids=$((numdirs + numfiles * numcomp))
6384         [[ $filenum -eq $countfids ]] ||
6385                 error "$LFS getstripe -v $dir: "\
6386                       "got $filenum want $countfids lmm_fid"
6387         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6388                 error "$LFS getstripe $dir: showed lmm_fid by default"
6389         echo "$LFS getstripe --verbose passed"
6390
6391         #check for FID information
6392         local fid1=$($LFS getstripe --fid $dir/file1)
6393         local fid2=$($LFS getstripe --verbose $dir/file1 |
6394                      awk '/lmm_fid: / { print $2; exit; }')
6395         local fid3=$($LFS path2fid $dir/file1)
6396
6397         [ "$fid1" != "$fid2" ] &&
6398                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6399         [ "$fid1" != "$fid3" ] &&
6400                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6401         echo "$LFS getstripe --fid passed"
6402
6403         #test lfs getstripe with --obd
6404         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6405                 error "$LFS getstripe --obd wrong_uuid: should return error"
6406
6407         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6408
6409         local ostidx=1
6410         local obduuid=$(ostuuid_from_index $ostidx)
6411         local found=$($LFS getstripe -r --obd $obduuid $dir |
6412                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6413
6414         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6415         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6416                 ((filenum--))
6417         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6418                 ((filenum--))
6419
6420         [[ $found -eq $filenum ]] ||
6421                 error "$LFS getstripe --obd: found $found expect $filenum"
6422         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6423                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6424                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6425                 error "$LFS getstripe --obd: should not show file on other obd"
6426         echo "$LFS getstripe --obd passed"
6427 }
6428 run_test 56a "check $LFS getstripe"
6429
6430 test_56b() {
6431         local dir=$DIR/$tdir
6432         local numdirs=3
6433
6434         test_mkdir $dir
6435         for i in $(seq $numdirs); do
6436                 test_mkdir $dir/dir$i
6437         done
6438
6439         # test lfs getdirstripe default mode is non-recursion, which is
6440         # different from lfs getstripe
6441         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6442
6443         [[ $dircnt -eq 1 ]] ||
6444                 error "$LFS getdirstripe: found $dircnt, not 1"
6445         dircnt=$($LFS getdirstripe --recursive $dir |
6446                 grep -c lmv_stripe_count)
6447         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6448                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6449 }
6450 run_test 56b "check $LFS getdirstripe"
6451
6452 test_56bb() {
6453         verify_yaml_available || skip_env "YAML verification not installed"
6454         local output_file=$DIR/$tfile.out
6455
6456         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6457
6458         cat $output_file
6459         cat $output_file | verify_yaml || error "layout is not valid YAML"
6460 }
6461 run_test 56bb "check $LFS getdirstripe layout is YAML"
6462
6463 test_56c() {
6464         remote_ost_nodsh && skip "remote OST with nodsh"
6465
6466         local ost_idx=0
6467         local ost_name=$(ostname_from_index $ost_idx)
6468         local old_status=$(ost_dev_status $ost_idx)
6469         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6470
6471         [[ -z "$old_status" ]] ||
6472                 skip_env "OST $ost_name is in $old_status status"
6473
6474         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6475         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6476                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6477         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6478                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6479                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6480         fi
6481
6482         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6483                 error "$LFS df -v showing inactive devices"
6484         sleep_maxage
6485
6486         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6487
6488         [[ "$new_status" =~ "D" ]] ||
6489                 error "$ost_name status is '$new_status', missing 'D'"
6490         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6491                 [[ "$new_status" =~ "N" ]] ||
6492                         error "$ost_name status is '$new_status', missing 'N'"
6493         fi
6494         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6495                 [[ "$new_status" =~ "f" ]] ||
6496                         error "$ost_name status is '$new_status', missing 'f'"
6497         fi
6498
6499         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6500         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6501                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6502         [[ -z "$p" ]] && restore_lustre_params < $p || true
6503         sleep_maxage
6504
6505         new_status=$(ost_dev_status $ost_idx)
6506         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6507                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6508         # can't check 'f' as devices may actually be on flash
6509 }
6510 run_test 56c "check 'lfs df' showing device status"
6511
6512 test_56d() {
6513         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6514         local osts=$($LFS df -v $MOUNT | grep -c OST)
6515
6516         $LFS df $MOUNT
6517
6518         (( mdts == MDSCOUNT )) ||
6519                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6520         (( osts == OSTCOUNT )) ||
6521                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6522 }
6523 run_test 56d "'lfs df -v' prints only configured devices"
6524
6525 test_56e() {
6526         err_enoent=2 # No such file or directory
6527         err_eopnotsupp=95 # Operation not supported
6528
6529         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6530         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6531
6532         # Check for handling of path not exists
6533         output=$($LFS df $enoent_mnt 2>&1)
6534         ret=$?
6535
6536         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6537         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6538                 error "expect failure $err_enoent, not $ret"
6539
6540         # Check for handling of non-Lustre FS
6541         output=$($LFS df $notsup_mnt)
6542         ret=$?
6543
6544         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6545         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6546                 error "expect success $err_eopnotsupp, not $ret"
6547
6548         # Check for multiple LustreFS argument
6549         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6550         ret=$?
6551
6552         [[ $output -eq 3 && $ret -eq 0 ]] ||
6553                 error "expect success 3, not $output, rc = $ret"
6554
6555         # Check for correct non-Lustre FS handling among multiple
6556         # LustreFS argument
6557         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6558                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6559         ret=$?
6560
6561         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6562                 error "expect success 2, not $output, rc = $ret"
6563 }
6564 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6565
6566 NUMFILES=3
6567 NUMDIRS=3
6568 setup_56() {
6569         local local_tdir="$1"
6570         local local_numfiles="$2"
6571         local local_numdirs="$3"
6572         local dir_params="$4"
6573         local dir_stripe_params="$5"
6574
6575         if [ ! -d "$local_tdir" ] ; then
6576                 test_mkdir -p $dir_stripe_params $local_tdir
6577                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6578                 for i in $(seq $local_numfiles) ; do
6579                         touch $local_tdir/file$i
6580                 done
6581                 for i in $(seq $local_numdirs) ; do
6582                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6583                         for j in $(seq $local_numfiles) ; do
6584                                 touch $local_tdir/dir$i/file$j
6585                         done
6586                 done
6587         fi
6588 }
6589
6590 setup_56_special() {
6591         local local_tdir=$1
6592         local local_numfiles=$2
6593         local local_numdirs=$3
6594
6595         setup_56 $local_tdir $local_numfiles $local_numdirs
6596
6597         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6598                 for i in $(seq $local_numfiles) ; do
6599                         mknod $local_tdir/loop${i}b b 7 $i
6600                         mknod $local_tdir/null${i}c c 1 3
6601                         ln -s $local_tdir/file1 $local_tdir/link${i}
6602                 done
6603                 for i in $(seq $local_numdirs) ; do
6604                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6605                         mknod $local_tdir/dir$i/null${i}c c 1 3
6606                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6607                 done
6608         fi
6609 }
6610
6611 test_56g() {
6612         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6613         local expected=$(($NUMDIRS + 2))
6614
6615         setup_56 $dir $NUMFILES $NUMDIRS
6616
6617         # test lfs find with -name
6618         for i in $(seq $NUMFILES) ; do
6619                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6620
6621                 [ $nums -eq $expected ] ||
6622                         error "lfs find -name '*$i' $dir wrong: "\
6623                               "found $nums, expected $expected"
6624         done
6625 }
6626 run_test 56g "check lfs find -name"
6627
6628 test_56h() {
6629         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6630         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6631
6632         setup_56 $dir $NUMFILES $NUMDIRS
6633
6634         # test lfs find with ! -name
6635         for i in $(seq $NUMFILES) ; do
6636                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6637
6638                 [ $nums -eq $expected ] ||
6639                         error "lfs find ! -name '*$i' $dir wrong: "\
6640                               "found $nums, expected $expected"
6641         done
6642 }
6643 run_test 56h "check lfs find ! -name"
6644
6645 test_56i() {
6646         local dir=$DIR/$tdir
6647
6648         test_mkdir $dir
6649
6650         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6651         local out=$($cmd)
6652
6653         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6654 }
6655 run_test 56i "check 'lfs find -ost UUID' skips directories"
6656
6657 test_56j() {
6658         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6659
6660         setup_56_special $dir $NUMFILES $NUMDIRS
6661
6662         local expected=$((NUMDIRS + 1))
6663         local cmd="$LFS find -type d $dir"
6664         local nums=$($cmd | wc -l)
6665
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668 }
6669 run_test 56j "check lfs find -type d"
6670
6671 test_56k() {
6672         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6673
6674         setup_56_special $dir $NUMFILES $NUMDIRS
6675
6676         local expected=$(((NUMDIRS + 1) * NUMFILES))
6677         local cmd="$LFS find -type f $dir"
6678         local nums=$($cmd | wc -l)
6679
6680         [ $nums -eq $expected ] ||
6681                 error "'$cmd' wrong: found $nums, expected $expected"
6682 }
6683 run_test 56k "check lfs find -type f"
6684
6685 test_56l() {
6686         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6687
6688         setup_56_special $dir $NUMFILES $NUMDIRS
6689
6690         local expected=$((NUMDIRS + NUMFILES))
6691         local cmd="$LFS find -type b $dir"
6692         local nums=$($cmd | wc -l)
6693
6694         [ $nums -eq $expected ] ||
6695                 error "'$cmd' wrong: found $nums, expected $expected"
6696 }
6697 run_test 56l "check lfs find -type b"
6698
6699 test_56m() {
6700         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6701
6702         setup_56_special $dir $NUMFILES $NUMDIRS
6703
6704         local expected=$((NUMDIRS + NUMFILES))
6705         local cmd="$LFS find -type c $dir"
6706         local nums=$($cmd | wc -l)
6707         [ $nums -eq $expected ] ||
6708                 error "'$cmd' wrong: found $nums, expected $expected"
6709 }
6710 run_test 56m "check lfs find -type c"
6711
6712 test_56n() {
6713         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6714         setup_56_special $dir $NUMFILES $NUMDIRS
6715
6716         local expected=$((NUMDIRS + NUMFILES))
6717         local cmd="$LFS find -type l $dir"
6718         local nums=$($cmd | wc -l)
6719
6720         [ $nums -eq $expected ] ||
6721                 error "'$cmd' wrong: found $nums, expected $expected"
6722 }
6723 run_test 56n "check lfs find -type l"
6724
6725 test_56o() {
6726         local dir=$DIR/$tdir
6727
6728         setup_56 $dir $NUMFILES $NUMDIRS
6729         utime $dir/file1 > /dev/null || error "utime (1)"
6730         utime $dir/file2 > /dev/null || error "utime (2)"
6731         utime $dir/dir1 > /dev/null || error "utime (3)"
6732         utime $dir/dir2 > /dev/null || error "utime (4)"
6733         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6734         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6735
6736         local expected=4
6737         local nums=$($LFS find -mtime +0 $dir | wc -l)
6738
6739         [ $nums -eq $expected ] ||
6740                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6741
6742         expected=12
6743         cmd="$LFS find -mtime 0 $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56o "check lfs find -mtime for old files"
6749
6750 test_56ob() {
6751         local dir=$DIR/$tdir
6752         local expected=1
6753         local count=0
6754
6755         # just to make sure there is something that won't be found
6756         test_mkdir $dir
6757         touch $dir/$tfile.now
6758
6759         for age in year week day hour min; do
6760                 count=$((count + 1))
6761
6762                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6763                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6764                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6765
6766                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6767                 local nums=$($cmd | wc -l)
6768                 [ $nums -eq $expected ] ||
6769                         error "'$cmd' wrong: found $nums, expected $expected"
6770
6771                 cmd="$LFS find $dir -atime $count${age:0:1}"
6772                 nums=$($cmd | wc -l)
6773                 [ $nums -eq $expected ] ||
6774                         error "'$cmd' wrong: found $nums, expected $expected"
6775         done
6776
6777         sleep 2
6778         cmd="$LFS find $dir -ctime +1s -type f"
6779         nums=$($cmd | wc -l)
6780         (( $nums == $count * 2 + 1)) ||
6781                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6782 }
6783 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6784
6785 test_newerXY_base() {
6786         local x=$1
6787         local y=$2
6788         local dir=$DIR/$tdir
6789         local ref
6790         local negref
6791
6792         if [ $y == "t" ]; then
6793                 if [ $x == "b" ]; then
6794                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6795                 else
6796                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6797                 fi
6798         else
6799                 ref=$DIR/$tfile.newer.$x$y
6800                 touch $ref || error "touch $ref failed"
6801         fi
6802
6803         echo "before = $ref"
6804         sleep 2
6805         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6806         sleep 2
6807         if [ $y == "t" ]; then
6808                 if [ $x == "b" ]; then
6809                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6810                 else
6811                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6812                 fi
6813         else
6814                 negref=$DIR/$tfile.negnewer.$x$y
6815                 touch $negref || error "touch $negref failed"
6816         fi
6817
6818         echo "after = $negref"
6819         local cmd="$LFS find $dir -newer$x$y $ref"
6820         local nums=$(eval $cmd | wc -l)
6821         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6822
6823         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6824                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6825
6826         cmd="$LFS find $dir ! -newer$x$y $negref"
6827         nums=$(eval $cmd | wc -l)
6828         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6829                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6830
6831         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6832         nums=$(eval $cmd | wc -l)
6833         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6834                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6835
6836         rm -rf $DIR/*
6837 }
6838
6839 test_56oc() {
6840         test_newerXY_base "a" "a"
6841         test_newerXY_base "a" "m"
6842         test_newerXY_base "a" "c"
6843         test_newerXY_base "m" "a"
6844         test_newerXY_base "m" "m"
6845         test_newerXY_base "m" "c"
6846         test_newerXY_base "c" "a"
6847         test_newerXY_base "c" "m"
6848         test_newerXY_base "c" "c"
6849
6850         test_newerXY_base "a" "t"
6851         test_newerXY_base "m" "t"
6852         test_newerXY_base "c" "t"
6853
6854         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6855            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6856                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6857
6858         test_newerXY_base "b" "b"
6859         test_newerXY_base "b" "t"
6860 }
6861 run_test 56oc "check lfs find -newerXY work"
6862
6863 test_56od() {
6864         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6865                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6866
6867         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6868                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6869
6870         local dir=$DIR/$tdir
6871         local ref=$DIR/$tfile.ref
6872         local negref=$DIR/$tfile.negref
6873
6874         mkdir $dir || error "mkdir $dir failed"
6875         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6876         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6877         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6878         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6879         touch $ref || error "touch $ref failed"
6880         # sleep 3 seconds at least
6881         sleep 3
6882
6883         local before=$(do_facet mds1 date +%s)
6884         local skew=$(($(date +%s) - before + 1))
6885
6886         if (( skew < 0 && skew > -5 )); then
6887                 sleep $((0 - skew + 1))
6888                 skew=0
6889         fi
6890
6891         # Set the dir stripe params to limit files all on MDT0,
6892         # otherwise we need to calc the max clock skew between
6893         # the client and MDTs.
6894         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6895         sleep 2
6896         touch $negref || error "touch $negref failed"
6897
6898         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6899         local nums=$($cmd | wc -l)
6900         local expected=$(((NUMFILES + 1) * NUMDIRS))
6901
6902         [ $nums -eq $expected ] ||
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904
6905         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6906         nums=$($cmd | wc -l)
6907         expected=$((NUMFILES + 1))
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910
6911         [ $skew -lt 0 ] && return
6912
6913         local after=$(do_facet mds1 date +%s)
6914         local age=$((after - before + 1 + skew))
6915
6916         cmd="$LFS find $dir -btime -${age}s -type f"
6917         nums=$($cmd | wc -l)
6918         expected=$(((NUMFILES + 1) * NUMDIRS))
6919
6920         echo "Clock skew between client and server: $skew, age:$age"
6921         [ $nums -eq $expected ] ||
6922                 error "'$cmd' wrong: found $nums, expected $expected"
6923
6924         expected=$(($NUMDIRS + 1))
6925         cmd="$LFS find $dir -btime -${age}s -type d"
6926         nums=$($cmd | wc -l)
6927         [ $nums -eq $expected ] ||
6928                 error "'$cmd' wrong: found $nums, expected $expected"
6929         rm -f $ref $negref || error "Failed to remove $ref $negref"
6930 }
6931 run_test 56od "check lfs find -btime with units"
6932
6933 test_56p() {
6934         [ $RUNAS_ID -eq $UID ] &&
6935                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6936
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir $NUMFILES $NUMDIRS
6940         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6941
6942         local expected=$NUMFILES
6943         local cmd="$LFS find -uid $RUNAS_ID $dir"
6944         local nums=$($cmd | wc -l)
6945
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948
6949         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6950         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6951         nums=$($cmd | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954 }
6955 run_test 56p "check lfs find -uid and ! -uid"
6956
6957 test_56q() {
6958         [ $RUNAS_ID -eq $UID ] &&
6959                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6960
6961         local dir=$DIR/$tdir
6962
6963         setup_56 $dir $NUMFILES $NUMDIRS
6964         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6965
6966         local expected=$NUMFILES
6967         local cmd="$LFS find -gid $RUNAS_GID $dir"
6968         local nums=$($cmd | wc -l)
6969
6970         [ $nums -eq $expected ] ||
6971                 error "'$cmd' wrong: found $nums, expected $expected"
6972
6973         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6974         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6975         nums=$($cmd | wc -l)
6976         [ $nums -eq $expected ] ||
6977                 error "'$cmd' wrong: found $nums, expected $expected"
6978 }
6979 run_test 56q "check lfs find -gid and ! -gid"
6980
6981 test_56r() {
6982         local dir=$DIR/$tdir
6983
6984         setup_56 $dir $NUMFILES $NUMDIRS
6985
6986         local expected=12
6987         local cmd="$LFS find -size 0 -type f -lazy $dir"
6988         local nums=$($cmd | wc -l)
6989
6990         [ $nums -eq $expected ] ||
6991                 error "'$cmd' wrong: found $nums, expected $expected"
6992         cmd="$LFS find -size 0 -type f $dir"
6993         nums=$($cmd | wc -l)
6994         [ $nums -eq $expected ] ||
6995                 error "'$cmd' wrong: found $nums, expected $expected"
6996
6997         expected=0
6998         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6999         nums=$($cmd | wc -l)
7000         [ $nums -eq $expected ] ||
7001                 error "'$cmd' wrong: found $nums, expected $expected"
7002         cmd="$LFS find ! -size 0 -type f $dir"
7003         nums=$($cmd | wc -l)
7004         [ $nums -eq $expected ] ||
7005                 error "'$cmd' wrong: found $nums, expected $expected"
7006
7007         echo "test" > $dir/$tfile
7008         echo "test2" > $dir/$tfile.2 && sync
7009         expected=1
7010         cmd="$LFS find -size 5 -type f -lazy $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014         cmd="$LFS find -size 5 -type f $dir"
7015         nums=$($cmd | wc -l)
7016         [ $nums -eq $expected ] ||
7017                 error "'$cmd' wrong: found $nums, expected $expected"
7018
7019         expected=1
7020         cmd="$LFS find -size +5 -type f -lazy $dir"
7021         nums=$($cmd | wc -l)
7022         [ $nums -eq $expected ] ||
7023                 error "'$cmd' wrong: found $nums, expected $expected"
7024         cmd="$LFS find -size +5 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=2
7030         cmd="$LFS find -size +0 -type f -lazy $dir"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034         cmd="$LFS find -size +0 -type f $dir"
7035         nums=$($cmd | wc -l)
7036         [ $nums -eq $expected ] ||
7037                 error "'$cmd' wrong: found $nums, expected $expected"
7038
7039         expected=2
7040         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7041         nums=$($cmd | wc -l)
7042         [ $nums -eq $expected ] ||
7043                 error "'$cmd' wrong: found $nums, expected $expected"
7044         cmd="$LFS find ! -size -5 -type f $dir"
7045         nums=$($cmd | wc -l)
7046         [ $nums -eq $expected ] ||
7047                 error "'$cmd' wrong: found $nums, expected $expected"
7048
7049         expected=12
7050         cmd="$LFS find -size -5 -type f -lazy $dir"
7051         nums=$($cmd | wc -l)
7052         [ $nums -eq $expected ] ||
7053                 error "'$cmd' wrong: found $nums, expected $expected"
7054         cmd="$LFS find -size -5 -type f $dir"
7055         nums=$($cmd | wc -l)
7056         [ $nums -eq $expected ] ||
7057                 error "'$cmd' wrong: found $nums, expected $expected"
7058 }
7059 run_test 56r "check lfs find -size works"
7060
7061 test_56ra_sub() {
7062         local expected=$1
7063         local glimpses=$2
7064         local cmd="$3"
7065
7066         cancel_lru_locks $OSC
7067
7068         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7069         local nums=$($cmd | wc -l)
7070
7071         [ $nums -eq $expected ] ||
7072                 error "'$cmd' wrong: found $nums, expected $expected"
7073
7074         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7075
7076         if (( rpcs_before + glimpses != rpcs_after )); then
7077                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7078                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7079
7080                 if [[ $glimpses == 0 ]]; then
7081                         error "'$cmd' should not send glimpse RPCs to OST"
7082                 else
7083                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7084                 fi
7085         fi
7086 }
7087
7088 test_56ra() {
7089         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7090                 skip "MDS < 2.12.58 doesn't return LSOM data"
7091         local dir=$DIR/$tdir
7092         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7093
7094         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7095
7096         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7097         $LCTL set_param -n llite.*.statahead_agl=0
7098         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7099
7100         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7101         # open and close all files to ensure LSOM is updated
7102         cancel_lru_locks $OSC
7103         find $dir -type f | xargs cat > /dev/null
7104
7105         #   expect_found  glimpse_rpcs  command_to_run
7106         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7107         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7108         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7109         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7110
7111         echo "test" > $dir/$tfile
7112         echo "test2" > $dir/$tfile.2 && sync
7113         cancel_lru_locks $OSC
7114         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7115
7116         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7117         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7118         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7119         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7120
7121         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7122         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7123         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7124         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7125         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7126         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7127 }
7128 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7129
7130 test_56rb() {
7131         local dir=$DIR/$tdir
7132         local tmp=$TMP/$tfile.log
7133         local mdt_idx;
7134
7135         test_mkdir -p $dir || error "failed to mkdir $dir"
7136         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7137                 error "failed to setstripe $dir/$tfile"
7138         mdt_idx=$($LFS getdirstripe -i $dir)
7139         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7140
7141         stack_trap "rm -f $tmp" EXIT
7142         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7143         ! grep -q obd_uuid $tmp ||
7144                 error "failed to find --size +100K --ost 0 $dir"
7145         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7146         ! grep -q obd_uuid $tmp ||
7147                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7148 }
7149 run_test 56rb "check lfs find --size --ost/--mdt works"
7150
7151 test_56rc() {
7152         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7153         local dir=$DIR/$tdir
7154         local found
7155
7156         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7157         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7158         (( $MDSCOUNT > 2 )) &&
7159                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7160         mkdir $dir/$tdir-{1..10}
7161         touch $dir/$tfile-{1..10}
7162
7163         found=$($LFS find $dir --mdt-count 2 | wc -l)
7164         expect=11
7165         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7166
7167         found=$($LFS find $dir -T +1 | wc -l)
7168         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7169         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7170
7171         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7172         expect=11
7173         (( $found == $expect )) || error "found $found all_char, expect $expect"
7174
7175         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7176         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7177         (( $found == $expect )) || error "found $found all_char, expect $expect"
7178 }
7179 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7180
7181 test_56rd() {
7182         local dir=$DIR/$tdir
7183
7184         test_mkdir $dir
7185         rm -f $dir/*
7186
7187         mkfifo $dir/fifo || error "failed to create fifo file"
7188         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7189                 error "should not fail even cannot get projid from pipe file"
7190         found=$($LFS find $dir -t p --printf "%y")
7191         [[ "p" == $found ]] || error "found $found, expect p"
7192
7193         mknod $dir/chardev c 1 5 ||
7194                 error "failed to create character device file"
7195         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7196                 error "should not fail even cannot get projid from chardev file"
7197         found=$($LFS find $dir -t c --printf "%y")
7198         [[ "c" == $found ]] || error "found $found, expect c"
7199
7200         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7201         (( found == 2 )) || error "unable to list all files"
7202 }
7203 run_test 56rd "check lfs find --printf special files"
7204
7205 test_56s() { # LU-611 #LU-9369
7206         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7207
7208         local dir=$DIR/$tdir
7209         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7210
7211         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7212         for i in $(seq $NUMDIRS); do
7213                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7214         done
7215
7216         local expected=$NUMDIRS
7217         local cmd="$LFS find -c $OSTCOUNT $dir"
7218         local nums=$($cmd | wc -l)
7219
7220         [ $nums -eq $expected ] || {
7221                 $LFS getstripe -R $dir
7222                 error "'$cmd' wrong: found $nums, expected $expected"
7223         }
7224
7225         expected=$((NUMDIRS + onestripe))
7226         cmd="$LFS find -stripe-count +0 -type f $dir"
7227         nums=$($cmd | wc -l)
7228         [ $nums -eq $expected ] || {
7229                 $LFS getstripe -R $dir
7230                 error "'$cmd' wrong: found $nums, expected $expected"
7231         }
7232
7233         expected=$onestripe
7234         cmd="$LFS find -stripe-count 1 -type f $dir"
7235         nums=$($cmd | wc -l)
7236         [ $nums -eq $expected ] || {
7237                 $LFS getstripe -R $dir
7238                 error "'$cmd' wrong: found $nums, expected $expected"
7239         }
7240
7241         cmd="$LFS find -stripe-count -2 -type f $dir"
7242         nums=$($cmd | wc -l)
7243         [ $nums -eq $expected ] || {
7244                 $LFS getstripe -R $dir
7245                 error "'$cmd' wrong: found $nums, expected $expected"
7246         }
7247
7248         expected=0
7249         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7250         nums=$($cmd | wc -l)
7251         [ $nums -eq $expected ] || {
7252                 $LFS getstripe -R $dir
7253                 error "'$cmd' wrong: found $nums, expected $expected"
7254         }
7255 }
7256 run_test 56s "check lfs find -stripe-count works"
7257
7258 test_56t() { # LU-611 #LU-9369
7259         local dir=$DIR/$tdir
7260
7261         setup_56 $dir 0 $NUMDIRS
7262         for i in $(seq $NUMDIRS); do
7263                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7264         done
7265
7266         local expected=$NUMDIRS
7267         local cmd="$LFS find -S 8M $dir"
7268         local nums=$($cmd | wc -l)
7269
7270         [ $nums -eq $expected ] || {
7271                 $LFS getstripe -R $dir
7272                 error "'$cmd' wrong: found $nums, expected $expected"
7273         }
7274         rm -rf $dir
7275
7276         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7277
7278         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7279
7280         expected=$(((NUMDIRS + 1) * NUMFILES))
7281         cmd="$LFS find -stripe-size 512k -type f $dir"
7282         nums=$($cmd | wc -l)
7283         [ $nums -eq $expected ] ||
7284                 error "'$cmd' wrong: found $nums, expected $expected"
7285
7286         cmd="$LFS find -stripe-size +320k -type f $dir"
7287         nums=$($cmd | wc -l)
7288         [ $nums -eq $expected ] ||
7289                 error "'$cmd' wrong: found $nums, expected $expected"
7290
7291         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7292         cmd="$LFS find -stripe-size +200k -type f $dir"
7293         nums=$($cmd | wc -l)
7294         [ $nums -eq $expected ] ||
7295                 error "'$cmd' wrong: found $nums, expected $expected"
7296
7297         cmd="$LFS find -stripe-size -640k -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] ||
7300                 error "'$cmd' wrong: found $nums, expected $expected"
7301
7302         expected=4
7303         cmd="$LFS find -stripe-size 256k -type f $dir"
7304         nums=$($cmd | wc -l)
7305         [ $nums -eq $expected ] ||
7306                 error "'$cmd' wrong: found $nums, expected $expected"
7307
7308         cmd="$LFS find -stripe-size -320k -type f $dir"
7309         nums=$($cmd | wc -l)
7310         [ $nums -eq $expected ] ||
7311                 error "'$cmd' wrong: found $nums, expected $expected"
7312
7313         expected=0
7314         cmd="$LFS find -stripe-size 1024k -type f $dir"
7315         nums=$($cmd | wc -l)
7316         [ $nums -eq $expected ] ||
7317                 error "'$cmd' wrong: found $nums, expected $expected"
7318 }
7319 run_test 56t "check lfs find -stripe-size works"
7320
7321 test_56u() { # LU-611
7322         local dir=$DIR/$tdir
7323
7324         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7325
7326         if [[ $OSTCOUNT -gt 1 ]]; then
7327                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7328                 onestripe=4
7329         else
7330                 onestripe=0
7331         fi
7332
7333         local expected=$(((NUMDIRS + 1) * NUMFILES))
7334         local cmd="$LFS find -stripe-index 0 -type f $dir"
7335         local nums=$($cmd | wc -l)
7336
7337         [ $nums -eq $expected ] ||
7338                 error "'$cmd' wrong: found $nums, expected $expected"
7339
7340         expected=$onestripe
7341         cmd="$LFS find -stripe-index 1 -type f $dir"
7342         nums=$($cmd | wc -l)
7343         [ $nums -eq $expected ] ||
7344                 error "'$cmd' wrong: found $nums, expected $expected"
7345
7346         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7347         nums=$($cmd | wc -l)
7348         [ $nums -eq $expected ] ||
7349                 error "'$cmd' wrong: found $nums, expected $expected"
7350
7351         expected=0
7352         # This should produce an error and not return any files
7353         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7354         nums=$($cmd 2>/dev/null | wc -l)
7355         [ $nums -eq $expected ] ||
7356                 error "'$cmd' wrong: found $nums, expected $expected"
7357
7358         if [[ $OSTCOUNT -gt 1 ]]; then
7359                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7360                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7361                 nums=$($cmd | wc -l)
7362                 [ $nums -eq $expected ] ||
7363                         error "'$cmd' wrong: found $nums, expected $expected"
7364         fi
7365 }
7366 run_test 56u "check lfs find -stripe-index works"
7367
7368 test_56v() {
7369         local mdt_idx=0
7370         local dir=$DIR/$tdir
7371
7372         setup_56 $dir $NUMFILES $NUMDIRS
7373
7374         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7375         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7376
7377         for file in $($LFS find -m $UUID $dir); do
7378                 file_midx=$($LFS getstripe -m $file)
7379                 [ $file_midx -eq $mdt_idx ] ||
7380                         error "lfs find -m $UUID != getstripe -m $file_midx"
7381         done
7382 }
7383 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7384
7385 test_56wa() {
7386         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7388
7389         local dir=$DIR/$tdir
7390
7391         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7392         stack_trap "rm -rf $dir"
7393
7394         local stripe_size=$($LFS getstripe -S -d $dir) ||
7395                 error "$LFS getstripe -S -d $dir failed"
7396         stripe_size=${stripe_size%% *}
7397
7398         local file_size=$((stripe_size * OSTCOUNT))
7399         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7400         local required_space=$((file_num * file_size))
7401         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7402                            head -n1)
7403         (( free_space >= required_space / 1024 )) ||
7404                 skip_env "need $required_space, have $free_space kbytes"
7405
7406         local dd_bs=65536
7407         local dd_count=$((file_size / dd_bs))
7408
7409         # write data into the files
7410         local i
7411         local j
7412         local file
7413
7414         for ((i = 1; i <= NUMFILES; i++ )); do
7415                 file=$dir/file$i
7416                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7417                         error "write data into $file failed"
7418         done
7419         for ((i = 1; i <= NUMDIRS; i++ )); do
7420                 for ((j = 1; j <= NUMFILES; j++ )); do
7421                         file=$dir/dir$i/file$j
7422                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7423                                 error "write data into $file failed"
7424                 done
7425         done
7426
7427         # $LFS_MIGRATE will fail if hard link migration is unsupported
7428         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7429                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7430                         error "creating links to $dir/dir1/file1 failed"
7431         fi
7432
7433         local expected=-1
7434
7435         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7436
7437         # lfs_migrate file
7438         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7439
7440         echo "$cmd"
7441         eval $cmd || error "$cmd failed"
7442
7443         check_stripe_count $dir/file1 $expected
7444
7445         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7446                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7447                 # OST 1 if it is on OST 0. This file is small enough to
7448                 # be on only one stripe.
7449                 file=$dir/migr_1_ost
7450                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7451                         error "write data into $file failed"
7452                 local obdidx=$($LFS getstripe -i $file)
7453                 local oldmd5=$(md5sum $file)
7454                 local newobdidx=0
7455
7456                 (( obdidx != 0 )) || newobdidx=1
7457                 cmd="$LFS migrate -i $newobdidx $file"
7458                 echo $cmd
7459                 eval $cmd || error "$cmd failed"
7460
7461                 local realobdix=$($LFS getstripe -i $file)
7462                 local newmd5=$(md5sum $file)
7463
7464                 (( $newobdidx == $realobdix )) ||
7465                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7466                 [[ "$oldmd5" == "$newmd5" ]] ||
7467                         error "md5sum differ: $oldmd5, $newmd5"
7468         fi
7469
7470         # lfs_migrate dir
7471         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7472         echo "$cmd"
7473         eval $cmd || error "$cmd failed"
7474
7475         for (( j = 1; j <= NUMFILES; j++ )); do
7476                 check_stripe_count $dir/dir1/file$j $expected
7477         done
7478
7479         # lfs_migrate works with lfs find
7480         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7481              $LFS_MIGRATE -y -c $expected"
7482         echo "$cmd"
7483         eval $cmd || error "$cmd failed"
7484
7485         for (( i = 2; i <= NUMFILES; i++ )); do
7486                 check_stripe_count $dir/file$i $expected
7487         done
7488         for (( i = 2; i <= NUMDIRS; i++ )); do
7489                 for (( j = 1; j <= NUMFILES; j++ )); do
7490                         check_stripe_count $dir/dir$i/file$j $expected
7491                 done
7492         done
7493 }
7494 run_test 56wa "check lfs_migrate -c stripe_count works"
7495
7496 test_56wb() {
7497         local file1=$DIR/$tdir/file1
7498         local create_pool=false
7499         local initial_pool=$($LFS getstripe -p $DIR)
7500         local pool_list=()
7501         local pool=""
7502
7503         echo -n "Creating test dir..."
7504         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7505         echo "done."
7506
7507         echo -n "Creating test file..."
7508         touch $file1 || error "cannot create file"
7509         echo "done."
7510
7511         echo -n "Detecting existing pools..."
7512         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7513
7514         if [ ${#pool_list[@]} -gt 0 ]; then
7515                 echo "${pool_list[@]}"
7516                 for thispool in "${pool_list[@]}"; do
7517                         if [[ -z "$initial_pool" ||
7518                               "$initial_pool" != "$thispool" ]]; then
7519                                 pool="$thispool"
7520                                 echo "Using existing pool '$pool'"
7521                                 break
7522                         fi
7523                 done
7524         else
7525                 echo "none detected."
7526         fi
7527         if [ -z "$pool" ]; then
7528                 pool=${POOL:-testpool}
7529                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7530                 echo -n "Creating pool '$pool'..."
7531                 create_pool=true
7532                 pool_add $pool &> /dev/null ||
7533                         error "pool_add failed"
7534                 echo "done."
7535
7536                 echo -n "Adding target to pool..."
7537                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7538                         error "pool_add_targets failed"
7539                 echo "done."
7540         fi
7541
7542         echo -n "Setting pool using -p option..."
7543         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7544                 error "migrate failed rc = $?"
7545         echo "done."
7546
7547         echo -n "Verifying test file is in pool after migrating..."
7548         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7549                 error "file was not migrated to pool $pool"
7550         echo "done."
7551
7552         echo -n "Removing test file from pool '$pool'..."
7553         # "lfs migrate $file" won't remove the file from the pool
7554         # until some striping information is changed.
7555         $LFS migrate -c 1 $file1 &> /dev/null ||
7556                 error "cannot remove from pool"
7557         [ "$($LFS getstripe -p $file1)" ] &&
7558                 error "pool still set"
7559         echo "done."
7560
7561         echo -n "Setting pool using --pool option..."
7562         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7563                 error "migrate failed rc = $?"
7564         echo "done."
7565
7566         # Clean up
7567         rm -f $file1
7568         if $create_pool; then
7569                 destroy_test_pools 2> /dev/null ||
7570                         error "destroy test pools failed"
7571         fi
7572 }
7573 run_test 56wb "check lfs_migrate pool support"
7574
7575 test_56wc() {
7576         local file1="$DIR/$tdir/$tfile"
7577         local md5
7578         local parent_ssize
7579         local parent_scount
7580         local cur_ssize
7581         local cur_scount
7582         local orig_ssize
7583         local new_scount
7584         local cur_comp
7585
7586         echo -n "Creating test dir..."
7587         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7588         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7589                 error "cannot set stripe by '-S 1M -c 1'"
7590         echo "done"
7591
7592         echo -n "Setting initial stripe for test file..."
7593         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7594                 error "cannot set stripe"
7595         cur_ssize=$($LFS getstripe -S "$file1")
7596         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7597         echo "done."
7598
7599         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7600         stack_trap "rm -f $file1"
7601         md5="$(md5sum $file1)"
7602
7603         # File currently set to -S 512K -c 1
7604
7605         # Ensure -c and -S options are rejected when -R is set
7606         echo -n "Verifying incompatible options are detected..."
7607         $LFS_MIGRATE -R -c 1 "$file1" &&
7608                 error "incompatible -R and -c options not detected"
7609         $LFS_MIGRATE -R -S 1M "$file1" &&
7610                 error "incompatible -R and -S options not detected"
7611         $LFS_MIGRATE -R -p pool "$file1" &&
7612                 error "incompatible -R and -p options not detected"
7613         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7614                 error "incompatible -R and -E options not detected"
7615         $LFS_MIGRATE -R -A "$file1" &&
7616                 error "incompatible -R and -A options not detected"
7617         $LFS_MIGRATE -A -c 1 "$file1" &&
7618                 error "incompatible -A and -c options not detected"
7619         $LFS_MIGRATE -A -S 1M "$file1" &&
7620                 error "incompatible -A and -S options not detected"
7621         $LFS_MIGRATE -A -p pool "$file1" &&
7622                 error "incompatible -A and -p options not detected"
7623         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7624                 error "incompatible -A and -E options not detected"
7625         echo "done."
7626
7627         # Ensure unrecognized options are passed through to 'lfs migrate'
7628         echo -n "Verifying -S option is passed through to lfs migrate..."
7629         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7630         cur_ssize=$($LFS getstripe -S "$file1")
7631         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7632         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7633         echo "done."
7634
7635         # File currently set to -S 1M -c 1
7636
7637         # Ensure long options are supported
7638         echo -n "Verifying long options supported..."
7639         $LFS_MIGRATE --non-block "$file1" ||
7640                 error "long option without argument not supported"
7641         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7642                 error "long option with argument not supported"
7643         cur_ssize=$($LFS getstripe -S "$file1")
7644         (( cur_ssize == 524288 )) ||
7645                 error "migrate --stripe-size $cur_ssize != 524288"
7646         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7647         echo "done."
7648
7649         # File currently set to -S 512K -c 1
7650
7651         if (( OSTCOUNT > 1 )); then
7652                 echo -n "Verifying explicit stripe count can be set..."
7653                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7654                 cur_scount=$($LFS getstripe -c "$file1")
7655                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7656                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7657                         error "file data has changed (3)"
7658                 echo "done."
7659         fi
7660
7661         # File currently set to -S 512K -c 1 or -S 512K -c 2
7662
7663         # Ensure parent striping is used if -R is set, and no stripe
7664         # count or size is specified
7665         echo -n "Setting stripe for parent directory..."
7666         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7667                 error "cannot set stripe '-S 2M -c 1'"
7668         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7669         echo "done."
7670
7671         echo -n "Verifying restripe option uses parent stripe settings..."
7672         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7673         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7674         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7675         cur_ssize=$($LFS getstripe -S "$file1")
7676         (( cur_ssize == parent_ssize )) ||
7677                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7678         cur_scount=$($LFS getstripe -c "$file1")
7679         (( cur_scount == parent_scount )) ||
7680                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7681         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7682         echo "done."
7683
7684         # File currently set to -S 1M -c 1
7685
7686         # Ensure striping is preserved if -R is not set, and no stripe
7687         # count or size is specified
7688         echo -n "Verifying striping size preserved when not specified..."
7689         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7690         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7691                 error "cannot set stripe on parent directory"
7692         $LFS_MIGRATE "$file1" || error "migrate failed"
7693         cur_ssize=$($LFS getstripe -S "$file1")
7694         (( cur_ssize == orig_ssize )) ||
7695                 error "migrate by default $cur_ssize != $orig_ssize"
7696         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7697         echo "done."
7698
7699         # Ensure file name properly detected when final option has no argument
7700         echo -n "Verifying file name properly detected..."
7701         $LFS_MIGRATE "$file1" ||
7702                 error "file name interpreted as option argument"
7703         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7704         echo "done."
7705
7706         # Ensure PFL arguments are passed through properly
7707         echo -n "Verifying PFL options passed through..."
7708         new_scount=$(((OSTCOUNT + 1) / 2))
7709         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7710                 error "migrate PFL arguments failed"
7711         cur_comp=$($LFS getstripe --comp-count $file1)
7712         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7713         cur_scount=$($LFS getstripe --stripe-count $file1)
7714         (( cur_scount == new_scount)) ||
7715                 error "PFL stripe count $cur_scount != $new_scount"
7716         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7717         echo "done."
7718 }
7719 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7720
7721 test_56wd() {
7722         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7723
7724         local file1=$DIR/$tdir/$tfile
7725
7726         echo -n "Creating test dir..."
7727         test_mkdir $DIR/$tdir || error "cannot create dir"
7728         echo "done."
7729
7730         echo -n "Creating test file..."
7731         echo "$tfile" > $file1
7732         echo "done."
7733
7734         # Ensure 'lfs migrate' will fail by using a non-existent option,
7735         # and make sure rsync is not called to recover
7736         echo -n "Make sure --no-rsync option works..."
7737         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7738                 grep -q 'refusing to fall back to rsync' ||
7739                 error "rsync was called with --no-rsync set"
7740         echo "done."
7741
7742         # Ensure rsync is called without trying 'lfs migrate' first
7743         echo -n "Make sure --rsync option works..."
7744         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7745                 grep -q 'falling back to rsync' &&
7746                 error "lfs migrate was called with --rsync set"
7747         echo "done."
7748 }
7749 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7750
7751 test_56we() {
7752         local td=$DIR/$tdir
7753         local tf=$td/$tfile
7754
7755         test_mkdir $td || error "cannot create $td"
7756         touch $tf || error "cannot touch $tf"
7757
7758         echo -n "Make sure --non-direct|-D works..."
7759         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7760                 grep -q "lfs migrate --non-direct" ||
7761                 error "--non-direct option cannot work correctly"
7762         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7763                 grep -q "lfs migrate -D" ||
7764                 error "-D option cannot work correctly"
7765         echo "done."
7766 }
7767 run_test 56we "check lfs_migrate --non-direct|-D support"
7768
7769 test_56x() {
7770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7771         check_swap_layouts_support
7772
7773         local dir=$DIR/$tdir
7774         local ref1=/etc/passwd
7775         local file1=$dir/file1
7776
7777         test_mkdir $dir || error "creating dir $dir"
7778         $LFS setstripe -c 2 $file1
7779         cp $ref1 $file1
7780         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7781         stripe=$($LFS getstripe -c $file1)
7782         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7783         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7784
7785         # clean up
7786         rm -f $file1
7787 }
7788 run_test 56x "lfs migration support"
7789
7790 test_56xa() {
7791         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7792         check_swap_layouts_support
7793
7794         local dir=$DIR/$tdir/$testnum
7795
7796         test_mkdir -p $dir
7797
7798         local ref1=/etc/passwd
7799         local file1=$dir/file1
7800
7801         $LFS setstripe -c 2 $file1
7802         cp $ref1 $file1
7803         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7804
7805         local stripe=$($LFS getstripe -c $file1)
7806
7807         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7808         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7809
7810         # clean up
7811         rm -f $file1
7812 }
7813 run_test 56xa "lfs migration --block support"
7814
7815 check_migrate_links() {
7816         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7817         local dir="$1"
7818         local file1="$dir/file1"
7819         local begin="$2"
7820         local count="$3"
7821         local runas="$4"
7822         local total_count=$(($begin + $count - 1))
7823         local symlink_count=10
7824         local uniq_count=10
7825
7826         if [ ! -f "$file1" ]; then
7827                 echo -n "creating initial file..."
7828                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7829                         error "cannot setstripe initial file"
7830                 echo "done"
7831
7832                 echo -n "creating symlinks..."
7833                 for s in $(seq 1 $symlink_count); do
7834                         ln -s "$file1" "$dir/slink$s" ||
7835                                 error "cannot create symlinks"
7836                 done
7837                 echo "done"
7838
7839                 echo -n "creating nonlinked files..."
7840                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7841                         error "cannot create nonlinked files"
7842                 echo "done"
7843         fi
7844
7845         # create hard links
7846         if [ ! -f "$dir/file$total_count" ]; then
7847                 echo -n "creating hard links $begin:$total_count..."
7848                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7849                         /dev/null || error "cannot create hard links"
7850                 echo "done"
7851         fi
7852
7853         echo -n "checking number of hard links listed in xattrs..."
7854         local fid=$($LFS getstripe -F "$file1")
7855         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7856
7857         echo "${#paths[*]}"
7858         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7859                         skip "hard link list has unexpected size, skipping test"
7860         fi
7861         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7862                         error "link names should exceed xattrs size"
7863         fi
7864
7865         echo -n "migrating files..."
7866         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7867         local rc=$?
7868         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7869         echo "done"
7870
7871         # make sure all links have been properly migrated
7872         echo -n "verifying files..."
7873         fid=$($LFS getstripe -F "$file1") ||
7874                 error "cannot get fid for file $file1"
7875         for i in $(seq 2 $total_count); do
7876                 local fid2=$($LFS getstripe -F $dir/file$i)
7877
7878                 [ "$fid2" == "$fid" ] ||
7879                         error "migrated hard link has mismatched FID"
7880         done
7881
7882         # make sure hard links were properly detected, and migration was
7883         # performed only once for the entire link set; nonlinked files should
7884         # also be migrated
7885         local actual=$(grep -c 'done' <<< "$migrate_out")
7886         local expected=$(($uniq_count + 1))
7887
7888         [ "$actual" -eq  "$expected" ] ||
7889                 error "hard links individually migrated ($actual != $expected)"
7890
7891         # make sure the correct number of hard links are present
7892         local hardlinks=$(stat -c '%h' "$file1")
7893
7894         [ $hardlinks -eq $total_count ] ||
7895                 error "num hard links $hardlinks != $total_count"
7896         echo "done"
7897
7898         return 0
7899 }
7900
7901 test_56xb() {
7902         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7903                 skip "Need MDS version at least 2.10.55"
7904
7905         local dir="$DIR/$tdir"
7906
7907         test_mkdir "$dir" || error "cannot create dir $dir"
7908
7909         echo "testing lfs migrate mode when all links fit within xattrs"
7910         check_migrate_links "$dir" 2 99
7911
7912         echo "testing rsync mode when all links fit within xattrs"
7913         check_migrate_links --rsync "$dir" 2 99
7914
7915         echo "testing lfs migrate mode when all links do not fit within xattrs"
7916         check_migrate_links "$dir" 101 100
7917
7918         echo "testing rsync mode when all links do not fit within xattrs"
7919         check_migrate_links --rsync "$dir" 101 100
7920
7921         chown -R $RUNAS_ID $dir
7922         echo "testing non-root lfs migrate mode when not all links are in xattr"
7923         check_migrate_links "$dir" 101 100 "$RUNAS"
7924
7925         # clean up
7926         rm -rf $dir
7927 }
7928 run_test 56xb "lfs migration hard link support"
7929
7930 test_56xc() {
7931         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7932
7933         local dir="$DIR/$tdir"
7934
7935         test_mkdir "$dir" || error "cannot create dir $dir"
7936
7937         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7938         echo -n "Setting initial stripe for 20MB test file..."
7939         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7940                 error "cannot setstripe 20MB file"
7941         echo "done"
7942         echo -n "Sizing 20MB test file..."
7943         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7944         echo "done"
7945         echo -n "Verifying small file autostripe count is 1..."
7946         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7947                 error "cannot migrate 20MB file"
7948         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7949                 error "cannot get stripe for $dir/20mb"
7950         [ $stripe_count -eq 1 ] ||
7951                 error "unexpected stripe count $stripe_count for 20MB file"
7952         rm -f "$dir/20mb"
7953         echo "done"
7954
7955         # Test 2: File is small enough to fit within the available space on
7956         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7957         # have at least an additional 1KB for each desired stripe for test 3
7958         echo -n "Setting stripe for 1GB test file..."
7959         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7960         echo "done"
7961         echo -n "Sizing 1GB test file..."
7962         # File size is 1GB + 3KB
7963         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7964         echo "done"
7965
7966         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7967         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7968         if (( avail > 524288 * OSTCOUNT )); then
7969                 echo -n "Migrating 1GB file..."
7970                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7971                         error "cannot migrate 1GB file"
7972                 echo "done"
7973                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7974                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7975                         error "cannot getstripe for 1GB file"
7976                 [ $stripe_count -eq 2 ] ||
7977                         error "unexpected stripe count $stripe_count != 2"
7978                 echo "done"
7979         fi
7980
7981         # Test 3: File is too large to fit within the available space on
7982         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7983         if [ $OSTCOUNT -ge 3 ]; then
7984                 # The required available space is calculated as
7985                 # file size (1GB + 3KB) / OST count (3).
7986                 local kb_per_ost=349526
7987
7988                 echo -n "Migrating 1GB file with limit..."
7989                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7990                         error "cannot migrate 1GB file with limit"
7991                 echo "done"
7992
7993                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7994                 echo -n "Verifying 1GB autostripe count with limited space..."
7995                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7996                         error "unexpected stripe count $stripe_count (min 3)"
7997                 echo "done"
7998         fi
7999
8000         # clean up
8001         rm -rf $dir
8002 }
8003 run_test 56xc "lfs migration autostripe"
8004
8005 test_56xd() {
8006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8007
8008         local dir=$DIR/$tdir
8009         local f_mgrt=$dir/$tfile.mgrt
8010         local f_yaml=$dir/$tfile.yaml
8011         local f_copy=$dir/$tfile.copy
8012         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8013         local layout_copy="-c 2 -S 2M -i 1"
8014         local yamlfile=$dir/yamlfile
8015         local layout_before;
8016         local layout_after;
8017
8018         test_mkdir "$dir" || error "cannot create dir $dir"
8019         stack_trap "rm -rf $dir"
8020         $LFS setstripe $layout_yaml $f_yaml ||
8021                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8022         $LFS getstripe --yaml $f_yaml > $yamlfile
8023         $LFS setstripe $layout_copy $f_copy ||
8024                 error "cannot setstripe $f_copy with layout $layout_copy"
8025         touch $f_mgrt
8026         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8027
8028         # 1. test option --yaml
8029         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8030                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8031         layout_before=$(get_layout_param $f_yaml)
8032         layout_after=$(get_layout_param $f_mgrt)
8033         [ "$layout_after" == "$layout_before" ] ||
8034                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8035
8036         # 2. test option --copy
8037         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8038                 error "cannot migrate $f_mgrt with --copy $f_copy"
8039         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8040         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8041         [ "$layout_after" == "$layout_before" ] ||
8042                 error "lfs_migrate --copy: $layout_after != $layout_before"
8043 }
8044 run_test 56xd "check lfs_migrate --yaml and --copy support"
8045
8046 test_56xe() {
8047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8048
8049         local dir=$DIR/$tdir
8050         local f_comp=$dir/$tfile
8051         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8052         local layout_before=""
8053         local layout_after=""
8054
8055         test_mkdir "$dir" || error "cannot create dir $dir"
8056         stack_trap "rm -rf $dir"
8057         $LFS setstripe $layout $f_comp ||
8058                 error "cannot setstripe $f_comp with layout $layout"
8059         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8060         dd if=/dev/zero of=$f_comp bs=1M count=4
8061
8062         # 1. migrate a comp layout file by lfs_migrate
8063         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8064         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8065         [ "$layout_before" == "$layout_after" ] ||
8066                 error "lfs_migrate: $layout_before != $layout_after"
8067
8068         # 2. migrate a comp layout file by lfs migrate
8069         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8070         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8071         [ "$layout_before" == "$layout_after" ] ||
8072                 error "lfs migrate: $layout_before != $layout_after"
8073 }
8074 run_test 56xe "migrate a composite layout file"
8075
8076 test_56xf() {
8077         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8078
8079         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8080                 skip "Need server version at least 2.13.53"
8081
8082         local dir=$DIR/$tdir
8083         local f_comp=$dir/$tfile
8084         local layout="-E 1M -c1 -E -1 -c2"
8085         local fid_before=""
8086         local fid_after=""
8087
8088         test_mkdir "$dir" || error "cannot create dir $dir"
8089         stack_trap "rm -rf $dir"
8090         $LFS setstripe $layout $f_comp ||
8091                 error "cannot setstripe $f_comp with layout $layout"
8092         fid_before=$($LFS getstripe --fid $f_comp)
8093         dd if=/dev/zero of=$f_comp bs=1M count=4
8094
8095         # 1. migrate a comp layout file to a comp layout
8096         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8097         fid_after=$($LFS getstripe --fid $f_comp)
8098         [ "$fid_before" == "$fid_after" ] ||
8099                 error "comp-to-comp migrate: $fid_before != $fid_after"
8100
8101         # 2. migrate a comp layout file to a plain layout
8102         $LFS migrate -c2 $f_comp ||
8103                 error "cannot migrate $f_comp by lfs migrate"
8104         fid_after=$($LFS getstripe --fid $f_comp)
8105         [ "$fid_before" == "$fid_after" ] ||
8106                 error "comp-to-plain migrate: $fid_before != $fid_after"
8107
8108         # 3. migrate a plain layout file to a comp layout
8109         $LFS migrate $layout $f_comp ||
8110                 error "cannot migrate $f_comp by lfs migrate"
8111         fid_after=$($LFS getstripe --fid $f_comp)
8112         [ "$fid_before" == "$fid_after" ] ||
8113                 error "plain-to-comp migrate: $fid_before != $fid_after"
8114 }
8115 run_test 56xf "FID is not lost during migration of a composite layout file"
8116
8117 check_file_ost_range() {
8118         local file="$1"
8119         shift
8120         local range="$*"
8121         local -a file_range
8122         local idx
8123
8124         file_range=($($LFS getstripe -y "$file" |
8125                 awk '/l_ost_idx:/ { print $NF }'))
8126
8127         if [[ "${#file_range[@]}" = 0 ]]; then
8128                 echo "No osts found for $file"
8129                 return 1
8130         fi
8131
8132         for idx in "${file_range[@]}"; do
8133                 [[ " $range " =~ " $idx " ]] ||
8134                         return 1
8135         done
8136
8137         return 0
8138 }
8139
8140 sub_test_56xg() {
8141         local stripe_opt="$1"
8142         local pool="$2"
8143         shift 2
8144         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8145
8146         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8147                 error "Fail to migrate $tfile on $pool"
8148         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8149                 error "$tfile is not in pool $pool"
8150         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8151                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8152 }
8153
8154 test_56xg() {
8155         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8156         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8157         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8158                 skip "Need MDS version newer than 2.14.52"
8159
8160         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8161         local -a pool_ranges=("0 0" "1 1" "0 1")
8162
8163         # init pools
8164         for i in "${!pool_names[@]}"; do
8165                 pool_add ${pool_names[$i]} ||
8166                         error "pool_add failed (pool: ${pool_names[$i]})"
8167                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8168                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8169         done
8170
8171         # init the file to migrate
8172         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8173                 error "Unable to create $tfile on OST1"
8174         stack_trap "rm -f $DIR/$tfile"
8175         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8176                 error "Unable to write on $tfile"
8177
8178         echo "1. migrate $tfile on pool ${pool_names[0]}"
8179         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8180
8181         echo "2. migrate $tfile on pool ${pool_names[2]}"
8182         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8183
8184         echo "3. migrate $tfile on pool ${pool_names[1]}"
8185         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8186
8187         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8188         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8189         echo
8190
8191         # Clean pools
8192         destroy_test_pools ||
8193                 error "pool_destroy failed"
8194 }
8195 run_test 56xg "lfs migrate pool support"
8196
8197 test_56xh() {
8198         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8199
8200         local size_mb=25
8201         local file1=$DIR/$tfile
8202         local tmp1=$TMP/$tfile.tmp
8203
8204         $LFS setstripe -c 2 $file1
8205
8206         stack_trap "rm -f $file1 $tmp1"
8207         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8208                         error "error creating $tmp1"
8209         ls -lsh $tmp1
8210         cp $tmp1 $file1
8211
8212         local start=$SECONDS
8213
8214         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8215                 error "migrate failed rc = $?"
8216
8217         local elapsed=$((SECONDS - start))
8218
8219         # with 1MB/s, elapsed should equal size_mb
8220         (( elapsed >= size_mb * 95 / 100 )) ||
8221                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8222
8223         (( elapsed <= size_mb * 120 / 100 )) ||
8224                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8225
8226         (( elapsed <= size_mb * 350 / 100 )) ||
8227                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8228
8229         stripe=$($LFS getstripe -c $file1)
8230         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8231         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8232
8233         # Clean up file (since it is multiple MB)
8234         rm -f $file1 $tmp1
8235 }
8236 run_test 56xh "lfs migrate bandwidth limitation support"
8237
8238 test_56xi() {
8239         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8240         verify_yaml_available || skip_env "YAML verification not installed"
8241
8242         local size_mb=5
8243         local file1=$DIR/$tfile.1
8244         local file2=$DIR/$tfile.2
8245         local file3=$DIR/$tfile.3
8246         local output_file=$DIR/$tfile.out
8247         local tmp1=$TMP/$tfile.tmp
8248
8249         $LFS setstripe -c 2 $file1
8250         $LFS setstripe -c 2 $file2
8251         $LFS setstripe -c 2 $file3
8252
8253         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8254         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8255                         error "error creating $tmp1"
8256         ls -lsh $tmp1
8257         cp $tmp1 $file1
8258         cp $tmp1 $file2
8259         cp $tmp1 $file3
8260
8261         $LFS migrate --stats --stats-interval=1 \
8262                 -c 1 $file1 $file2 $file3 1> $output_file ||
8263                 error "migrate failed rc = $?"
8264
8265         cat $output_file
8266         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8267
8268         # Clean up file (since it is multiple MB)
8269         rm -f $file1 $file2 $file3 $tmp1 $output_file
8270 }
8271 run_test 56xi "lfs migrate stats support"
8272
8273 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8274         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8275
8276         local file=$DIR/$tfile
8277         local linkdir=$DIR/$tdir
8278
8279         test_mkdir $linkdir || error "fail to create $linkdir"
8280         $LFS setstripe -i 0 -c 1 -S1M $file
8281         stack_trap "rm -rf $file $linkdir"
8282         dd if=/dev/urandom of=$file bs=1M count=10 ||
8283                 error "fail to create $file"
8284
8285         # Create file links
8286         local cpts
8287         local threads_max
8288         local nlinks
8289
8290         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8291         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8292         (( nlinks = thread_max * 3 / 2 / cpts))
8293
8294         echo "create $nlinks hard links of $file"
8295         createmany -l $file $linkdir/link $nlinks
8296
8297         # Parallel migrates (should not block)
8298         local i
8299         for ((i = 0; i < nlinks; i++)); do
8300                 echo $linkdir/link$i
8301         done | xargs -n1 -P $nlinks $LFS migrate -c2
8302
8303         local stripe_count
8304         stripe_count=$($LFS getstripe -c $file) ||
8305                 error "fail to get stripe count on $file"
8306
8307         ((stripe_count == 2)) ||
8308                 error "fail to migrate $file (stripe_count = $stripe_count)"
8309 }
8310 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8311
8312 test_56xk() {
8313         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8314
8315         local size_mb=5
8316         local file1=$DIR/$tfile
8317
8318         stack_trap "rm -f $file1"
8319         $LFS setstripe -c 1 $file1
8320         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8321                 error "error creating $file1"
8322         $LFS mirror extend -N $file1 || error "can't mirror"
8323         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8324                 error "can't dd"
8325         $LFS getstripe $file1 | grep stale ||
8326                 error "one component must be stale"
8327
8328         local start=$SECONDS
8329         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8330                 error "migrate failed rc = $?"
8331         local elapsed=$((SECONDS - start))
8332         $LFS getstripe $file1 | grep stale &&
8333                 error "all components must be sync"
8334
8335         # with 1MB/s, elapsed should equal size_mb
8336         (( elapsed >= size_mb * 95 / 100 )) ||
8337                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8338
8339         (( elapsed <= size_mb * 120 / 100 )) ||
8340                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8341
8342         (( elapsed <= size_mb * 350 / 100 )) ||
8343                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8344 }
8345 run_test 56xk "lfs mirror resync bandwidth limitation support"
8346
8347 test_56xl() {
8348         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8349         verify_yaml_available || skip_env "YAML verification not installed"
8350
8351         local size_mb=5
8352         local file1=$DIR/$tfile.1
8353         local output_file=$DIR/$tfile.out
8354
8355         stack_trap "rm -f $file1"
8356         $LFS setstripe -c 1 $file1
8357         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8358                 error "error creating $file1"
8359         $LFS mirror extend -N $file1 || error "can't mirror"
8360         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8361                 error "can't dd"
8362         $LFS getstripe $file1 | grep stale ||
8363                 error "one component must be stale"
8364         $LFS getstripe $file1
8365
8366         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8367                 error "resync failed rc = $?"
8368         $LFS getstripe $file1 | grep stale &&
8369                 error "all components must be sync"
8370
8371         cat $output_file
8372         cat $output_file | verify_yaml || error "stats is not valid YAML"
8373 }
8374 run_test 56xl "lfs mirror resync stats support"
8375
8376 test_56y() {
8377         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8378                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8379
8380         local res=""
8381         local dir=$DIR/$tdir
8382         local f1=$dir/file1
8383         local f2=$dir/file2
8384
8385         test_mkdir -p $dir || error "creating dir $dir"
8386         touch $f1 || error "creating std file $f1"
8387         $MULTIOP $f2 H2c || error "creating released file $f2"
8388
8389         # a directory can be raid0, so ask only for files
8390         res=$($LFS find $dir -L raid0 -type f | wc -l)
8391         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8392
8393         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8394         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8395
8396         # only files can be released, so no need to force file search
8397         res=$($LFS find $dir -L released)
8398         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8399
8400         res=$($LFS find $dir -type f \! -L released)
8401         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8402 }
8403 run_test 56y "lfs find -L raid0|released"
8404
8405 test_56z() { # LU-4824
8406         # This checks to make sure 'lfs find' continues after errors
8407         # There are two classes of errors that should be caught:
8408         # - If multiple paths are provided, all should be searched even if one
8409         #   errors out
8410         # - If errors are encountered during the search, it should not terminate
8411         #   early
8412         local dir=$DIR/$tdir
8413         local i
8414
8415         test_mkdir $dir
8416         for i in d{0..9}; do
8417                 test_mkdir $dir/$i
8418                 touch $dir/$i/$tfile
8419         done
8420         $LFS find $DIR/non_existent_dir $dir &&
8421                 error "$LFS find did not return an error"
8422         # Make a directory unsearchable. This should NOT be the last entry in
8423         # directory order.  Arbitrarily pick the 6th entry
8424         chmod 700 $($LFS find $dir -type d | sed '6!d')
8425
8426         $RUNAS $LFS find $DIR/non_existent $dir
8427         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8428
8429         # The user should be able to see 10 directories and 9 files
8430         (( count == 19 )) ||
8431                 error "$LFS find found $count != 19 entries after error"
8432 }
8433 run_test 56z "lfs find should continue after an error"
8434
8435 test_56aa() { # LU-5937
8436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8437
8438         local dir=$DIR/$tdir
8439
8440         mkdir $dir
8441         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8442
8443         createmany -o $dir/striped_dir/${tfile}- 1024
8444         local dirs=$($LFS find --size +8k $dir/)
8445
8446         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8447 }
8448 run_test 56aa "lfs find --size under striped dir"
8449
8450 test_56ab() { # LU-10705
8451         test_mkdir $DIR/$tdir
8452         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8453         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8454         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8455         # Flush writes to ensure valid blocks.  Need to be more thorough for
8456         # ZFS, since blocks are not allocated/returned to client immediately.
8457         sync_all_data
8458         wait_zfs_commit ost1 2
8459         cancel_lru_locks osc
8460         ls -ls $DIR/$tdir
8461
8462         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8463
8464         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8465
8466         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8467         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8468
8469         rm -f $DIR/$tdir/$tfile.[123]
8470 }
8471 run_test 56ab "lfs find --blocks"
8472
8473 # LU-11188
8474 test_56aca() {
8475         local dir="$DIR/$tdir"
8476         local perms=(001 002 003 004 005 006 007
8477                      010 020 030 040 050 060 070
8478                      100 200 300 400 500 600 700
8479                      111 222 333 444 555 666 777)
8480         local perm_minus=(8 8 4 8 4 4 2
8481                           8 8 4 8 4 4 2
8482                           8 8 4 8 4 4 2
8483                           4 4 2 4 2 2 1)
8484         local perm_slash=(8  8 12  8 12 12 14
8485                           8  8 12  8 12 12 14
8486                           8  8 12  8 12 12 14
8487                          16 16 24 16 24 24 28)
8488
8489         test_mkdir "$dir"
8490         for perm in ${perms[*]}; do
8491                 touch "$dir/$tfile.$perm"
8492                 chmod $perm "$dir/$tfile.$perm"
8493         done
8494
8495         for ((i = 0; i < ${#perms[*]}; i++)); do
8496                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8497                 (( $num == 1 )) ||
8498                         error "lfs find -perm ${perms[i]}:"\
8499                               "$num != 1"
8500
8501                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8502                 (( $num == ${perm_minus[i]} )) ||
8503                         error "lfs find -perm -${perms[i]}:"\
8504                               "$num != ${perm_minus[i]}"
8505
8506                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8507                 (( $num == ${perm_slash[i]} )) ||
8508                         error "lfs find -perm /${perms[i]}:"\
8509                               "$num != ${perm_slash[i]}"
8510         done
8511 }
8512 run_test 56aca "check lfs find -perm with octal representation"
8513
8514 test_56acb() {
8515         local dir=$DIR/$tdir
8516         # p is the permission of write and execute for user, group and other
8517         # without the umask. It is used to test +wx.
8518         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8519         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8520         local symbolic=(+t  a+t u+t g+t o+t
8521                         g+s u+s o+s +s o+sr
8522                         o=r,ug+o,u+w
8523                         u+ g+ o+ a+ ugo+
8524                         u- g- o- a- ugo-
8525                         u= g= o= a= ugo=
8526                         o=r,ug+o,u+w u=r,a+u,u+w
8527                         g=r,ugo=g,u+w u+x,+X +X
8528                         u+x,u+X u+X u+x,g+X o+r,+X
8529                         u+x,go+X +wx +rwx)
8530
8531         test_mkdir $dir
8532         for perm in ${perms[*]}; do
8533                 touch "$dir/$tfile.$perm"
8534                 chmod $perm "$dir/$tfile.$perm"
8535         done
8536
8537         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8538                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8539
8540                 (( $num == 1 )) ||
8541                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8542         done
8543 }
8544 run_test 56acb "check lfs find -perm with symbolic representation"
8545
8546 test_56acc() {
8547         local dir=$DIR/$tdir
8548         local tests="17777 787 789 abcd
8549                 ug=uu ug=a ug=gu uo=ou urw
8550                 u+xg+x a=r,u+x,"
8551
8552         test_mkdir $dir
8553         for err in $tests; do
8554                 if $LFS find $dir -perm $err 2>/dev/null; then
8555                         error "lfs find -perm $err: parsing should have failed"
8556                 fi
8557         done
8558 }
8559 run_test 56acc "check parsing error for lfs find -perm"
8560
8561 test_56ba() {
8562         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8563                 skip "Need MDS version at least 2.10.50"
8564
8565         # Create composite files with one component
8566         local dir=$DIR/$tdir
8567
8568         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8569         # Create composite files with three components
8570         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8571         # LU-16904 Create plain layout files
8572         lfs setstripe -c 1 $dir/$tfile-{1..10}
8573
8574         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8575
8576         [[ $nfiles == 10 ]] ||
8577                 error "lfs find -E 1M found $nfiles != 10 files"
8578
8579         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8580         [[ $nfiles == 25 ]] ||
8581                 error "lfs find ! -E 1M found $nfiles != 25 files"
8582
8583         # All files have a component that starts at 0
8584         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8585         [[ $nfiles == 35 ]] ||
8586                 error "lfs find --component-start 0 - $nfiles != 35 files"
8587
8588         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8589         [[ $nfiles == 15 ]] ||
8590                 error "lfs find --component-start 2M - $nfiles != 15 files"
8591
8592         # All files created here have a componenet that does not starts at 2M
8593         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8594         [[ $nfiles == 35 ]] ||
8595                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8596
8597         # Find files with a specified number of components
8598         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8599         [[ $nfiles == 15 ]] ||
8600                 error "lfs find --component-count 3 - $nfiles != 15 files"
8601
8602         # Remember non-composite files have a component count of zero
8603         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8604         [[ $nfiles == 10 ]] ||
8605                 error "lfs find --component-count 0 - $nfiles != 10 files"
8606
8607         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8608         [[ $nfiles == 20 ]] ||
8609                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8610
8611         # All files have a flag called "init"
8612         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8613         [[ $nfiles == 35 ]] ||
8614                 error "lfs find --component-flags init - $nfiles != 35 files"
8615
8616         # Multi-component files will have a component not initialized
8617         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8618         [[ $nfiles == 15 ]] ||
8619                 error "lfs find !--component-flags init - $nfiles != 15 files"
8620
8621         rm -rf $dir
8622
8623 }
8624 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8625
8626 test_56ca() {
8627         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8628                 skip "Need MDS version at least 2.10.57"
8629
8630         local td=$DIR/$tdir
8631         local tf=$td/$tfile
8632         local dir
8633         local nfiles
8634         local cmd
8635         local i
8636         local j
8637
8638         # create mirrored directories and mirrored files
8639         mkdir $td || error "mkdir $td failed"
8640         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8641         createmany -o $tf- 10 || error "create $tf- failed"
8642
8643         for i in $(seq 2); do
8644                 dir=$td/dir$i
8645                 mkdir $dir || error "mkdir $dir failed"
8646                 $LFS mirror create -N$((3 + i)) $dir ||
8647                         error "create mirrored dir $dir failed"
8648                 createmany -o $dir/$tfile- 10 ||
8649                         error "create $dir/$tfile- failed"
8650         done
8651
8652         # change the states of some mirrored files
8653         echo foo > $tf-6
8654         for i in $(seq 2); do
8655                 dir=$td/dir$i
8656                 for j in $(seq 4 9); do
8657                         echo foo > $dir/$tfile-$j
8658                 done
8659         done
8660
8661         # find mirrored files with specific mirror count
8662         cmd="$LFS find --mirror-count 3 --type f $td"
8663         nfiles=$($cmd | wc -l)
8664         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8665
8666         cmd="$LFS find ! --mirror-count 3 --type f $td"
8667         nfiles=$($cmd | wc -l)
8668         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8669
8670         cmd="$LFS find --mirror-count +2 --type f $td"
8671         nfiles=$($cmd | wc -l)
8672         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8673
8674         cmd="$LFS find --mirror-count -6 --type f $td"
8675         nfiles=$($cmd | wc -l)
8676         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8677
8678         # find mirrored files with specific file state
8679         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8680         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8681
8682         cmd="$LFS find --mirror-state=ro --type f $td"
8683         nfiles=$($cmd | wc -l)
8684         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8685
8686         cmd="$LFS find ! --mirror-state=ro --type f $td"
8687         nfiles=$($cmd | wc -l)
8688         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8689
8690         cmd="$LFS find --mirror-state=wp --type f $td"
8691         nfiles=$($cmd | wc -l)
8692         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8693
8694         cmd="$LFS find ! --mirror-state=sp --type f $td"
8695         nfiles=$($cmd | wc -l)
8696         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8697 }
8698 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8699
8700 test_56da() { # LU-14179
8701         local path=$DIR/$tdir
8702
8703         test_mkdir $path
8704         cd $path
8705
8706         local longdir=$(str_repeat 'a' 255)
8707
8708         for i in {1..15}; do
8709                 path=$path/$longdir
8710                 test_mkdir $longdir
8711                 cd $longdir
8712         done
8713
8714         local len=${#path}
8715         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8716
8717         test_mkdir $lastdir
8718         cd $lastdir
8719         # PATH_MAX-1
8720         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8721
8722         # NAME_MAX
8723         touch $(str_repeat 'f' 255)
8724
8725         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8726                 error "lfs find reported an error"
8727
8728         rm -rf $DIR/$tdir
8729 }
8730 run_test 56da "test lfs find with long paths"
8731
8732 test_56ea() { #LU-10378
8733         local path=$DIR/$tdir
8734         local pool=$TESTNAME
8735
8736         # Create ost pool
8737         pool_add $pool || error "pool_add $pool failed"
8738         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8739                 error "adding targets to $pool failed"
8740
8741         # Set default pool on directory before creating file
8742         mkdir $path || error "mkdir $path failed"
8743         $LFS setstripe -p $pool $path ||
8744                 error "set OST pool on $pool failed"
8745         touch $path/$tfile || error "touch $path/$tfile failed"
8746
8747         # Compare basic file attributes from -printf and stat
8748         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8749         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8750
8751         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8752                 error "Attrs from lfs find and stat don't match"
8753
8754         # Compare Lustre attributes from lfs find and lfs getstripe
8755         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8756         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8757         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8758         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8759         local fpool=$($LFS getstripe --pool $path/$tfile)
8760         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8761
8762         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8763                 error "Attrs from lfs find and lfs getstripe don't match"
8764
8765         # Verify behavior for unknown escape/format sequences
8766         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8767
8768         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8769                 error "Escape/format codes don't match"
8770 }
8771 run_test 56ea "test lfs find -printf option"
8772
8773 test_56eb() {
8774         local dir=$DIR/$tdir
8775         local subdir_1=$dir/subdir_1
8776
8777         test_mkdir -p $subdir_1
8778         ln -s subdir_1 $dir/link_1
8779
8780         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8781                 error "symlink is not followed"
8782
8783         $LFS getstripe --no-follow $dir |
8784                 grep "^$dir/link_1 has no stripe info$" ||
8785                 error "symlink should not have stripe info"
8786
8787         touch $dir/testfile
8788         ln -s testfile $dir/file_link_2
8789
8790         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8791                 error "symlink is not followed"
8792
8793         $LFS getstripe --no-follow $dir |
8794                 grep "^$dir/file_link_2 has no stripe info$" ||
8795                 error "symlink should not have stripe info"
8796 }
8797 run_test 56eb "check lfs getstripe on symlink"
8798
8799 test_56ec() {
8800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8801         local dir=$DIR/$tdir
8802         local srcfile=$dir/srcfile
8803         local srcyaml=$dir/srcyaml
8804         local destfile=$dir/destfile
8805
8806         test_mkdir -p $dir
8807
8808         $LFS setstripe -i 1 $srcfile
8809         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8810         # if the setstripe yaml parsing fails for any reason, the command can
8811         # randomly assign the correct OST index, leading to an erroneous
8812         # success. but the chance of false success is low enough that a
8813         # regression should still be quickly caught.
8814         $LFS setstripe --yaml=$srcyaml $destfile
8815
8816         local srcindex=$($LFS getstripe -i $srcfile)
8817         local destindex=$($LFS getstripe -i $destfile)
8818
8819         if [[ ! $srcindex -eq $destindex ]]; then
8820                 error "setstripe did not set OST index correctly"
8821         fi
8822 }
8823 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8824
8825 test_56eda() {
8826         local dir=$DIR/$tdir
8827         local subdir=$dir/subdir
8828         local file1=$dir/$tfile
8829         local file2=$dir/$tfile\2
8830         local link=$dir/$tfile-link
8831         local nfiles
8832
8833         test_mkdir -p $dir
8834         $LFS setdirstripe -c1 $subdir
8835         touch $file1
8836         touch $file2
8837         ln $file2 $link
8838
8839         nfiles=$($LFS find --links 1 $dir | wc -l)
8840         (( $nfiles == 1 )) ||
8841                 error "lfs find --links expected 1 file, got $nfiles"
8842
8843         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8844         (( $nfiles == 2 )) ||
8845                 error "lfs find --links expected 2 files, got $nfiles"
8846
8847         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8848         (( $nfiles == 1 )) ||
8849                 error "lfs find --links expected 1 directory, got $nfiles"
8850 }
8851 run_test 56eda "check lfs find --links"
8852
8853 test_56edb() {
8854         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8855
8856         local dir=$DIR/$tdir
8857         local stripedir=$dir/stripedir
8858         local nfiles
8859
8860         test_mkdir -p $dir
8861
8862         $LFS setdirstripe -c2 $stripedir
8863
8864         $LFS getdirstripe $stripedir
8865
8866         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8867         (( $nfiles == 1 )) ||
8868                 error "lfs find --links expected 1 directory, got $nfiles"
8869 }
8870 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8871
8872 test_56ef() {
8873         local dir=$DIR/$tdir
8874         local dir1=$dir/d1
8875         local dir2=$dir/d2
8876         local nfiles
8877
8878         test_mkdir -p $dir
8879
8880         mkdir $dir1
8881         mkdir $dir2
8882
8883         touch $dir1/f
8884         touch $dir2/f
8885
8886         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8887         (( $nfiles == 2 )) ||
8888                 error "(1) lfs find expected 2 files, got $nfiles"
8889
8890         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8891         (( $nfiles == 2 )) ||
8892                 error "(2) lfs find expected 2 files, got $nfiles"
8893
8894         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8895         (( $nfiles == 2 )) ||
8896                 error "(3) lfs find expected 2 files, got $nfiles"
8897 }
8898 run_test 56ef "lfs find with multiple paths"
8899
8900 test_57a() {
8901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8902         # note test will not do anything if MDS is not local
8903         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8904                 skip_env "ldiskfs only test"
8905         fi
8906         remote_mds_nodsh && skip "remote MDS with nodsh"
8907
8908         local MNTDEV="osd*.*MDT*.mntdev"
8909         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8910         [ -z "$DEV" ] && error "can't access $MNTDEV"
8911         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8912                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8913                         error "can't access $DEV"
8914                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8915                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8916                 rm $TMP/t57a.dump
8917         done
8918 }
8919 run_test 57a "verify MDS filesystem created with large inodes =="
8920
8921 test_57b() {
8922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8923         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8924                 skip_env "ldiskfs only test"
8925         fi
8926         remote_mds_nodsh && skip "remote MDS with nodsh"
8927
8928         local dir=$DIR/$tdir
8929         local filecount=100
8930         local file1=$dir/f1
8931         local fileN=$dir/f$filecount
8932
8933         rm -rf $dir || error "removing $dir"
8934         test_mkdir -c1 $dir
8935         local mdtidx=$($LFS getstripe -m $dir)
8936         local mdtname=MDT$(printf %04x $mdtidx)
8937         local facet=mds$((mdtidx + 1))
8938
8939         echo "mcreating $filecount files"
8940         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8941
8942         # verify that files do not have EAs yet
8943         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8944                 error "$file1 has an EA"
8945         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8946                 error "$fileN has an EA"
8947
8948         sync
8949         sleep 1
8950         df $dir  #make sure we get new statfs data
8951         local mdsfree=$(do_facet $facet \
8952                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8953         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8954         local file
8955
8956         echo "opening files to create objects/EAs"
8957         for file in $(seq -f $dir/f%g 1 $filecount); do
8958                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8959                         error "opening $file"
8960         done
8961
8962         # verify that files have EAs now
8963         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
8964                 error "$file1 missing EA"
8965         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
8966                 error "$fileN missing EA"
8967
8968         sleep 1  #make sure we get new statfs data
8969         df $dir
8970         local mdsfree2=$(do_facet $facet \
8971                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8972         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8973
8974         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8975                 if [ "$mdsfree" != "$mdsfree2" ]; then
8976                         error "MDC before $mdcfree != after $mdcfree2"
8977                 else
8978                         echo "MDC before $mdcfree != after $mdcfree2"
8979                         echo "unable to confirm if MDS has large inodes"
8980                 fi
8981         fi
8982         rm -rf $dir
8983 }
8984 run_test 57b "default LOV EAs are stored inside large inodes ==="
8985
8986 test_58() {
8987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8988         [ -z "$(which wiretest 2>/dev/null)" ] &&
8989                         skip_env "could not find wiretest"
8990
8991         wiretest
8992 }
8993 run_test 58 "verify cross-platform wire constants =============="
8994
8995 test_59() {
8996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8997
8998         echo "touch 130 files"
8999         createmany -o $DIR/f59- 130
9000         echo "rm 130 files"
9001         unlinkmany $DIR/f59- 130
9002         sync
9003         # wait for commitment of removal
9004         wait_delete_completed
9005 }
9006 run_test 59 "verify cancellation of llog records async ========="
9007
9008 TEST60_HEAD="test_60 run $RANDOM"
9009 test_60a() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011         remote_mgs_nodsh && skip "remote MGS with nodsh"
9012         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9013                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9014                         skip_env "missing subtest run-llog.sh"
9015
9016         log "$TEST60_HEAD - from kernel mode"
9017         do_facet mgs "$LCTL dk > /dev/null"
9018         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9019         do_facet mgs $LCTL dk > $TMP/$tfile
9020
9021         # LU-6388: test llog_reader
9022         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9023         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9024         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9025                         skip_env "missing llog_reader"
9026         local fstype=$(facet_fstype mgs)
9027         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9028                 skip_env "Only for ldiskfs or zfs type mgs"
9029
9030         local mntpt=$(facet_mntpt mgs)
9031         local mgsdev=$(mgsdevname 1)
9032         local fid_list
9033         local fid
9034         local rec_list
9035         local rec
9036         local rec_type
9037         local obj_file
9038         local path
9039         local seq
9040         local oid
9041         local pass=true
9042
9043         #get fid and record list
9044         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9045                 tail -n 4))
9046         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9047                 tail -n 4))
9048         #remount mgs as ldiskfs or zfs type
9049         stop mgs || error "stop mgs failed"
9050         mount_fstype mgs || error "remount mgs failed"
9051         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9052                 fid=${fid_list[i]}
9053                 rec=${rec_list[i]}
9054                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9055                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9056                 oid=$((16#$oid))
9057
9058                 case $fstype in
9059                         ldiskfs )
9060                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9061                         zfs )
9062                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9063                 esac
9064                 echo "obj_file is $obj_file"
9065                 do_facet mgs $llog_reader $obj_file
9066
9067                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9068                         awk '{ print $3 }' | sed -e "s/^type=//g")
9069                 if [ $rec_type != $rec ]; then
9070                         echo "FAILED test_60a wrong record type $rec_type," \
9071                               "should be $rec"
9072                         pass=false
9073                         break
9074                 fi
9075
9076                 #check obj path if record type is LLOG_LOGID_MAGIC
9077                 if [ "$rec" == "1064553b" ]; then
9078                         path=$(do_facet mgs $llog_reader $obj_file |
9079                                 grep "path=" | awk '{ print $NF }' |
9080                                 sed -e "s/^path=//g")
9081                         if [ $obj_file != $mntpt/$path ]; then
9082                                 echo "FAILED test_60a wrong obj path" \
9083                                       "$montpt/$path, should be $obj_file"
9084                                 pass=false
9085                                 break
9086                         fi
9087                 fi
9088         done
9089         rm -f $TMP/$tfile
9090         #restart mgs before "error", otherwise it will block the next test
9091         stop mgs || error "stop mgs failed"
9092         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9093         $pass || error "test failed, see FAILED test_60a messages for specifics"
9094 }
9095 run_test 60a "llog_test run from kernel module and test llog_reader"
9096
9097 test_60b() { # bug 6411
9098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9099
9100         dmesg > $DIR/$tfile
9101         LLOG_COUNT=$(do_facet mgs dmesg |
9102                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9103                           /llog_[a-z]*.c:[0-9]/ {
9104                                 if (marker)
9105                                         from_marker++
9106                                 from_begin++
9107                           }
9108                           END {
9109                                 if (marker)
9110                                         print from_marker
9111                                 else
9112                                         print from_begin
9113                           }")
9114
9115         [[ $LLOG_COUNT -gt 120 ]] &&
9116                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9117 }
9118 run_test 60b "limit repeated messages from CERROR/CWARN"
9119
9120 test_60c() {
9121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9122
9123         echo "create 5000 files"
9124         createmany -o $DIR/f60c- 5000
9125 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9126         lctl set_param fail_loc=0x80000137
9127         unlinkmany $DIR/f60c- 5000
9128         lctl set_param fail_loc=0
9129 }
9130 run_test 60c "unlink file when mds full"
9131
9132 test_60d() {
9133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9134
9135         SAVEPRINTK=$(lctl get_param -n printk)
9136         # verify "lctl mark" is even working"
9137         MESSAGE="test message ID $RANDOM $$"
9138         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9139         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9140
9141         lctl set_param printk=0 || error "set lnet.printk failed"
9142         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9143         MESSAGE="new test message ID $RANDOM $$"
9144         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9145         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9146         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9147
9148         lctl set_param -n printk="$SAVEPRINTK"
9149 }
9150 run_test 60d "test printk console message masking"
9151
9152 test_60e() {
9153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9154         remote_mds_nodsh && skip "remote MDS with nodsh"
9155
9156         touch $DIR/$tfile
9157 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9158         do_facet mds1 lctl set_param fail_loc=0x15b
9159         rm $DIR/$tfile
9160 }
9161 run_test 60e "no space while new llog is being created"
9162
9163 test_60f() {
9164         local old_path=$($LCTL get_param -n debug_path)
9165
9166         stack_trap "$LCTL set_param debug_path=$old_path"
9167         stack_trap "rm -f $TMP/$tfile*"
9168         rm -f $TMP/$tfile* 2> /dev/null
9169         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9170         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9171         test_mkdir $DIR/$tdir
9172         # retry in case the open is cached and not released
9173         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9174                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9175                 sleep 0.1
9176         done
9177         ls $TMP/$tfile*
9178         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9179 }
9180 run_test 60f "change debug_path works"
9181
9182 test_60g() {
9183         local pid
9184         local i
9185
9186         test_mkdir -c $MDSCOUNT $DIR/$tdir
9187
9188         (
9189                 local index=0
9190                 while true; do
9191                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9192                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9193                                 2>/dev/null
9194                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9195                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9196                         index=$((index + 1))
9197                 done
9198         ) &
9199
9200         pid=$!
9201
9202         for i in {0..100}; do
9203                 # define OBD_FAIL_OSD_TXN_START    0x19a
9204                 local index=$((i % MDSCOUNT + 1))
9205
9206                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9207                         > /dev/null
9208                 sleep 0.01
9209         done
9210
9211         kill -9 $pid
9212
9213         for i in $(seq $MDSCOUNT); do
9214                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9215         done
9216
9217         mkdir $DIR/$tdir/new || error "mkdir failed"
9218         rmdir $DIR/$tdir/new || error "rmdir failed"
9219
9220         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9221                 -t namespace
9222         for i in $(seq $MDSCOUNT); do
9223                 wait_update_facet mds$i "$LCTL get_param -n \
9224                         mdd.$(facet_svc mds$i).lfsck_namespace |
9225                         awk '/^status/ { print \\\$2 }'" "completed"
9226         done
9227
9228         ls -R $DIR/$tdir
9229         rm -rf $DIR/$tdir || error "rmdir failed"
9230 }
9231 run_test 60g "transaction abort won't cause MDT hung"
9232
9233 test_60h() {
9234         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9235                 skip "Need MDS version at least 2.12.52"
9236         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9237
9238         local f
9239
9240         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9241         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9242         for fail_loc in 0x80000188 0x80000189; do
9243                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9244                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9245                         error "mkdir $dir-$fail_loc failed"
9246                 for i in {0..10}; do
9247                         # create may fail on missing stripe
9248                         echo $i > $DIR/$tdir-$fail_loc/$i
9249                 done
9250                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9251                         error "getdirstripe $tdir-$fail_loc failed"
9252                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9253                         error "migrate $tdir-$fail_loc failed"
9254                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9255                         error "getdirstripe $tdir-$fail_loc failed"
9256                 pushd $DIR/$tdir-$fail_loc
9257                 for f in *; do
9258                         echo $f | cmp $f - || error "$f data mismatch"
9259                 done
9260                 popd
9261                 rm -rf $DIR/$tdir-$fail_loc
9262         done
9263 }
9264 run_test 60h "striped directory with missing stripes can be accessed"
9265
9266 function t60i_load() {
9267         mkdir $DIR/$tdir
9268         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9269         $LCTL set_param fail_loc=0x131c fail_val=1
9270         for ((i=0; i<5000; i++)); do
9271                 touch $DIR/$tdir/f$i
9272         done
9273 }
9274
9275 test_60i() {
9276         changelog_register || error "changelog_register failed"
9277         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9278         changelog_users $SINGLEMDS | grep -q $cl_user ||
9279                 error "User $cl_user not found in changelog_users"
9280         changelog_chmask "ALL"
9281         t60i_load &
9282         local PID=$!
9283         for((i=0; i<100; i++)); do
9284                 changelog_dump >/dev/null ||
9285                         error "can't read changelog"
9286         done
9287         kill $PID
9288         wait $PID
9289         changelog_deregister || error "changelog_deregister failed"
9290         $LCTL set_param fail_loc=0
9291 }
9292 run_test 60i "llog: new record vs reader race"
9293
9294 test_60j() {
9295         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9296                 skip "need MDS version at least 2.15.50"
9297         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9298         remote_mds_nodsh && skip "remote MDS with nodsh"
9299         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9300
9301         changelog_users $SINGLEMDS | grep "^cl" &&
9302                 skip "active changelog user"
9303
9304         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9305
9306         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9307                 skip_env "missing llog_reader"
9308
9309         mkdir_on_mdt0 $DIR/$tdir
9310
9311         local f=$DIR/$tdir/$tfile
9312         local mdt_dev
9313         local tmpfile
9314         local plain
9315
9316         changelog_register || error "cannot register changelog user"
9317
9318         # set changelog_mask to ALL
9319         changelog_chmask "ALL"
9320         changelog_clear
9321
9322         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9323         unlinkmany ${f}- 100 || error "unlinkmany failed"
9324
9325         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9326         mdt_dev=$(facet_device $SINGLEMDS)
9327
9328         do_facet $SINGLEMDS sync
9329         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9330                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9331                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9332
9333         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9334
9335         # if $tmpfile is not on EXT3 filesystem for some reason
9336         [[ ${plain:0:1} == 'O' ]] ||
9337                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9338
9339         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9340                 $mdt_dev; stat -c %s $tmpfile")
9341         echo "Truncate llog from $size to $((size - size % 8192))"
9342         size=$((size - size % 8192))
9343         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9344         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9345                 grep -c 'in bitmap only')
9346         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9347
9348         size=$((size - 9000))
9349         echo "Corrupt llog in the middle at $size"
9350         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9351                 count=333 conv=notrunc
9352         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9353                 grep -c 'next chunk')
9354         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9355 }
9356 run_test 60j "llog_reader reports corruptions"
9357
9358 test_61a() {
9359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9360
9361         f="$DIR/f61"
9362         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9363         cancel_lru_locks osc
9364         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9365         sync
9366 }
9367 run_test 61a "mmap() writes don't make sync hang ================"
9368
9369 test_61b() {
9370         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9371 }
9372 run_test 61b "mmap() of unstriped file is successful"
9373
9374 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9375 # Though this test is irrelevant anymore, it helped to reveal some
9376 # other grant bugs (LU-4482), let's keep it.
9377 test_63a() {   # was test_63
9378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9379
9380         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9381
9382         for i in `seq 10` ; do
9383                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9384                 sleep 5
9385                 kill $!
9386                 sleep 1
9387         done
9388
9389         rm -f $DIR/f63 || true
9390 }
9391 run_test 63a "Verify oig_wait interruption does not crash ======="
9392
9393 # bug 2248 - async write errors didn't return to application on sync
9394 # bug 3677 - async write errors left page locked
9395 test_63b() {
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397
9398         debugsave
9399         lctl set_param debug=-1
9400
9401         # ensure we have a grant to do async writes
9402         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9403         rm $DIR/$tfile
9404
9405         sync    # sync lest earlier test intercept the fail_loc
9406
9407         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9408         lctl set_param fail_loc=0x80000406
9409         $MULTIOP $DIR/$tfile Owy && \
9410                 error "sync didn't return ENOMEM"
9411         sync; sleep 2; sync     # do a real sync this time to flush page
9412         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9413                 error "locked page left in cache after async error" || true
9414         debugrestore
9415 }
9416 run_test 63b "async write errors should be returned to fsync ==="
9417
9418 test_64a () {
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420
9421         lfs df $DIR
9422         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9423 }
9424 run_test 64a "verify filter grant calculations (in kernel) ====="
9425
9426 test_64b () {
9427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9428
9429         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9430 }
9431 run_test 64b "check out-of-space detection on client"
9432
9433 test_64c() {
9434         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9435 }
9436 run_test 64c "verify grant shrink"
9437
9438 import_param() {
9439         local tgt=$1
9440         local param=$2
9441
9442         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9443 }
9444
9445 # this does exactly what osc_request.c:osc_announce_cached() does in
9446 # order to calculate max amount of grants to ask from server
9447 want_grant() {
9448         local tgt=$1
9449
9450         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9451         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9452
9453         ((rpc_in_flight++));
9454         nrpages=$((nrpages * rpc_in_flight))
9455
9456         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9457
9458         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9459
9460         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9461         local undirty=$((nrpages * PAGE_SIZE))
9462
9463         local max_extent_pages
9464         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9465         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9466         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9467         local grant_extent_tax
9468         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9469
9470         undirty=$((undirty + nrextents * grant_extent_tax))
9471
9472         echo $undirty
9473 }
9474
9475 # this is size of unit for grant allocation. It should be equal to
9476 # what tgt_grant.c:tgt_grant_chunk() calculates
9477 grant_chunk() {
9478         local tgt=$1
9479         local max_brw_size
9480         local grant_extent_tax
9481
9482         max_brw_size=$(import_param $tgt max_brw_size)
9483
9484         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9485
9486         echo $(((max_brw_size + grant_extent_tax) * 2))
9487 }
9488
9489 test_64d() {
9490         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9491                 skip "OST < 2.10.55 doesn't limit grants enough"
9492
9493         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9494
9495         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9496                 skip "no grant_param connect flag"
9497
9498         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9499
9500         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9501         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9502
9503
9504         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9505         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9506
9507         $LFS setstripe $DIR/$tfile -i 0 -c 1
9508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9509         ddpid=$!
9510
9511         while kill -0 $ddpid; do
9512                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9513
9514                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9515                         kill $ddpid
9516                         error "cur_grant $cur_grant > $max_cur_granted"
9517                 fi
9518
9519                 sleep 1
9520         done
9521 }
9522 run_test 64d "check grant limit exceed"
9523
9524 check_grants() {
9525         local tgt=$1
9526         local expected=$2
9527         local msg=$3
9528         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9529
9530         ((cur_grants == expected)) ||
9531                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9532 }
9533
9534 round_up_p2() {
9535         echo $((($1 + $2 - 1) & ~($2 - 1)))
9536 }
9537
9538 test_64e() {
9539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9540         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9541                 skip "Need OSS version at least 2.11.56"
9542
9543         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9544         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9545         $LCTL set_param debug=+cache
9546
9547         # Remount client to reset grant
9548         remount_client $MOUNT || error "failed to remount client"
9549         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9550
9551         local init_grants=$(import_param $osc_tgt initial_grant)
9552
9553         check_grants $osc_tgt $init_grants "init grants"
9554
9555         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9556         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9557         local gbs=$(import_param $osc_tgt grant_block_size)
9558
9559         # write random number of bytes from max_brw_size / 4 to max_brw_size
9560         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9561         # align for direct io
9562         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9563         # round to grant consumption unit
9564         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9565
9566         local grants=$((wb_round_up + extent_tax))
9567
9568         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9569         stack_trap "rm -f $DIR/$tfile"
9570
9571         # define OBD_FAIL_TGT_NO_GRANT 0x725
9572         # make the server not grant more back
9573         do_facet ost1 $LCTL set_param fail_loc=0x725
9574         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9575
9576         do_facet ost1 $LCTL set_param fail_loc=0
9577
9578         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9579
9580         rm -f $DIR/$tfile || error "rm failed"
9581
9582         # Remount client to reset grant
9583         remount_client $MOUNT || error "failed to remount client"
9584         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9585
9586         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9587
9588         # define OBD_FAIL_TGT_NO_GRANT 0x725
9589         # make the server not grant more back
9590         do_facet ost1 $LCTL set_param fail_loc=0x725
9591         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9592         do_facet ost1 $LCTL set_param fail_loc=0
9593
9594         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9595 }
9596 run_test 64e "check grant consumption (no grant allocation)"
9597
9598 test_64f() {
9599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9600
9601         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9602         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9603         $LCTL set_param debug=+cache
9604
9605         # Remount client to reset grant
9606         remount_client $MOUNT || error "failed to remount client"
9607         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9608
9609         local init_grants=$(import_param $osc_tgt initial_grant)
9610         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9611         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9612         local gbs=$(import_param $osc_tgt grant_block_size)
9613         local chunk=$(grant_chunk $osc_tgt)
9614
9615         # write random number of bytes from max_brw_size / 4 to max_brw_size
9616         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9617         # align for direct io
9618         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9619         # round to grant consumption unit
9620         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9621
9622         local grants=$((wb_round_up + extent_tax))
9623
9624         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9625         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9626                 error "error writing to $DIR/$tfile"
9627
9628         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9629                 "direct io with grant allocation"
9630
9631         rm -f $DIR/$tfile || error "rm failed"
9632
9633         # Remount client to reset grant
9634         remount_client $MOUNT || error "failed to remount client"
9635         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9636
9637         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9638
9639         # Testing that buffered IO consumes grant on the client
9640
9641         # Delay the RPC on the server so it's guaranteed to not complete even
9642         # if the RPC is sent from the client
9643         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9644         $LCTL set_param fail_loc=0x50a fail_val=3
9645         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9646                 error "error writing to $DIR/$tfile with buffered IO"
9647
9648         check_grants $osc_tgt $((init_grants - grants)) \
9649                 "buffered io, not write rpc"
9650
9651         # Clear the fail loc and do a sync on the client
9652         $LCTL set_param fail_loc=0 fail_val=0
9653         sync
9654
9655         # RPC is now known to have sent
9656         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9657                 "buffered io, one RPC"
9658 }
9659 run_test 64f "check grant consumption (with grant allocation)"
9660
9661 test_64g() {
9662         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9663                 skip "Need MDS version at least 2.14.56"
9664
9665         local mdts=$(comma_list $(mdts_nodes))
9666
9667         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9668                         tr '\n' ' ')
9669         stack_trap "$LCTL set_param $old"
9670
9671         # generate dirty pages and increase dirty granted on MDT
9672         stack_trap "rm -f $DIR/$tfile-*"
9673         for (( i = 0; i < 10; i++)); do
9674                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9675                         error "can't set stripe"
9676                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9677                         error "can't dd"
9678                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9679                         $LFS getstripe $DIR/$tfile-$i
9680                         error "not DoM file"
9681                 }
9682         done
9683
9684         # flush dirty pages
9685         sync
9686
9687         # wait until grant shrink reset grant dirty on MDTs
9688         for ((i = 0; i < 120; i++)); do
9689                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9690                         awk '{sum=sum+$1} END {print sum}')
9691                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9692                 echo "$grant_dirty grants, $vm_dirty pages"
9693                 (( grant_dirty + vm_dirty == 0 )) && break
9694                 (( i == 3 )) && sync &&
9695                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9696                 sleep 1
9697         done
9698
9699         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9700                 awk '{sum=sum+$1} END {print sum}')
9701         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9702 }
9703 run_test 64g "grant shrink on MDT"
9704
9705 test_64h() {
9706         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9707                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9708
9709         local instance=$($LFS getname -i $DIR)
9710         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9711         local num_exps=$(do_facet ost1 \
9712             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9713         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9714         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9715         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9716
9717         # 10MiB is for file to be written, max_brw_size * 16 *
9718         # num_exps is space reserve so that tgt_grant_shrink() decided
9719         # to not shrink
9720         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9721         (( avail * 1024 < expect )) &&
9722                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9723
9724         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9725         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9726         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9727         $LCTL set_param osc.*OST0000*.grant_shrink=1
9728         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9729
9730         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9731         stack_trap "rm -f $DIR/$tfile"
9732         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9733
9734         # drop cache so that coming read would do rpc
9735         cancel_lru_locks osc
9736
9737         # shrink interval is set to 10, pause for 7 seconds so that
9738         # grant thread did not wake up yet but coming read entered
9739         # shrink mode for rpc (osc_should_shrink_grant())
9740         sleep 7
9741
9742         declare -a cur_grant_bytes
9743         declare -a tot_granted
9744         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9745         tot_granted[0]=$(do_facet ost1 \
9746             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9747
9748         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9749
9750         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9751         tot_granted[1]=$(do_facet ost1 \
9752             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9753
9754         # grant change should be equal on both sides
9755         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9756                 tot_granted[0] - tot_granted[1])) ||
9757                 error "grant change mismatch, "                                \
9758                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9759                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9760 }
9761 run_test 64h "grant shrink on read"
9762
9763 test_64i() {
9764         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9765                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9766
9767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9768         remote_ost_nodsh && skip "remote OSTs with nodsh"
9769
9770         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9771         stack_trap "rm -f $DIR/$tfile"
9772
9773         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9774
9775         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9776         local instance=$($LFS getname -i $DIR)
9777
9778         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9779         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9780
9781         # shrink grants and simulate rpc loss
9782         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9783         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9784         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9785
9786         fail ost1
9787
9788         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9789
9790         local testid=$(echo $TESTNAME | tr '_' ' ')
9791
9792         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9793                 grep "GRANT, real grant" &&
9794                 error "client has more grants then it owns" || true
9795 }
9796 run_test 64i "shrink on reconnect"
9797
9798 # bug 1414 - set/get directories' stripe info
9799 test_65a() {
9800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9801
9802         test_mkdir $DIR/$tdir
9803         touch $DIR/$tdir/f1
9804         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9805 }
9806 run_test 65a "directory with no stripe info"
9807
9808 test_65b() {
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         test_mkdir $DIR/$tdir
9812         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9813
9814         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9815                                                 error "setstripe"
9816         touch $DIR/$tdir/f2
9817         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9818 }
9819 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9820
9821 test_65c() {
9822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9823         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9824
9825         test_mkdir $DIR/$tdir
9826         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9827
9828         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9829                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9830         touch $DIR/$tdir/f3
9831         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9832 }
9833 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9834
9835 test_65d() {
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837
9838         test_mkdir $DIR/$tdir
9839         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9840         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9841
9842         if [[ $STRIPECOUNT -le 0 ]]; then
9843                 sc=1
9844         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9845                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9846                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9847         else
9848                 sc=$(($STRIPECOUNT - 1))
9849         fi
9850         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9851         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9852         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9853                 error "lverify failed"
9854 }
9855 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9856
9857 test_65e() {
9858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9859
9860         # LU-16904 delete layout when root is set as PFL layout
9861         save_layout_restore_at_exit $MOUNT
9862         $LFS setstripe -d $MOUNT || error "setstripe failed"
9863
9864         test_mkdir $DIR/$tdir
9865
9866         $LFS setstripe $DIR/$tdir || error "setstripe"
9867         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9868                                         error "no stripe info failed"
9869         touch $DIR/$tdir/f6
9870         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9871 }
9872 run_test 65e "directory setstripe defaults"
9873
9874 test_65f() {
9875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9876
9877         test_mkdir $DIR/${tdir}f
9878         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9879                 error "setstripe succeeded" || true
9880 }
9881 run_test 65f "dir setstripe permission (should return error) ==="
9882
9883 test_65g() {
9884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9885
9886         # LU-16904 delete layout when root is set as PFL layout
9887         save_layout_restore_at_exit $MOUNT
9888         $LFS setstripe -d $MOUNT || error "setstripe failed"
9889
9890         test_mkdir $DIR/$tdir
9891         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9892
9893         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9894                 error "setstripe -S failed"
9895         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9896         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9897                 error "delete default stripe failed"
9898 }
9899 run_test 65g "directory setstripe -d"
9900
9901 test_65h() {
9902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9903
9904         test_mkdir $DIR/$tdir
9905         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9906
9907         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9908                 error "setstripe -S failed"
9909         test_mkdir $DIR/$tdir/dd1
9910         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9911                 error "stripe info inherit failed"
9912 }
9913 run_test 65h "directory stripe info inherit ===================="
9914
9915 test_65i() {
9916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9917
9918         save_layout_restore_at_exit $MOUNT
9919
9920         # bug6367: set non-default striping on root directory
9921         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9922
9923         # bug12836: getstripe on -1 default directory striping
9924         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9925
9926         # bug12836: getstripe -v on -1 default directory striping
9927         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9928
9929         # bug12836: new find on -1 default directory striping
9930         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9931 }
9932 run_test 65i "various tests to set root directory striping"
9933
9934 test_65j() { # bug6367
9935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9936
9937         sync; sleep 1
9938
9939         # if we aren't already remounting for each test, do so for this test
9940         if [ "$I_MOUNTED" = "yes" ]; then
9941                 cleanup || error "failed to unmount"
9942                 setup
9943         fi
9944
9945         save_layout_restore_at_exit $MOUNT
9946
9947         $LFS setstripe -d $MOUNT || error "setstripe failed"
9948 }
9949 run_test 65j "set default striping on root directory (bug 6367)="
9950
9951 cleanup_65k() {
9952         rm -rf $DIR/$tdir
9953         wait_delete_completed
9954         do_facet $SINGLEMDS "lctl set_param -n \
9955                 osp.$ost*MDT0000.max_create_count=$max_count"
9956         do_facet $SINGLEMDS "lctl set_param -n \
9957                 osp.$ost*MDT0000.create_count=$count"
9958         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9959         echo $INACTIVE_OSC "is Activate"
9960
9961         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9962 }
9963
9964 test_65k() { # bug11679
9965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9966         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9967         remote_mds_nodsh && skip "remote MDS with nodsh"
9968
9969         local disable_precreate=true
9970         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9971                 disable_precreate=false
9972
9973         echo "Check OST status: "
9974         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9975                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9976
9977         for OSC in $MDS_OSCS; do
9978                 echo $OSC "is active"
9979                 do_facet $SINGLEMDS lctl --device %$OSC activate
9980         done
9981
9982         for INACTIVE_OSC in $MDS_OSCS; do
9983                 local ost=$(osc_to_ost $INACTIVE_OSC)
9984                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9985                                lov.*md*.target_obd |
9986                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9987
9988                 mkdir -p $DIR/$tdir
9989                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9990                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9991
9992                 echo "Deactivate: " $INACTIVE_OSC
9993                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9994
9995                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9996                               osp.$ost*MDT0000.create_count")
9997                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9998                                   osp.$ost*MDT0000.max_create_count")
9999                 $disable_precreate &&
10000                         do_facet $SINGLEMDS "lctl set_param -n \
10001                                 osp.$ost*MDT0000.max_create_count=0"
10002
10003                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10004                         [ -f $DIR/$tdir/$idx ] && continue
10005                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10006                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10007                                 { cleanup_65k;
10008                                   error "setstripe $idx should succeed"; }
10009                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10010                 done
10011                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10012                 rmdir $DIR/$tdir
10013
10014                 do_facet $SINGLEMDS "lctl set_param -n \
10015                         osp.$ost*MDT0000.max_create_count=$max_count"
10016                 do_facet $SINGLEMDS "lctl set_param -n \
10017                         osp.$ost*MDT0000.create_count=$count"
10018                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10019                 echo $INACTIVE_OSC "is Activate"
10020
10021                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10022         done
10023 }
10024 run_test 65k "validate manual striping works properly with deactivated OSCs"
10025
10026 test_65l() { # bug 12836
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028
10029         test_mkdir -p $DIR/$tdir/test_dir
10030         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10031         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10032 }
10033 run_test 65l "lfs find on -1 stripe dir ========================"
10034
10035 test_65m() {
10036         local layout=$(save_layout $MOUNT)
10037         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10038                 restore_layout $MOUNT $layout
10039                 error "setstripe should fail by non-root users"
10040         }
10041         true
10042 }
10043 run_test 65m "normal user can't set filesystem default stripe"
10044
10045 test_65n() {
10046         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10047         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10048                 skip "Need MDS version at least 2.12.50"
10049         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10050
10051         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10052         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10053         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10054
10055         save_layout_restore_at_exit $MOUNT
10056
10057         # new subdirectory under root directory should not inherit
10058         # the default layout from root
10059         # LU-16904 check if the root is set as PFL layout
10060         local numcomp=$($LFS getstripe --component-count $MOUNT)
10061
10062         if [[ $numcomp -eq 0 ]]; then
10063                 local dir1=$MOUNT/$tdir-1
10064                 mkdir $dir1 || error "mkdir $dir1 failed"
10065                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10066                         error "$dir1 shouldn't have LOV EA"
10067         fi
10068
10069         # delete the default layout on root directory
10070         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10071
10072         local dir2=$MOUNT/$tdir-2
10073         mkdir $dir2 || error "mkdir $dir2 failed"
10074         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10075                 error "$dir2 shouldn't have LOV EA"
10076
10077         # set a new striping pattern on root directory
10078         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10079         local new_def_stripe_size=$((def_stripe_size * 2))
10080         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10081                 error "set stripe size on $MOUNT failed"
10082
10083         # new file created in $dir2 should inherit the new stripe size from
10084         # the filesystem default
10085         local file2=$dir2/$tfile-2
10086         touch $file2 || error "touch $file2 failed"
10087
10088         local file2_stripe_size=$($LFS getstripe -S $file2)
10089         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10090         {
10091                 echo "file2_stripe_size: '$file2_stripe_size'"
10092                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10093                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10094         }
10095
10096         local dir3=$MOUNT/$tdir-3
10097         mkdir $dir3 || error "mkdir $dir3 failed"
10098         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10099         # the root layout, which is the actual default layout that will be used
10100         # when new files are created in $dir3.
10101         local dir3_layout=$(get_layout_param $dir3)
10102         local root_dir_layout=$(get_layout_param $MOUNT)
10103         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10104         {
10105                 echo "dir3_layout: '$dir3_layout'"
10106                 echo "root_dir_layout: '$root_dir_layout'"
10107                 error "$dir3 should show the default layout from $MOUNT"
10108         }
10109
10110         # set OST pool on root directory
10111         local pool=$TESTNAME
10112         pool_add $pool || error "add $pool failed"
10113         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10114                 error "add targets to $pool failed"
10115
10116         $LFS setstripe -p $pool $MOUNT ||
10117                 error "set OST pool on $MOUNT failed"
10118
10119         # new file created in $dir3 should inherit the pool from
10120         # the filesystem default
10121         local file3=$dir3/$tfile-3
10122         touch $file3 || error "touch $file3 failed"
10123
10124         local file3_pool=$($LFS getstripe -p $file3)
10125         [[ "$file3_pool" = "$pool" ]] ||
10126                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10127
10128         local dir4=$MOUNT/$tdir-4
10129         mkdir $dir4 || error "mkdir $dir4 failed"
10130         local dir4_layout=$(get_layout_param $dir4)
10131         root_dir_layout=$(get_layout_param $MOUNT)
10132         echo "$LFS getstripe -d $dir4"
10133         $LFS getstripe -d $dir4
10134         echo "$LFS getstripe -d $MOUNT"
10135         $LFS getstripe -d $MOUNT
10136         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10137         {
10138                 echo "dir4_layout: '$dir4_layout'"
10139                 echo "root_dir_layout: '$root_dir_layout'"
10140                 error "$dir4 should show the default layout from $MOUNT"
10141         }
10142
10143         # new file created in $dir4 should inherit the pool from
10144         # the filesystem default
10145         local file4=$dir4/$tfile-4
10146         touch $file4 || error "touch $file4 failed"
10147
10148         local file4_pool=$($LFS getstripe -p $file4)
10149         [[ "$file4_pool" = "$pool" ]] ||
10150                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10151
10152         # new subdirectory under non-root directory should inherit
10153         # the default layout from its parent directory
10154         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10155                 error "set directory layout on $dir4 failed"
10156
10157         local dir5=$dir4/$tdir-5
10158         mkdir $dir5 || error "mkdir $dir5 failed"
10159
10160         dir4_layout=$(get_layout_param $dir4)
10161         local dir5_layout=$(get_layout_param $dir5)
10162         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10163         {
10164                 echo "dir4_layout: '$dir4_layout'"
10165                 echo "dir5_layout: '$dir5_layout'"
10166                 error "$dir5 should inherit the default layout from $dir4"
10167         }
10168
10169         # though subdir under ROOT doesn't inherit default layout, but
10170         # its sub dir/file should be created with default layout.
10171         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10172         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10173                 skip "Need MDS version at least 2.12.59"
10174
10175         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10176         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10177         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10178
10179         if [ $default_lmv_hash == "none" ]; then
10180                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10181         else
10182                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10183                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10184         fi
10185
10186         $LFS setdirstripe -D -c 2 $MOUNT ||
10187                 error "setdirstripe -D -c 2 failed"
10188         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10189         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10190         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10191
10192         # $dir4 layout includes pool
10193         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10194         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10195                 error "pool lost on setstripe"
10196         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10197         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10198                 error "pool lost on compound layout setstripe"
10199 }
10200 run_test 65n "don't inherit default layout from root for new subdirectories"
10201
10202 test_65o() {
10203         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10204                 skip "need MDS version at least 2.14.57"
10205
10206         # set OST pool on root directory
10207         local pool=$TESTNAME
10208
10209         pool_add $pool || error "add $pool failed"
10210         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10211                 error "add targets to $pool failed"
10212
10213         local dir1=$MOUNT/$tdir
10214
10215         mkdir $dir1 || error "mkdir $dir1 failed"
10216
10217         # set a new striping pattern on root directory
10218         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10219
10220         $LFS setstripe -p $pool $dir1 ||
10221                 error "set directory layout on $dir1 failed"
10222
10223         # $dir1 layout includes pool
10224         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10225         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10226                 error "pool lost on setstripe"
10227         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10228         $LFS getstripe $dir1
10229         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10230                 error "pool lost on compound layout setstripe"
10231
10232         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10233                 error "setdirstripe failed on sub-dir with inherited pool"
10234         $LFS getstripe $dir1/dir2
10235         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10236                 error "pool lost on compound layout setdirstripe"
10237
10238         $LFS setstripe -E -1 -c 1 $dir1
10239         $LFS getstripe -d $dir1
10240         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10241                 error "pool lost on setstripe"
10242 }
10243 run_test 65o "pool inheritance for mdt component"
10244
10245 test_65p () { # LU-16152
10246         local src_dir=$DIR/$tdir/src_dir
10247         local dst_dir=$DIR/$tdir/dst_dir
10248         local yaml_file=$DIR/$tdir/layout.yaml
10249         local border
10250
10251         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10252                 skip "Need at least version 2.15.51"
10253
10254         test_mkdir -p $src_dir
10255         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10256                 error "failed to setstripe"
10257         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10258                 error "failed to getstripe"
10259
10260         test_mkdir -p $dst_dir
10261         $LFS setstripe --yaml $yaml_file $dst_dir ||
10262                 error "failed to setstripe with yaml file"
10263         border=$($LFS getstripe -d $dst_dir |
10264                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10265                 error "failed to getstripe"
10266
10267         # 2048M is 0x80000000, or 2147483648
10268         (( $border == 2147483648 )) ||
10269                 error "failed to handle huge number in yaml layout"
10270 }
10271 run_test 65p "setstripe with yaml file and huge number"
10272
10273 # bug 2543 - update blocks count on client
10274 test_66() {
10275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10276
10277         local COUNT=${COUNT:-8}
10278         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10279         sync; sync_all_data; sync; sync_all_data
10280         cancel_lru_locks osc
10281         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10282         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10283 }
10284 run_test 66 "update inode blocks count on client ==============="
10285
10286 meminfo() {
10287         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10288 }
10289
10290 swap_used() {
10291         swapon -s | awk '($1 == "'$1'") { print $4 }'
10292 }
10293
10294 # bug5265, obdfilter oa2dentry return -ENOENT
10295 # #define OBD_FAIL_SRV_ENOENT 0x217
10296 test_69() {
10297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10298         remote_ost_nodsh && skip "remote OST with nodsh"
10299
10300         f="$DIR/$tfile"
10301         $LFS setstripe -c 1 -i 0 $f
10302         stack_trap "rm -f $f ${f}.2"
10303
10304         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10305
10306         do_facet ost1 lctl set_param fail_loc=0x217
10307         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10308         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10309
10310         do_facet ost1 lctl set_param fail_loc=0
10311         $DIRECTIO write $f 0 2 || error "write error"
10312
10313         cancel_lru_locks osc
10314         $DIRECTIO read $f 0 1 || error "read error"
10315
10316         do_facet ost1 lctl set_param fail_loc=0x217
10317         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10318
10319         do_facet ost1 lctl set_param fail_loc=0
10320 }
10321 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10322
10323 test_71() {
10324         test_mkdir $DIR/$tdir
10325         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10326         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10327 }
10328 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10329
10330 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332         [ "$RUNAS_ID" = "$UID" ] &&
10333                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10334         # Check that testing environment is properly set up. Skip if not
10335         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10336                 skip_env "User $RUNAS_ID does not exist - skipping"
10337
10338         touch $DIR/$tfile
10339         chmod 777 $DIR/$tfile
10340         chmod ug+s $DIR/$tfile
10341         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10342                 error "$RUNAS dd $DIR/$tfile failed"
10343         # See if we are still setuid/sgid
10344         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10345                 error "S/gid is not dropped on write"
10346         # Now test that MDS is updated too
10347         cancel_lru_locks mdc
10348         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10349                 error "S/gid is not dropped on MDS"
10350         rm -f $DIR/$tfile
10351 }
10352 run_test 72a "Test that remove suid works properly (bug5695) ===="
10353
10354 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10355         local perm
10356
10357         [ "$RUNAS_ID" = "$UID" ] &&
10358                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10359         [ "$RUNAS_ID" -eq 0 ] &&
10360                 skip_env "RUNAS_ID = 0 -- skipping"
10361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10362         # Check that testing environment is properly set up. Skip if not
10363         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10364                 skip_env "User $RUNAS_ID does not exist - skipping"
10365
10366         touch $DIR/${tfile}-f{g,u}
10367         test_mkdir $DIR/${tfile}-dg
10368         test_mkdir $DIR/${tfile}-du
10369         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10370         chmod g+s $DIR/${tfile}-{f,d}g
10371         chmod u+s $DIR/${tfile}-{f,d}u
10372         for perm in 777 2777 4777; do
10373                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10374                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10375                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10376                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10377         done
10378         true
10379 }
10380 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10381
10382 # bug 3462 - multiple simultaneous MDC requests
10383 test_73() {
10384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10385
10386         test_mkdir $DIR/d73-1
10387         test_mkdir $DIR/d73-2
10388         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10389         pid1=$!
10390
10391         lctl set_param fail_loc=0x80000129
10392         $MULTIOP $DIR/d73-1/f73-2 Oc &
10393         sleep 1
10394         lctl set_param fail_loc=0
10395
10396         $MULTIOP $DIR/d73-2/f73-3 Oc &
10397         pid3=$!
10398
10399         kill -USR1 $pid1
10400         wait $pid1 || return 1
10401
10402         sleep 25
10403
10404         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10405         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10406         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10407
10408         rm -rf $DIR/d73-*
10409 }
10410 run_test 73 "multiple MDC requests (should not deadlock)"
10411
10412 test_74a() { # bug 6149, 6184
10413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10414
10415         touch $DIR/f74a
10416         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10417         #
10418         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10419         # will spin in a tight reconnection loop
10420         $LCTL set_param fail_loc=0x8000030e
10421         # get any lock that won't be difficult - lookup works.
10422         ls $DIR/f74a
10423         $LCTL set_param fail_loc=0
10424         rm -f $DIR/f74a
10425         true
10426 }
10427 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10428
10429 test_74b() { # bug 13310
10430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10431
10432         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10433         #
10434         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10435         # will spin in a tight reconnection loop
10436         $LCTL set_param fail_loc=0x8000030e
10437         # get a "difficult" lock
10438         touch $DIR/f74b
10439         $LCTL set_param fail_loc=0
10440         rm -f $DIR/f74b
10441         true
10442 }
10443 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10444
10445 test_74c() {
10446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10447
10448         #define OBD_FAIL_LDLM_NEW_LOCK
10449         $LCTL set_param fail_loc=0x319
10450         touch $DIR/$tfile && error "touch successful"
10451         $LCTL set_param fail_loc=0
10452         true
10453 }
10454 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10455
10456 slab_lic=/sys/kernel/slab/lustre_inode_cache
10457 num_objects() {
10458         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10459         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10460                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10461 }
10462
10463 test_76a() { # Now for b=20433, added originally in b=1443
10464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10465
10466         cancel_lru_locks osc
10467         # there may be some slab objects cached per core
10468         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10469         local before=$(num_objects)
10470         local count=$((512 * cpus))
10471         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10472         local margin=$((count / 10))
10473         if [[ -f $slab_lic/aliases ]]; then
10474                 local aliases=$(cat $slab_lic/aliases)
10475                 (( aliases > 0 )) && margin=$((margin * aliases))
10476         fi
10477
10478         echo "before slab objects: $before"
10479         for i in $(seq $count); do
10480                 touch $DIR/$tfile
10481                 rm -f $DIR/$tfile
10482         done
10483         cancel_lru_locks osc
10484         local after=$(num_objects)
10485         echo "created: $count, after slab objects: $after"
10486         # shared slab counts are not very accurate, allow significant margin
10487         # the main goal is that the cache growth is not permanently > $count
10488         while (( after > before + margin )); do
10489                 sleep 1
10490                 after=$(num_objects)
10491                 wait=$((wait + 1))
10492                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10493                 if (( wait > 60 )); then
10494                         error "inode slab grew from $before+$margin to $after"
10495                 fi
10496         done
10497 }
10498 run_test 76a "confirm clients recycle inodes properly ===="
10499
10500 test_76b() {
10501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10502         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10503
10504         local count=512
10505         local before=$(num_objects)
10506
10507         for i in $(seq $count); do
10508                 mkdir $DIR/$tdir
10509                 rmdir $DIR/$tdir
10510         done
10511
10512         local after=$(num_objects)
10513         local wait=0
10514
10515         while (( after > before )); do
10516                 sleep 1
10517                 after=$(num_objects)
10518                 wait=$((wait + 1))
10519                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10520                 if (( wait > 60 )); then
10521                         error "inode slab grew from $before to $after"
10522                 fi
10523         done
10524
10525         echo "slab objects before: $before, after: $after"
10526 }
10527 run_test 76b "confirm clients recycle directory inodes properly ===="
10528
10529 export ORIG_CSUM=""
10530 set_checksums()
10531 {
10532         # Note: in sptlrpc modes which enable its own bulk checksum, the
10533         # original crc32_le bulk checksum will be automatically disabled,
10534         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10535         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10536         # In this case set_checksums() will not be no-op, because sptlrpc
10537         # bulk checksum will be enabled all through the test.
10538
10539         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10540         lctl set_param -n osc.*.checksums $1
10541         return 0
10542 }
10543
10544 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10545                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10546 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10547                              tr -d [] | head -n1)}
10548 set_checksum_type()
10549 {
10550         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10551         rc=$?
10552         log "set checksum type to $1, rc = $rc"
10553         return $rc
10554 }
10555
10556 get_osc_checksum_type()
10557 {
10558         # arugment 1: OST name, like OST0000
10559         ost=$1
10560         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10561                         sed 's/.*\[\(.*\)\].*/\1/g')
10562         rc=$?
10563         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10564         echo $checksum_type
10565 }
10566
10567 F77_TMP=$TMP/f77-temp
10568 F77SZ=8
10569 setup_f77() {
10570         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10571                 error "error writing to $F77_TMP"
10572 }
10573
10574 test_77a() { # bug 10889
10575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10576         $GSS && skip_env "could not run with gss"
10577
10578         [ ! -f $F77_TMP ] && setup_f77
10579         set_checksums 1
10580         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10581         set_checksums 0
10582         rm -f $DIR/$tfile
10583 }
10584 run_test 77a "normal checksum read/write operation"
10585
10586 test_77b() { # bug 10889
10587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10588         $GSS && skip_env "could not run with gss"
10589
10590         [ ! -f $F77_TMP ] && setup_f77
10591         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10592         $LCTL set_param fail_loc=0x80000409
10593         set_checksums 1
10594
10595         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10596                 error "dd error: $?"
10597         $LCTL set_param fail_loc=0
10598
10599         for algo in $CKSUM_TYPES; do
10600                 cancel_lru_locks osc
10601                 set_checksum_type $algo
10602                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10603                 $LCTL set_param fail_loc=0x80000408
10604                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10605                 $LCTL set_param fail_loc=0
10606         done
10607         set_checksums 0
10608         set_checksum_type $ORIG_CSUM_TYPE
10609         rm -f $DIR/$tfile
10610 }
10611 run_test 77b "checksum error on client write, read"
10612
10613 cleanup_77c() {
10614         trap 0
10615         set_checksums 0
10616         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10617         $check_ost &&
10618                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10619         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10620         $check_ost && [ -n "$ost_file_prefix" ] &&
10621                 do_facet ost1 rm -f ${ost_file_prefix}\*
10622 }
10623
10624 test_77c() {
10625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10626         $GSS && skip_env "could not run with gss"
10627         remote_ost_nodsh && skip "remote OST with nodsh"
10628
10629         local bad1
10630         local osc_file_prefix
10631         local osc_file
10632         local check_ost=false
10633         local ost_file_prefix
10634         local ost_file
10635         local orig_cksum
10636         local dump_cksum
10637         local fid
10638
10639         # ensure corruption will occur on first OSS/OST
10640         $LFS setstripe -i 0 $DIR/$tfile
10641
10642         [ ! -f $F77_TMP ] && setup_f77
10643         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10644                 error "dd write error: $?"
10645         fid=$($LFS path2fid $DIR/$tfile)
10646
10647         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10648         then
10649                 check_ost=true
10650                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10651                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10652         else
10653                 echo "OSS do not support bulk pages dump upon error"
10654         fi
10655
10656         osc_file_prefix=$($LCTL get_param -n debug_path)
10657         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10658
10659         trap cleanup_77c EXIT
10660
10661         set_checksums 1
10662         # enable bulk pages dump upon error on Client
10663         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10664         # enable bulk pages dump upon error on OSS
10665         $check_ost &&
10666                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10667
10668         # flush Client cache to allow next read to reach OSS
10669         cancel_lru_locks osc
10670
10671         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10672         $LCTL set_param fail_loc=0x80000408
10673         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10674         $LCTL set_param fail_loc=0
10675
10676         rm -f $DIR/$tfile
10677
10678         # check cksum dump on Client
10679         osc_file=$(ls ${osc_file_prefix}*)
10680         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10681         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10682         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10683         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10684         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10685                      cksum)
10686         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10687         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10688                 error "dump content does not match on Client"
10689
10690         $check_ost || skip "No need to check cksum dump on OSS"
10691
10692         # check cksum dump on OSS
10693         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10694         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10695         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10696         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10697         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10698                 error "dump content does not match on OSS"
10699
10700         cleanup_77c
10701 }
10702 run_test 77c "checksum error on client read with debug"
10703
10704 test_77d() { # bug 10889
10705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10706         $GSS && skip_env "could not run with gss"
10707
10708         stack_trap "rm -f $DIR/$tfile"
10709         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10710         $LCTL set_param fail_loc=0x80000409
10711         set_checksums 1
10712         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10713                 error "direct write: rc=$?"
10714         $LCTL set_param fail_loc=0
10715         set_checksums 0
10716
10717         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10718         $LCTL set_param fail_loc=0x80000408
10719         set_checksums 1
10720         cancel_lru_locks osc
10721         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10722                 error "direct read: rc=$?"
10723         $LCTL set_param fail_loc=0
10724         set_checksums 0
10725 }
10726 run_test 77d "checksum error on OST direct write, read"
10727
10728 test_77f() { # bug 10889
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730         $GSS && skip_env "could not run with gss"
10731
10732         set_checksums 1
10733         stack_trap "rm -f $DIR/$tfile"
10734         for algo in $CKSUM_TYPES; do
10735                 cancel_lru_locks osc
10736                 set_checksum_type $algo
10737                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10738                 $LCTL set_param fail_loc=0x409
10739                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10740                         error "direct write succeeded"
10741                 $LCTL set_param fail_loc=0
10742         done
10743         set_checksum_type $ORIG_CSUM_TYPE
10744         set_checksums 0
10745 }
10746 run_test 77f "repeat checksum error on write (expect error)"
10747
10748 test_77g() { # bug 10889
10749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10750         $GSS && skip_env "could not run with gss"
10751         remote_ost_nodsh && skip "remote OST with nodsh"
10752
10753         [ ! -f $F77_TMP ] && setup_f77
10754
10755         local file=$DIR/$tfile
10756         stack_trap "rm -f $file" EXIT
10757
10758         $LFS setstripe -c 1 -i 0 $file
10759         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10760         do_facet ost1 lctl set_param fail_loc=0x8000021a
10761         set_checksums 1
10762         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10763                 error "write error: rc=$?"
10764         do_facet ost1 lctl set_param fail_loc=0
10765         set_checksums 0
10766
10767         cancel_lru_locks osc
10768         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10769         do_facet ost1 lctl set_param fail_loc=0x8000021b
10770         set_checksums 1
10771         cmp $F77_TMP $file || error "file compare failed"
10772         do_facet ost1 lctl set_param fail_loc=0
10773         set_checksums 0
10774 }
10775 run_test 77g "checksum error on OST write, read"
10776
10777 test_77k() { # LU-10906
10778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10779         $GSS && skip_env "could not run with gss"
10780
10781         local cksum_param="osc.$FSNAME*.checksums"
10782         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10783         local checksum
10784         local i
10785
10786         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10787         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10788         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10789
10790         for i in 0 1; do
10791                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10792                         error "failed to set checksum=$i on MGS"
10793                 wait_update $HOSTNAME "$get_checksum" $i
10794                 #remount
10795                 echo "remount client, checksum should be $i"
10796                 remount_client $MOUNT || error "failed to remount client"
10797                 checksum=$(eval $get_checksum)
10798                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10799         done
10800         # remove persistent param to avoid races with checksum mountopt below
10801         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10802                 error "failed to delete checksum on MGS"
10803
10804         for opt in "checksum" "nochecksum"; do
10805                 #remount with mount option
10806                 echo "remount client with option $opt, checksum should be $i"
10807                 umount_client $MOUNT || error "failed to umount client"
10808                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10809                         error "failed to mount client with option '$opt'"
10810                 checksum=$(eval $get_checksum)
10811                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10812                 i=$((i - 1))
10813         done
10814
10815         remount_client $MOUNT || error "failed to remount client"
10816 }
10817 run_test 77k "enable/disable checksum correctly"
10818
10819 test_77l() {
10820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10821         $GSS && skip_env "could not run with gss"
10822
10823         set_checksums 1
10824         stack_trap "set_checksums $ORIG_CSUM" EXIT
10825         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10826
10827         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10828
10829         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10830         for algo in $CKSUM_TYPES; do
10831                 set_checksum_type $algo || error "fail to set checksum type $algo"
10832                 osc_algo=$(get_osc_checksum_type OST0000)
10833                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10834
10835                 # no locks, no reqs to let the connection idle
10836                 cancel_lru_locks osc
10837                 lru_resize_disable osc
10838                 wait_osc_import_state client ost1 IDLE
10839
10840                 # ensure ost1 is connected
10841                 stat $DIR/$tfile >/dev/null || error "can't stat"
10842                 wait_osc_import_state client ost1 FULL
10843
10844                 osc_algo=$(get_osc_checksum_type OST0000)
10845                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10846         done
10847         return 0
10848 }
10849 run_test 77l "preferred checksum type is remembered after reconnected"
10850
10851 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10852 rm -f $F77_TMP
10853 unset F77_TMP
10854
10855 test_77m() {
10856         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10857                 skip "Need at least version 2.14.52"
10858         local param=checksum_speed
10859
10860         $LCTL get_param $param || error "reading $param failed"
10861
10862         csum_speeds=$($LCTL get_param -n $param)
10863
10864         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10865                 error "known checksum types are missing"
10866 }
10867 run_test 77m "Verify checksum_speed is correctly read"
10868
10869 check_filefrag_77n() {
10870         local nr_ext=0
10871         local starts=()
10872         local ends=()
10873
10874         while read extidx a b start end rest; do
10875                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10876                         nr_ext=$(( $nr_ext + 1 ))
10877                         starts+=( ${start%..} )
10878                         ends+=( ${end%:} )
10879                 fi
10880         done < <( filefrag -sv $1 )
10881
10882         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10883         return 1
10884 }
10885
10886 test_77n() {
10887         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10888
10889         touch $DIR/$tfile
10890         $TRUNCATE $DIR/$tfile 0
10891         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10892         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10893         check_filefrag_77n $DIR/$tfile ||
10894                 skip "$tfile blocks not contiguous around hole"
10895
10896         set_checksums 1
10897         stack_trap "set_checksums $ORIG_CSUM" EXIT
10898         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10899         stack_trap "rm -f $DIR/$tfile"
10900
10901         for algo in $CKSUM_TYPES; do
10902                 if [[ "$algo" =~ ^t10 ]]; then
10903                         set_checksum_type $algo ||
10904                                 error "fail to set checksum type $algo"
10905                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10906                                 error "fail to read $tfile with $algo"
10907                 fi
10908         done
10909         rm -f $DIR/$tfile
10910         return 0
10911 }
10912 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10913
10914 test_77o() {
10915         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10916                 skip "Need MDS version at least 2.14.55"
10917         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10918                 skip "Need OST version at least 2.14.55"
10919         local ofd=obdfilter
10920         local mdt=mdt
10921
10922         # print OST checksum_type
10923         echo "$ofd.$FSNAME-*.checksum_type:"
10924         do_nodes $(comma_list $(osts_nodes)) \
10925                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10926
10927         # print MDT checksum_type
10928         echo "$mdt.$FSNAME-*.checksum_type:"
10929         do_nodes $(comma_list $(mdts_nodes)) \
10930                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10931
10932         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10933                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10934
10935         (( $o_count == $OSTCOUNT )) ||
10936                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10937
10938         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10939                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10940
10941         (( $m_count == $MDSCOUNT )) ||
10942                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10943 }
10944 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10945
10946 cleanup_test_78() {
10947         trap 0
10948         rm -f $DIR/$tfile
10949 }
10950
10951 test_78() { # bug 10901
10952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10953         remote_ost || skip_env "local OST"
10954
10955         NSEQ=5
10956         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10957         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10958         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10959         echo "MemTotal: $MEMTOTAL"
10960
10961         # reserve 256MB of memory for the kernel and other running processes,
10962         # and then take 1/2 of the remaining memory for the read/write buffers.
10963         if [ $MEMTOTAL -gt 512 ] ;then
10964                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10965         else
10966                 # for those poor memory-starved high-end clusters...
10967                 MEMTOTAL=$((MEMTOTAL / 2))
10968         fi
10969         echo "Mem to use for directio: $MEMTOTAL"
10970
10971         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10972         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10973         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10974         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10975                 head -n1)
10976         echo "Smallest OST: $SMALLESTOST"
10977         [[ $SMALLESTOST -lt 10240 ]] &&
10978                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10979
10980         trap cleanup_test_78 EXIT
10981
10982         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10983                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10984
10985         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10986         echo "File size: $F78SIZE"
10987         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10988         for i in $(seq 1 $NSEQ); do
10989                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10990                 echo directIO rdwr round $i of $NSEQ
10991                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10992         done
10993
10994         cleanup_test_78
10995 }
10996 run_test 78 "handle large O_DIRECT writes correctly ============"
10997
10998 test_79() { # bug 12743
10999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11000
11001         wait_delete_completed
11002
11003         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11004         BKFREE=$(calc_osc_kbytes kbytesfree)
11005         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11006
11007         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11008         DFTOTAL=`echo $STRING | cut -d, -f1`
11009         DFUSED=`echo $STRING  | cut -d, -f2`
11010         DFAVAIL=`echo $STRING | cut -d, -f3`
11011         DFFREE=$(($DFTOTAL - $DFUSED))
11012
11013         ALLOWANCE=$((64 * $OSTCOUNT))
11014
11015         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11016            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11017                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11018         fi
11019         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11020            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11021                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11022         fi
11023         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11024            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11025                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11026         fi
11027 }
11028 run_test 79 "df report consistency check ======================="
11029
11030 test_80() { # bug 10718
11031         remote_ost_nodsh && skip "remote OST with nodsh"
11032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11033
11034         # relax strong synchronous semantics for slow backends like ZFS
11035         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11036                 local soc="obdfilter.*.sync_lock_cancel"
11037                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11038
11039                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11040                 if [ -z "$save" ]; then
11041                         soc="obdfilter.*.sync_on_lock_cancel"
11042                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11043                 fi
11044
11045                 if [ "$save" != "never" ]; then
11046                         local hosts=$(comma_list $(osts_nodes))
11047
11048                         do_nodes $hosts $LCTL set_param $soc=never
11049                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11050                 fi
11051         fi
11052
11053         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11054         sync; sleep 1; sync
11055         local before=$(date +%s)
11056         cancel_lru_locks osc
11057         local after=$(date +%s)
11058         local diff=$((after - before))
11059         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11060
11061         rm -f $DIR/$tfile
11062 }
11063 run_test 80 "Page eviction is equally fast at high offsets too"
11064
11065 test_81a() { # LU-456
11066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11067         remote_ost_nodsh && skip "remote OST with nodsh"
11068
11069         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11070         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11071         do_facet ost1 lctl set_param fail_loc=0x80000228
11072
11073         # write should trigger a retry and success
11074         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11075         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11076         RC=$?
11077         if [ $RC -ne 0 ] ; then
11078                 error "write should success, but failed for $RC"
11079         fi
11080 }
11081 run_test 81a "OST should retry write when get -ENOSPC ==============="
11082
11083 test_81b() { # LU-456
11084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11085         remote_ost_nodsh && skip "remote OST with nodsh"
11086
11087         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11088         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11089         do_facet ost1 lctl set_param fail_loc=0x228
11090
11091         # write should retry several times and return -ENOSPC finally
11092         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11093         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11094         RC=$?
11095         ENOSPC=28
11096         if [ $RC -ne $ENOSPC ] ; then
11097                 error "dd should fail for -ENOSPC, but succeed."
11098         fi
11099 }
11100 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11101
11102 test_99() {
11103         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11104
11105         test_mkdir $DIR/$tdir.cvsroot
11106         chown $RUNAS_ID $DIR/$tdir.cvsroot
11107
11108         cd $TMP
11109         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11110
11111         cd /etc/init.d
11112         # some versions of cvs import exit(1) when asked to import links or
11113         # files they can't read.  ignore those files.
11114         local toignore=$(find . -type l -printf '-I %f\n' -o \
11115                          ! -perm /4 -printf '-I %f\n')
11116         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11117                 $tdir.reposname vtag rtag
11118
11119         cd $DIR
11120         test_mkdir $DIR/$tdir.reposname
11121         chown $RUNAS_ID $DIR/$tdir.reposname
11122         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11123
11124         cd $DIR/$tdir.reposname
11125         $RUNAS touch foo99
11126         $RUNAS cvs add -m 'addmsg' foo99
11127         $RUNAS cvs update
11128         $RUNAS cvs commit -m 'nomsg' foo99
11129         rm -fr $DIR/$tdir.cvsroot
11130 }
11131 run_test 99 "cvs strange file/directory operations"
11132
11133 test_100() {
11134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11135         [[ "$NETTYPE" =~ tcp ]] ||
11136                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11137         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11138         remote_ost_nodsh && skip "remote OST with nodsh"
11139         remote_mds_nodsh && skip "remote MDS with nodsh"
11140         remote_servers || skip "useless for local single node setup"
11141
11142         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11143                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11144
11145                 rc=0
11146                 if (( ${LOCAL/*:/} >= 1024 )); then
11147                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11148                         ss -tna
11149                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11150                 fi
11151         done
11152         (( $rc == 0 )) || error "privileged port not found" )
11153 }
11154 run_test 100 "check local port using privileged port"
11155
11156 function get_named_value()
11157 {
11158     local tag=$1
11159
11160     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11161 }
11162
11163 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
11164                    awk '/^max_cached_mb/ { print $2 }')
11165
11166 cleanup_101a() {
11167         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
11168         trap 0
11169 }
11170
11171 test_101a() {
11172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11173
11174         local s
11175         local discard
11176         local nreads=10000
11177         local cache_limit=32
11178
11179         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11180         trap cleanup_101a EXIT
11181         $LCTL set_param -n llite.*.read_ahead_stats=0
11182         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11183
11184         #
11185         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11186         #
11187         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11188         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11189
11190         discard=0
11191         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11192                    get_named_value 'read.but.discarded'); do
11193                         discard=$(($discard + $s))
11194         done
11195         cleanup_101a
11196
11197         $LCTL get_param osc.*-osc*.rpc_stats
11198         $LCTL get_param llite.*.read_ahead_stats
11199
11200         # Discard is generally zero, but sometimes a few random reads line up
11201         # and trigger larger readahead, which is wasted & leads to discards.
11202         if [[ $(($discard)) -gt $nreads ]]; then
11203                 error "too many ($discard) discarded pages"
11204         fi
11205         rm -f $DIR/$tfile || true
11206 }
11207 run_test 101a "check read-ahead for random reads"
11208
11209 setup_test101bc() {
11210         test_mkdir $DIR/$tdir
11211         local ssize=$1
11212         local FILE_LENGTH=$2
11213         STRIPE_OFFSET=0
11214
11215         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11216
11217         local list=$(comma_list $(osts_nodes))
11218         set_osd_param $list '' read_cache_enable 0
11219         set_osd_param $list '' writethrough_cache_enable 0
11220
11221         trap cleanup_test101bc EXIT
11222         # prepare the read-ahead file
11223         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11224
11225         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11226                                 count=$FILE_SIZE_MB 2> /dev/null
11227
11228 }
11229
11230 cleanup_test101bc() {
11231         trap 0
11232         rm -rf $DIR/$tdir
11233         rm -f $DIR/$tfile
11234
11235         local list=$(comma_list $(osts_nodes))
11236         set_osd_param $list '' read_cache_enable 1
11237         set_osd_param $list '' writethrough_cache_enable 1
11238 }
11239
11240 calc_total() {
11241         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11242 }
11243
11244 ra_check_101() {
11245         local read_size=$1
11246         local stripe_size=$2
11247         local stride_length=$((stripe_size / read_size))
11248         local stride_width=$((stride_length * OSTCOUNT))
11249         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11250                                 (stride_width - stride_length) ))
11251         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11252                   get_named_value 'read.but.discarded' | calc_total)
11253
11254         if [[ $discard -gt $discard_limit ]]; then
11255                 $LCTL get_param llite.*.read_ahead_stats
11256                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11257         else
11258                 echo "Read-ahead success for size ${read_size}"
11259         fi
11260 }
11261
11262 test_101b() {
11263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11265
11266         local STRIPE_SIZE=1048576
11267         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11268
11269         if [ $SLOW == "yes" ]; then
11270                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11271         else
11272                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11273         fi
11274
11275         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11276
11277         # prepare the read-ahead file
11278         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11279         cancel_lru_locks osc
11280         for BIDX in 2 4 8 16 32 64 128 256
11281         do
11282                 local BSIZE=$((BIDX*4096))
11283                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11284                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11285                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11286                 $LCTL set_param -n llite.*.read_ahead_stats=0
11287                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11288                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11289                 cancel_lru_locks osc
11290                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11291         done
11292         cleanup_test101bc
11293         true
11294 }
11295 run_test 101b "check stride-io mode read-ahead ================="
11296
11297 test_101c() {
11298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11299
11300         local STRIPE_SIZE=1048576
11301         local FILE_LENGTH=$((STRIPE_SIZE*100))
11302         local nreads=10000
11303         local rsize=65536
11304         local osc_rpc_stats
11305
11306         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11307
11308         cancel_lru_locks osc
11309         $LCTL set_param osc.*.rpc_stats=0
11310         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11311         $LCTL get_param osc.*.rpc_stats
11312         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11313                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11314                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11315                 local size
11316
11317                 if [ $lines -le 20 ]; then
11318                         echo "continue debug"
11319                         continue
11320                 fi
11321                 for size in 1 2 4 8; do
11322                         local rpc=$(echo "$stats" |
11323                                     awk '($1 == "'$size':") {print $2; exit; }')
11324                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11325                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11326                 done
11327                 echo "$osc_rpc_stats check passed!"
11328         done
11329         cleanup_test101bc
11330         true
11331 }
11332 run_test 101c "check stripe_size aligned read-ahead"
11333
11334 test_101d() {
11335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11336
11337         local file=$DIR/$tfile
11338         local sz_MB=${FILESIZE_101d:-80}
11339         local ra_MB=${READAHEAD_MB:-40}
11340
11341         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11342         [ $free_MB -lt $sz_MB ] &&
11343                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11344
11345         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11346         $LFS setstripe -c -1 $file || error "setstripe failed"
11347
11348         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11349         echo Cancel LRU locks on lustre client to flush the client cache
11350         cancel_lru_locks osc
11351
11352         echo Disable read-ahead
11353         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11354         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11355         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11356         $LCTL get_param -n llite.*.max_read_ahead_mb
11357
11358         echo "Reading the test file $file with read-ahead disabled"
11359         local sz_KB=$((sz_MB * 1024 / 4))
11360         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11361         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11362         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11363                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11364
11365         echo "Cancel LRU locks on lustre client to flush the client cache"
11366         cancel_lru_locks osc
11367         echo Enable read-ahead with ${ra_MB}MB
11368         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11369
11370         echo "Reading the test file $file with read-ahead enabled"
11371         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11372                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11373
11374         echo "read-ahead disabled time read $raOFF"
11375         echo "read-ahead enabled time read $raON"
11376
11377         rm -f $file
11378         wait_delete_completed
11379
11380         # use awk for this check instead of bash because it handles decimals
11381         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11382                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11383 }
11384 run_test 101d "file read with and without read-ahead enabled"
11385
11386 test_101e() {
11387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11388
11389         local file=$DIR/$tfile
11390         local size_KB=500  #KB
11391         local count=100
11392         local bsize=1024
11393
11394         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11395         local need_KB=$((count * size_KB))
11396         [[ $free_KB -le $need_KB ]] &&
11397                 skip_env "Need free space $need_KB, have $free_KB"
11398
11399         echo "Creating $count ${size_KB}K test files"
11400         for ((i = 0; i < $count; i++)); do
11401                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11402         done
11403
11404         echo "Cancel LRU locks on lustre client to flush the client cache"
11405         cancel_lru_locks $OSC
11406
11407         echo "Reset readahead stats"
11408         $LCTL set_param -n llite.*.read_ahead_stats=0
11409
11410         for ((i = 0; i < $count; i++)); do
11411                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11412         done
11413
11414         $LCTL get_param llite.*.max_cached_mb
11415         $LCTL get_param llite.*.read_ahead_stats
11416         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11417                      get_named_value 'misses' | calc_total)
11418
11419         for ((i = 0; i < $count; i++)); do
11420                 rm -rf $file.$i 2>/dev/null
11421         done
11422
11423         #10000 means 20% reads are missing in readahead
11424         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11425 }
11426 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11427
11428 test_101f() {
11429         which iozone || skip_env "no iozone installed"
11430
11431         local old_debug=$($LCTL get_param debug)
11432         old_debug=${old_debug#*=}
11433         $LCTL set_param debug="reada mmap"
11434
11435         # create a test file
11436         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11437
11438         echo Cancel LRU locks on lustre client to flush the client cache
11439         cancel_lru_locks osc
11440
11441         echo Reset readahead stats
11442         $LCTL set_param -n llite.*.read_ahead_stats=0
11443
11444         echo mmap read the file with small block size
11445         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11446                 > /dev/null 2>&1
11447
11448         echo checking missing pages
11449         $LCTL get_param llite.*.read_ahead_stats
11450         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11451                         get_named_value 'misses' | calc_total)
11452
11453         $LCTL set_param debug="$old_debug"
11454         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11455         rm -f $DIR/$tfile
11456 }
11457 run_test 101f "check mmap read performance"
11458
11459 test_101g_brw_size_test() {
11460         local mb=$1
11461         local pages=$((mb * 1048576 / PAGE_SIZE))
11462         local file=$DIR/$tfile
11463
11464         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11465                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11466         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11467                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11468                         return 2
11469         done
11470
11471         stack_trap "rm -f $file" EXIT
11472         $LCTL set_param -n osc.*.rpc_stats=0
11473
11474         # 10 RPCs should be enough for the test
11475         local count=10
11476         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11477                 { error "dd write ${mb} MB blocks failed"; return 3; }
11478         cancel_lru_locks osc
11479         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11480                 { error "dd write ${mb} MB blocks failed"; return 4; }
11481
11482         # calculate number of full-sized read and write RPCs
11483         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11484                 sed -n '/pages per rpc/,/^$/p' |
11485                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11486                 END { print reads,writes }'))
11487         # allow one extra full-sized read RPC for async readahead
11488         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11489                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11490         [[ ${rpcs[1]} == $count ]] ||
11491                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11492 }
11493
11494 test_101g() {
11495         remote_ost_nodsh && skip "remote OST with nodsh"
11496
11497         local rpcs
11498         local osts=$(get_facets OST)
11499         local list=$(comma_list $(osts_nodes))
11500         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11501         local brw_size="obdfilter.*.brw_size"
11502
11503         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11504
11505         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11506
11507         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11508                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11509                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11510            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11511                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11512                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11513
11514                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11515                         suffix="M"
11516
11517                 if [[ $orig_mb -lt 16 ]]; then
11518                         save_lustre_params $osts "$brw_size" > $p
11519                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11520                                 error "set 16MB RPC size failed"
11521
11522                         echo "remount client to enable new RPC size"
11523                         remount_client $MOUNT || error "remount_client failed"
11524                 fi
11525
11526                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11527                 # should be able to set brw_size=12, but no rpc_stats for that
11528                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11529         fi
11530
11531         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11532
11533         if [[ $orig_mb -lt 16 ]]; then
11534                 restore_lustre_params < $p
11535                 remount_client $MOUNT || error "remount_client restore failed"
11536         fi
11537
11538         rm -f $p $DIR/$tfile
11539 }
11540 run_test 101g "Big bulk(4/16 MiB) readahead"
11541
11542 test_101h() {
11543         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11544
11545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11546                 error "dd 70M file failed"
11547         echo Cancel LRU locks on lustre client to flush the client cache
11548         cancel_lru_locks osc
11549
11550         echo "Reset readahead stats"
11551         $LCTL set_param -n llite.*.read_ahead_stats 0
11552
11553         echo "Read 10M of data but cross 64M bundary"
11554         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11555         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11556                      get_named_value 'misses' | calc_total)
11557         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11558         rm -f $p $DIR/$tfile
11559 }
11560 run_test 101h "Readahead should cover current read window"
11561
11562 test_101i() {
11563         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11564                 error "dd 10M file failed"
11565
11566         local max_per_file_mb=$($LCTL get_param -n \
11567                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11568         cancel_lru_locks osc
11569         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11570         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11571                 error "set max_read_ahead_per_file_mb to 1 failed"
11572
11573         echo "Reset readahead stats"
11574         $LCTL set_param llite.*.read_ahead_stats=0
11575
11576         dd if=$DIR/$tfile of=/dev/null bs=2M
11577
11578         $LCTL get_param llite.*.read_ahead_stats
11579         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11580                      awk '/misses/ { print $2 }')
11581         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11582         rm -f $DIR/$tfile
11583 }
11584 run_test 101i "allow current readahead to exceed reservation"
11585
11586 test_101j() {
11587         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11588                 error "setstripe $DIR/$tfile failed"
11589         local file_size=$((1048576 * 16))
11590         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11591         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11592
11593         echo Disable read-ahead
11594         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11595
11596         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11597         for blk in $PAGE_SIZE 1048576 $file_size; do
11598                 cancel_lru_locks osc
11599                 echo "Reset readahead stats"
11600                 $LCTL set_param -n llite.*.read_ahead_stats=0
11601                 local count=$(($file_size / $blk))
11602                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11603                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11604                              get_named_value 'failed.to.fast.read' | calc_total)
11605                 $LCTL get_param -n llite.*.read_ahead_stats
11606                 [ $miss -eq $count ] || error "expected $count got $miss"
11607         done
11608
11609         rm -f $p $DIR/$tfile
11610 }
11611 run_test 101j "A complete read block should be submitted when no RA"
11612
11613 test_readahead_base() {
11614         local file=$DIR/$tfile
11615         local size=$1
11616         local iosz
11617         local ramax
11618         local ranum
11619
11620         $LCTL set_param -n llite.*.read_ahead_stats=0
11621         # The first page is not accounted into readahead
11622         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11623         iosz=$(((size + 1048575) / 1048576 * 1048576))
11624         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11625
11626         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11627         fallocate -l $size $file || error "failed to fallocate $file"
11628         cancel_lru_locks osc
11629         $MULTIOP $file or${iosz}c || error "failed to read $file"
11630         $LCTL get_param -n llite.*.read_ahead_stats
11631         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11632                 awk '/readahead.pages/ { print $7 }' | calc_total)
11633         (( $ranum <= $ramax )) ||
11634                 error "read-ahead pages is $ranum more than $ramax"
11635         rm -rf $file || error "failed to remove $file"
11636 }
11637
11638 test_101m()
11639 {
11640         local file=$DIR/$tfile
11641         local ramax
11642         local ranum
11643         local size
11644         local iosz
11645
11646         check_set_fallocate_or_skip
11647         stack_trap "rm -f $file" EXIT
11648
11649         test_readahead_base 4096
11650
11651         # file size: 16K = 16384
11652         test_readahead_base 16384
11653         test_readahead_base 16385
11654         test_readahead_base 16383
11655
11656         # file size: 1M + 1 = 1048576 + 1
11657         test_readahead_base 1048577
11658         # file size: 1M + 16K
11659         test_readahead_base $((1048576 + 16384))
11660
11661         # file size: stripe_size * (stripe_count - 1) + 16K
11662         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11663         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11664         # file size: stripe_size * stripe_count + 16K
11665         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11666         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11667         # file size: 2 * stripe_size * stripe_count + 16K
11668         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11669         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11670 }
11671 run_test 101m "read ahead for small file and last stripe of the file"
11672
11673 setup_test102() {
11674         test_mkdir $DIR/$tdir
11675         chown $RUNAS_ID $DIR/$tdir
11676         STRIPE_SIZE=65536
11677         STRIPE_OFFSET=1
11678         STRIPE_COUNT=$OSTCOUNT
11679         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11680
11681         trap cleanup_test102 EXIT
11682         cd $DIR
11683         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11684         cd $DIR/$tdir
11685         for num in 1 2 3 4; do
11686                 for count in $(seq 1 $STRIPE_COUNT); do
11687                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11688                                 local size=`expr $STRIPE_SIZE \* $num`
11689                                 local file=file"$num-$idx-$count"
11690                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11691                         done
11692                 done
11693         done
11694
11695         cd $DIR
11696         $1 tar cf $TMP/f102.tar $tdir --xattrs
11697 }
11698
11699 cleanup_test102() {
11700         trap 0
11701         rm -f $TMP/f102.tar
11702         rm -rf $DIR/d0.sanity/d102
11703 }
11704
11705 test_102a() {
11706         [ "$UID" != 0 ] && skip "must run as root"
11707         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11708                 skip_env "must have user_xattr"
11709
11710         [ -z "$(which setfattr 2>/dev/null)" ] &&
11711                 skip_env "could not find setfattr"
11712
11713         local testfile=$DIR/$tfile
11714
11715         touch $testfile
11716         echo "set/get xattr..."
11717         setfattr -n trusted.name1 -v value1 $testfile ||
11718                 error "setfattr -n trusted.name1=value1 $testfile failed"
11719         getfattr -n trusted.name1 $testfile 2> /dev/null |
11720           grep "trusted.name1=.value1" ||
11721                 error "$testfile missing trusted.name1=value1"
11722
11723         setfattr -n user.author1 -v author1 $testfile ||
11724                 error "setfattr -n user.author1=author1 $testfile failed"
11725         getfattr -n user.author1 $testfile 2> /dev/null |
11726           grep "user.author1=.author1" ||
11727                 error "$testfile missing trusted.author1=author1"
11728
11729         echo "listxattr..."
11730         setfattr -n trusted.name2 -v value2 $testfile ||
11731                 error "$testfile unable to set trusted.name2"
11732         setfattr -n trusted.name3 -v value3 $testfile ||
11733                 error "$testfile unable to set trusted.name3"
11734         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11735             grep "trusted.name" | wc -l) -eq 3 ] ||
11736                 error "$testfile missing 3 trusted.name xattrs"
11737
11738         setfattr -n user.author2 -v author2 $testfile ||
11739                 error "$testfile unable to set user.author2"
11740         setfattr -n user.author3 -v author3 $testfile ||
11741                 error "$testfile unable to set user.author3"
11742         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11743             grep "user.author" | wc -l) -eq 3 ] ||
11744                 error "$testfile missing 3 user.author xattrs"
11745
11746         echo "remove xattr..."
11747         setfattr -x trusted.name1 $testfile ||
11748                 error "$testfile error deleting trusted.name1"
11749         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11750                 error "$testfile did not delete trusted.name1 xattr"
11751
11752         setfattr -x user.author1 $testfile ||
11753                 error "$testfile error deleting user.author1"
11754         echo "set lustre special xattr ..."
11755         $LFS setstripe -c1 $testfile
11756         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11757                 awk -F "=" '/trusted.lov/ { print $2 }' )
11758         setfattr -n "trusted.lov" -v $lovea $testfile ||
11759                 error "$testfile doesn't ignore setting trusted.lov again"
11760         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11761                 error "$testfile allow setting invalid trusted.lov"
11762         rm -f $testfile
11763 }
11764 run_test 102a "user xattr test =================================="
11765
11766 check_102b_layout() {
11767         local layout="$*"
11768         local testfile=$DIR/$tfile
11769
11770         echo "test layout '$layout'"
11771         $LFS setstripe $layout $testfile || error "setstripe failed"
11772         $LFS getstripe -y $testfile
11773
11774         echo "get/set/list trusted.lov xattr ..." # b=10930
11775         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11776         [[ "$value" =~ "trusted.lov" ]] ||
11777                 error "can't get trusted.lov from $testfile"
11778         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11779                 error "getstripe failed"
11780
11781         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11782
11783         value=$(cut -d= -f2 <<<$value)
11784         # LU-13168: truncated xattr should fail if short lov_user_md header
11785         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11786                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11787         for len in $lens; do
11788                 echo "setfattr $len $testfile.2"
11789                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11790                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11791         done
11792         local stripe_size=$($LFS getstripe -S $testfile.2)
11793         local stripe_count=$($LFS getstripe -c $testfile.2)
11794         [[ $stripe_size -eq 65536 ]] ||
11795                 error "stripe size $stripe_size != 65536"
11796         [[ $stripe_count -eq $stripe_count_orig ]] ||
11797                 error "stripe count $stripe_count != $stripe_count_orig"
11798         rm $testfile $testfile.2
11799 }
11800
11801 test_102b() {
11802         [ -z "$(which setfattr 2>/dev/null)" ] &&
11803                 skip_env "could not find setfattr"
11804         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11805
11806         # check plain layout
11807         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11808
11809         # and also check composite layout
11810         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11811
11812 }
11813 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11814
11815 test_102c() {
11816         [ -z "$(which setfattr 2>/dev/null)" ] &&
11817                 skip_env "could not find setfattr"
11818         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11819
11820         # b10930: get/set/list lustre.lov xattr
11821         echo "get/set/list lustre.lov xattr ..."
11822         test_mkdir $DIR/$tdir
11823         chown $RUNAS_ID $DIR/$tdir
11824         local testfile=$DIR/$tdir/$tfile
11825         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11826                 error "setstripe failed"
11827         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11828                 error "getstripe failed"
11829         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11830         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11831
11832         local testfile2=${testfile}2
11833         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11834                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11835
11836         $RUNAS $MCREATE $testfile2
11837         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11838         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11839         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11840         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11841         [ $stripe_count -eq $STRIPECOUNT ] ||
11842                 error "stripe count $stripe_count != $STRIPECOUNT"
11843 }
11844 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11845
11846 compare_stripe_info1() {
11847         local stripe_index_all_zero=true
11848
11849         for num in 1 2 3 4; do
11850                 for count in $(seq 1 $STRIPE_COUNT); do
11851                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11852                                 local size=$((STRIPE_SIZE * num))
11853                                 local file=file"$num-$offset-$count"
11854                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11855                                 [[ $stripe_size -ne $size ]] &&
11856                                     error "$file: size $stripe_size != $size"
11857                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11858                                 # allow fewer stripes to be created, ORI-601
11859                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11860                                     error "$file: count $stripe_count != $count"
11861                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11862                                 [[ $stripe_index -ne 0 ]] &&
11863                                         stripe_index_all_zero=false
11864                         done
11865                 done
11866         done
11867         $stripe_index_all_zero &&
11868                 error "all files are being extracted starting from OST index 0"
11869         return 0
11870 }
11871
11872 have_xattrs_include() {
11873         tar --help | grep -q xattrs-include &&
11874                 echo --xattrs-include="lustre.*"
11875 }
11876
11877 test_102d() {
11878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11880
11881         XINC=$(have_xattrs_include)
11882         setup_test102
11883         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11884         cd $DIR/$tdir/$tdir
11885         compare_stripe_info1
11886 }
11887 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11888
11889 test_102f() {
11890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11891         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11892
11893         XINC=$(have_xattrs_include)
11894         setup_test102
11895         test_mkdir $DIR/$tdir.restore
11896         cd $DIR
11897         tar cf - --xattrs $tdir | tar xf - \
11898                 -C $DIR/$tdir.restore --xattrs $XINC
11899         cd $DIR/$tdir.restore/$tdir
11900         compare_stripe_info1
11901 }
11902 run_test 102f "tar copy files, not keep osts"
11903
11904 grow_xattr() {
11905         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11906                 skip "must have user_xattr"
11907         [ -z "$(which setfattr 2>/dev/null)" ] &&
11908                 skip_env "could not find setfattr"
11909         [ -z "$(which getfattr 2>/dev/null)" ] &&
11910                 skip_env "could not find getfattr"
11911
11912         local xsize=${1:-1024}  # in bytes
11913         local file=$DIR/$tfile
11914         local value="$(generate_string $xsize)"
11915         local xbig=trusted.big
11916         local toobig=$2
11917
11918         touch $file
11919         log "save $xbig on $file"
11920         if [ -z "$toobig" ]
11921         then
11922                 setfattr -n $xbig -v $value $file ||
11923                         error "saving $xbig on $file failed"
11924         else
11925                 setfattr -n $xbig -v $value $file &&
11926                         error "saving $xbig on $file succeeded"
11927                 return 0
11928         fi
11929
11930         local orig=$(get_xattr_value $xbig $file)
11931         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11932
11933         local xsml=trusted.sml
11934         log "save $xsml on $file"
11935         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11936
11937         local new=$(get_xattr_value $xbig $file)
11938         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11939
11940         log "grow $xsml on $file"
11941         setfattr -n $xsml -v "$value" $file ||
11942                 error "growing $xsml on $file failed"
11943
11944         new=$(get_xattr_value $xbig $file)
11945         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11946         log "$xbig still valid after growing $xsml"
11947
11948         rm -f $file
11949 }
11950
11951 test_102h() { # bug 15777
11952         grow_xattr 1024
11953 }
11954 run_test 102h "grow xattr from inside inode to external block"
11955
11956 test_102ha() {
11957         large_xattr_enabled || skip_env "ea_inode feature disabled"
11958
11959         echo "setting xattr of max xattr size: $(max_xattr_size)"
11960         grow_xattr $(max_xattr_size)
11961
11962         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11963         echo "This should fail:"
11964         grow_xattr $(($(max_xattr_size) + 10)) 1
11965 }
11966 run_test 102ha "grow xattr from inside inode to external inode"
11967
11968 test_102i() { # bug 17038
11969         [ -z "$(which getfattr 2>/dev/null)" ] &&
11970                 skip "could not find getfattr"
11971
11972         touch $DIR/$tfile
11973         ln -s $DIR/$tfile $DIR/${tfile}link
11974         getfattr -n trusted.lov $DIR/$tfile ||
11975                 error "lgetxattr on $DIR/$tfile failed"
11976         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11977                 grep -i "no such attr" ||
11978                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11979         rm -f $DIR/$tfile $DIR/${tfile}link
11980 }
11981 run_test 102i "lgetxattr test on symbolic link ============"
11982
11983 test_102j() {
11984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11985         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11986
11987         XINC=$(have_xattrs_include)
11988         setup_test102 "$RUNAS"
11989         chown $RUNAS_ID $DIR/$tdir
11990         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11991         cd $DIR/$tdir/$tdir
11992         compare_stripe_info1 "$RUNAS"
11993 }
11994 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11995
11996 test_102k() {
11997         [ -z "$(which setfattr 2>/dev/null)" ] &&
11998                 skip "could not find setfattr"
11999
12000         touch $DIR/$tfile
12001         # b22187 just check that does not crash for regular file.
12002         setfattr -n trusted.lov $DIR/$tfile
12003         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12004         local test_kdir=$DIR/$tdir
12005         test_mkdir $test_kdir
12006         local default_size=$($LFS getstripe -S $test_kdir)
12007         local default_count=$($LFS getstripe -c $test_kdir)
12008         local default_offset=$($LFS getstripe -i $test_kdir)
12009         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12010                 error 'dir setstripe failed'
12011         setfattr -n trusted.lov $test_kdir
12012         local stripe_size=$($LFS getstripe -S $test_kdir)
12013         local stripe_count=$($LFS getstripe -c $test_kdir)
12014         local stripe_offset=$($LFS getstripe -i $test_kdir)
12015         [ $stripe_size -eq $default_size ] ||
12016                 error "stripe size $stripe_size != $default_size"
12017         [ $stripe_count -eq $default_count ] ||
12018                 error "stripe count $stripe_count != $default_count"
12019         [ $stripe_offset -eq $default_offset ] ||
12020                 error "stripe offset $stripe_offset != $default_offset"
12021         rm -rf $DIR/$tfile $test_kdir
12022 }
12023 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12024
12025 test_102l() {
12026         [ -z "$(which getfattr 2>/dev/null)" ] &&
12027                 skip "could not find getfattr"
12028
12029         # LU-532 trusted. xattr is invisible to non-root
12030         local testfile=$DIR/$tfile
12031
12032         touch $testfile
12033
12034         echo "listxattr as user..."
12035         chown $RUNAS_ID $testfile
12036         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12037             grep -q "trusted" &&
12038                 error "$testfile trusted xattrs are user visible"
12039
12040         return 0;
12041 }
12042 run_test 102l "listxattr size test =================================="
12043
12044 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12045         local path=$DIR/$tfile
12046         touch $path
12047
12048         listxattr_size_check $path || error "listattr_size_check $path failed"
12049 }
12050 run_test 102m "Ensure listxattr fails on small bufffer ========"
12051
12052 cleanup_test102
12053
12054 getxattr() { # getxattr path name
12055         # Return the base64 encoding of the value of xattr name on path.
12056         local path=$1
12057         local name=$2
12058
12059         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12060         # file: $path
12061         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12062         #
12063         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12064
12065         getfattr --absolute-names --encoding=base64 --name=$name $path |
12066                 awk -F= -v name=$name '$1 == name {
12067                         print substr($0, index($0, "=") + 1);
12068         }'
12069 }
12070
12071 test_102n() { # LU-4101 mdt: protect internal xattrs
12072         [ -z "$(which setfattr 2>/dev/null)" ] &&
12073                 skip "could not find setfattr"
12074         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12075         then
12076                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12077         fi
12078
12079         local file0=$DIR/$tfile.0
12080         local file1=$DIR/$tfile.1
12081         local xattr0=$TMP/$tfile.0
12082         local xattr1=$TMP/$tfile.1
12083         local namelist="lov lma lmv link fid version som hsm"
12084         local name
12085         local value
12086
12087         rm -rf $file0 $file1 $xattr0 $xattr1
12088         touch $file0 $file1
12089
12090         # Get 'before' xattrs of $file1.
12091         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12092
12093         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12094                 namelist+=" lfsck_namespace"
12095         for name in $namelist; do
12096                 # Try to copy xattr from $file0 to $file1.
12097                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12098
12099                 setfattr --name=trusted.$name --value="$value" $file1 ||
12100                         error "setxattr 'trusted.$name' failed"
12101
12102                 # Try to set a garbage xattr.
12103                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12104
12105                 if [[ x$name == "xlov" ]]; then
12106                         setfattr --name=trusted.lov --value="$value" $file1 &&
12107                         error "setxattr invalid 'trusted.lov' success"
12108                 else
12109                         setfattr --name=trusted.$name --value="$value" $file1 ||
12110                                 error "setxattr invalid 'trusted.$name' failed"
12111                 fi
12112
12113                 # Try to remove the xattr from $file1. We don't care if this
12114                 # appears to succeed or fail, we just don't want there to be
12115                 # any changes or crashes.
12116                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12117         done
12118
12119         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12120         then
12121                 name="lfsck_ns"
12122                 # Try to copy xattr from $file0 to $file1.
12123                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12124
12125                 setfattr --name=trusted.$name --value="$value" $file1 ||
12126                         error "setxattr 'trusted.$name' failed"
12127
12128                 # Try to set a garbage xattr.
12129                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12130
12131                 setfattr --name=trusted.$name --value="$value" $file1 ||
12132                         error "setxattr 'trusted.$name' failed"
12133
12134                 # Try to remove the xattr from $file1. We don't care if this
12135                 # appears to succeed or fail, we just don't want there to be
12136                 # any changes or crashes.
12137                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12138         fi
12139
12140         # Get 'after' xattrs of file1.
12141         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12142
12143         if ! diff $xattr0 $xattr1; then
12144                 error "before and after xattrs of '$file1' differ"
12145         fi
12146
12147         rm -rf $file0 $file1 $xattr0 $xattr1
12148
12149         return 0
12150 }
12151 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12152
12153 test_102p() { # LU-4703 setxattr did not check ownership
12154         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12155                 skip "MDS needs to be at least 2.5.56"
12156
12157         local testfile=$DIR/$tfile
12158
12159         touch $testfile
12160
12161         echo "setfacl as user..."
12162         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12163         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12164
12165         echo "setfattr as user..."
12166         setfacl -m "u:$RUNAS_ID:---" $testfile
12167         $RUNAS setfattr -x system.posix_acl_access $testfile
12168         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12169 }
12170 run_test 102p "check setxattr(2) correctly fails without permission"
12171
12172 test_102q() {
12173         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12174                 skip "MDS needs to be at least 2.6.92"
12175
12176         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12177 }
12178 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12179
12180 test_102r() {
12181         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12182                 skip "MDS needs to be at least 2.6.93"
12183
12184         touch $DIR/$tfile || error "touch"
12185         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12186         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12187         rm $DIR/$tfile || error "rm"
12188
12189         #normal directory
12190         mkdir -p $DIR/$tdir || error "mkdir"
12191         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12192         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12193         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12194                 error "$testfile error deleting user.author1"
12195         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12196                 grep "user.$(basename $tdir)" &&
12197                 error "$tdir did not delete user.$(basename $tdir)"
12198         rmdir $DIR/$tdir || error "rmdir"
12199
12200         #striped directory
12201         test_mkdir $DIR/$tdir
12202         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12203         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12204         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12205                 error "$testfile error deleting user.author1"
12206         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12207                 grep "user.$(basename $tdir)" &&
12208                 error "$tdir did not delete user.$(basename $tdir)"
12209         rmdir $DIR/$tdir || error "rm striped dir"
12210 }
12211 run_test 102r "set EAs with empty values"
12212
12213 test_102s() {
12214         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12215                 skip "MDS needs to be at least 2.11.52"
12216
12217         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12218
12219         save_lustre_params client "llite.*.xattr_cache" > $save
12220
12221         for cache in 0 1; do
12222                 lctl set_param llite.*.xattr_cache=$cache
12223
12224                 rm -f $DIR/$tfile
12225                 touch $DIR/$tfile || error "touch"
12226                 for prefix in lustre security system trusted user; do
12227                         # Note getxattr() may fail with 'Operation not
12228                         # supported' or 'No such attribute' depending
12229                         # on prefix and cache.
12230                         getfattr -n $prefix.n102s $DIR/$tfile &&
12231                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12232                 done
12233         done
12234
12235         restore_lustre_params < $save
12236 }
12237 run_test 102s "getting nonexistent xattrs should fail"
12238
12239 test_102t() {
12240         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12241                 skip "MDS needs to be at least 2.11.52"
12242
12243         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12244
12245         save_lustre_params client "llite.*.xattr_cache" > $save
12246
12247         for cache in 0 1; do
12248                 lctl set_param llite.*.xattr_cache=$cache
12249
12250                 for buf_size in 0 256; do
12251                         rm -f $DIR/$tfile
12252                         touch $DIR/$tfile || error "touch"
12253                         setfattr -n user.multiop $DIR/$tfile
12254                         $MULTIOP $DIR/$tfile oa$buf_size ||
12255                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12256                 done
12257         done
12258
12259         restore_lustre_params < $save
12260 }
12261 run_test 102t "zero length xattr values handled correctly"
12262
12263 run_acl_subtest()
12264 {
12265         local test=$LUSTRE/tests/acl/$1.test
12266         local tmp=$(mktemp -t $1-XXXXXX).test
12267         local bin=$2
12268         local dmn=$3
12269         local grp=$4
12270         local nbd=$5
12271         export LANG=C
12272
12273
12274         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12275         local sedgroups="-e s/:users/:$grp/g"
12276         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12277
12278         sed $sedusers $sedgroups < $test > $tmp
12279         stack_trap "rm -f $tmp"
12280         [[ -s $tmp ]] || error "sed failed to create test script"
12281
12282         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12283         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12284 }
12285
12286 test_103a() {
12287         [ "$UID" != 0 ] && skip "must run as root"
12288         $GSS && skip_env "could not run under gss"
12289         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12290                 skip_env "must have acl enabled"
12291         which setfacl || skip_env "could not find setfacl"
12292         remote_mds_nodsh && skip "remote MDS with nodsh"
12293
12294         local mdts=$(comma_list $(mdts_nodes))
12295         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12296
12297         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12298         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12299
12300         ACLBIN=${ACLBIN:-"bin"}
12301         ACLDMN=${ACLDMN:-"daemon"}
12302         ACLGRP=${ACLGRP:-"users"}
12303         ACLNBD=${ACLNBD:-"nobody"}
12304
12305         if ! id $ACLBIN ||
12306            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12307                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12308                 ACLBIN=$USER0
12309                 if ! id $ACLBIN ; then
12310                         cat /etc/passwd
12311                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12312                 fi
12313         fi
12314         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12315            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12316                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12317                 ACLDMN=$USER1
12318                 if ! id $ACLDMN ; then
12319                         cat /etc/passwd
12320                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12321                 fi
12322         fi
12323         if ! getent group $ACLGRP; then
12324                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12325                 ACLGRP="$TSTUSR"
12326                 if ! getent group $ACLGRP; then
12327                         echo "cannot find group '$ACLGRP', adding it"
12328                         cat /etc/group
12329                         add_group 60000 $ACLGRP
12330                 fi
12331         fi
12332
12333         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12334         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12335         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12336
12337         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12338                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12339                 ACLGRP="$TSTUSR"
12340                 if ! getent group $ACLGRP; then
12341                         echo "cannot find group '$ACLGRP', adding it"
12342                         cat /etc/group
12343                         add_group 60000 $ACLGRP
12344                 fi
12345                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12346                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12347                         cat /etc/group
12348                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12349                 fi
12350         fi
12351
12352         gpasswd -a $ACLDMN $ACLBIN ||
12353                 error "setting client group failed"             # LU-5641
12354         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12355                 error "setting MDS group failed"                # LU-5641
12356
12357         declare -a identity_old
12358
12359         for num in $(seq $MDSCOUNT); do
12360                 switch_identity $num true || identity_old[$num]=$?
12361         done
12362
12363         SAVE_UMASK=$(umask)
12364         umask 0022
12365         mkdir -p $DIR/$tdir
12366         cd $DIR/$tdir
12367
12368         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12369         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12370         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12371         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12372         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12373         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12374         if ! id -u $ACLNBD ||
12375            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12376                 ACLNBD="nfsnobody"
12377                 if ! id -u $ACLNBD; then
12378                         ACLNBD=""
12379                 fi
12380         fi
12381         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12382                 add_group $(id -u $ACLNBD) $ACLNBD
12383                 if ! getent group $ACLNBD; then
12384                         ACLNBD=""
12385                 fi
12386         fi
12387         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12388            [[ -n "$ACLNBD" ]] && which setfattr; then
12389                 run_acl_subtest permissions_xattr \
12390                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12391         elif [[ -z "$ACLNBD" ]]; then
12392                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12393         else
12394                 echo "skip 'permission_xattr' test - missing setfattr command"
12395         fi
12396         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12397
12398         # inheritance test got from HP
12399         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12400         chmod +x make-tree || error "chmod +x failed"
12401         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12402         rm -f make-tree
12403
12404         echo "LU-974 ignore umask when acl is enabled..."
12405         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12406         if [ $MDSCOUNT -ge 2 ]; then
12407                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12408         fi
12409
12410         echo "LU-2561 newly created file is same size as directory..."
12411         if [ "$mds1_FSTYPE" != "zfs" ]; then
12412                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12413         else
12414                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12415         fi
12416
12417         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12418
12419         cd $SAVE_PWD
12420         umask $SAVE_UMASK
12421
12422         for num in $(seq $MDSCOUNT); do
12423                 if [ "${identity_old[$num]}" = 1 ]; then
12424                         switch_identity $num false || identity_old[$num]=$?
12425                 fi
12426         done
12427 }
12428 run_test 103a "acl test"
12429
12430 test_103b() {
12431         declare -a pids
12432         local U
12433
12434         stack_trap "rm -f $DIR/$tfile.*"
12435         for U in {0..511}; do
12436                 {
12437                 local O=$(printf "%04o" $U)
12438
12439                 umask $(printf "%04o" $((511 ^ $O)))
12440                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12441                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12442
12443                 (( $S == ($O & 0666) )) ||
12444                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12445
12446                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12447                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12448                 (( $S == ($O & 0666) )) ||
12449                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12450
12451                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12452                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12453                 (( $S == ($O & 0666) )) ||
12454                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12455                 rm -f $DIR/$tfile.[smp]$0
12456                 } &
12457                 local pid=$!
12458
12459                 # limit the concurrently running threads to 64. LU-11878
12460                 local idx=$((U % 64))
12461                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12462                 pids[idx]=$pid
12463         done
12464         wait
12465 }
12466 run_test 103b "umask lfs setstripe"
12467
12468 test_103c() {
12469         mkdir -p $DIR/$tdir
12470         cp -rp $DIR/$tdir $DIR/$tdir.bak
12471
12472         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12473                 error "$DIR/$tdir shouldn't contain default ACL"
12474         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12475                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12476         true
12477 }
12478 run_test 103c "'cp -rp' won't set empty acl"
12479
12480 test_103e() {
12481         local numacl
12482         local fileacl
12483         local saved_debug=$($LCTL get_param -n debug)
12484
12485         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12486                 skip "MDS needs to be at least 2.14.52"
12487
12488         large_xattr_enabled || skip_env "ea_inode feature disabled"
12489
12490         mkdir -p $DIR/$tdir
12491         # add big LOV EA to cause reply buffer overflow earlier
12492         $LFS setstripe -C 1000 $DIR/$tdir
12493         lctl set_param mdc.*-mdc*.stats=clear
12494
12495         $LCTL set_param debug=0
12496         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12497         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12498
12499         # add a large number of default ACLs (expect 8000+ for 2.13+)
12500         for U in {2..7000}; do
12501                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12502                         error "Able to add just $U default ACLs"
12503         done
12504         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12505         echo "$numacl default ACLs created"
12506
12507         stat $DIR/$tdir || error "Cannot stat directory"
12508         # check file creation
12509         touch $DIR/$tdir/$tfile ||
12510                 error "failed to create $tfile with $numacl default ACLs"
12511         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12512         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12513         echo "$fileacl ACLs were inherited"
12514         (( $fileacl == $numacl )) ||
12515                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12516         # check that new ACLs creation adds new ACLs to inherited ACLs
12517         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12518                 error "Cannot set new ACL"
12519         numacl=$((numacl + 1))
12520         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12521         (( $fileacl == $numacl )) ||
12522                 error "failed to add new ACL: $fileacl != $numacl as expected"
12523         # adds more ACLs to a file to reach their maximum at 8000+
12524         numacl=0
12525         for U in {20000..25000}; do
12526                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12527                 numacl=$((numacl + 1))
12528         done
12529         echo "Added $numacl more ACLs to the file"
12530         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12531         echo "Total $fileacl ACLs in file"
12532         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12533         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12534         rmdir $DIR/$tdir || error "Cannot remove directory"
12535 }
12536 run_test 103e "inheritance of big amount of default ACLs"
12537
12538 test_103f() {
12539         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12540                 skip "MDS needs to be at least 2.14.51"
12541
12542         large_xattr_enabled || skip_env "ea_inode feature disabled"
12543
12544         # enable changelog to consume more internal MDD buffers
12545         changelog_register
12546
12547         mkdir -p $DIR/$tdir
12548         # add big LOV EA
12549         $LFS setstripe -C 1000 $DIR/$tdir
12550         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12551         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12552         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12553         rmdir $DIR/$tdir || error "Cannot remove directory"
12554 }
12555 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12556
12557 test_104a() {
12558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12559
12560         touch $DIR/$tfile
12561         lfs df || error "lfs df failed"
12562         lfs df -ih || error "lfs df -ih failed"
12563         lfs df -h $DIR || error "lfs df -h $DIR failed"
12564         lfs df -i $DIR || error "lfs df -i $DIR failed"
12565         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12566         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12567
12568         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12569         lctl --device %$OSC deactivate
12570         lfs df || error "lfs df with deactivated OSC failed"
12571         lctl --device %$OSC activate
12572         # wait the osc back to normal
12573         wait_osc_import_ready client ost
12574
12575         lfs df || error "lfs df with reactivated OSC failed"
12576         rm -f $DIR/$tfile
12577 }
12578 run_test 104a "lfs df [-ih] [path] test ========================="
12579
12580 test_104b() {
12581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12582         [ $RUNAS_ID -eq $UID ] &&
12583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12584
12585         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12586                         grep "Permission denied" | wc -l)))
12587         if [ $denied_cnt -ne 0 ]; then
12588                 error "lfs check servers test failed"
12589         fi
12590 }
12591 run_test 104b "$RUNAS lfs check servers test ===================="
12592
12593 #
12594 # Verify $1 is within range of $2.
12595 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12596 # $1 is <= 2% of $2. Else Fail.
12597 #
12598 value_in_range() {
12599         # Strip all units (M, G, T)
12600         actual=$(echo $1 | tr -d A-Z)
12601         expect=$(echo $2 | tr -d A-Z)
12602
12603         expect_lo=$(($expect * 98 / 100)) # 2% below
12604         expect_hi=$(($expect * 102 / 100)) # 2% above
12605
12606         # permit 2% drift above and below
12607         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12608 }
12609
12610 test_104c() {
12611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12612         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12613
12614         local ost_param="osd-zfs.$FSNAME-OST0000."
12615         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12616         local ofacets=$(get_facets OST)
12617         local mfacets=$(get_facets MDS)
12618         local saved_ost_blocks=
12619         local saved_mdt_blocks=
12620
12621         echo "Before recordsize change"
12622         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12623         df=($(df -h | grep "$MOUNT"$))
12624
12625         # For checking.
12626         echo "lfs output : ${lfs_df[*]}"
12627         echo "df  output : ${df[*]}"
12628
12629         for facet in ${ofacets//,/ }; do
12630                 if [ -z $saved_ost_blocks ]; then
12631                         saved_ost_blocks=$(do_facet $facet \
12632                                 lctl get_param -n $ost_param.blocksize)
12633                         echo "OST Blocksize: $saved_ost_blocks"
12634                 fi
12635                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12636                 do_facet $facet zfs set recordsize=32768 $ost
12637         done
12638
12639         # BS too small. Sufficient for functional testing.
12640         for facet in ${mfacets//,/ }; do
12641                 if [ -z $saved_mdt_blocks ]; then
12642                         saved_mdt_blocks=$(do_facet $facet \
12643                                 lctl get_param -n $mdt_param.blocksize)
12644                         echo "MDT Blocksize: $saved_mdt_blocks"
12645                 fi
12646                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12647                 do_facet $facet zfs set recordsize=32768 $mdt
12648         done
12649
12650         # Give new values chance to reflect change
12651         sleep 2
12652
12653         echo "After recordsize change"
12654         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12655         df_after=($(df -h | grep "$MOUNT"$))
12656
12657         # For checking.
12658         echo "lfs output : ${lfs_df_after[*]}"
12659         echo "df  output : ${df_after[*]}"
12660
12661         # Verify lfs df
12662         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12663                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12664         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12665                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12666         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12667                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12668
12669         # Verify df
12670         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12671                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12672         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12673                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12674         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12675                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12676
12677         # Restore MDT recordize back to original
12678         for facet in ${mfacets//,/ }; do
12679                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12680                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12681         done
12682
12683         # Restore OST recordize back to original
12684         for facet in ${ofacets//,/ }; do
12685                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12686                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12687         done
12688
12689         return 0
12690 }
12691 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12692
12693 test_104d() {
12694         (( $RUNAS_ID != $UID )) ||
12695                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12696
12697         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12698                 skip "lustre version doesn't support lctl dl with non-root"
12699
12700         # debugfs only allows root users to access files, so the
12701         # previous move of the "devices" file to debugfs broke
12702         # "lctl dl" for non-root users. The LU-9680 Netlink
12703         # interface again allows non-root users to list devices.
12704         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12705                 error "lctl dl doesn't work for non root"
12706
12707         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12708         [ "$ost_count" -eq $OSTCOUNT ]  ||
12709                 error "lctl dl reports wrong number of OST devices"
12710
12711         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12712         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12713                 error "lctl dl reports wrong number of MDT devices"
12714 }
12715 run_test 104d "$RUNAS lctl dl test"
12716
12717 test_105a() {
12718         # doesn't work on 2.4 kernels
12719         touch $DIR/$tfile
12720         if $(flock_is_enabled); then
12721                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12722         else
12723                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12724         fi
12725         rm -f $DIR/$tfile
12726 }
12727 run_test 105a "flock when mounted without -o flock test ========"
12728
12729 test_105b() {
12730         touch $DIR/$tfile
12731         if $(flock_is_enabled); then
12732                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12733         else
12734                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12735         fi
12736         rm -f $DIR/$tfile
12737 }
12738 run_test 105b "fcntl when mounted without -o flock test ========"
12739
12740 test_105c() {
12741         touch $DIR/$tfile
12742         if $(flock_is_enabled); then
12743                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12744         else
12745                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12746         fi
12747         rm -f $DIR/$tfile
12748 }
12749 run_test 105c "lockf when mounted without -o flock test"
12750
12751 test_105d() { # bug 15924
12752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12753
12754         test_mkdir $DIR/$tdir
12755         flock_is_enabled || skip_env "mount w/o flock enabled"
12756         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12757         $LCTL set_param fail_loc=0x80000315
12758         flocks_test 2 $DIR/$tdir
12759 }
12760 run_test 105d "flock race (should not freeze) ========"
12761
12762 test_105e() { # bug 22660 && 22040
12763         flock_is_enabled || skip_env "mount w/o flock enabled"
12764
12765         touch $DIR/$tfile
12766         flocks_test 3 $DIR/$tfile
12767 }
12768 run_test 105e "Two conflicting flocks from same process"
12769
12770 test_106() { #bug 10921
12771         test_mkdir $DIR/$tdir
12772         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12773         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12774 }
12775 run_test 106 "attempt exec of dir followed by chown of that dir"
12776
12777 test_107() {
12778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12779
12780         CDIR=`pwd`
12781         local file=core
12782
12783         cd $DIR
12784         rm -f $file
12785
12786         local save_pattern=$(sysctl -n kernel.core_pattern)
12787         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12788         sysctl -w kernel.core_pattern=$file
12789         sysctl -w kernel.core_uses_pid=0
12790
12791         ulimit -c unlimited
12792         sleep 60 &
12793         SLEEPPID=$!
12794
12795         sleep 1
12796
12797         kill -s 11 $SLEEPPID
12798         wait $SLEEPPID
12799         if [ -e $file ]; then
12800                 size=`stat -c%s $file`
12801                 [ $size -eq 0 ] && error "Fail to create core file $file"
12802         else
12803                 error "Fail to create core file $file"
12804         fi
12805         rm -f $file
12806         sysctl -w kernel.core_pattern=$save_pattern
12807         sysctl -w kernel.core_uses_pid=$save_uses_pid
12808         cd $CDIR
12809 }
12810 run_test 107 "Coredump on SIG"
12811
12812 test_110() {
12813         test_mkdir $DIR/$tdir
12814         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12815         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12816                 error "mkdir with 256 char should fail, but did not"
12817         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12818                 error "create with 255 char failed"
12819         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12820                 error "create with 256 char should fail, but did not"
12821
12822         ls -l $DIR/$tdir
12823         rm -rf $DIR/$tdir
12824 }
12825 run_test 110 "filename length checking"
12826
12827 test_116a() { # was previously test_116()
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12830         remote_mds_nodsh && skip "remote MDS with nodsh"
12831
12832         echo -n "Free space priority "
12833         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12834                 head -n1
12835         declare -a AVAIL
12836         free_min_max
12837
12838         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12839         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12840         stack_trap simple_cleanup_common
12841
12842         # Check if we need to generate uneven OSTs
12843         test_mkdir -p $DIR/$tdir/OST${MINI}
12844         local FILL=$((MINV / 4))
12845         local DIFF=$((MAXV - MINV))
12846         local DIFF2=$((DIFF * 100 / MINV))
12847
12848         local threshold=$(do_facet $SINGLEMDS \
12849                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12850         threshold=${threshold%%%}
12851         echo -n "Check for uneven OSTs: "
12852         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12853
12854         if [[ $DIFF2 -gt $threshold ]]; then
12855                 echo "ok"
12856                 echo "Don't need to fill OST$MINI"
12857         else
12858                 # generate uneven OSTs. Write 2% over the QOS threshold value
12859                 echo "no"
12860                 DIFF=$((threshold - DIFF2 + 2))
12861                 DIFF2=$((MINV * DIFF / 100))
12862                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12863                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12864                         error "setstripe failed"
12865                 DIFF=$((DIFF2 / 2048))
12866                 i=0
12867                 while [ $i -lt $DIFF ]; do
12868                         i=$((i + 1))
12869                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12870                                 bs=2M count=1 2>/dev/null
12871                         echo -n .
12872                 done
12873                 echo .
12874                 sync
12875                 sleep_maxage
12876                 free_min_max
12877         fi
12878
12879         DIFF=$((MAXV - MINV))
12880         DIFF2=$((DIFF * 100 / MINV))
12881         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12882         if [ $DIFF2 -gt $threshold ]; then
12883                 echo "ok"
12884         else
12885                 skip "QOS imbalance criteria not met"
12886         fi
12887
12888         MINI1=$MINI
12889         MINV1=$MINV
12890         MAXI1=$MAXI
12891         MAXV1=$MAXV
12892
12893         # now fill using QOS
12894         $LFS setstripe -c 1 $DIR/$tdir
12895         FILL=$((FILL / 200))
12896         if [ $FILL -gt 600 ]; then
12897                 FILL=600
12898         fi
12899         echo "writing $FILL files to QOS-assigned OSTs"
12900         i=0
12901         while [ $i -lt $FILL ]; do
12902                 i=$((i + 1))
12903                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12904                         count=1 2>/dev/null
12905                 echo -n .
12906         done
12907         echo "wrote $i 200k files"
12908         sync
12909         sleep_maxage
12910
12911         echo "Note: free space may not be updated, so measurements might be off"
12912         free_min_max
12913         DIFF2=$((MAXV - MINV))
12914         echo "free space delta: orig $DIFF final $DIFF2"
12915         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12916         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12917         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12918         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12919         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12920         if [[ $DIFF -gt 0 ]]; then
12921                 FILL=$((DIFF2 * 100 / DIFF - 100))
12922                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12923         fi
12924
12925         # Figure out which files were written where
12926         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12927                awk '/'$MINI1': / {print $2; exit}')
12928         echo $UUID
12929         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12930         echo "$MINC files created on smaller OST $MINI1"
12931         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12932                awk '/'$MAXI1': / {print $2; exit}')
12933         echo $UUID
12934         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12935         echo "$MAXC files created on larger OST $MAXI1"
12936         if [[ $MINC -gt 0 ]]; then
12937                 FILL=$((MAXC * 100 / MINC - 100))
12938                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12939         fi
12940         [[ $MAXC -gt $MINC ]] ||
12941                 error_ignore LU-9 "stripe QOS didn't balance free space"
12942 }
12943 run_test 116a "stripe QOS: free space balance ==================="
12944
12945 test_116b() { # LU-2093
12946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12947         remote_mds_nodsh && skip "remote MDS with nodsh"
12948
12949 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12950         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12951                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12952         [ -z "$old_rr" ] && skip "no QOS"
12953         do_facet $SINGLEMDS lctl set_param \
12954                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12955         mkdir -p $DIR/$tdir
12956         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12957         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12958         do_facet $SINGLEMDS lctl set_param fail_loc=0
12959         rm -rf $DIR/$tdir
12960         do_facet $SINGLEMDS lctl set_param \
12961                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12962 }
12963 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12964
12965 test_117() # bug 10891
12966 {
12967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12968
12969         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12970         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12971         lctl set_param fail_loc=0x21e
12972         > $DIR/$tfile || error "truncate failed"
12973         lctl set_param fail_loc=0
12974         echo "Truncate succeeded."
12975         rm -f $DIR/$tfile
12976 }
12977 run_test 117 "verify osd extend =========="
12978
12979 NO_SLOW_RESENDCOUNT=4
12980 export OLD_RESENDCOUNT=""
12981 set_resend_count () {
12982         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12983         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12984         lctl set_param -n $PROC_RESENDCOUNT $1
12985         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12986 }
12987
12988 # for reduce test_118* time (b=14842)
12989 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12990
12991 # Reset async IO behavior after error case
12992 reset_async() {
12993         FILE=$DIR/reset_async
12994
12995         # Ensure all OSCs are cleared
12996         $LFS setstripe -c -1 $FILE
12997         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12998         sync
12999         rm $FILE
13000 }
13001
13002 test_118a() #bug 11710
13003 {
13004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13005
13006         reset_async
13007
13008         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13009         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13010         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13011
13012         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13013                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13014                 return 1;
13015         fi
13016         rm -f $DIR/$tfile
13017 }
13018 run_test 118a "verify O_SYNC works =========="
13019
13020 test_118b()
13021 {
13022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13023         remote_ost_nodsh && skip "remote OST with nodsh"
13024
13025         reset_async
13026
13027         #define OBD_FAIL_SRV_ENOENT 0x217
13028         set_nodes_failloc "$(osts_nodes)" 0x217
13029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13030         RC=$?
13031         set_nodes_failloc "$(osts_nodes)" 0
13032         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13033         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13034                     grep -c writeback)
13035
13036         if [[ $RC -eq 0 ]]; then
13037                 error "Must return error due to dropped pages, rc=$RC"
13038                 return 1;
13039         fi
13040
13041         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13042                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13043                 return 1;
13044         fi
13045
13046         echo "Dirty pages not leaked on ENOENT"
13047
13048         # Due to the above error the OSC will issue all RPCs syncronously
13049         # until a subsequent RPC completes successfully without error.
13050         $MULTIOP $DIR/$tfile Ow4096yc
13051         rm -f $DIR/$tfile
13052
13053         return 0
13054 }
13055 run_test 118b "Reclaim dirty pages on fatal error =========="
13056
13057 test_118c()
13058 {
13059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13060
13061         # for 118c, restore the original resend count, LU-1940
13062         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13063                                 set_resend_count $OLD_RESENDCOUNT
13064         remote_ost_nodsh && skip "remote OST with nodsh"
13065
13066         reset_async
13067
13068         #define OBD_FAIL_OST_EROFS               0x216
13069         set_nodes_failloc "$(osts_nodes)" 0x216
13070
13071         # multiop should block due to fsync until pages are written
13072         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13073         MULTIPID=$!
13074         sleep 1
13075
13076         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13077                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13078         fi
13079
13080         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13081                     grep -c writeback)
13082         if [[ $WRITEBACK -eq 0 ]]; then
13083                 error "No page in writeback, writeback=$WRITEBACK"
13084         fi
13085
13086         set_nodes_failloc "$(osts_nodes)" 0
13087         wait $MULTIPID
13088         RC=$?
13089         if [[ $RC -ne 0 ]]; then
13090                 error "Multiop fsync failed, rc=$RC"
13091         fi
13092
13093         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13094         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13095                     grep -c writeback)
13096         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13097                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13098         fi
13099
13100         rm -f $DIR/$tfile
13101         echo "Dirty pages flushed via fsync on EROFS"
13102         return 0
13103 }
13104 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13105
13106 # continue to use small resend count to reduce test_118* time (b=14842)
13107 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13108
13109 test_118d()
13110 {
13111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13112         remote_ost_nodsh && skip "remote OST with nodsh"
13113
13114         reset_async
13115
13116         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13117         set_nodes_failloc "$(osts_nodes)" 0x214
13118         # multiop should block due to fsync until pages are written
13119         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13120         MULTIPID=$!
13121         sleep 1
13122
13123         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13124                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13125         fi
13126
13127         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13128                     grep -c writeback)
13129         if [[ $WRITEBACK -eq 0 ]]; then
13130                 error "No page in writeback, writeback=$WRITEBACK"
13131         fi
13132
13133         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13134         set_nodes_failloc "$(osts_nodes)" 0
13135
13136         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13137         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13138                     grep -c writeback)
13139         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13140                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13141         fi
13142
13143         rm -f $DIR/$tfile
13144         echo "Dirty pages gaurenteed flushed via fsync"
13145         return 0
13146 }
13147 run_test 118d "Fsync validation inject a delay of the bulk =========="
13148
13149 test_118f() {
13150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13151
13152         reset_async
13153
13154         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13155         lctl set_param fail_loc=0x8000040a
13156
13157         # Should simulate EINVAL error which is fatal
13158         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13159         RC=$?
13160         if [[ $RC -eq 0 ]]; then
13161                 error "Must return error due to dropped pages, rc=$RC"
13162         fi
13163
13164         lctl set_param fail_loc=0x0
13165
13166         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13167         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13168         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13169                     grep -c writeback)
13170         if [[ $LOCKED -ne 0 ]]; then
13171                 error "Locked pages remain in cache, locked=$LOCKED"
13172         fi
13173
13174         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13175                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13176         fi
13177
13178         rm -f $DIR/$tfile
13179         echo "No pages locked after fsync"
13180
13181         reset_async
13182         return 0
13183 }
13184 run_test 118f "Simulate unrecoverable OSC side error =========="
13185
13186 test_118g() {
13187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13188
13189         reset_async
13190
13191         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13192         lctl set_param fail_loc=0x406
13193
13194         # simulate local -ENOMEM
13195         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13196         RC=$?
13197
13198         lctl set_param fail_loc=0
13199         if [[ $RC -eq 0 ]]; then
13200                 error "Must return error due to dropped pages, rc=$RC"
13201         fi
13202
13203         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13204         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13205         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13206                         grep -c writeback)
13207         if [[ $LOCKED -ne 0 ]]; then
13208                 error "Locked pages remain in cache, locked=$LOCKED"
13209         fi
13210
13211         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13212                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13213         fi
13214
13215         rm -f $DIR/$tfile
13216         echo "No pages locked after fsync"
13217
13218         reset_async
13219         return 0
13220 }
13221 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13222
13223 test_118h() {
13224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13225         remote_ost_nodsh && skip "remote OST with nodsh"
13226
13227         reset_async
13228
13229         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13230         set_nodes_failloc "$(osts_nodes)" 0x20e
13231         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13232         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13233         RC=$?
13234
13235         set_nodes_failloc "$(osts_nodes)" 0
13236         if [[ $RC -eq 0 ]]; then
13237                 error "Must return error due to dropped pages, rc=$RC"
13238         fi
13239
13240         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13241         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13242         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13243                     grep -c writeback)
13244         if [[ $LOCKED -ne 0 ]]; then
13245                 error "Locked pages remain in cache, locked=$LOCKED"
13246         fi
13247
13248         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13249                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13250         fi
13251
13252         rm -f $DIR/$tfile
13253         echo "No pages locked after fsync"
13254
13255         return 0
13256 }
13257 run_test 118h "Verify timeout in handling recoverables errors  =========="
13258
13259 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13260
13261 test_118i() {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263         remote_ost_nodsh && skip "remote OST with nodsh"
13264
13265         reset_async
13266
13267         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13268         set_nodes_failloc "$(osts_nodes)" 0x20e
13269
13270         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13271         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13272         PID=$!
13273         sleep 5
13274         set_nodes_failloc "$(osts_nodes)" 0
13275
13276         wait $PID
13277         RC=$?
13278         if [[ $RC -ne 0 ]]; then
13279                 error "got error, but should be not, rc=$RC"
13280         fi
13281
13282         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13283         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13284         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13285         if [[ $LOCKED -ne 0 ]]; then
13286                 error "Locked pages remain in cache, locked=$LOCKED"
13287         fi
13288
13289         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13290                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13291         fi
13292
13293         rm -f $DIR/$tfile
13294         echo "No pages locked after fsync"
13295
13296         return 0
13297 }
13298 run_test 118i "Fix error before timeout in recoverable error  =========="
13299
13300 [ "$SLOW" = "no" ] && set_resend_count 4
13301
13302 test_118j() {
13303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13304         remote_ost_nodsh && skip "remote OST with nodsh"
13305
13306         reset_async
13307
13308         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13309         set_nodes_failloc "$(osts_nodes)" 0x220
13310
13311         # return -EIO from OST
13312         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13313         RC=$?
13314         set_nodes_failloc "$(osts_nodes)" 0x0
13315         if [[ $RC -eq 0 ]]; then
13316                 error "Must return error due to dropped pages, rc=$RC"
13317         fi
13318
13319         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13320         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13321         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13322         if [[ $LOCKED -ne 0 ]]; then
13323                 error "Locked pages remain in cache, locked=$LOCKED"
13324         fi
13325
13326         # in recoverable error on OST we want resend and stay until it finished
13327         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13328                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13329         fi
13330
13331         rm -f $DIR/$tfile
13332         echo "No pages locked after fsync"
13333
13334         return 0
13335 }
13336 run_test 118j "Simulate unrecoverable OST side error =========="
13337
13338 test_118k()
13339 {
13340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13341         remote_ost_nodsh && skip "remote OSTs with nodsh"
13342
13343         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13344         set_nodes_failloc "$(osts_nodes)" 0x20e
13345         test_mkdir $DIR/$tdir
13346
13347         for ((i=0;i<10;i++)); do
13348                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13349                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13350                 SLEEPPID=$!
13351                 sleep 0.500s
13352                 kill $SLEEPPID
13353                 wait $SLEEPPID
13354         done
13355
13356         set_nodes_failloc "$(osts_nodes)" 0
13357         rm -rf $DIR/$tdir
13358 }
13359 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13360
13361 test_118l() # LU-646
13362 {
13363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13364
13365         test_mkdir $DIR/$tdir
13366         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13367         rm -rf $DIR/$tdir
13368 }
13369 run_test 118l "fsync dir"
13370
13371 test_118m() # LU-3066
13372 {
13373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13374
13375         test_mkdir $DIR/$tdir
13376         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13377         rm -rf $DIR/$tdir
13378 }
13379 run_test 118m "fdatasync dir ========="
13380
13381 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13382
13383 test_118n()
13384 {
13385         local begin
13386         local end
13387
13388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13389         remote_ost_nodsh && skip "remote OSTs with nodsh"
13390
13391         # Sleep to avoid a cached response.
13392         #define OBD_STATFS_CACHE_SECONDS 1
13393         sleep 2
13394
13395         # Inject a 10 second delay in the OST_STATFS handler.
13396         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13397         set_nodes_failloc "$(osts_nodes)" 0x242
13398
13399         begin=$SECONDS
13400         stat --file-system $MOUNT > /dev/null
13401         end=$SECONDS
13402
13403         set_nodes_failloc "$(osts_nodes)" 0
13404
13405         if ((end - begin > 20)); then
13406             error "statfs took $((end - begin)) seconds, expected 10"
13407         fi
13408 }
13409 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13410
13411 test_119a() # bug 11737
13412 {
13413         BSIZE=$((512 * 1024))
13414         directio write $DIR/$tfile 0 1 $BSIZE
13415         # We ask to read two blocks, which is more than a file size.
13416         # directio will indicate an error when requested and actual
13417         # sizes aren't equeal (a normal situation in this case) and
13418         # print actual read amount.
13419         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13420         if [ "$NOB" != "$BSIZE" ]; then
13421                 error "read $NOB bytes instead of $BSIZE"
13422         fi
13423         rm -f $DIR/$tfile
13424 }
13425 run_test 119a "Short directIO read must return actual read amount"
13426
13427 test_119b() # bug 11737
13428 {
13429         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13430
13431         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13432         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13433         sync
13434         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13435                 error "direct read failed"
13436         rm -f $DIR/$tfile
13437 }
13438 run_test 119b "Sparse directIO read must return actual read amount"
13439
13440 test_119c() # bug 13099
13441 {
13442         BSIZE=1048576
13443         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13444         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13445         rm -f $DIR/$tfile
13446 }
13447 run_test 119c "Testing for direct read hitting hole"
13448
13449 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13450 # Maloo test history
13451
13452 test_119e()
13453 {
13454         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13455
13456         local stripe_size=$((1024 * 1024)) #1 MiB
13457         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13458         local file_size=$((25 * stripe_size))
13459         local bsizes
13460
13461         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13462         stack_trap "rm -f $DIR/$tfile*"
13463
13464         # Just a bit bigger than the largest size in the test set below
13465         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13466                 error "buffered i/o to create file failed"
13467
13468         if zfs_or_rotational; then
13469                 # DIO on ZFS can take up to 2 seconds per IO
13470                 # rotational is better, but still slow.
13471                 # Limit testing on those media to larger sizes
13472                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13473         else
13474                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13475                         $((stripe_size * 4))"
13476         fi
13477
13478         for bs in $bsizes; do
13479                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13480                 echo "Read/write with DIO at size $bs"
13481                 # Read and write with DIO from source to dest
13482                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13483                         iflag=direct oflag=direct ||
13484                         error "dio failed"
13485
13486                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13487                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13488                         error "size incorrect, file copy read/write bsize: $bs"
13489                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13490                         error "files differ, bsize $bs"
13491                 rm -f $DIR/$tfile.2
13492         done
13493 }
13494 run_test 119e "Basic tests of dio read and write at various sizes"
13495
13496 test_119f()
13497 {
13498         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13499
13500         local stripe_size=$((1024 * 1024)) #1 MiB
13501         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13502         local file_size=$((25 * stripe_size))
13503         local bsizes
13504
13505         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13506         stack_trap "rm -f $DIR/$tfile*"
13507
13508         # Just a bit bigger than the largest size in the test set below
13509         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13510                 error "buffered i/o to create file failed"
13511
13512         if zfs_or_rotational; then
13513                 # DIO on ZFS can take up to 2 seconds per IO
13514                 # rotational is better, but still slow.
13515                 # Limit testing on those media to larger sizes
13516                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13517         else
13518                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13519                         $((stripe_size * 4))"
13520         fi
13521
13522         for bs in $bsizes; do
13523                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13524                 # Read and write with DIO from source to dest in two
13525                 # threads - should give correct copy of file
13526
13527                 echo "bs: $bs"
13528                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13529                         oflag=direct conv=notrunc &
13530                 pid_dio1=$!
13531                 # Note block size is different here for a more interesting race
13532                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13533                         iflag=direct oflag=direct conv=notrunc &
13534                 pid_dio2=$!
13535                 wait $pid_dio1
13536                 rc1=$?
13537                 wait $pid_dio2
13538                 rc2=$?
13539                 if (( rc1 != 0 )); then
13540                         error "dio copy 1 w/bsize $bs failed: $rc1"
13541                 fi
13542                 if (( rc2 != 0 )); then
13543                         error "dio copy 2 w/bsize $bs failed: $rc2"
13544                 fi
13545
13546
13547                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13548                         error "size incorrect, file copy read/write bsize: $bs"
13549                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13550                         error "files differ, bsize $bs"
13551                 rm -f $DIR/$tfile.2
13552         done
13553 }
13554 run_test 119f "dio vs dio race"
13555
13556 test_119g()
13557 {
13558         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13559
13560         local stripe_size=$((1024 * 1024)) #1 MiB
13561         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13562         local file_size=$((25 * stripe_size))
13563         local bsizes
13564
13565         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13566         stack_trap "rm -f $DIR/$tfile*"
13567
13568         # Just a bit bigger than the largest size in the test set below
13569         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13570                 error "buffered i/o to create file failed"
13571
13572         if zfs_or_rotational; then
13573                 # DIO on ZFS can take up to 2 seconds per IO
13574                 # rotational is better, but still slow.
13575                 # Limit testing on those media to larger sizes
13576                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size"
13577         else
13578                 bsizes="$PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
13579                         $((stripe_size * 4))"
13580         fi
13581
13582         for bs in $bsizes; do
13583                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13584                 echo "bs: $bs"
13585                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13586                         oflag=direct conv=notrunc &
13587                 pid_dio1=$!
13588                 # Buffered I/O with similar but not the same block size
13589                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13590                 pid_bio2=$!
13591                 wait $pid_dio1
13592                 rc1=$?
13593                 wait $pid_bio2
13594                 rc2=$?
13595                 if (( rc1 != 0 )); then
13596                         error "dio copy 1 w/bsize $bs failed: $rc1"
13597                 fi
13598                 if (( rc2 != 0 )); then
13599                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13600                 fi
13601
13602                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13603                         error "size incorrect"
13604                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13605                         error "files differ, bsize $bs"
13606                 rm -f $DIR/$tfile.2
13607         done
13608 }
13609 run_test 119g "dio vs buffered I/O race"
13610
13611 test_120a() {
13612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13613         remote_mds_nodsh && skip "remote MDS with nodsh"
13614         test_mkdir -i0 -c1 $DIR/$tdir
13615         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13616                 skip_env "no early lock cancel on server"
13617
13618         lru_resize_disable mdc
13619         lru_resize_disable osc
13620         cancel_lru_locks mdc
13621         # asynchronous object destroy at MDT could cause bl ast to client
13622         cancel_lru_locks osc
13623
13624         stat $DIR/$tdir > /dev/null
13625         can1=$(do_facet mds1 \
13626                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13627                awk '/ldlm_cancel/ {print $2}')
13628         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13629                awk '/ldlm_bl_callback/ {print $2}')
13630         test_mkdir -i0 -c1 $DIR/$tdir/d1
13631         can2=$(do_facet mds1 \
13632                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13633                awk '/ldlm_cancel/ {print $2}')
13634         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13635                awk '/ldlm_bl_callback/ {print $2}')
13636         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13637         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13638         lru_resize_enable mdc
13639         lru_resize_enable osc
13640 }
13641 run_test 120a "Early Lock Cancel: mkdir test"
13642
13643 test_120b() {
13644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13645         remote_mds_nodsh && skip "remote MDS with nodsh"
13646         test_mkdir $DIR/$tdir
13647         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13648                 skip_env "no early lock cancel on server"
13649
13650         lru_resize_disable mdc
13651         lru_resize_disable osc
13652         cancel_lru_locks mdc
13653         stat $DIR/$tdir > /dev/null
13654         can1=$(do_facet $SINGLEMDS \
13655                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13656                awk '/ldlm_cancel/ {print $2}')
13657         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13658                awk '/ldlm_bl_callback/ {print $2}')
13659         touch $DIR/$tdir/f1
13660         can2=$(do_facet $SINGLEMDS \
13661                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13662                awk '/ldlm_cancel/ {print $2}')
13663         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13664                awk '/ldlm_bl_callback/ {print $2}')
13665         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13666         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13667         lru_resize_enable mdc
13668         lru_resize_enable osc
13669 }
13670 run_test 120b "Early Lock Cancel: create test"
13671
13672 test_120c() {
13673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13674         remote_mds_nodsh && skip "remote MDS with nodsh"
13675         test_mkdir -i0 -c1 $DIR/$tdir
13676         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13677                 skip "no early lock cancel on server"
13678
13679         lru_resize_disable mdc
13680         lru_resize_disable osc
13681         test_mkdir -i0 -c1 $DIR/$tdir/d1
13682         test_mkdir -i0 -c1 $DIR/$tdir/d2
13683         touch $DIR/$tdir/d1/f1
13684         cancel_lru_locks mdc
13685         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13686         can1=$(do_facet mds1 \
13687                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13688                awk '/ldlm_cancel/ {print $2}')
13689         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13690                awk '/ldlm_bl_callback/ {print $2}')
13691         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13692         can2=$(do_facet mds1 \
13693                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13694                awk '/ldlm_cancel/ {print $2}')
13695         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13696                awk '/ldlm_bl_callback/ {print $2}')
13697         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13698         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13699         lru_resize_enable mdc
13700         lru_resize_enable osc
13701 }
13702 run_test 120c "Early Lock Cancel: link test"
13703
13704 test_120d() {
13705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13706         remote_mds_nodsh && skip "remote MDS with nodsh"
13707         test_mkdir -i0 -c1 $DIR/$tdir
13708         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13709                 skip_env "no early lock cancel on server"
13710
13711         lru_resize_disable mdc
13712         lru_resize_disable osc
13713         touch $DIR/$tdir
13714         cancel_lru_locks mdc
13715         stat $DIR/$tdir > /dev/null
13716         can1=$(do_facet mds1 \
13717                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13718                awk '/ldlm_cancel/ {print $2}')
13719         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13720                awk '/ldlm_bl_callback/ {print $2}')
13721         chmod a+x $DIR/$tdir
13722         can2=$(do_facet mds1 \
13723                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13724                awk '/ldlm_cancel/ {print $2}')
13725         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13726                awk '/ldlm_bl_callback/ {print $2}')
13727         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13728         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13729         lru_resize_enable mdc
13730         lru_resize_enable osc
13731 }
13732 run_test 120d "Early Lock Cancel: setattr test"
13733
13734 test_120e() {
13735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13736         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13737                 skip_env "no early lock cancel on server"
13738         remote_mds_nodsh && skip "remote MDS with nodsh"
13739
13740         local dlmtrace_set=false
13741
13742         test_mkdir -i0 -c1 $DIR/$tdir
13743         lru_resize_disable mdc
13744         lru_resize_disable osc
13745         ! $LCTL get_param debug | grep -q dlmtrace &&
13746                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13747         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13748         cancel_lru_locks mdc
13749         cancel_lru_locks osc
13750         dd if=$DIR/$tdir/f1 of=/dev/null
13751         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13752         # XXX client can not do early lock cancel of OST lock
13753         # during unlink (LU-4206), so cancel osc lock now.
13754         sleep 2
13755         cancel_lru_locks osc
13756         can1=$(do_facet mds1 \
13757                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13758                awk '/ldlm_cancel/ {print $2}')
13759         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13760                awk '/ldlm_bl_callback/ {print $2}')
13761         unlink $DIR/$tdir/f1
13762         sleep 5
13763         can2=$(do_facet mds1 \
13764                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13765                awk '/ldlm_cancel/ {print $2}')
13766         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13767                awk '/ldlm_bl_callback/ {print $2}')
13768         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13769                 $LCTL dk $TMP/cancel.debug.txt
13770         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13771                 $LCTL dk $TMP/blocking.debug.txt
13772         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13773         lru_resize_enable mdc
13774         lru_resize_enable osc
13775 }
13776 run_test 120e "Early Lock Cancel: unlink test"
13777
13778 test_120f() {
13779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13780         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13781                 skip_env "no early lock cancel on server"
13782         remote_mds_nodsh && skip "remote MDS with nodsh"
13783
13784         test_mkdir -i0 -c1 $DIR/$tdir
13785         lru_resize_disable mdc
13786         lru_resize_disable osc
13787         test_mkdir -i0 -c1 $DIR/$tdir/d1
13788         test_mkdir -i0 -c1 $DIR/$tdir/d2
13789         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13790         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13791         cancel_lru_locks mdc
13792         cancel_lru_locks osc
13793         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13794         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13795         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13796         # XXX client can not do early lock cancel of OST lock
13797         # during rename (LU-4206), so cancel osc lock now.
13798         sleep 2
13799         cancel_lru_locks osc
13800         can1=$(do_facet mds1 \
13801                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13802                awk '/ldlm_cancel/ {print $2}')
13803         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13804                awk '/ldlm_bl_callback/ {print $2}')
13805         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13806         sleep 5
13807         can2=$(do_facet mds1 \
13808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13809                awk '/ldlm_cancel/ {print $2}')
13810         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13811                awk '/ldlm_bl_callback/ {print $2}')
13812         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13813         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13814         lru_resize_enable mdc
13815         lru_resize_enable osc
13816 }
13817 run_test 120f "Early Lock Cancel: rename test"
13818
13819 test_120g() {
13820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13821         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13822                 skip_env "no early lock cancel on server"
13823         remote_mds_nodsh && skip "remote MDS with nodsh"
13824
13825         lru_resize_disable mdc
13826         lru_resize_disable osc
13827         count=10000
13828         echo create $count files
13829         test_mkdir $DIR/$tdir
13830         cancel_lru_locks mdc
13831         cancel_lru_locks osc
13832         t0=$(date +%s)
13833
13834         can0=$(do_facet $SINGLEMDS \
13835                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13836                awk '/ldlm_cancel/ {print $2}')
13837         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13838                awk '/ldlm_bl_callback/ {print $2}')
13839         createmany -o $DIR/$tdir/f $count
13840         sync
13841         can1=$(do_facet $SINGLEMDS \
13842                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13843                awk '/ldlm_cancel/ {print $2}')
13844         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13845                awk '/ldlm_bl_callback/ {print $2}')
13846         t1=$(date +%s)
13847         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13848         echo rm $count files
13849         rm -r $DIR/$tdir
13850         sync
13851         can2=$(do_facet $SINGLEMDS \
13852                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13853                awk '/ldlm_cancel/ {print $2}')
13854         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13855                awk '/ldlm_bl_callback/ {print $2}')
13856         t2=$(date +%s)
13857         echo total: $count removes in $((t2-t1))
13858         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13859         sleep 2
13860         # wait for commitment of removal
13861         lru_resize_enable mdc
13862         lru_resize_enable osc
13863 }
13864 run_test 120g "Early Lock Cancel: performance test"
13865
13866 test_121() { #bug #10589
13867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13868
13869         rm -rf $DIR/$tfile
13870         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13871 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13872         lctl set_param fail_loc=0x310
13873         cancel_lru_locks osc > /dev/null
13874         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13875         lctl set_param fail_loc=0
13876         [[ $reads -eq $writes ]] ||
13877                 error "read $reads blocks, must be $writes blocks"
13878 }
13879 run_test 121 "read cancel race ========="
13880
13881 test_123a_base() { # was test 123, statahead(bug 11401)
13882         local lsx="$1"
13883
13884         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13885
13886         SLOWOK=0
13887         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13888                 log "testing UP system. Performance may be lower than expected."
13889                 SLOWOK=1
13890         fi
13891         running_in_vm && SLOWOK=1
13892
13893         $LCTL set_param mdc.*.batch_stats=0
13894
13895         rm -rf $DIR/$tdir
13896         test_mkdir $DIR/$tdir
13897         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13898         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13899         MULT=10
13900         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13901                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13902
13903                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13904                 lctl set_param -n llite.*.statahead_max 0
13905                 lctl get_param llite.*.statahead_max
13906                 cancel_lru_locks mdc
13907                 cancel_lru_locks osc
13908                 stime=$(date +%s)
13909                 time $lsx $DIR/$tdir | wc -l
13910                 etime=$(date +%s)
13911                 delta=$((etime - stime))
13912                 log "$lsx $i files without statahead: $delta sec"
13913                 lctl set_param llite.*.statahead_max=$max
13914
13915                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13916                          awk '/statahead.wrong:/ { print $NF }')
13917                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13918                 cancel_lru_locks mdc
13919                 cancel_lru_locks osc
13920                 stime=$(date +%s)
13921                 time $lsx $DIR/$tdir | wc -l
13922                 etime=$(date +%s)
13923                 delta_sa=$((etime - stime))
13924                 log "$lsx $i files with statahead: $delta_sa sec"
13925                 lctl get_param -n llite.*.statahead_stats
13926                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13927                          awk '/statahead.wrong:/ { print $NF }')
13928
13929                 [[ $swrong -lt $ewrong ]] &&
13930                         log "statahead was stopped, maybe too many locks held!"
13931                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13932
13933                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13934                         max=$(lctl get_param -n llite.*.statahead_max |
13935                                 head -n 1)
13936                         lctl set_param -n llite.*.statahead_max 0
13937                         lctl get_param llite.*.statahead_max
13938                         cancel_lru_locks mdc
13939                         cancel_lru_locks osc
13940                         stime=$(date +%s)
13941                         time $lsx $DIR/$tdir | wc -l
13942                         etime=$(date +%s)
13943                         delta=$((etime - stime))
13944                         log "$lsx $i files again without statahead: $delta sec"
13945                         lctl set_param llite.*.statahead_max=$max
13946                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13947                                 if [ $SLOWOK -eq 0 ]; then
13948                                         error "$lsx $i files is slower with statahead!"
13949                                 else
13950                                         log "$lsx $i files is slower with statahead!"
13951                                 fi
13952                                 break
13953                         fi
13954                 fi
13955
13956                 [ $delta -gt 20 ] && break
13957                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13958                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13959         done
13960         log "$lsx done"
13961
13962         stime=$(date +%s)
13963         rm -r $DIR/$tdir
13964         sync
13965         etime=$(date +%s)
13966         delta=$((etime - stime))
13967         log "rm -r $DIR/$tdir/: $delta seconds"
13968         log "rm done"
13969         lctl get_param -n llite.*.statahead_stats
13970         $LCTL get_param mdc.*.batch_stats
13971 }
13972
13973 test_123aa() {
13974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13975
13976         test_123a_base "ls -l"
13977 }
13978 run_test 123aa "verify statahead work"
13979
13980 test_123ab() {
13981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13982
13983         statx_supported || skip_env "Test must be statx() syscall supported"
13984
13985         test_123a_base "$STATX -l"
13986 }
13987 run_test 123ab "verify statahead work by using statx"
13988
13989 test_123ac() {
13990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13991
13992         statx_supported || skip_env "Test must be statx() syscall supported"
13993
13994         local rpcs_before
13995         local rpcs_after
13996         local agl_before
13997         local agl_after
13998
13999         cancel_lru_locks $OSC
14000         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14001         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14002                      awk '/agl.total:/ { print $NF }')
14003         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14004         test_123a_base "$STATX --cached=always -D"
14005         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14006                     awk '/agl.total:/ { print $NF }')
14007         [ $agl_before -eq $agl_after ] ||
14008                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14009         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14010         [ $rpcs_after -eq $rpcs_before ] ||
14011                 error "$STATX should not send glimpse RPCs to $OSC"
14012 }
14013 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14014
14015 test_batch_statahead() {
14016         local max=$1
14017         local batch_max=$2
14018         local num=10000
14019         local batch_rpcs
14020         local unbatch_rpcs
14021         local hit_total
14022
14023         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14024         $LCTL set_param mdc.*.batch_stats=0
14025         $LCTL set_param llite.*.statahead_max=$max
14026         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14027         # Verify that batched statahead is faster than one without statahead
14028         test_123a_base "ls -l"
14029
14030         stack_trap "rm -rf $DIR/$tdir" EXIT
14031         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14032         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14033
14034         # unbatched statahead
14035         $LCTL set_param llite.*.statahead_batch_max=0
14036         $LCTL set_param llite.*.statahead_stats=clear
14037         $LCTL set_param mdc.*.stats=clear
14038         cancel_lru_locks mdc
14039         cancel_lru_locks osc
14040         time ls -l $DIR/$tdir | wc -l
14041         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14042         sleep 2
14043         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14044                     awk '/hit.total:/ { print $NF }')
14045         # hit ratio should be larger than 75% (7500).
14046         (( $hit_total > 7500 )) ||
14047                 error "unbatched statahead hit count ($hit_total) is too low"
14048
14049         # batched statahead
14050         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14051         $LCTL set_param llite.*.statahead_stats=clear
14052         $LCTL set_param mdc.*.batch_stats=clear
14053         $LCTL set_param mdc.*.stats=clear
14054         cancel_lru_locks mdc
14055         cancel_lru_locks osc
14056         time ls -l $DIR/$tdir | wc -l
14057         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14058         # wait for statahead thread to quit and update statahead stats
14059         sleep 2
14060         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14061                     awk '/hit.total:/ { print $NF }')
14062         # hit ratio should be larger than 75% (7500).
14063         (( $hit_total > 7500 )) ||
14064                 error "batched statahead hit count ($hit_total) is too low"
14065
14066         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14067         (( $unbatch_rpcs > $batch_rpcs )) ||
14068                 error "batched statahead does not reduce RPC count"
14069         $LCTL get_param mdc.*.batch_stats
14070 }
14071
14072 test_123ad() {
14073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14074
14075         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14076                 skip "Need server version at least 2.15.53"
14077
14078         local max
14079         local batch_max
14080
14081         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14082         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14083
14084         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14085         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14086
14087         test_batch_statahead 32 32
14088         test_batch_statahead 2048 256
14089 }
14090 run_test 123ad "Verify batching statahead works correctly"
14091
14092 test_123b () { # statahead(bug 15027)
14093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14094
14095         test_mkdir $DIR/$tdir
14096         createmany -o $DIR/$tdir/$tfile-%d 1000
14097
14098         cancel_lru_locks mdc
14099         cancel_lru_locks osc
14100
14101 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14102         lctl set_param fail_loc=0x80000803
14103         ls -lR $DIR/$tdir > /dev/null
14104         log "ls done"
14105         lctl set_param fail_loc=0x0
14106         lctl get_param -n llite.*.statahead_stats
14107         rm -r $DIR/$tdir
14108         sync
14109
14110 }
14111 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14112
14113 test_123c() {
14114         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14115
14116         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14117         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14118         touch $DIR/$tdir.1/{1..3}
14119         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14120
14121         remount_client $MOUNT
14122
14123         $MULTIOP $DIR/$tdir.0 Q
14124
14125         # let statahead to complete
14126         ls -l $DIR/$tdir.0 > /dev/null
14127
14128         testid=$(echo $TESTNAME | tr '_' ' ')
14129         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14130                 error "statahead warning" || true
14131 }
14132 run_test 123c "Can not initialize inode warning on DNE statahead"
14133
14134 test_123d() {
14135         local num=100
14136         local swrong
14137         local ewrong
14138
14139         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14140         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14141                 error "setdirstripe $DIR/$tdir failed"
14142         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14143         remount_client $MOUNT
14144         $LCTL get_param llite.*.statahead_max
14145         $LCTL set_param llite.*.statahead_stats=0 ||
14146                 error "clear statahead_stats failed"
14147         swrong=$(lctl get_param -n llite.*.statahead_stats |
14148                  awk '/statahead.wrong:/ { print $NF }')
14149         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14150         # wait for statahead thread finished to update hit/miss stats.
14151         sleep 1
14152         $LCTL get_param -n llite.*.statahead_stats
14153         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14154                  awk '/statahead.wrong:/ { print $NF }')
14155         (( $swrong == $ewrong )) ||
14156                 log "statahead was stopped, maybe too many locks held!"
14157 }
14158 run_test 123d "Statahead on striped directories works correctly"
14159
14160 test_123e() {
14161         local max
14162         local batch_max
14163         local dir=$DIR/$tdir
14164
14165         mkdir $dir || error "mkdir $dir failed"
14166         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14167         stack_trap "rm -rf $dir"
14168
14169         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14170
14171         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14172         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14173         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14174         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14175
14176         $LCTL set_param llite.*.statahead_max=2048
14177         $LCTL set_param llite.*.statahead_batch_max=1024
14178
14179         ls -l $dir
14180         $LCTL get_param mdc.*.batch_stats
14181         $LCTL get_param llite.*.statahead_*
14182 }
14183 run_test 123e "statahead with large wide striping"
14184
14185 test_123f() {
14186         local max
14187         local batch_max
14188         local dir=$DIR/$tdir
14189
14190         mkdir $dir || error "mkdir $dir failed"
14191         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14192         stack_trap "rm -rf $dir"
14193
14194         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14195
14196         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14197         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14198
14199         $LCTL set_param llite.*.statahead_max=64
14200         $LCTL set_param llite.*.statahead_batch_max=64
14201
14202         ls -l $dir
14203         lctl get_param mdc.*.batch_stats
14204         lctl get_param llite.*.statahead_*
14205
14206         $LCTL set_param llite.*.statahead_max=$max
14207         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14208 }
14209 run_test 123f "Retry mechanism with large wide striping files"
14210
14211 test_124a() {
14212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14213         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14214                 skip_env "no lru resize on server"
14215
14216         local NR=2000
14217
14218         test_mkdir $DIR/$tdir
14219
14220         log "create $NR files at $DIR/$tdir"
14221         createmany -o $DIR/$tdir/f $NR ||
14222                 error "failed to create $NR files in $DIR/$tdir"
14223
14224         cancel_lru_locks mdc
14225         ls -l $DIR/$tdir > /dev/null
14226
14227         local NSDIR=""
14228         local LRU_SIZE=0
14229         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14230                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14231                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14232                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14233                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14234                         log "NSDIR=$NSDIR"
14235                         log "NS=$(basename $NSDIR)"
14236                         break
14237                 fi
14238         done
14239
14240         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14241                 skip "Not enough cached locks created!"
14242         fi
14243         log "LRU=$LRU_SIZE"
14244
14245         local SLEEP=30
14246
14247         # We know that lru resize allows one client to hold $LIMIT locks
14248         # for 10h. After that locks begin to be killed by client.
14249         local MAX_HRS=10
14250         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14251         log "LIMIT=$LIMIT"
14252         if [ $LIMIT -lt $LRU_SIZE ]; then
14253                 skip "Limit is too small $LIMIT"
14254         fi
14255
14256         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14257         # killing locks. Some time was spent for creating locks. This means
14258         # that up to the moment of sleep finish we must have killed some of
14259         # them (10-100 locks). This depends on how fast ther were created.
14260         # Many of them were touched in almost the same moment and thus will
14261         # be killed in groups.
14262         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14263
14264         # Use $LRU_SIZE_B here to take into account real number of locks
14265         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14266         local LRU_SIZE_B=$LRU_SIZE
14267         log "LVF=$LVF"
14268         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14269         log "OLD_LVF=$OLD_LVF"
14270         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14271
14272         # Let's make sure that we really have some margin. Client checks
14273         # cached locks every 10 sec.
14274         SLEEP=$((SLEEP+20))
14275         log "Sleep ${SLEEP} sec"
14276         local SEC=0
14277         while ((SEC<$SLEEP)); do
14278                 echo -n "..."
14279                 sleep 5
14280                 SEC=$((SEC+5))
14281                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14282                 echo -n "$LRU_SIZE"
14283         done
14284         echo ""
14285         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14286         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14287
14288         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14289                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14290                 unlinkmany $DIR/$tdir/f $NR
14291                 return
14292         }
14293
14294         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14295         log "unlink $NR files at $DIR/$tdir"
14296         unlinkmany $DIR/$tdir/f $NR
14297 }
14298 run_test 124a "lru resize ======================================="
14299
14300 get_max_pool_limit()
14301 {
14302         local limit=$($LCTL get_param \
14303                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14304         local max=0
14305         for l in $limit; do
14306                 if [[ $l -gt $max ]]; then
14307                         max=$l
14308                 fi
14309         done
14310         echo $max
14311 }
14312
14313 test_124b() {
14314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14315         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14316                 skip_env "no lru resize on server"
14317
14318         LIMIT=$(get_max_pool_limit)
14319
14320         NR=$(($(default_lru_size)*20))
14321         if [[ $NR -gt $LIMIT ]]; then
14322                 log "Limit lock number by $LIMIT locks"
14323                 NR=$LIMIT
14324         fi
14325
14326         IFree=$(mdsrate_inodes_available)
14327         if [ $IFree -lt $NR ]; then
14328                 log "Limit lock number by $IFree inodes"
14329                 NR=$IFree
14330         fi
14331
14332         lru_resize_disable mdc
14333         test_mkdir -p $DIR/$tdir/disable_lru_resize
14334
14335         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14336         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14337         cancel_lru_locks mdc
14338         stime=`date +%s`
14339         PID=""
14340         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14341         PID="$PID $!"
14342         sleep 2
14343         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14344         PID="$PID $!"
14345         sleep 2
14346         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14347         PID="$PID $!"
14348         wait $PID
14349         etime=`date +%s`
14350         nolruresize_delta=$((etime-stime))
14351         log "ls -la time: $nolruresize_delta seconds"
14352         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14353         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14354
14355         lru_resize_enable mdc
14356         test_mkdir -p $DIR/$tdir/enable_lru_resize
14357
14358         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14359         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14360         cancel_lru_locks mdc
14361         stime=`date +%s`
14362         PID=""
14363         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14364         PID="$PID $!"
14365         sleep 2
14366         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14367         PID="$PID $!"
14368         sleep 2
14369         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14370         PID="$PID $!"
14371         wait $PID
14372         etime=`date +%s`
14373         lruresize_delta=$((etime-stime))
14374         log "ls -la time: $lruresize_delta seconds"
14375         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14376
14377         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14378                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14379         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14380                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14381         else
14382                 log "lru resize performs the same with no lru resize"
14383         fi
14384         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14385 }
14386 run_test 124b "lru resize (performance test) ======================="
14387
14388 test_124c() {
14389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14390         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14391                 skip_env "no lru resize on server"
14392
14393         # cache ununsed locks on client
14394         local nr=100
14395         cancel_lru_locks mdc
14396         test_mkdir $DIR/$tdir
14397         createmany -o $DIR/$tdir/f $nr ||
14398                 error "failed to create $nr files in $DIR/$tdir"
14399         ls -l $DIR/$tdir > /dev/null
14400
14401         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14402         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14403         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14404         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14405         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14406
14407         # set lru_max_age to 1 sec
14408         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14409         echo "sleep $((recalc_p * 2)) seconds..."
14410         sleep $((recalc_p * 2))
14411
14412         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14413         # restore lru_max_age
14414         $LCTL set_param -n $nsdir.lru_max_age $max_age
14415         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14416         unlinkmany $DIR/$tdir/f $nr
14417 }
14418 run_test 124c "LRUR cancel very aged locks"
14419
14420 test_124d() {
14421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14422         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14423                 skip_env "no lru resize on server"
14424
14425         # cache ununsed locks on client
14426         local nr=100
14427
14428         lru_resize_disable mdc
14429         stack_trap "lru_resize_enable mdc" EXIT
14430
14431         cancel_lru_locks mdc
14432
14433         # asynchronous object destroy at MDT could cause bl ast to client
14434         test_mkdir $DIR/$tdir
14435         createmany -o $DIR/$tdir/f $nr ||
14436                 error "failed to create $nr files in $DIR/$tdir"
14437         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14438
14439         ls -l $DIR/$tdir > /dev/null
14440
14441         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14442         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14443         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14444         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14445
14446         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14447
14448         # set lru_max_age to 1 sec
14449         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14450         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14451
14452         echo "sleep $((recalc_p * 2)) seconds..."
14453         sleep $((recalc_p * 2))
14454
14455         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14456
14457         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14458 }
14459 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14460
14461 test_125() { # 13358
14462         $LCTL get_param -n llite.*.client_type | grep -q local ||
14463                 skip "must run as local client"
14464         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14465                 skip_env "must have acl enabled"
14466         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14467         id $USER0 || skip_env "missing user $USER0"
14468
14469         test_mkdir $DIR/$tdir
14470         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14471         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14472                 error "setfacl $DIR/$tdir failed"
14473         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14474 }
14475 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14476
14477 test_126() { # bug 12829/13455
14478         $GSS && skip_env "must run as gss disabled"
14479         $LCTL get_param -n llite.*.client_type | grep -q local ||
14480                 skip "must run as local client"
14481         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14482
14483         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14484         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14485         rm -f $DIR/$tfile
14486         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14487 }
14488 run_test 126 "check that the fsgid provided by the client is taken into account"
14489
14490 test_127a() { # bug 15521
14491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14492         local name count samp unit min max sum sumsq
14493         local tmpfile=$TMP/$tfile.tmp
14494
14495         # enable stats header if it is disabled
14496         $LCTL set_param enable_stats_header=1
14497
14498         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14499         echo "stats before reset"
14500         stack_trap "rm -f $tmpfile"
14501         local now=$(date +%s)
14502
14503         $LCTL get_param osc.*.stats | tee $tmpfile
14504
14505         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14506         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14507         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14508         local uptime=$(awk '{ print $1 }' /proc/uptime)
14509
14510         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14511         (( ${snapshot_time%\.*} >= $now - 5 &&
14512            ${snapshot_time%\.*} <= $now + 5 )) ||
14513                 error "snapshot_time=$snapshot_time != now=$now"
14514         # elapsed _should_ be from mount, but at least less than uptime
14515         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14516                 error "elapsed=$elapsed > uptime=$uptime"
14517         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14518            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14519                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14520
14521         $LCTL set_param osc.*.stats=0
14522         local reset=$(date +%s)
14523         local fsize=$((2048 * 1024))
14524
14525         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14526         cancel_lru_locks osc
14527         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14528
14529         now=$(date +%s)
14530         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14531         while read name count samp unit min max sum sumsq; do
14532                 [[ "$samp" == "samples" ]] || continue
14533
14534                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14535                 [ ! $min ] && error "Missing min value for $name proc entry"
14536                 eval $name=$count || error "Wrong proc format"
14537
14538                 case $name in
14539                 read_bytes|write_bytes)
14540                         [[ "$unit" =~ "bytes" ]] ||
14541                                 error "unit is not 'bytes': $unit"
14542                         (( $min >= 4096 )) || error "min is too small: $min"
14543                         (( $min <= $fsize )) || error "min is too big: $min"
14544                         (( $max >= 4096 )) || error "max is too small: $max"
14545                         (( $max <= $fsize )) || error "max is too big: $max"
14546                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14547                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14548                                 error "sumsquare is too small: $sumsq"
14549                         (( $sumsq <= $fsize * $fsize )) ||
14550                                 error "sumsquare is too big: $sumsq"
14551                         ;;
14552                 ost_read|ost_write)
14553                         [[ "$unit" =~ "usec" ]] ||
14554                                 error "unit is not 'usec': $unit"
14555                         ;;
14556                 *)      ;;
14557                 esac
14558         done < $tmpfile
14559
14560         #check that we actually got some stats
14561         [ "$read_bytes" ] || error "Missing read_bytes stats"
14562         [ "$write_bytes" ] || error "Missing write_bytes stats"
14563         [ "$read_bytes" != 0 ] || error "no read done"
14564         [ "$write_bytes" != 0 ] || error "no write done"
14565
14566         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14567         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14568         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14569
14570         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14571         (( ${snapshot_time%\.*} >= $now - 5 &&
14572            ${snapshot_time%\.*} <= $now + 5 )) ||
14573                 error "reset snapshot_time=$snapshot_time != now=$now"
14574         # elapsed should be from time of stats reset
14575         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14576            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14577                 error "reset elapsed=$elapsed > $now - $reset"
14578         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14579            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14580                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14581 }
14582 run_test 127a "verify the client stats are sane"
14583
14584 test_127b() { # bug LU-333
14585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14586         local name count samp unit min max sum sumsq
14587
14588         echo "stats before reset"
14589         $LCTL get_param llite.*.stats
14590         $LCTL set_param llite.*.stats=0
14591
14592         # perform 2 reads and writes so MAX is different from SUM.
14593         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14594         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14595         cancel_lru_locks osc
14596         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14597         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14598
14599         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14600         stack_trap "rm -f $TMP/$tfile.tmp"
14601         while read name count samp unit min max sum sumsq; do
14602                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14603                 eval $name=$count || error "Wrong proc format"
14604
14605                 case $name in
14606                 read_bytes|write_bytes)
14607                         [[ "$unit" =~ "bytes" ]] ||
14608                                 error "unit is not 'bytes': $unit"
14609                         (( $count == 2 )) || error "count is not 2: $count"
14610                         (( $min == $PAGE_SIZE )) ||
14611                                 error "min is not $PAGE_SIZE: $min"
14612                         (( $max == $PAGE_SIZE )) ||
14613                                 error "max is not $PAGE_SIZE: $max"
14614                         (( $sum == $PAGE_SIZE * 2 )) ||
14615                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14616                         ;;
14617                 read|write)
14618                         [[ "$unit" =~ "usec" ]] ||
14619                                 error "unit is not 'usec': $unit"
14620                         ;;
14621                 *)      ;;
14622                 esac
14623         done < $TMP/$tfile.tmp
14624
14625         #check that we actually got some stats
14626         [ "$read_bytes" ] || error "Missing read_bytes stats"
14627         [ "$write_bytes" ] || error "Missing write_bytes stats"
14628         [ "$read_bytes" != 0 ] || error "no read done"
14629         [ "$write_bytes" != 0 ] || error "no write done"
14630 }
14631 run_test 127b "verify the llite client stats are sane"
14632
14633 test_127c() { # LU-12394
14634         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14635         local size
14636         local bsize
14637         local reads
14638         local writes
14639         local count
14640
14641         $LCTL set_param llite.*.extents_stats=1
14642         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14643
14644         # Use two stripes so there is enough space in default config
14645         $LFS setstripe -c 2 $DIR/$tfile
14646
14647         # Extent stats start at 0-4K and go in power of two buckets
14648         # LL_HIST_START = 12 --> 2^12 = 4K
14649         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14650         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14651         # small configs
14652         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14653                 do
14654                 # Write and read, 2x each, second time at a non-zero offset
14655                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14656                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14657                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14658                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14659                 rm -f $DIR/$tfile
14660         done
14661
14662         $LCTL get_param llite.*.extents_stats
14663
14664         count=2
14665         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14666                 do
14667                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14668                                 grep -m 1 $bsize)
14669                 reads=$(echo $bucket | awk '{print $5}')
14670                 writes=$(echo $bucket | awk '{print $9}')
14671                 [ "$reads" -eq $count ] ||
14672                         error "$reads reads in < $bsize bucket, expect $count"
14673                 [ "$writes" -eq $count ] ||
14674                         error "$writes writes in < $bsize bucket, expect $count"
14675         done
14676
14677         # Test mmap write and read
14678         $LCTL set_param llite.*.extents_stats=c
14679         size=512
14680         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14681         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14682         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14683
14684         $LCTL get_param llite.*.extents_stats
14685
14686         count=$(((size*1024) / PAGE_SIZE))
14687
14688         bsize=$((2 * PAGE_SIZE / 1024))K
14689
14690         bucket=$($LCTL get_param -n llite.*.extents_stats |
14691                         grep -m 1 $bsize)
14692         reads=$(echo $bucket | awk '{print $5}')
14693         writes=$(echo $bucket | awk '{print $9}')
14694         # mmap writes fault in the page first, creating an additonal read
14695         [ "$reads" -eq $((2 * count)) ] ||
14696                 error "$reads reads in < $bsize bucket, expect $count"
14697         [ "$writes" -eq $count ] ||
14698                 error "$writes writes in < $bsize bucket, expect $count"
14699 }
14700 run_test 127c "test llite extent stats with regular & mmap i/o"
14701
14702 test_128() { # bug 15212
14703         touch $DIR/$tfile
14704         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14705                 find $DIR/$tfile
14706                 find $DIR/$tfile
14707         EOF
14708
14709         result=$(grep error $TMP/$tfile.log)
14710         rm -f $DIR/$tfile $TMP/$tfile.log
14711         [ -z "$result" ] ||
14712                 error "consecutive find's under interactive lfs failed"
14713 }
14714 run_test 128 "interactive lfs for 2 consecutive find's"
14715
14716 set_dir_limits () {
14717         local mntdev
14718         local canondev
14719         local node
14720
14721         local ldproc=/proc/fs/ldiskfs
14722         local facets=$(get_facets MDS)
14723
14724         for facet in ${facets//,/ }; do
14725                 canondev=$(ldiskfs_canon \
14726                            *.$(convert_facet2label $facet).mntdev $facet)
14727                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14728                         ldproc=/sys/fs/ldiskfs
14729                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14730                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14731         done
14732 }
14733
14734 check_mds_dmesg() {
14735         local facets=$(get_facets MDS)
14736         for facet in ${facets//,/ }; do
14737                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14738         done
14739         return 1
14740 }
14741
14742 test_129() {
14743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14744         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14745                 skip "Need MDS version with at least 2.5.56"
14746         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14747                 skip_env "ldiskfs only test"
14748         fi
14749         remote_mds_nodsh && skip "remote MDS with nodsh"
14750
14751         local ENOSPC=28
14752         local has_warning=false
14753
14754         rm -rf $DIR/$tdir
14755         mkdir -p $DIR/$tdir
14756
14757         # block size of mds1
14758         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14759         set_dir_limits $maxsize $((maxsize * 6 / 8))
14760         stack_trap "set_dir_limits 0 0"
14761         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14762         local dirsize=$(stat -c%s "$DIR/$tdir")
14763         local nfiles=0
14764         while (( $dirsize <= $maxsize )); do
14765                 $MCREATE $DIR/$tdir/file_base_$nfiles
14766                 rc=$?
14767                 # check two errors:
14768                 # ENOSPC for ext4 max_dir_size, which has been used since
14769                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14770                 if (( rc == ENOSPC )); then
14771                         set_dir_limits 0 0
14772                         echo "rc=$rc returned as expected after $nfiles files"
14773
14774                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14775                                 error "create failed w/o dir size limit"
14776
14777                         # messages may be rate limited if test is run repeatedly
14778                         check_mds_dmesg '"is approaching max"' ||
14779                                 echo "warning message should be output"
14780                         check_mds_dmesg '"has reached max"' ||
14781                                 echo "reached message should be output"
14782
14783                         dirsize=$(stat -c%s "$DIR/$tdir")
14784
14785                         [[ $dirsize -ge $maxsize ]] && return 0
14786                         error "dirsize $dirsize < $maxsize after $nfiles files"
14787                 elif (( rc != 0 )); then
14788                         break
14789                 fi
14790                 nfiles=$((nfiles + 1))
14791                 dirsize=$(stat -c%s "$DIR/$tdir")
14792         done
14793
14794         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14795 }
14796 run_test 129 "test directory size limit ========================"
14797
14798 OLDIFS="$IFS"
14799 cleanup_130() {
14800         trap 0
14801         IFS="$OLDIFS"
14802         rm -f $DIR/$tfile
14803 }
14804
14805 test_130a() {
14806         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14807         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14808
14809         trap cleanup_130 EXIT RETURN
14810
14811         local fm_file=$DIR/$tfile
14812         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14813         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14814                 error "dd failed for $fm_file"
14815
14816         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14817         filefrag -ves $fm_file
14818         local rc=$?
14819         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14820                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14821         (( $rc == 0 )) || error "filefrag $fm_file failed"
14822
14823         filefrag_op=$(filefrag -ve -k $fm_file |
14824                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14825         local lun=$($LFS getstripe -i $fm_file)
14826
14827         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14828         IFS=$'\n'
14829         local tot_len=0
14830         for line in $filefrag_op; do
14831                 local frag_lun=$(echo $line | cut -d: -f5)
14832                 local ext_len=$(echo $line | cut -d: -f4)
14833
14834                 if (( $frag_lun != $lun )); then
14835                         error "FIEMAP on 1-stripe file($fm_file) failed"
14836                         return
14837                 fi
14838                 (( tot_len += ext_len ))
14839         done
14840
14841         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14842                 error "FIEMAP on 1-stripe file($fm_file) failed"
14843                 return
14844         fi
14845
14846         echo "FIEMAP on single striped file succeeded"
14847 }
14848 run_test 130a "FIEMAP (1-stripe file)"
14849
14850 test_130b() {
14851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14852
14853         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14854         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14855         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14856                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14857
14858         trap cleanup_130 EXIT RETURN
14859
14860         local fm_file=$DIR/$tfile
14861         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14862                 error "setstripe on $fm_file"
14863
14864         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14865                 error "dd failed on $fm_file"
14866
14867         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14868         filefrag_op=$(filefrag -ve -k $fm_file |
14869                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14870
14871         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14872                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14873
14874         IFS=$'\n'
14875         local tot_len=0
14876         local num_luns=1
14877
14878         for line in $filefrag_op; do
14879                 local frag_lun=$(echo $line | cut -d: -f5 |
14880                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14881                 local ext_len=$(echo $line | cut -d: -f4)
14882                 if (( $frag_lun != $last_lun )); then
14883                         if (( tot_len != 1024 )); then
14884                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14885                                 return
14886                         else
14887                                 (( num_luns += 1 ))
14888                                 tot_len=0
14889                         fi
14890                 fi
14891                 (( tot_len += ext_len ))
14892                 last_lun=$frag_lun
14893         done
14894         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14895                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14896                 return
14897         fi
14898
14899         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14900 }
14901 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14902
14903 test_130c() {
14904         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14905
14906         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14907         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14908         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14909                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14910
14911         trap cleanup_130 EXIT RETURN
14912
14913         local fm_file=$DIR/$tfile
14914         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14915
14916         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14917                 error "dd failed on $fm_file"
14918
14919         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14920         filefrag_op=$(filefrag -ve -k $fm_file |
14921                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14922
14923         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14924                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14925
14926         IFS=$'\n'
14927         local tot_len=0
14928         local num_luns=1
14929         for line in $filefrag_op; do
14930                 local frag_lun=$(echo $line | cut -d: -f5 |
14931                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14932                 local ext_len=$(echo $line | cut -d: -f4)
14933                 if (( $frag_lun != $last_lun )); then
14934                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14935                         if (( logical != 512 )); then
14936                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14937                                 return
14938                         fi
14939                         if (( tot_len != 512 )); then
14940                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14941                                 return
14942                         else
14943                                 (( num_luns += 1 ))
14944                                 tot_len=0
14945                         fi
14946                 fi
14947                 (( tot_len += ext_len ))
14948                 last_lun=$frag_lun
14949         done
14950         if (( num_luns != 2 || tot_len != 512 )); then
14951                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14952                 return
14953         fi
14954
14955         echo "FIEMAP on 2-stripe file with hole succeeded"
14956 }
14957 run_test 130c "FIEMAP (2-stripe file with hole)"
14958
14959 test_130d() {
14960         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14961
14962         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14963         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14964         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14965                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14966
14967         trap cleanup_130 EXIT RETURN
14968
14969         local fm_file=$DIR/$tfile
14970         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14971                         error "setstripe on $fm_file"
14972
14973         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14974         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14975                 error "dd failed on $fm_file"
14976
14977         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14978         filefrag_op=$(filefrag -ve -k $fm_file |
14979                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14980
14981         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14982                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14983
14984         IFS=$'\n'
14985         local tot_len=0
14986         local num_luns=1
14987         for line in $filefrag_op; do
14988                 local frag_lun=$(echo $line | cut -d: -f5 |
14989                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14990                 local ext_len=$(echo $line | cut -d: -f4)
14991                 if (( $frag_lun != $last_lun )); then
14992                         if (( tot_len != 1024 )); then
14993                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14994                                 return
14995                         else
14996                                 (( num_luns += 1 ))
14997                                 local tot_len=0
14998                         fi
14999                 fi
15000                 (( tot_len += ext_len ))
15001                 last_lun=$frag_lun
15002         done
15003         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15004                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15005                 return
15006         fi
15007
15008         echo "FIEMAP on N-stripe file succeeded"
15009 }
15010 run_test 130d "FIEMAP (N-stripe file)"
15011
15012 test_130e() {
15013         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15014
15015         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15016         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15017         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15018                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15019
15020         trap cleanup_130 EXIT RETURN
15021
15022         local fm_file=$DIR/$tfile
15023         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15024         stack_trap "rm -f $fm_file"
15025
15026         local num_blks=512
15027         local expected_len=$(( (num_blks / 2) * 64 ))
15028         for ((i = 0; i < $num_blks; i++)); do
15029                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15030                         conv=notrunc > /dev/null 2>&1
15031         done
15032
15033         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15034         filefrag_op=$(filefrag -ve -k $fm_file |
15035                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15036
15037         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15038
15039         IFS=$'\n'
15040         local tot_len=0
15041         local num_luns=1
15042         for line in $filefrag_op; do
15043                 local frag_lun=$(echo $line | cut -d: -f5)
15044                 local ext_len=$(echo $line | cut -d: -f4)
15045                 if (( $frag_lun != $last_lun )); then
15046                         if (( tot_len != $expected_len )); then
15047                                 error "OST$last_lun $tot_len != $expected_len"
15048                         else
15049                                 (( num_luns += 1 ))
15050                                 tot_len=0
15051                         fi
15052                 fi
15053                 (( tot_len += ext_len ))
15054                 last_lun=$frag_lun
15055         done
15056         if (( num_luns != 2 || tot_len != $expected_len )); then
15057                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15058         fi
15059
15060         echo "FIEMAP with continuation calls succeeded"
15061 }
15062 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15063
15064 test_130f() {
15065         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15066         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15067         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15068                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15069
15070         local fm_file=$DIR/$tfile
15071         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15072                 error "multiop create with lov_delay_create on $fm_file"
15073
15074         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15075         filefrag_extents=$(filefrag -vek $fm_file |
15076                            awk '/extents? found/ { print $2 }')
15077         if (( $filefrag_extents != 0 )); then
15078                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15079         fi
15080
15081         rm -f $fm_file
15082 }
15083 run_test 130f "FIEMAP (unstriped file)"
15084
15085 test_130g() {
15086         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15087                 skip "Need MDS version with at least 2.12.53 for overstriping"
15088         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15089         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15090         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15091                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15092
15093         local file=$DIR/$tfile
15094         local nr=$((OSTCOUNT * 100))
15095
15096         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
15097
15098         stack_trap "rm -f $file"
15099         dd if=/dev/zero of=$file count=$nr bs=1M
15100         sync
15101         nr=$($LFS getstripe -c $file)
15102
15103         local extents=$(filefrag -v $file |
15104                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15105
15106         echo "filefrag list $extents extents in file with stripecount $nr"
15107         if (( extents < nr )); then
15108                 $LFS getstripe $file
15109                 filefrag -v $file
15110                 error "filefrag printed $extents < $nr extents"
15111         fi
15112 }
15113 run_test 130g "FIEMAP (overstripe file)"
15114
15115 # Test for writev/readv
15116 test_131a() {
15117         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15118                 error "writev test failed"
15119         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15120                 error "readv failed"
15121         rm -f $DIR/$tfile
15122 }
15123 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15124
15125 test_131b() {
15126         local fsize=$((524288 + 1048576 + 1572864))
15127         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15128                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15129                         error "append writev test failed"
15130
15131         ((fsize += 1572864 + 1048576))
15132         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15133                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15134                         error "append writev test failed"
15135         rm -f $DIR/$tfile
15136 }
15137 run_test 131b "test append writev"
15138
15139 test_131c() {
15140         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15141         error "NOT PASS"
15142 }
15143 run_test 131c "test read/write on file w/o objects"
15144
15145 test_131d() {
15146         rwv -f $DIR/$tfile -w -n 1 1572864
15147         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15148         if [ "$NOB" != 1572864 ]; then
15149                 error "Short read filed: read $NOB bytes instead of 1572864"
15150         fi
15151         rm -f $DIR/$tfile
15152 }
15153 run_test 131d "test short read"
15154
15155 test_131e() {
15156         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15157         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15158         error "read hitting hole failed"
15159         rm -f $DIR/$tfile
15160 }
15161 run_test 131e "test read hitting hole"
15162
15163 check_stats() {
15164         local facet=$1
15165         local op=$2
15166         local want=${3:-0}
15167         local res
15168
15169         # open             11 samples [usecs] 468 4793 13658 35791898
15170         case $facet in
15171         mds*) res=($(do_facet $facet \
15172                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15173                  ;;
15174         ost*) res=($(do_facet $facet \
15175                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15176                  ;;
15177         *) error "Wrong facet '$facet'" ;;
15178         esac
15179         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15180         # if $want is zero, it means any stat increment is ok.
15181         if (( $want > 0 )); then
15182                 local count=${res[1]}
15183
15184                 if (( $count != $want )); then
15185                         if [[ $facet =~ "mds" ]]; then
15186                                 do_nodes $(comma_list $(mdts_nodes)) \
15187                                         $LCTL get_param mdt.*.md_stats
15188                         else
15189                                 do_nodes $(comma_list $(osts-nodes)) \
15190                                         $LCTL get_param obdfilter.*.stats
15191                         fi
15192                         error "The $op counter on $facet is $count, not $want"
15193                 fi
15194         fi
15195 }
15196
15197 test_133a() {
15198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15199         remote_ost_nodsh && skip "remote OST with nodsh"
15200         remote_mds_nodsh && skip "remote MDS with nodsh"
15201         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15202                 skip_env "MDS doesn't support rename stats"
15203
15204         local testdir=$DIR/${tdir}/stats_testdir
15205
15206         mkdir -p $DIR/${tdir}
15207
15208         # clear stats.
15209         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15210         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15211
15212         # verify mdt stats first.
15213         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15214         check_stats $SINGLEMDS "mkdir" 1
15215
15216         # clear "open" from "lfs mkdir" above
15217         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15218         touch ${testdir}/${tfile} || error "touch failed"
15219         check_stats $SINGLEMDS "open" 1
15220         check_stats $SINGLEMDS "close" 1
15221         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15222                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15223                 check_stats $SINGLEMDS "mknod" 2
15224         }
15225         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15226         check_stats $SINGLEMDS "unlink" 1
15227         rm -f ${testdir}/${tfile} || error "file remove failed"
15228         check_stats $SINGLEMDS "unlink" 2
15229
15230         # remove working dir and check mdt stats again.
15231         rmdir ${testdir} || error "rmdir failed"
15232         check_stats $SINGLEMDS "rmdir" 1
15233
15234         local testdir1=$DIR/${tdir}/stats_testdir1
15235         mkdir_on_mdt0 -p ${testdir}
15236         mkdir_on_mdt0 -p ${testdir1}
15237         touch ${testdir1}/test1
15238         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15239         check_stats $SINGLEMDS "crossdir_rename" 1
15240
15241         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15242         check_stats $SINGLEMDS "samedir_rename" 1
15243
15244         rm -rf $DIR/${tdir}
15245 }
15246 run_test 133a "Verifying MDT stats ========================================"
15247
15248 test_133b() {
15249         local res
15250
15251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15252         remote_ost_nodsh && skip "remote OST with nodsh"
15253         remote_mds_nodsh && skip "remote MDS with nodsh"
15254
15255         local testdir=$DIR/${tdir}/stats_testdir
15256
15257         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15258         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15259         touch ${testdir}/${tfile} || error "touch failed"
15260         cancel_lru_locks mdc
15261
15262         # clear stats.
15263         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15264         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15265
15266         # extra mdt stats verification.
15267         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15268         check_stats $SINGLEMDS "setattr" 1
15269         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15270         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15271         then            # LU-1740
15272                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15273                 check_stats $SINGLEMDS "getattr" 1
15274         fi
15275         rm -rf $DIR/${tdir}
15276
15277         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15278         # so the check below is not reliable
15279         [ $MDSCOUNT -eq 1 ] || return 0
15280
15281         # Sleep to avoid a cached response.
15282         #define OBD_STATFS_CACHE_SECONDS 1
15283         sleep 2
15284         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15285         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15286         $LFS df || error "lfs failed"
15287         check_stats $SINGLEMDS "statfs" 1
15288
15289         # check aggregated statfs (LU-10018)
15290         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15291                 return 0
15292         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15293                 return 0
15294         sleep 2
15295         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15296         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15297         df $DIR
15298         check_stats $SINGLEMDS "statfs" 1
15299
15300         # We want to check that the client didn't send OST_STATFS to
15301         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15302         # extra care is needed here.
15303         if remote_mds; then
15304                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15305                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15306
15307                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15308                 [ "$res" ] && error "OST got STATFS"
15309         fi
15310
15311         return 0
15312 }
15313 run_test 133b "Verifying extra MDT stats =================================="
15314
15315 test_133c() {
15316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15317         remote_ost_nodsh && skip "remote OST with nodsh"
15318         remote_mds_nodsh && skip "remote MDS with nodsh"
15319
15320         local testdir=$DIR/$tdir/stats_testdir
15321
15322         test_mkdir -p $testdir
15323
15324         # verify obdfilter stats.
15325         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15326         sync
15327         cancel_lru_locks osc
15328         wait_delete_completed
15329
15330         # clear stats.
15331         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15332         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15333
15334         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15335                 error "dd failed"
15336         sync
15337         cancel_lru_locks osc
15338         check_stats ost1 "write" 1
15339
15340         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15341         check_stats ost1 "read" 1
15342
15343         > $testdir/$tfile || error "truncate failed"
15344         check_stats ost1 "punch" 1
15345
15346         rm -f $testdir/$tfile || error "file remove failed"
15347         wait_delete_completed
15348         check_stats ost1 "destroy" 1
15349
15350         rm -rf $DIR/$tdir
15351 }
15352 run_test 133c "Verifying OST stats ========================================"
15353
15354 order_2() {
15355         local value=$1
15356         local orig=$value
15357         local order=1
15358
15359         while [ $value -ge 2 ]; do
15360                 order=$((order*2))
15361                 value=$((value/2))
15362         done
15363
15364         if [ $orig -gt $order ]; then
15365                 order=$((order*2))
15366         fi
15367         echo $order
15368 }
15369
15370 size_in_KMGT() {
15371     local value=$1
15372     local size=('K' 'M' 'G' 'T');
15373     local i=0
15374     local size_string=$value
15375
15376     while [ $value -ge 1024 ]; do
15377         if [ $i -gt 3 ]; then
15378             #T is the biggest unit we get here, if that is bigger,
15379             #just return XXXT
15380             size_string=${value}T
15381             break
15382         fi
15383         value=$((value >> 10))
15384         if [ $value -lt 1024 ]; then
15385             size_string=${value}${size[$i]}
15386             break
15387         fi
15388         i=$((i + 1))
15389     done
15390
15391     echo $size_string
15392 }
15393
15394 get_rename_size() {
15395         local size=$1
15396         local context=${2:-.}
15397         local sample=$(do_facet $SINGLEMDS $LCTL \
15398                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15399                 grep -A1 $context |
15400                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15401         echo $sample
15402 }
15403
15404 test_133d() {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406         remote_ost_nodsh && skip "remote OST with nodsh"
15407         remote_mds_nodsh && skip "remote MDS with nodsh"
15408         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15409                 skip_env "MDS doesn't support rename stats"
15410
15411         local testdir1=$DIR/${tdir}/stats_testdir1
15412         local testdir2=$DIR/${tdir}/stats_testdir2
15413         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15414
15415         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15416
15417         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15418         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15419
15420         createmany -o $testdir1/test 512 || error "createmany failed"
15421
15422         # check samedir rename size
15423         mv ${testdir1}/test0 ${testdir1}/test_0
15424
15425         local testdir1_size=$(ls -l $DIR/${tdir} |
15426                 awk '/stats_testdir1/ {print $5}')
15427         local testdir2_size=$(ls -l $DIR/${tdir} |
15428                 awk '/stats_testdir2/ {print $5}')
15429
15430         testdir1_size=$(order_2 $testdir1_size)
15431         testdir2_size=$(order_2 $testdir2_size)
15432
15433         testdir1_size=$(size_in_KMGT $testdir1_size)
15434         testdir2_size=$(size_in_KMGT $testdir2_size)
15435
15436         echo "source rename dir size: ${testdir1_size}"
15437         echo "target rename dir size: ${testdir2_size}"
15438
15439         local cmd="do_facet $SINGLEMDS $LCTL "
15440         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15441
15442         eval $cmd || error "$cmd failed"
15443         local samedir=$($cmd | grep 'same_dir')
15444         local same_sample=$(get_rename_size $testdir1_size)
15445         [ -z "$samedir" ] && error "samedir_rename_size count error"
15446         [[ $same_sample -eq 1 ]] ||
15447                 error "samedir_rename_size error $same_sample"
15448         echo "Check same dir rename stats success"
15449
15450         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15451
15452         # check crossdir rename size
15453         mv ${testdir1}/test_0 ${testdir2}/test_0
15454
15455         testdir1_size=$(ls -l $DIR/${tdir} |
15456                 awk '/stats_testdir1/ {print $5}')
15457         testdir2_size=$(ls -l $DIR/${tdir} |
15458                 awk '/stats_testdir2/ {print $5}')
15459
15460         testdir1_size=$(order_2 $testdir1_size)
15461         testdir2_size=$(order_2 $testdir2_size)
15462
15463         testdir1_size=$(size_in_KMGT $testdir1_size)
15464         testdir2_size=$(size_in_KMGT $testdir2_size)
15465
15466         echo "source rename dir size: ${testdir1_size}"
15467         echo "target rename dir size: ${testdir2_size}"
15468
15469         eval $cmd || error "$cmd failed"
15470         local crossdir=$($cmd | grep 'crossdir')
15471         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15472         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15473         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15474         [[ $src_sample -eq 1 ]] ||
15475                 error "crossdir_rename_size error $src_sample"
15476         [[ $tgt_sample -eq 1 ]] ||
15477                 error "crossdir_rename_size error $tgt_sample"
15478         echo "Check cross dir rename stats success"
15479         rm -rf $DIR/${tdir}
15480 }
15481 run_test 133d "Verifying rename_stats ========================================"
15482
15483 test_133e() {
15484         remote_mds_nodsh && skip "remote MDS with nodsh"
15485         remote_ost_nodsh && skip "remote OST with nodsh"
15486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15487
15488         local testdir=$DIR/${tdir}/stats_testdir
15489         local ctr f0 f1 bs=32768 count=42 sum
15490
15491         mkdir -p ${testdir} || error "mkdir failed"
15492
15493         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15494
15495         for ctr in {write,read}_bytes; do
15496                 sync
15497                 cancel_lru_locks osc
15498
15499                 do_facet ost1 $LCTL set_param -n \
15500                         "obdfilter.*.exports.clear=clear"
15501
15502                 if [ $ctr = write_bytes ]; then
15503                         f0=/dev/zero
15504                         f1=${testdir}/${tfile}
15505                 else
15506                         f0=${testdir}/${tfile}
15507                         f1=/dev/null
15508                 fi
15509
15510                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15511                         error "dd failed"
15512                 sync
15513                 cancel_lru_locks osc
15514
15515                 sum=$(do_facet ost1 $LCTL get_param \
15516                         "obdfilter.*.exports.*.stats" |
15517                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15518                                 $1 == ctr { sum += $7 }
15519                                 END { printf("%0.0f", sum) }')
15520
15521                 if ((sum != bs * count)); then
15522                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15523                 fi
15524         done
15525
15526         rm -rf $DIR/${tdir}
15527 }
15528 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15529
15530 test_133f() {
15531         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15532                 skip "too old lustre for get_param -R ($facet_ver)"
15533
15534         # verifying readability.
15535         $LCTL get_param -R '*' &> /dev/null
15536
15537         # Verifing writability with badarea_io.
15538         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15539         local skipped_params='force_lbug|changelog_mask|daemon_file'
15540         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15541                 egrep -v "$skipped_params" |
15542                 xargs -n 1 find $proc_dirs -name |
15543                 xargs -n 1 badarea_io ||
15544                 error "client badarea_io failed"
15545
15546         # remount the FS in case writes/reads /proc break the FS
15547         cleanup || error "failed to unmount"
15548         setup || error "failed to setup"
15549 }
15550 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15551
15552 test_133g() {
15553         remote_mds_nodsh && skip "remote MDS with nodsh"
15554         remote_ost_nodsh && skip "remote OST with nodsh"
15555
15556         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15557         local proc_dirs_str=$(eval echo $proc_dirs)
15558         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15559         local facet
15560         for facet in mds1 ost1; do
15561                 local facet_ver=$(lustre_version_code $facet)
15562                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15563                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15564                 else
15565                         log "$facet: too old lustre for get_param -R"
15566                 fi
15567                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15568                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15569                                 tr -d = | egrep -v $skipped_params |
15570                                 xargs -n 1 find $proc_dirs_str -name |
15571                                 xargs -n 1 badarea_io" ||
15572                                         error "$facet badarea_io failed"
15573                 else
15574                         skip_noexit "$facet: too old lustre for get_param -R"
15575                 fi
15576         done
15577
15578         # remount the FS in case writes/reads /proc break the FS
15579         cleanup || error "failed to unmount"
15580         setup || error "failed to setup"
15581 }
15582 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15583
15584 test_133h() {
15585         remote_mds_nodsh && skip "remote MDS with nodsh"
15586         remote_ost_nodsh && skip "remote OST with nodsh"
15587         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15588                 skip "Need MDS version at least 2.9.54"
15589
15590         local facet
15591         for facet in client mds1 ost1; do
15592                 # Get the list of files that are missing the terminating newline
15593                 local plist=$(do_facet $facet
15594                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15595                 local ent
15596                 for ent in $plist; do
15597                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15598                                 awk -v FS='\v' -v RS='\v\v' \
15599                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15600                                         print FILENAME}'" 2>/dev/null)
15601                         [ -z $missing ] || {
15602                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15603                                 error "file does not end with newline: $facet-$ent"
15604                         }
15605                 done
15606         done
15607 }
15608 run_test 133h "Proc files should end with newlines"
15609
15610 test_134a() {
15611         remote_mds_nodsh && skip "remote MDS with nodsh"
15612         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15613                 skip "Need MDS version at least 2.7.54"
15614
15615         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15616         cancel_lru_locks mdc
15617
15618         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15619         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15620         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15621
15622         local nr=1000
15623         createmany -o $DIR/$tdir/f $nr ||
15624                 error "failed to create $nr files in $DIR/$tdir"
15625         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15626
15627         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15628         do_facet mds1 $LCTL set_param fail_loc=0x327
15629         do_facet mds1 $LCTL set_param fail_val=500
15630         touch $DIR/$tdir/m
15631
15632         echo "sleep 10 seconds ..."
15633         sleep 10
15634         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15635
15636         do_facet mds1 $LCTL set_param fail_loc=0
15637         do_facet mds1 $LCTL set_param fail_val=0
15638         [ $lck_cnt -lt $unused ] ||
15639                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15640
15641         rm $DIR/$tdir/m
15642         unlinkmany $DIR/$tdir/f $nr
15643 }
15644 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15645
15646 test_134b() {
15647         remote_mds_nodsh && skip "remote MDS with nodsh"
15648         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15649                 skip "Need MDS version at least 2.7.54"
15650
15651         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15652         cancel_lru_locks mdc
15653
15654         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15655                         ldlm.lock_reclaim_threshold_mb)
15656         # disable reclaim temporarily
15657         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15658
15659         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15660         do_facet mds1 $LCTL set_param fail_loc=0x328
15661         do_facet mds1 $LCTL set_param fail_val=500
15662
15663         $LCTL set_param debug=+trace
15664
15665         local nr=600
15666         createmany -o $DIR/$tdir/f $nr &
15667         local create_pid=$!
15668
15669         echo "Sleep $TIMEOUT seconds ..."
15670         sleep $TIMEOUT
15671         if ! ps -p $create_pid  > /dev/null 2>&1; then
15672                 do_facet mds1 $LCTL set_param fail_loc=0
15673                 do_facet mds1 $LCTL set_param fail_val=0
15674                 do_facet mds1 $LCTL set_param \
15675                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15676                 error "createmany finished incorrectly!"
15677         fi
15678         do_facet mds1 $LCTL set_param fail_loc=0
15679         do_facet mds1 $LCTL set_param fail_val=0
15680         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15681         wait $create_pid || return 1
15682
15683         unlinkmany $DIR/$tdir/f $nr
15684 }
15685 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15686
15687 test_135() {
15688         remote_mds_nodsh && skip "remote MDS with nodsh"
15689         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15690                 skip "Need MDS version at least 2.13.50"
15691         local fname
15692
15693         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15694
15695 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15696         #set only one record at plain llog
15697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15698
15699         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15700
15701         #fill already existed plain llog each 64767
15702         #wrapping whole catalog
15703         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15704
15705         createmany -o $DIR/$tdir/$tfile_ 64700
15706         for (( i = 0; i < 64700; i = i + 2 ))
15707         do
15708                 rm $DIR/$tdir/$tfile_$i &
15709                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15710                 local pid=$!
15711                 wait $pid
15712         done
15713
15714         #waiting osp synchronization
15715         wait_delete_completed
15716 }
15717 run_test 135 "Race catalog processing"
15718
15719 test_136() {
15720         remote_mds_nodsh && skip "remote MDS with nodsh"
15721         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15722                 skip "Need MDS version at least 2.13.50"
15723         local fname
15724
15725         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15726         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15727         #set only one record at plain llog
15728 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15729         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15730
15731         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15732
15733         #fill already existed 2 plain llogs each 64767
15734         #wrapping whole catalog
15735         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15736         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15737         wait_delete_completed
15738
15739         createmany -o $DIR/$tdir/$tfile_ 10
15740         sleep 25
15741
15742         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15743         for (( i = 0; i < 10; i = i + 3 ))
15744         do
15745                 rm $DIR/$tdir/$tfile_$i &
15746                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15747                 local pid=$!
15748                 wait $pid
15749                 sleep 7
15750                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15751         done
15752
15753         #waiting osp synchronization
15754         wait_delete_completed
15755 }
15756 run_test 136 "Race catalog processing 2"
15757
15758 test_140() { #bug-17379
15759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15760
15761         test_mkdir $DIR/$tdir
15762         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15763         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15764
15765         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15766         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15767         local i=0
15768         while i=$((i + 1)); do
15769                 test_mkdir $i
15770                 cd $i || error "Changing to $i"
15771                 ln -s ../stat stat || error "Creating stat symlink"
15772                 # Read the symlink until ELOOP present,
15773                 # not LBUGing the system is considered success,
15774                 # we didn't overrun the stack.
15775                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15776                 if [ $ret -ne 0 ]; then
15777                         if [ $ret -eq 40 ]; then
15778                                 break  # -ELOOP
15779                         else
15780                                 error "Open stat symlink"
15781                                         return
15782                         fi
15783                 fi
15784         done
15785         i=$((i - 1))
15786         echo "The symlink depth = $i"
15787         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15788                 error "Invalid symlink depth"
15789
15790         # Test recursive symlink
15791         ln -s symlink_self symlink_self
15792         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15793         echo "open symlink_self returns $ret"
15794         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15795 }
15796 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15797
15798 test_150a() {
15799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15800
15801         local TF="$TMP/$tfile"
15802
15803         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15804         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15805         cp $TF $DIR/$tfile
15806         cancel_lru_locks $OSC
15807         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15808         remount_client $MOUNT
15809         df -P $MOUNT
15810         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15811
15812         $TRUNCATE $TF 6000
15813         $TRUNCATE $DIR/$tfile 6000
15814         cancel_lru_locks $OSC
15815         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15816
15817         echo "12345" >>$TF
15818         echo "12345" >>$DIR/$tfile
15819         cancel_lru_locks $OSC
15820         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15821
15822         echo "12345" >>$TF
15823         echo "12345" >>$DIR/$tfile
15824         cancel_lru_locks $OSC
15825         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15826 }
15827 run_test 150a "truncate/append tests"
15828
15829 test_150b() {
15830         check_set_fallocate_or_skip
15831         local out
15832
15833         touch $DIR/$tfile
15834         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15835         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15836                 skip_eopnotsupp "$out|check_fallocate failed"
15837 }
15838 run_test 150b "Verify fallocate (prealloc) functionality"
15839
15840 test_150bb() {
15841         check_set_fallocate_or_skip
15842
15843         touch $DIR/$tfile
15844         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15845         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15846         > $DIR/$tfile
15847         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15848         # precomputed md5sum for 20MB of zeroes
15849         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15850         local sum=($(md5sum $DIR/$tfile))
15851
15852         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15853
15854         check_set_fallocate 1
15855
15856         > $DIR/$tfile
15857         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15858         sum=($(md5sum $DIR/$tfile))
15859
15860         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15861 }
15862 run_test 150bb "Verify fallocate modes both zero space"
15863
15864 test_150c() {
15865         check_set_fallocate_or_skip
15866         local striping="-c2"
15867
15868         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15869         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15870         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15871         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15872         local want=$((OSTCOUNT * 1048576))
15873
15874         # Must allocate all requested space, not more than 5% extra
15875         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15876                 error "bytes $bytes is not $want"
15877
15878         rm -f $DIR/$tfile
15879
15880         echo "verify fallocate on PFL file"
15881
15882         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15883
15884         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15885                 error "Create $DIR/$tfile failed"
15886         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15887         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15888         want=$((512 * 1048576))
15889
15890         # Must allocate all requested space, not more than 5% extra
15891         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15892                 error "bytes $bytes is not $want"
15893 }
15894 run_test 150c "Verify fallocate Size and Blocks"
15895
15896 test_150d() {
15897         check_set_fallocate_or_skip
15898         local striping="-c2"
15899
15900         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15901
15902         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
15903         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15904                 error "setstripe failed"
15905         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15906         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15907         local want=$((OSTCOUNT * 1048576))
15908
15909         # Must allocate all requested space, not more than 5% extra
15910         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15911                 error "bytes $bytes is not $want"
15912 }
15913 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15914
15915 test_150e() {
15916         check_set_fallocate_or_skip
15917
15918         echo "df before:"
15919         $LFS df
15920         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15921         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15922                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15923
15924         # Find OST with Minimum Size
15925         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15926                        sort -un | head -1)
15927
15928         # Get 100MB per OST of the available space to reduce run time
15929         # else 60% of the available space if we are running SLOW tests
15930         if [ $SLOW == "no" ]; then
15931                 local space=$((1024 * 100 * OSTCOUNT))
15932         else
15933                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15934         fi
15935
15936         fallocate -l${space}k $DIR/$tfile ||
15937                 error "fallocate ${space}k $DIR/$tfile failed"
15938         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15939
15940         # get size immediately after fallocate. This should be correctly
15941         # updated
15942         local size=$(stat -c '%s' $DIR/$tfile)
15943         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15944
15945         # Sleep for a while for statfs to get updated. And not pull from cache.
15946         sleep 2
15947
15948         echo "df after fallocate:"
15949         $LFS df
15950
15951         (( size / 1024 == space )) || error "size $size != requested $space"
15952         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15953                 error "used $used < space $space"
15954
15955         rm $DIR/$tfile || error "rm failed"
15956         sync
15957         wait_delete_completed
15958
15959         echo "df after unlink:"
15960         $LFS df
15961 }
15962 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15963
15964 test_150f() {
15965         local size
15966         local blocks
15967         local want_size_before=20480 # in bytes
15968         local want_blocks_before=40 # 512 sized blocks
15969         local want_blocks_after=24  # 512 sized blocks
15970         local length=$(((want_blocks_before - want_blocks_after) * 512))
15971
15972         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15973                 skip "need at least 2.14.0 for fallocate punch"
15974
15975         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15976                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15977         fi
15978
15979         check_set_fallocate_or_skip
15980         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15981
15982         [[ "x$DOM" == "xyes" ]] &&
15983                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15984
15985         echo "Verify fallocate punch: Range within the file range"
15986         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15987                 error "dd failed for bs 4096 and count 5"
15988
15989         # Call fallocate with punch range which is within the file range
15990         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15991                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15992         # client must see changes immediately after fallocate
15993         size=$(stat -c '%s' $DIR/$tfile)
15994         blocks=$(stat -c '%b' $DIR/$tfile)
15995
15996         # Verify punch worked.
15997         (( blocks == want_blocks_after )) ||
15998                 error "punch failed: blocks $blocks != $want_blocks_after"
15999
16000         (( size == want_size_before )) ||
16001                 error "punch failed: size $size != $want_size_before"
16002
16003         # Verify there is hole in file
16004         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16005         # precomputed md5sum
16006         local expect="4a9a834a2db02452929c0a348273b4aa"
16007
16008         cksum=($(md5sum $DIR/$tfile))
16009         [[ "${cksum[0]}" == "$expect" ]] ||
16010                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16011
16012         # Start second sub-case for fallocate punch.
16013         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16014         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16015                 error "dd failed for bs 4096 and count 5"
16016
16017         # Punch range less than block size will have no change in block count
16018         want_blocks_after=40  # 512 sized blocks
16019
16020         # Punch overlaps two blocks and less than blocksize
16021         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16022                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16023         size=$(stat -c '%s' $DIR/$tfile)
16024         blocks=$(stat -c '%b' $DIR/$tfile)
16025
16026         # Verify punch worked.
16027         (( blocks == want_blocks_after )) ||
16028                 error "punch failed: blocks $blocks != $want_blocks_after"
16029
16030         (( size == want_size_before )) ||
16031                 error "punch failed: size $size != $want_size_before"
16032
16033         # Verify if range is really zero'ed out. We expect Zeros.
16034         # precomputed md5sum
16035         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16036         cksum=($(md5sum $DIR/$tfile))
16037         [[ "${cksum[0]}" == "$expect" ]] ||
16038                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16039 }
16040 run_test 150f "Verify fallocate punch functionality"
16041
16042 test_150g() {
16043         local space
16044         local size
16045         local blocks
16046         local blocks_after
16047         local size_after
16048         local BS=4096 # Block size in bytes
16049
16050         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16051                 skip "need at least 2.14.0 for fallocate punch"
16052
16053         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16054                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16055         fi
16056
16057         check_set_fallocate_or_skip
16058         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16059
16060         if [[ "x$DOM" == "xyes" ]]; then
16061                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16062                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16063         else
16064                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16065                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16066         fi
16067
16068         # Get 100MB per OST of the available space to reduce run time
16069         # else 60% of the available space if we are running SLOW tests
16070         if [ $SLOW == "no" ]; then
16071                 space=$((1024 * 100 * OSTCOUNT))
16072         else
16073                 # Find OST with Minimum Size
16074                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16075                         sort -un | head -1)
16076                 echo "min size OST: $space"
16077                 space=$(((space * 60)/100 * OSTCOUNT))
16078         fi
16079         # space in 1k units, round to 4k blocks
16080         local blkcount=$((space * 1024 / $BS))
16081
16082         echo "Verify fallocate punch: Very large Range"
16083         fallocate -l${space}k $DIR/$tfile ||
16084                 error "fallocate ${space}k $DIR/$tfile failed"
16085         # write 1M at the end, start and in the middle
16086         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16087                 error "dd failed: bs $BS count 256"
16088         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16089                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16090         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16091                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16092
16093         # Gather stats.
16094         size=$(stat -c '%s' $DIR/$tfile)
16095
16096         # gather punch length.
16097         local punch_size=$((size - (BS * 2)))
16098
16099         echo "punch_size = $punch_size"
16100         echo "size - punch_size: $((size - punch_size))"
16101         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16102
16103         # Call fallocate to punch all except 2 blocks. We leave the
16104         # first and the last block
16105         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16106         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16107                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16108
16109         size_after=$(stat -c '%s' $DIR/$tfile)
16110         blocks_after=$(stat -c '%b' $DIR/$tfile)
16111
16112         # Verify punch worked.
16113         # Size should be kept
16114         (( size == size_after )) ||
16115                 error "punch failed: size $size != $size_after"
16116
16117         # two 4k data blocks to remain plus possible 1 extra extent block
16118         (( blocks_after <= ((BS / 512) * 3) )) ||
16119                 error "too many blocks remains: $blocks_after"
16120
16121         # Verify that file has hole between the first and the last blocks
16122         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16123         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16124
16125         echo "Hole at [$hole_start, $hole_end)"
16126         (( hole_start == BS )) ||
16127                 error "no hole at offset $BS after punch"
16128
16129         (( hole_end == BS + punch_size )) ||
16130                 error "data at offset $hole_end < $((BS + punch_size))"
16131 }
16132 run_test 150g "Verify fallocate punch on large range"
16133
16134 test_150h() {
16135         local file=$DIR/$tfile
16136         local size
16137
16138         check_set_fallocate_or_skip
16139         statx_supported || skip_env "Test must be statx() syscall supported"
16140
16141         # fallocate() does not update the size information on the MDT
16142         fallocate -l 16K $file || error "failed to fallocate $file"
16143         cancel_lru_locks $OSC
16144         # STATX with cached-always mode will not send glimpse RPCs to OST,
16145         # it uses the caching attrs on the client side as much as possible.
16146         size=$($STATX --cached=always -c %s $file)
16147         [ $size == 16384 ] ||
16148                 error "size after fallocate() is $size, expected 16384"
16149 }
16150 run_test 150h "Verify extend fallocate updates the file size"
16151
16152 #LU-2902 roc_hit was not able to read all values from lproc
16153 function roc_hit_init() {
16154         local list=$(comma_list $(osts_nodes))
16155         local dir=$DIR/$tdir-check
16156         local file=$dir/$tfile
16157         local BEFORE
16158         local AFTER
16159         local idx
16160
16161         test_mkdir $dir
16162         #use setstripe to do a write to every ost
16163         for i in $(seq 0 $((OSTCOUNT-1))); do
16164                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16165                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16166                 idx=$(printf %04x $i)
16167                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16168                         awk '$1 == "cache_access" {sum += $7}
16169                                 END { printf("%0.0f", sum) }')
16170
16171                 cancel_lru_locks osc
16172                 cat $file >/dev/null
16173
16174                 AFTER=$(get_osd_param $list *OST*$idx stats |
16175                         awk '$1 == "cache_access" {sum += $7}
16176                                 END { printf("%0.0f", sum) }')
16177
16178                 echo BEFORE:$BEFORE AFTER:$AFTER
16179                 if ! let "AFTER - BEFORE == 4"; then
16180                         rm -rf $dir
16181                         error "roc_hit is not safe to use"
16182                 fi
16183                 rm $file
16184         done
16185
16186         rm -rf $dir
16187 }
16188
16189 function roc_hit() {
16190         local list=$(comma_list $(osts_nodes))
16191         echo $(get_osd_param $list '' stats |
16192                 awk '$1 == "cache_hit" {sum += $7}
16193                         END { printf("%0.0f", sum) }')
16194 }
16195
16196 function set_cache() {
16197         local on=1
16198
16199         if [ "$2" == "off" ]; then
16200                 on=0;
16201         fi
16202         local list=$(comma_list $(osts_nodes))
16203         set_osd_param $list '' $1_cache_enable $on
16204
16205         cancel_lru_locks osc
16206 }
16207
16208 test_151() {
16209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16210         remote_ost_nodsh && skip "remote OST with nodsh"
16211         (( CLIENT_VERSION == OST1_VERSION )) ||
16212                 skip "LU-13081: no interop testing for OSS cache"
16213
16214         local CPAGES=3
16215         local list=$(comma_list $(osts_nodes))
16216
16217         # check whether obdfilter is cache capable at all
16218         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16219                 skip "not cache-capable obdfilter"
16220         fi
16221
16222         # check cache is enabled on all obdfilters
16223         if get_osd_param $list '' read_cache_enable | grep 0; then
16224                 skip "oss cache is disabled"
16225         fi
16226
16227         set_osd_param $list '' writethrough_cache_enable 1
16228
16229         # check write cache is enabled on all obdfilters
16230         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16231                 skip "oss write cache is NOT enabled"
16232         fi
16233
16234         roc_hit_init
16235
16236         #define OBD_FAIL_OBD_NO_LRU  0x609
16237         do_nodes $list $LCTL set_param fail_loc=0x609
16238
16239         # pages should be in the case right after write
16240         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16241                 error "dd failed"
16242
16243         local BEFORE=$(roc_hit)
16244         cancel_lru_locks osc
16245         cat $DIR/$tfile >/dev/null
16246         local AFTER=$(roc_hit)
16247
16248         do_nodes $list $LCTL set_param fail_loc=0
16249
16250         if ! let "AFTER - BEFORE == CPAGES"; then
16251                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16252         fi
16253
16254         cancel_lru_locks osc
16255         # invalidates OST cache
16256         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16257         set_osd_param $list '' read_cache_enable 0
16258         cat $DIR/$tfile >/dev/null
16259
16260         # now data shouldn't be found in the cache
16261         BEFORE=$(roc_hit)
16262         cancel_lru_locks osc
16263         cat $DIR/$tfile >/dev/null
16264         AFTER=$(roc_hit)
16265         if let "AFTER - BEFORE != 0"; then
16266                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16267         fi
16268
16269         set_osd_param $list '' read_cache_enable 1
16270         rm -f $DIR/$tfile
16271 }
16272 run_test 151 "test cache on oss and controls ==============================="
16273
16274 test_152() {
16275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16276
16277         local TF="$TMP/$tfile"
16278
16279         # simulate ENOMEM during write
16280 #define OBD_FAIL_OST_NOMEM      0x226
16281         lctl set_param fail_loc=0x80000226
16282         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16283         cp $TF $DIR/$tfile
16284         sync || error "sync failed"
16285         lctl set_param fail_loc=0
16286
16287         # discard client's cache
16288         cancel_lru_locks osc
16289
16290         # simulate ENOMEM during read
16291         lctl set_param fail_loc=0x80000226
16292         cmp $TF $DIR/$tfile || error "cmp failed"
16293         lctl set_param fail_loc=0
16294
16295         rm -f $TF
16296 }
16297 run_test 152 "test read/write with enomem ============================"
16298
16299 test_153() {
16300         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16301 }
16302 run_test 153 "test if fdatasync does not crash ======================="
16303
16304 dot_lustre_fid_permission_check() {
16305         local fid=$1
16306         local ffid=$MOUNT/.lustre/fid/$fid
16307         local test_dir=$2
16308
16309         echo "stat fid $fid"
16310         stat $ffid || error "stat $ffid failed."
16311         echo "touch fid $fid"
16312         touch $ffid || error "touch $ffid failed."
16313         echo "write to fid $fid"
16314         cat /etc/hosts > $ffid || error "write $ffid failed."
16315         echo "read fid $fid"
16316         diff /etc/hosts $ffid || error "read $ffid failed."
16317         echo "append write to fid $fid"
16318         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16319         echo "rename fid $fid"
16320         mv $ffid $test_dir/$tfile.1 &&
16321                 error "rename $ffid to $tfile.1 should fail."
16322         touch $test_dir/$tfile.1
16323         mv $test_dir/$tfile.1 $ffid &&
16324                 error "rename $tfile.1 to $ffid should fail."
16325         rm -f $test_dir/$tfile.1
16326         echo "truncate fid $fid"
16327         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16328         echo "link fid $fid"
16329         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16330         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16331                 id $USER0 || skip_env "missing user $USER0"
16332                 echo "setfacl fid $fid"
16333                 setfacl -R -m u:$USER0:rwx $ffid ||
16334                         error "setfacl $ffid failed"
16335                 echo "getfacl fid $fid"
16336                 getfacl $ffid || error "getfacl $ffid failed."
16337         fi
16338         echo "unlink fid $fid"
16339         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16340         echo "mknod fid $fid"
16341         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16342
16343         fid=[0xf00000400:0x1:0x0]
16344         ffid=$MOUNT/.lustre/fid/$fid
16345
16346         echo "stat non-exist fid $fid"
16347         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16348         echo "write to non-exist fid $fid"
16349         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16350         echo "link new fid $fid"
16351         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16352
16353         mkdir -p $test_dir/$tdir
16354         touch $test_dir/$tdir/$tfile
16355         fid=$($LFS path2fid $test_dir/$tdir)
16356         rc=$?
16357         [ $rc -ne 0 ] &&
16358                 error "error: could not get fid for $test_dir/$dir/$tfile."
16359
16360         ffid=$MOUNT/.lustre/fid/$fid
16361
16362         echo "ls $fid"
16363         ls $ffid || error "ls $ffid failed."
16364         echo "touch $fid/$tfile.1"
16365         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16366
16367         echo "touch $MOUNT/.lustre/fid/$tfile"
16368         touch $MOUNT/.lustre/fid/$tfile && \
16369                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16370
16371         echo "setxattr to $MOUNT/.lustre/fid"
16372         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16373
16374         echo "listxattr for $MOUNT/.lustre/fid"
16375         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16376
16377         echo "delxattr from $MOUNT/.lustre/fid"
16378         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16379
16380         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16381         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16382                 error "touch invalid fid should fail."
16383
16384         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16385         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16386                 error "touch non-normal fid should fail."
16387
16388         echo "rename $tdir to $MOUNT/.lustre/fid"
16389         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16390                 error "rename to $MOUNT/.lustre/fid should fail."
16391
16392         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16393         then            # LU-3547
16394                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16395                 local new_obf_mode=777
16396
16397                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16398                 chmod $new_obf_mode $DIR/.lustre/fid ||
16399                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16400
16401                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16402                 [ $obf_mode -eq $new_obf_mode ] ||
16403                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16404
16405                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16406                 chmod $old_obf_mode $DIR/.lustre/fid ||
16407                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16408         fi
16409
16410         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16411         fid=$($LFS path2fid $test_dir/$tfile-2)
16412
16413         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16414         then # LU-5424
16415                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16416                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16417                         error "create lov data thru .lustre failed"
16418         fi
16419         echo "cp /etc/passwd $test_dir/$tfile-2"
16420         cp /etc/passwd $test_dir/$tfile-2 ||
16421                 error "copy to $test_dir/$tfile-2 failed."
16422         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16423         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16424                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16425
16426         rm -rf $test_dir/tfile.lnk
16427         rm -rf $test_dir/$tfile-2
16428 }
16429
16430 test_154A() {
16431         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16432                 skip "Need MDS version at least 2.4.1"
16433
16434         local tf=$DIR/$tfile
16435         touch $tf
16436
16437         local fid=$($LFS path2fid $tf)
16438         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16439
16440         # check that we get the same pathname back
16441         local rootpath
16442         local found
16443         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16444                 echo "$rootpath $fid"
16445                 found=$($LFS fid2path $rootpath "$fid")
16446                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16447                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16448         done
16449
16450         # check wrong root path format
16451         rootpath=$MOUNT"_wrong"
16452         found=$($LFS fid2path $rootpath "$fid")
16453         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16454 }
16455 run_test 154A "lfs path2fid and fid2path basic checks"
16456
16457 test_154B() {
16458         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16459                 skip "Need MDS version at least 2.4.1"
16460
16461         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16462         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16463         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16464         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16465
16466         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16467         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16468
16469         # check that we get the same pathname
16470         echo "PFID: $PFID, name: $name"
16471         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16472         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16473         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16474                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16475
16476         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16477 }
16478 run_test 154B "verify the ll_decode_linkea tool"
16479
16480 test_154a() {
16481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16482         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16483         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16484                 skip "Need MDS version at least 2.2.51"
16485         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16486
16487         cp /etc/hosts $DIR/$tfile
16488
16489         fid=$($LFS path2fid $DIR/$tfile)
16490         rc=$?
16491         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16492
16493         dot_lustre_fid_permission_check "$fid" $DIR ||
16494                 error "dot lustre permission check $fid failed"
16495
16496         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16497
16498         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16499
16500         touch $MOUNT/.lustre/file &&
16501                 error "creation is not allowed under .lustre"
16502
16503         mkdir $MOUNT/.lustre/dir &&
16504                 error "mkdir is not allowed under .lustre"
16505
16506         rm -rf $DIR/$tfile
16507 }
16508 run_test 154a "Open-by-FID"
16509
16510 test_154b() {
16511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16512         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16513         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16514         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16515                 skip "Need MDS version at least 2.2.51"
16516
16517         local remote_dir=$DIR/$tdir/remote_dir
16518         local MDTIDX=1
16519         local rc=0
16520
16521         mkdir -p $DIR/$tdir
16522         $LFS mkdir -i $MDTIDX $remote_dir ||
16523                 error "create remote directory failed"
16524
16525         cp /etc/hosts $remote_dir/$tfile
16526
16527         fid=$($LFS path2fid $remote_dir/$tfile)
16528         rc=$?
16529         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16530
16531         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16532                 error "dot lustre permission check $fid failed"
16533         rm -rf $DIR/$tdir
16534 }
16535 run_test 154b "Open-by-FID for remote directory"
16536
16537 test_154c() {
16538         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16539                 skip "Need MDS version at least 2.4.1"
16540
16541         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16542         local FID1=$($LFS path2fid $DIR/$tfile.1)
16543         local FID2=$($LFS path2fid $DIR/$tfile.2)
16544         local FID3=$($LFS path2fid $DIR/$tfile.3)
16545
16546         local N=1
16547         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16548                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16549                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16550                 local want=FID$N
16551                 [ "$FID" = "${!want}" ] ||
16552                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16553                 N=$((N + 1))
16554         done
16555
16556         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16557         do
16558                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16559                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16560                 N=$((N + 1))
16561         done
16562 }
16563 run_test 154c "lfs path2fid and fid2path multiple arguments"
16564
16565 test_154d() {
16566         remote_mds_nodsh && skip "remote MDS with nodsh"
16567         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16568                 skip "Need MDS version at least 2.5.53"
16569
16570         if remote_mds; then
16571                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16572         else
16573                 nid="0@lo"
16574         fi
16575         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16576         local fd
16577         local cmd
16578
16579         rm -f $DIR/$tfile
16580         touch $DIR/$tfile
16581
16582         local fid=$($LFS path2fid $DIR/$tfile)
16583         # Open the file
16584         fd=$(free_fd)
16585         cmd="exec $fd<$DIR/$tfile"
16586         eval $cmd
16587         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16588         echo "$fid_list" | grep "$fid"
16589         rc=$?
16590
16591         cmd="exec $fd>/dev/null"
16592         eval $cmd
16593         if [ $rc -ne 0 ]; then
16594                 error "FID $fid not found in open files list $fid_list"
16595         fi
16596 }
16597 run_test 154d "Verify open file fid"
16598
16599 test_154e()
16600 {
16601         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16602                 skip "Need MDS version at least 2.6.50"
16603
16604         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16605                 error ".lustre returned by readdir"
16606         fi
16607 }
16608 run_test 154e ".lustre is not returned by readdir"
16609
16610 test_154f() {
16611         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16612
16613         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16614         mkdir_on_mdt0 $DIR/$tdir
16615         # test dirs inherit from its stripe
16616         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16617         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16618         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16619         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16620         touch $DIR/f
16621
16622         # get fid of parents
16623         local FID0=$($LFS path2fid $DIR/$tdir)
16624         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16625         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16626         local FID3=$($LFS path2fid $DIR)
16627
16628         # check that path2fid --parents returns expected <parent_fid>/name
16629         # 1) test for a directory (single parent)
16630         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16631         [ "$parent" == "$FID0/foo1" ] ||
16632                 error "expected parent: $FID0/foo1, got: $parent"
16633
16634         # 2) test for a file with nlink > 1 (multiple parents)
16635         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16636         echo "$parent" | grep -F "$FID1/$tfile" ||
16637                 error "$FID1/$tfile not returned in parent list"
16638         echo "$parent" | grep -F "$FID2/link" ||
16639                 error "$FID2/link not returned in parent list"
16640
16641         # 3) get parent by fid
16642         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16643         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16644         echo "$parent" | grep -F "$FID1/$tfile" ||
16645                 error "$FID1/$tfile not returned in parent list (by fid)"
16646         echo "$parent" | grep -F "$FID2/link" ||
16647                 error "$FID2/link not returned in parent list (by fid)"
16648
16649         # 4) test for entry in root directory
16650         parent=$($LFS path2fid --parents $DIR/f)
16651         echo "$parent" | grep -F "$FID3/f" ||
16652                 error "$FID3/f not returned in parent list"
16653
16654         # 5) test it on root directory
16655         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16656                 error "$MOUNT should not have parents"
16657
16658         # enable xattr caching and check that linkea is correctly updated
16659         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16660         save_lustre_params client "llite.*.xattr_cache" > $save
16661         lctl set_param llite.*.xattr_cache 1
16662
16663         # 6.1) linkea update on rename
16664         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16665
16666         # get parents by fid
16667         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16668         # foo1 should no longer be returned in parent list
16669         echo "$parent" | grep -F "$FID1" &&
16670                 error "$FID1 should no longer be in parent list"
16671         # the new path should appear
16672         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16673                 error "$FID2/$tfile.moved is not in parent list"
16674
16675         # 6.2) linkea update on unlink
16676         rm -f $DIR/$tdir/foo2/link
16677         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16678         # foo2/link should no longer be returned in parent list
16679         echo "$parent" | grep -F "$FID2/link" &&
16680                 error "$FID2/link should no longer be in parent list"
16681         true
16682
16683         rm -f $DIR/f
16684         restore_lustre_params < $save
16685         rm -f $save
16686 }
16687 run_test 154f "get parent fids by reading link ea"
16688
16689 test_154g()
16690 {
16691         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16692            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16693                 skip "Need MDS version at least 2.6.92"
16694
16695         mkdir_on_mdt0 $DIR/$tdir
16696         llapi_fid_test -d $DIR/$tdir
16697 }
16698 run_test 154g "various llapi FID tests"
16699
16700 test_154h()
16701 {
16702         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16703                 skip "Need client at least version 2.15.55.1"
16704
16705         # Create an empty file
16706         touch $DIR/$tfile
16707
16708         # Get FID (interactive mode) and save under $TMP/$tfile.log
16709         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16710                 path2fid $DIR/$tfile
16711         EOF
16712
16713         fid=$(cat $TMP/$tfile.log)
16714         # $fid should not be empty
16715         [[ ! -z $fid ]] || error "FID is empty"
16716         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16717 }
16718 run_test 154h "Verify interactive path2fid"
16719
16720 test_155_small_load() {
16721     local temp=$TMP/$tfile
16722     local file=$DIR/$tfile
16723
16724     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16725         error "dd of=$temp bs=6096 count=1 failed"
16726     cp $temp $file
16727     cancel_lru_locks $OSC
16728     cmp $temp $file || error "$temp $file differ"
16729
16730     $TRUNCATE $temp 6000
16731     $TRUNCATE $file 6000
16732     cmp $temp $file || error "$temp $file differ (truncate1)"
16733
16734     echo "12345" >>$temp
16735     echo "12345" >>$file
16736     cmp $temp $file || error "$temp $file differ (append1)"
16737
16738     echo "12345" >>$temp
16739     echo "12345" >>$file
16740     cmp $temp $file || error "$temp $file differ (append2)"
16741
16742     rm -f $temp $file
16743     true
16744 }
16745
16746 test_155_big_load() {
16747         remote_ost_nodsh && skip "remote OST with nodsh"
16748
16749         local temp=$TMP/$tfile
16750         local file=$DIR/$tfile
16751
16752         free_min_max
16753         local cache_size=$(do_facet ost$((MAXI+1)) \
16754                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16755
16756         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16757         # pre-set value
16758         if [ -z "$cache_size" ]; then
16759                 cache_size=256
16760         fi
16761         local large_file_size=$((cache_size * 2))
16762
16763         echo "OSS cache size: $cache_size KB"
16764         echo "Large file size: $large_file_size KB"
16765
16766         [ $MAXV -le $large_file_size ] &&
16767                 skip_env "max available OST size needs > $large_file_size KB"
16768
16769         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16770
16771         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16772                 error "dd of=$temp bs=$large_file_size count=1k failed"
16773         cp $temp $file
16774         ls -lh $temp $file
16775         cancel_lru_locks osc
16776         cmp $temp $file || error "$temp $file differ"
16777
16778         rm -f $temp $file
16779         true
16780 }
16781
16782 save_writethrough() {
16783         local facets=$(get_facets OST)
16784
16785         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16786 }
16787
16788 test_155a() {
16789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16790
16791         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16792
16793         save_writethrough $p
16794
16795         set_cache read on
16796         set_cache writethrough on
16797         test_155_small_load
16798         restore_lustre_params < $p
16799         rm -f $p
16800 }
16801 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16802
16803 test_155b() {
16804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16805
16806         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16807
16808         save_writethrough $p
16809
16810         set_cache read on
16811         set_cache writethrough off
16812         test_155_small_load
16813         restore_lustre_params < $p
16814         rm -f $p
16815 }
16816 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16817
16818 test_155c() {
16819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16820
16821         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16822
16823         save_writethrough $p
16824
16825         set_cache read off
16826         set_cache writethrough on
16827         test_155_small_load
16828         restore_lustre_params < $p
16829         rm -f $p
16830 }
16831 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16832
16833 test_155d() {
16834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16835
16836         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16837
16838         save_writethrough $p
16839
16840         set_cache read off
16841         set_cache writethrough off
16842         test_155_small_load
16843         restore_lustre_params < $p
16844         rm -f $p
16845 }
16846 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16847
16848 test_155e() {
16849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16850
16851         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16852
16853         save_writethrough $p
16854
16855         set_cache read on
16856         set_cache writethrough on
16857         test_155_big_load
16858         restore_lustre_params < $p
16859         rm -f $p
16860 }
16861 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16862
16863 test_155f() {
16864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16865
16866         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16867
16868         save_writethrough $p
16869
16870         set_cache read on
16871         set_cache writethrough off
16872         test_155_big_load
16873         restore_lustre_params < $p
16874         rm -f $p
16875 }
16876 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16877
16878 test_155g() {
16879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16880
16881         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16882
16883         save_writethrough $p
16884
16885         set_cache read off
16886         set_cache writethrough on
16887         test_155_big_load
16888         restore_lustre_params < $p
16889         rm -f $p
16890 }
16891 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16892
16893 test_155h() {
16894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16895
16896         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16897
16898         save_writethrough $p
16899
16900         set_cache read off
16901         set_cache writethrough off
16902         test_155_big_load
16903         restore_lustre_params < $p
16904         rm -f $p
16905 }
16906 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16907
16908 test_156() {
16909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16910         remote_ost_nodsh && skip "remote OST with nodsh"
16911         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16912                 skip "stats not implemented on old servers"
16913         [ "$ost1_FSTYPE" = "zfs" ] &&
16914                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16915         (( CLIENT_VERSION == OST1_VERSION )) ||
16916                 skip "LU-13081: no interop testing for OSS cache"
16917
16918         local CPAGES=3
16919         local BEFORE
16920         local AFTER
16921         local file="$DIR/$tfile"
16922         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16923
16924         save_writethrough $p
16925         roc_hit_init
16926
16927         log "Turn on read and write cache"
16928         set_cache read on
16929         set_cache writethrough on
16930
16931         log "Write data and read it back."
16932         log "Read should be satisfied from the cache."
16933         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16934         BEFORE=$(roc_hit)
16935         cancel_lru_locks osc
16936         cat $file >/dev/null
16937         AFTER=$(roc_hit)
16938         if ! let "AFTER - BEFORE == CPAGES"; then
16939                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16940         else
16941                 log "cache hits: before: $BEFORE, after: $AFTER"
16942         fi
16943
16944         log "Read again; it should be satisfied from the cache."
16945         BEFORE=$AFTER
16946         cancel_lru_locks osc
16947         cat $file >/dev/null
16948         AFTER=$(roc_hit)
16949         if ! let "AFTER - BEFORE == CPAGES"; then
16950                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16951         else
16952                 log "cache hits:: before: $BEFORE, after: $AFTER"
16953         fi
16954
16955         log "Turn off the read cache and turn on the write cache"
16956         set_cache read off
16957         set_cache writethrough on
16958
16959         log "Read again; it should be satisfied from the cache."
16960         BEFORE=$(roc_hit)
16961         cancel_lru_locks osc
16962         cat $file >/dev/null
16963         AFTER=$(roc_hit)
16964         if ! let "AFTER - BEFORE == CPAGES"; then
16965                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16966         else
16967                 log "cache hits:: before: $BEFORE, after: $AFTER"
16968         fi
16969
16970         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16971                 # > 2.12.56 uses pagecache if cached
16972                 log "Read again; it should not be satisfied from the cache."
16973                 BEFORE=$AFTER
16974                 cancel_lru_locks osc
16975                 cat $file >/dev/null
16976                 AFTER=$(roc_hit)
16977                 if ! let "AFTER - BEFORE == 0"; then
16978                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16979                 else
16980                         log "cache hits:: before: $BEFORE, after: $AFTER"
16981                 fi
16982         fi
16983
16984         log "Write data and read it back."
16985         log "Read should be satisfied from the cache."
16986         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16987         BEFORE=$(roc_hit)
16988         cancel_lru_locks osc
16989         cat $file >/dev/null
16990         AFTER=$(roc_hit)
16991         if ! let "AFTER - BEFORE == CPAGES"; then
16992                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16993         else
16994                 log "cache hits:: before: $BEFORE, after: $AFTER"
16995         fi
16996
16997         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16998                 # > 2.12.56 uses pagecache if cached
16999                 log "Read again; it should not be satisfied from the cache."
17000                 BEFORE=$AFTER
17001                 cancel_lru_locks osc
17002                 cat $file >/dev/null
17003                 AFTER=$(roc_hit)
17004                 if ! let "AFTER - BEFORE == 0"; then
17005                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17006                 else
17007                         log "cache hits:: before: $BEFORE, after: $AFTER"
17008                 fi
17009         fi
17010
17011         log "Turn off read and write cache"
17012         set_cache read off
17013         set_cache writethrough off
17014
17015         log "Write data and read it back"
17016         log "It should not be satisfied from the cache."
17017         rm -f $file
17018         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17019         cancel_lru_locks osc
17020         BEFORE=$(roc_hit)
17021         cat $file >/dev/null
17022         AFTER=$(roc_hit)
17023         if ! let "AFTER - BEFORE == 0"; then
17024                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17025         else
17026                 log "cache hits:: before: $BEFORE, after: $AFTER"
17027         fi
17028
17029         log "Turn on the read cache and turn off the write cache"
17030         set_cache read on
17031         set_cache writethrough off
17032
17033         log "Write data and read it back"
17034         log "It should not be satisfied from the cache."
17035         rm -f $file
17036         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17037         BEFORE=$(roc_hit)
17038         cancel_lru_locks osc
17039         cat $file >/dev/null
17040         AFTER=$(roc_hit)
17041         if ! let "AFTER - BEFORE == 0"; then
17042                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17043         else
17044                 log "cache hits:: before: $BEFORE, after: $AFTER"
17045         fi
17046
17047         log "Read again; it should be satisfied from the cache."
17048         BEFORE=$(roc_hit)
17049         cancel_lru_locks osc
17050         cat $file >/dev/null
17051         AFTER=$(roc_hit)
17052         if ! let "AFTER - BEFORE == CPAGES"; then
17053                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17054         else
17055                 log "cache hits:: before: $BEFORE, after: $AFTER"
17056         fi
17057
17058         restore_lustre_params < $p
17059         rm -f $p $file
17060 }
17061 run_test 156 "Verification of tunables"
17062
17063 test_160a() {
17064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17065         remote_mds_nodsh && skip "remote MDS with nodsh"
17066         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17067                 skip "Need MDS version at least 2.2.0"
17068
17069         changelog_register || error "changelog_register failed"
17070         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17071         changelog_users $SINGLEMDS | grep -q $cl_user ||
17072                 error "User $cl_user not found in changelog_users"
17073
17074         mkdir_on_mdt0 $DIR/$tdir
17075
17076         # change something
17077         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17078         changelog_clear 0 || error "changelog_clear failed"
17079         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17080         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17081         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17082         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17083         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17084         rm $DIR/$tdir/pics/desktop.jpg
17085
17086         echo "verifying changelog mask"
17087         changelog_chmask "-MKDIR"
17088         changelog_chmask "-CLOSE"
17089
17090         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17091         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17092
17093         changelog_chmask "+MKDIR"
17094         changelog_chmask "+CLOSE"
17095
17096         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17097         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17098
17099         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17100         CLOSES=$(changelog_dump | grep -c "CLOSE")
17101         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17102         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17103
17104         # verify contents
17105         echo "verifying target fid"
17106         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17107         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17108         [ "$fidc" == "$fidf" ] ||
17109                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17110         echo "verifying parent fid"
17111         # The FID returned from the Changelog may be the directory shard on
17112         # a different MDT, and not the FID returned by path2fid on the parent.
17113         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17114         # since this is what will matter when recreating this file in the tree.
17115         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17116         local pathp=$($LFS fid2path $MOUNT "$fidp")
17117         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17118                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17119
17120         echo "getting records for $cl_user"
17121         changelog_users $SINGLEMDS
17122         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17123         local nclr=3
17124         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17125                 error "changelog_clear failed"
17126         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17127         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17128         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17129                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17130
17131         local min0_rec=$(changelog_users $SINGLEMDS |
17132                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17133         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17134                           awk '{ print $1; exit; }')
17135
17136         changelog_dump | tail -n 5
17137         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17138         [ $first_rec == $((min0_rec + 1)) ] ||
17139                 error "first index should be $min0_rec + 1 not $first_rec"
17140
17141         # LU-3446 changelog index reset on MDT restart
17142         local cur_rec1=$(changelog_users $SINGLEMDS |
17143                          awk '/^current.index:/ { print $NF }')
17144         changelog_clear 0 ||
17145                 error "clear all changelog records for $cl_user failed"
17146         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17147         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17148                 error "Fail to start $SINGLEMDS"
17149         local cur_rec2=$(changelog_users $SINGLEMDS |
17150                          awk '/^current.index:/ { print $NF }')
17151         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17152         [ $cur_rec1 == $cur_rec2 ] ||
17153                 error "current index should be $cur_rec1 not $cur_rec2"
17154
17155         echo "verifying users from this test are deregistered"
17156         changelog_deregister || error "changelog_deregister failed"
17157         changelog_users $SINGLEMDS | grep -q $cl_user &&
17158                 error "User '$cl_user' still in changelog_users"
17159
17160         # lctl get_param -n mdd.*.changelog_users
17161         # current_index: 144
17162         # ID    index (idle seconds)
17163         # cl3   144   (2) mask=<list>
17164         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17165                 # this is the normal case where all users were deregistered
17166                 # make sure no new records are added when no users are present
17167                 local last_rec1=$(changelog_users $SINGLEMDS |
17168                                   awk '/^current.index:/ { print $NF }')
17169                 touch $DIR/$tdir/chloe
17170                 local last_rec2=$(changelog_users $SINGLEMDS |
17171                                   awk '/^current.index:/ { print $NF }')
17172                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17173                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17174         else
17175                 # any changelog users must be leftovers from a previous test
17176                 changelog_users $SINGLEMDS
17177                 echo "other changelog users; can't verify off"
17178         fi
17179 }
17180 run_test 160a "changelog sanity"
17181
17182 test_160b() { # LU-3587
17183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17184         remote_mds_nodsh && skip "remote MDS with nodsh"
17185         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17186                 skip "Need MDS version at least 2.2.0"
17187
17188         changelog_register || error "changelog_register failed"
17189         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17190         changelog_users $SINGLEMDS | grep -q $cl_user ||
17191                 error "User '$cl_user' not found in changelog_users"
17192
17193         local longname1=$(str_repeat a 255)
17194         local longname2=$(str_repeat b 255)
17195
17196         cd $DIR
17197         echo "creating very long named file"
17198         touch $longname1 || error "create of '$longname1' failed"
17199         echo "renaming very long named file"
17200         mv $longname1 $longname2
17201
17202         changelog_dump | grep RENME | tail -n 5
17203         rm -f $longname2
17204 }
17205 run_test 160b "Verify that very long rename doesn't crash in changelog"
17206
17207 test_160c() {
17208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17209         remote_mds_nodsh && skip "remote MDS with nodsh"
17210
17211         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17212                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17213                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17214                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17215
17216         local rc=0
17217
17218         # Registration step
17219         changelog_register || error "changelog_register failed"
17220
17221         rm -rf $DIR/$tdir
17222         mkdir -p $DIR/$tdir
17223         $MCREATE $DIR/$tdir/foo_160c
17224         changelog_chmask "-TRUNC"
17225         $TRUNCATE $DIR/$tdir/foo_160c 200
17226         changelog_chmask "+TRUNC"
17227         $TRUNCATE $DIR/$tdir/foo_160c 199
17228         changelog_dump | tail -n 5
17229         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17230         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17231 }
17232 run_test 160c "verify that changelog log catch the truncate event"
17233
17234 test_160d() {
17235         remote_mds_nodsh && skip "remote MDS with nodsh"
17236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17238         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17239                 skip "Need MDS version at least 2.7.60"
17240
17241         # Registration step
17242         changelog_register || error "changelog_register failed"
17243
17244         mkdir -p $DIR/$tdir/migrate_dir
17245         changelog_clear 0 || error "changelog_clear failed"
17246
17247         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17248         changelog_dump | tail -n 5
17249         local migrates=$(changelog_dump | grep -c "MIGRT")
17250         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17251 }
17252 run_test 160d "verify that changelog log catch the migrate event"
17253
17254 test_160e() {
17255         remote_mds_nodsh && skip "remote MDS with nodsh"
17256
17257         # Create a user
17258         changelog_register || error "changelog_register failed"
17259
17260         local MDT0=$(facet_svc $SINGLEMDS)
17261         local rc
17262
17263         # No user (expect fail)
17264         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17265         rc=$?
17266         if [ $rc -eq 0 ]; then
17267                 error "Should fail without user"
17268         elif [ $rc -ne 4 ]; then
17269                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17270         fi
17271
17272         # Delete a future user (expect fail)
17273         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17274         rc=$?
17275         if [ $rc -eq 0 ]; then
17276                 error "Deleted non-existant user cl77"
17277         elif [ $rc -ne 2 ]; then
17278                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17279         fi
17280
17281         # Clear to a bad index (1 billion should be safe)
17282         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17283         rc=$?
17284
17285         if [ $rc -eq 0 ]; then
17286                 error "Successfully cleared to invalid CL index"
17287         elif [ $rc -ne 22 ]; then
17288                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17289         fi
17290 }
17291 run_test 160e "changelog negative testing (should return errors)"
17292
17293 test_160f() {
17294         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17295         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17296                 skip "Need MDS version at least 2.10.56"
17297
17298         local mdts=$(comma_list $(mdts_nodes))
17299
17300         # Create a user
17301         changelog_register || error "first changelog_register failed"
17302         changelog_register || error "second changelog_register failed"
17303         local cl_users
17304         declare -A cl_user1
17305         declare -A cl_user2
17306         local user_rec1
17307         local user_rec2
17308         local i
17309
17310         # generate some changelog records to accumulate on each MDT
17311         # use all_char because created files should be evenly distributed
17312         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17313                 error "test_mkdir $tdir failed"
17314         log "$(date +%s): creating first files"
17315         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17316                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17317                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17318         done
17319
17320         # check changelogs have been generated
17321         local start=$SECONDS
17322         local idle_time=$((MDSCOUNT * 5 + 5))
17323         local nbcl=$(changelog_dump | wc -l)
17324         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17325
17326         for param in "changelog_max_idle_time=$idle_time" \
17327                      "changelog_gc=1" \
17328                      "changelog_min_gc_interval=2" \
17329                      "changelog_min_free_cat_entries=3"; do
17330                 local MDT0=$(facet_svc $SINGLEMDS)
17331                 local var="${param%=*}"
17332                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17333
17334                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17335                 do_nodes $mdts $LCTL set_param mdd.*.$param
17336         done
17337
17338         # force cl_user2 to be idle (1st part), but also cancel the
17339         # cl_user1 records so that it is not evicted later in the test.
17340         local sleep1=$((idle_time / 2))
17341         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17342         sleep $sleep1
17343
17344         # simulate changelog catalog almost full
17345         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17346         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17347
17348         for i in $(seq $MDSCOUNT); do
17349                 cl_users=(${CL_USERS[mds$i]})
17350                 cl_user1[mds$i]="${cl_users[0]}"
17351                 cl_user2[mds$i]="${cl_users[1]}"
17352
17353                 [ -n "${cl_user1[mds$i]}" ] ||
17354                         error "mds$i: no user registered"
17355                 [ -n "${cl_user2[mds$i]}" ] ||
17356                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17357
17358                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17359                 [ -n "$user_rec1" ] ||
17360                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17361                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17362                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17363                 [ -n "$user_rec2" ] ||
17364                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17365                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17366                      "$user_rec1 + 2 == $user_rec2"
17367                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17368                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17369                               "$user_rec1 + 2, but is $user_rec2"
17370                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17371                 [ -n "$user_rec2" ] ||
17372                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17373                 [ $user_rec1 == $user_rec2 ] ||
17374                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17375                               "$user_rec1, but is $user_rec2"
17376         done
17377
17378         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17379         local sleep2=$((idle_time - (SECONDS - start) + 1))
17380         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17381         sleep $sleep2
17382
17383         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17384         # cl_user1 should be OK because it recently processed records.
17385         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17386         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17387                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17388                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17389         done
17390
17391         # ensure gc thread is done
17392         for i in $(mdts_nodes); do
17393                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17394                         error "$i: GC-thread not done"
17395         done
17396
17397         local first_rec
17398         for (( i = 1; i <= MDSCOUNT; i++ )); do
17399                 # check cl_user1 still registered
17400                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17401                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17402                 # check cl_user2 unregistered
17403                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17404                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17405
17406                 # check changelogs are present and starting at $user_rec1 + 1
17407                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17408                 [ -n "$user_rec1" ] ||
17409                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17410                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17411                             awk '{ print $1; exit; }')
17412
17413                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17414                 [ $((user_rec1 + 1)) == $first_rec ] ||
17415                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17416         done
17417 }
17418 run_test 160f "changelog garbage collect (timestamped users)"
17419
17420 test_160g() {
17421         remote_mds_nodsh && skip "remote MDS with nodsh"
17422         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17423                 skip "Need MDS version at least 2.14.55"
17424
17425         local mdts=$(comma_list $(mdts_nodes))
17426
17427         # Create a user
17428         changelog_register || error "first changelog_register failed"
17429         changelog_register || error "second changelog_register failed"
17430         local cl_users
17431         declare -A cl_user1
17432         declare -A cl_user2
17433         local user_rec1
17434         local user_rec2
17435         local i
17436
17437         # generate some changelog records to accumulate on each MDT
17438         # use all_char because created files should be evenly distributed
17439         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17440                 error "test_mkdir $tdir failed"
17441         for ((i = 0; i < MDSCOUNT; i++)); do
17442                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17443                         error "create $DIR/$tdir/d$i.1 failed"
17444         done
17445
17446         # check changelogs have been generated
17447         local nbcl=$(changelog_dump | wc -l)
17448         (( $nbcl > 0 )) || error "no changelogs found"
17449
17450         # reduce the max_idle_indexes value to make sure we exceed it
17451         for param in "changelog_max_idle_indexes=2" \
17452                      "changelog_gc=1" \
17453                      "changelog_min_gc_interval=2"; do
17454                 local MDT0=$(facet_svc $SINGLEMDS)
17455                 local var="${param%=*}"
17456                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17457
17458                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17459                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17460                         error "unable to set mdd.*.$param"
17461         done
17462
17463         local start=$SECONDS
17464         for i in $(seq $MDSCOUNT); do
17465                 cl_users=(${CL_USERS[mds$i]})
17466                 cl_user1[mds$i]="${cl_users[0]}"
17467                 cl_user2[mds$i]="${cl_users[1]}"
17468
17469                 [ -n "${cl_user1[mds$i]}" ] ||
17470                         error "mds$i: user1 is not registered"
17471                 [ -n "${cl_user2[mds$i]}" ] ||
17472                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17473
17474                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17475                 [ -n "$user_rec1" ] ||
17476                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17477                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17478                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17479                 [ -n "$user_rec2" ] ||
17480                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17481                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17482                      "$user_rec1 + 2 == $user_rec2"
17483                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17484                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17485                               "expected $user_rec1 + 2, but is $user_rec2"
17486                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17487                 [ -n "$user_rec2" ] ||
17488                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17489                 [ $user_rec1 == $user_rec2 ] ||
17490                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17491                               "expected $user_rec1, but is $user_rec2"
17492         done
17493
17494         # ensure we are past the previous changelog_min_gc_interval set above
17495         local sleep2=$((start + 2 - SECONDS))
17496         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17497         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17498         # cl_user1 should be OK because it recently processed records.
17499         for ((i = 0; i < MDSCOUNT; i++)); do
17500                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17501                         error "create $DIR/$tdir/d$i.3 failed"
17502         done
17503
17504         # ensure gc thread is done
17505         for i in $(mdts_nodes); do
17506                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17507                         error "$i: GC-thread not done"
17508         done
17509
17510         local first_rec
17511         for (( i = 1; i <= MDSCOUNT; i++ )); do
17512                 # check cl_user1 still registered
17513                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17514                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17515                 # check cl_user2 unregistered
17516                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17517                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17518
17519                 # check changelogs are present and starting at $user_rec1 + 1
17520                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17521                 [ -n "$user_rec1" ] ||
17522                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17523                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17524                             awk '{ print $1; exit; }')
17525
17526                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17527                 [ $((user_rec1 + 1)) == $first_rec ] ||
17528                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17529         done
17530 }
17531 run_test 160g "changelog garbage collect on idle records"
17532
17533 test_160h() {
17534         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17535         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17536                 skip "Need MDS version at least 2.10.56"
17537
17538         local mdts=$(comma_list $(mdts_nodes))
17539
17540         # Create a user
17541         changelog_register || error "first changelog_register failed"
17542         changelog_register || error "second changelog_register failed"
17543         local cl_users
17544         declare -A cl_user1
17545         declare -A cl_user2
17546         local user_rec1
17547         local user_rec2
17548         local i
17549
17550         # generate some changelog records to accumulate on each MDT
17551         # use all_char because created files should be evenly distributed
17552         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17553                 error "test_mkdir $tdir failed"
17554         for ((i = 0; i < MDSCOUNT; i++)); do
17555                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17556                         error "create $DIR/$tdir/d$i.1 failed"
17557         done
17558
17559         # check changelogs have been generated
17560         local nbcl=$(changelog_dump | wc -l)
17561         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17562
17563         for param in "changelog_max_idle_time=10" \
17564                      "changelog_gc=1" \
17565                      "changelog_min_gc_interval=2"; do
17566                 local MDT0=$(facet_svc $SINGLEMDS)
17567                 local var="${param%=*}"
17568                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17569
17570                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17571                 do_nodes $mdts $LCTL set_param mdd.*.$param
17572         done
17573
17574         # force cl_user2 to be idle (1st part)
17575         sleep 9
17576
17577         for i in $(seq $MDSCOUNT); do
17578                 cl_users=(${CL_USERS[mds$i]})
17579                 cl_user1[mds$i]="${cl_users[0]}"
17580                 cl_user2[mds$i]="${cl_users[1]}"
17581
17582                 [ -n "${cl_user1[mds$i]}" ] ||
17583                         error "mds$i: no user registered"
17584                 [ -n "${cl_user2[mds$i]}" ] ||
17585                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17586
17587                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17588                 [ -n "$user_rec1" ] ||
17589                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17590                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17591                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17592                 [ -n "$user_rec2" ] ||
17593                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17594                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17595                      "$user_rec1 + 2 == $user_rec2"
17596                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17597                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17598                               "$user_rec1 + 2, but is $user_rec2"
17599                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17600                 [ -n "$user_rec2" ] ||
17601                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17602                 [ $user_rec1 == $user_rec2 ] ||
17603                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17604                               "$user_rec1, but is $user_rec2"
17605         done
17606
17607         # force cl_user2 to be idle (2nd part) and to reach
17608         # changelog_max_idle_time
17609         sleep 2
17610
17611         # force each GC-thread start and block then
17612         # one per MDT/MDD, set fail_val accordingly
17613         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17614         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17615
17616         # generate more changelogs to trigger fail_loc
17617         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17618                 error "create $DIR/$tdir/${tfile}bis failed"
17619
17620         # stop MDT to stop GC-thread, should be done in back-ground as it will
17621         # block waiting for the thread to be released and exit
17622         declare -A stop_pids
17623         for i in $(seq $MDSCOUNT); do
17624                 stop mds$i &
17625                 stop_pids[mds$i]=$!
17626         done
17627
17628         for i in $(mdts_nodes); do
17629                 local facet
17630                 local nb=0
17631                 local facets=$(facets_up_on_host $i)
17632
17633                 for facet in ${facets//,/ }; do
17634                         if [[ $facet == mds* ]]; then
17635                                 nb=$((nb + 1))
17636                         fi
17637                 done
17638                 # ensure each MDS's gc threads are still present and all in "R"
17639                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17640                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17641                         error "$i: expected $nb GC-thread"
17642                 wait_update $i \
17643                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17644                         "R" 20 ||
17645                         error "$i: GC-thread not found in R-state"
17646                 # check umounts of each MDT on MDS have reached kthread_stop()
17647                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17648                         error "$i: expected $nb umount"
17649                 wait_update $i \
17650                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17651                         error "$i: umount not found in D-state"
17652         done
17653
17654         # release all GC-threads
17655         do_nodes $mdts $LCTL set_param fail_loc=0
17656
17657         # wait for MDT stop to complete
17658         for i in $(seq $MDSCOUNT); do
17659                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17660         done
17661
17662         # XXX
17663         # may try to check if any orphan changelog records are present
17664         # via ldiskfs/zfs and llog_reader...
17665
17666         # re-start/mount MDTs
17667         for i in $(seq $MDSCOUNT); do
17668                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17669                         error "Fail to start mds$i"
17670         done
17671
17672         local first_rec
17673         for i in $(seq $MDSCOUNT); do
17674                 # check cl_user1 still registered
17675                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17677                 # check cl_user2 unregistered
17678                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17679                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17680
17681                 # check changelogs are present and starting at $user_rec1 + 1
17682                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17683                 [ -n "$user_rec1" ] ||
17684                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17685                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17686                             awk '{ print $1; exit; }')
17687
17688                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17689                 [ $((user_rec1 + 1)) == $first_rec ] ||
17690                         error "mds$i: first index should be $user_rec1 + 1, " \
17691                               "but is $first_rec"
17692         done
17693 }
17694 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17695               "during mount"
17696
17697 test_160i() {
17698
17699         local mdts=$(comma_list $(mdts_nodes))
17700
17701         changelog_register || error "first changelog_register failed"
17702
17703         # generate some changelog records to accumulate on each MDT
17704         # use all_char because created files should be evenly distributed
17705         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17706                 error "test_mkdir $tdir failed"
17707         for ((i = 0; i < MDSCOUNT; i++)); do
17708                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17709                         error "create $DIR/$tdir/d$i.1 failed"
17710         done
17711
17712         # check changelogs have been generated
17713         local nbcl=$(changelog_dump | wc -l)
17714         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17715
17716         # simulate race between register and unregister
17717         # XXX as fail_loc is set per-MDS, with DNE configs the race
17718         # simulation will only occur for one MDT per MDS and for the
17719         # others the normal race scenario will take place
17720         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17721         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17722         do_nodes $mdts $LCTL set_param fail_val=1
17723
17724         # unregister 1st user
17725         changelog_deregister &
17726         local pid1=$!
17727         # wait some time for deregister work to reach race rdv
17728         sleep 2
17729         # register 2nd user
17730         changelog_register || error "2nd user register failed"
17731
17732         wait $pid1 || error "1st user deregister failed"
17733
17734         local i
17735         local last_rec
17736         declare -A LAST_REC
17737         for i in $(seq $MDSCOUNT); do
17738                 if changelog_users mds$i | grep "^cl"; then
17739                         # make sure new records are added with one user present
17740                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17741                                           awk '/^current.index:/ { print $NF }')
17742                 else
17743                         error "mds$i has no user registered"
17744                 fi
17745         done
17746
17747         # generate more changelog records to accumulate on each MDT
17748         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17749                 error "create $DIR/$tdir/${tfile}bis failed"
17750
17751         for i in $(seq $MDSCOUNT); do
17752                 last_rec=$(changelog_users $SINGLEMDS |
17753                            awk '/^current.index:/ { print $NF }')
17754                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17755                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17756                         error "changelogs are off on mds$i"
17757         done
17758 }
17759 run_test 160i "changelog user register/unregister race"
17760
17761 test_160j() {
17762         remote_mds_nodsh && skip "remote MDS with nodsh"
17763         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17764                 skip "Need MDS version at least 2.12.56"
17765
17766         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17767         stack_trap "umount $MOUNT2" EXIT
17768
17769         changelog_register || error "first changelog_register failed"
17770         stack_trap "changelog_deregister" EXIT
17771
17772         # generate some changelog
17773         # use all_char because created files should be evenly distributed
17774         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17775                 error "mkdir $tdir failed"
17776         for ((i = 0; i < MDSCOUNT; i++)); do
17777                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17778                         error "create $DIR/$tdir/d$i.1 failed"
17779         done
17780
17781         # open the changelog device
17782         exec 3>/dev/changelog-$FSNAME-MDT0000
17783         stack_trap "exec 3>&-" EXIT
17784         exec 4</dev/changelog-$FSNAME-MDT0000
17785         stack_trap "exec 4<&-" EXIT
17786
17787         # umount the first lustre mount
17788         umount $MOUNT
17789         stack_trap "mount_client $MOUNT" EXIT
17790
17791         # read changelog, which may or may not fail, but should not crash
17792         cat <&4 >/dev/null
17793
17794         # clear changelog
17795         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17796         changelog_users $SINGLEMDS | grep -q $cl_user ||
17797                 error "User $cl_user not found in changelog_users"
17798
17799         printf 'clear:'$cl_user':0' >&3
17800 }
17801 run_test 160j "client can be umounted while its chanangelog is being used"
17802
17803 test_160k() {
17804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17805         remote_mds_nodsh && skip "remote MDS with nodsh"
17806
17807         mkdir -p $DIR/$tdir/1/1
17808
17809         changelog_register || error "changelog_register failed"
17810         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17811
17812         changelog_users $SINGLEMDS | grep -q $cl_user ||
17813                 error "User '$cl_user' not found in changelog_users"
17814 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17815         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17816         rmdir $DIR/$tdir/1/1 & sleep 1
17817         mkdir $DIR/$tdir/2
17818         touch $DIR/$tdir/2/2
17819         rm -rf $DIR/$tdir/2
17820
17821         wait
17822         sleep 4
17823
17824         changelog_dump | grep rmdir || error "rmdir not recorded"
17825 }
17826 run_test 160k "Verify that changelog records are not lost"
17827
17828 # Verifies that a file passed as a parameter has recently had an operation
17829 # performed on it that has generated an MTIME changelog which contains the
17830 # correct parent FID. As files might reside on a different MDT from the
17831 # parent directory in DNE configurations, the FIDs are translated to paths
17832 # before being compared, which should be identical
17833 compare_mtime_changelog() {
17834         local file="${1}"
17835         local mdtidx
17836         local mtime
17837         local cl_fid
17838         local pdir
17839         local dir
17840
17841         mdtidx=$($LFS getstripe --mdt-index $file)
17842         mdtidx=$(printf "%04x" $mdtidx)
17843
17844         # Obtain the parent FID from the MTIME changelog
17845         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17846         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17847
17848         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17849         [ -z "$cl_fid" ] && error "parent FID not present"
17850
17851         # Verify that the path for the parent FID is the same as the path for
17852         # the test directory
17853         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17854
17855         dir=$(dirname $1)
17856
17857         [[ "${pdir%/}" == "$dir" ]] ||
17858                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17859 }
17860
17861 test_160l() {
17862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17863
17864         remote_mds_nodsh && skip "remote MDS with nodsh"
17865         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17866                 skip "Need MDS version at least 2.13.55"
17867
17868         local cl_user
17869
17870         changelog_register || error "changelog_register failed"
17871         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17872
17873         changelog_users $SINGLEMDS | grep -q $cl_user ||
17874                 error "User '$cl_user' not found in changelog_users"
17875
17876         # Clear some types so that MTIME changelogs are generated
17877         changelog_chmask "-CREAT"
17878         changelog_chmask "-CLOSE"
17879
17880         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17881
17882         # Test CL_MTIME during setattr
17883         touch $DIR/$tdir/$tfile
17884         compare_mtime_changelog $DIR/$tdir/$tfile
17885
17886         # Test CL_MTIME during close
17887         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17888         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17889 }
17890 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17891
17892 test_160m() {
17893         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17894         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17895                 skip "Need MDS version at least 2.14.51"
17896         local cl_users
17897         local cl_user1
17898         local cl_user2
17899         local pid1
17900
17901         # Create a user
17902         changelog_register || error "first changelog_register failed"
17903         changelog_register || error "second changelog_register failed"
17904
17905         cl_users=(${CL_USERS[mds1]})
17906         cl_user1="${cl_users[0]}"
17907         cl_user2="${cl_users[1]}"
17908         # generate some changelog records to accumulate on MDT0
17909         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17910         createmany -m $DIR/$tdir/$tfile 50 ||
17911                 error "create $DIR/$tdir/$tfile failed"
17912         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17913         rm -f $DIR/$tdir
17914
17915         # check changelogs have been generated
17916         local nbcl=$(changelog_dump | wc -l)
17917         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17918
17919 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17920         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17921
17922         __changelog_clear mds1 $cl_user1 +10
17923         __changelog_clear mds1 $cl_user2 0 &
17924         pid1=$!
17925         sleep 2
17926         __changelog_clear mds1 $cl_user1 0 ||
17927                 error "fail to cancel record for $cl_user1"
17928         wait $pid1
17929         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17930 }
17931 run_test 160m "Changelog clear race"
17932
17933 test_160n() {
17934         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17935         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17936                 skip "Need MDS version at least 2.14.51"
17937         local cl_users
17938         local cl_user1
17939         local cl_user2
17940         local pid1
17941         local first_rec
17942         local last_rec=0
17943
17944         # Create a user
17945         changelog_register || error "first changelog_register failed"
17946
17947         cl_users=(${CL_USERS[mds1]})
17948         cl_user1="${cl_users[0]}"
17949
17950         # generate some changelog records to accumulate on MDT0
17951         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17952         first_rec=$(changelog_users $SINGLEMDS |
17953                         awk '/^current.index:/ { print $NF }')
17954         while (( last_rec < (( first_rec + 65000)) )); do
17955                 createmany -m $DIR/$tdir/$tfile 10000 ||
17956                         error "create $DIR/$tdir/$tfile failed"
17957
17958                 for i in $(seq 0 10000); do
17959                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17960                                 > /dev/null
17961                 done
17962
17963                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17964                         error "unlinkmany failed unlink"
17965                 last_rec=$(changelog_users $SINGLEMDS |
17966                         awk '/^current.index:/ { print $NF }')
17967                 echo last record $last_rec
17968                 (( last_rec == 0 )) && error "no changelog found"
17969         done
17970
17971 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17972         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17973
17974         __changelog_clear mds1 $cl_user1 0 &
17975         pid1=$!
17976         sleep 2
17977         __changelog_clear mds1 $cl_user1 0 ||
17978                 error "fail to cancel record for $cl_user1"
17979         wait $pid1
17980         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17981 }
17982 run_test 160n "Changelog destroy race"
17983
17984 test_160o() {
17985         local mdt="$(facet_svc $SINGLEMDS)"
17986
17987         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17988         remote_mds_nodsh && skip "remote MDS with nodsh"
17989         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17990                 skip "Need MDS version at least 2.14.52"
17991
17992         changelog_register --user test_160o -m unlnk+close+open ||
17993                 error "changelog_register failed"
17994
17995         do_facet $SINGLEMDS $LCTL --device $mdt \
17996                                 changelog_register -u "Tt3_-#" &&
17997                 error "bad symbols in name should fail"
17998
17999         do_facet $SINGLEMDS $LCTL --device $mdt \
18000                                 changelog_register -u test_160o &&
18001                 error "the same name registration should fail"
18002
18003         do_facet $SINGLEMDS $LCTL --device $mdt \
18004                         changelog_register -u test_160toolongname &&
18005                 error "too long name registration should fail"
18006
18007         changelog_chmask "MARK+HSM"
18008         lctl get_param mdd.*.changelog*mask
18009         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18010         changelog_users $SINGLEMDS | grep -q $cl_user ||
18011                 error "User $cl_user not found in changelog_users"
18012         #verify username
18013         echo $cl_user | grep -q test_160o ||
18014                 error "User $cl_user has no specific name 'test160o'"
18015
18016         # change something
18017         changelog_clear 0 || error "changelog_clear failed"
18018         # generate some changelog records to accumulate on MDT0
18019         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18020         touch $DIR/$tdir/$tfile                 # open 1
18021
18022         OPENS=$(changelog_dump | grep -c "OPEN")
18023         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18024
18025         # must be no MKDIR it wasn't set as user mask
18026         MKDIR=$(changelog_dump | grep -c "MKDIR")
18027         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18028
18029         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18030                                 mdd.$mdt.changelog_current_mask -n)
18031         # register maskless user
18032         changelog_register || error "changelog_register failed"
18033         # effective mask should be not changed because it is not minimal
18034         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18035                                 mdd.$mdt.changelog_current_mask -n)
18036         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18037         # set server mask to minimal value
18038         changelog_chmask "MARK"
18039         # check effective mask again, should be treated as DEFMASK now
18040         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18041                                 mdd.$mdt.changelog_current_mask -n)
18042         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18043
18044         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18045                 # set server mask back to some value
18046                 changelog_chmask "CLOSE,UNLNK"
18047                 # check effective mask again, should not remain as DEFMASK
18048                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18049                                 mdd.$mdt.changelog_current_mask -n)
18050                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18051         fi
18052
18053         do_facet $SINGLEMDS $LCTL --device $mdt \
18054                                 changelog_deregister -u test_160o ||
18055                 error "cannot deregister by name"
18056 }
18057 run_test 160o "changelog user name and mask"
18058
18059 test_160p() {
18060         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18061         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18062                 skip "Need MDS version at least 2.14.51"
18063         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18064         local cl_users
18065         local cl_user1
18066         local entry_count
18067
18068         # Create a user
18069         changelog_register || error "first changelog_register failed"
18070
18071         cl_users=(${CL_USERS[mds1]})
18072         cl_user1="${cl_users[0]}"
18073
18074         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18075         createmany -m $DIR/$tdir/$tfile 50 ||
18076                 error "create $DIR/$tdir/$tfile failed"
18077         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18078         rm -rf $DIR/$tdir
18079
18080         # check changelogs have been generated
18081         entry_count=$(changelog_dump | wc -l)
18082         ((entry_count != 0)) || error "no changelog entries found"
18083
18084         # remove changelog_users and check that orphan entries are removed
18085         stop mds1
18086         local dev=$(mdsdevname 1)
18087         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18088         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18089         entry_count=$(changelog_dump | wc -l)
18090         ((entry_count == 0)) ||
18091                 error "found $entry_count changelog entries, expected none"
18092 }
18093 run_test 160p "Changelog orphan cleanup with no users"
18094
18095 test_160q() {
18096         local mdt="$(facet_svc $SINGLEMDS)"
18097         local clu
18098
18099         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18100         remote_mds_nodsh && skip "remote MDS with nodsh"
18101         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18102                 skip "Need MDS version at least 2.14.54"
18103
18104         # set server mask to minimal value like server init does
18105         changelog_chmask "MARK"
18106         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18107                 error "changelog_register failed"
18108         # check effective mask again, should be treated as DEFMASK now
18109         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18110                                 mdd.$mdt.changelog_current_mask -n)
18111         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18112                 error "changelog_deregister failed"
18113         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18114 }
18115 run_test 160q "changelog effective mask is DEFMASK if not set"
18116
18117 test_160s() {
18118         remote_mds_nodsh && skip "remote MDS with nodsh"
18119         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18120                 skip "Need MDS version at least 2.14.55"
18121
18122         local mdts=$(comma_list $(mdts_nodes))
18123
18124         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18125         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18126                                        fail_val=$((24 * 3600 * 10))
18127
18128         # Create a user which is 10 days old
18129         changelog_register || error "first changelog_register failed"
18130         local cl_users
18131         declare -A cl_user1
18132         local i
18133
18134         # generate some changelog records to accumulate on each MDT
18135         # use all_char because created files should be evenly distributed
18136         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18137                 error "test_mkdir $tdir failed"
18138         for ((i = 0; i < MDSCOUNT; i++)); do
18139                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18140                         error "create $DIR/$tdir/d$i.1 failed"
18141         done
18142
18143         # check changelogs have been generated
18144         local nbcl=$(changelog_dump | wc -l)
18145         (( nbcl > 0 )) || error "no changelogs found"
18146
18147         # reduce the max_idle_indexes value to make sure we exceed it
18148         for param in "changelog_max_idle_indexes=2097446912" \
18149                      "changelog_max_idle_time=2592000" \
18150                      "changelog_gc=1" \
18151                      "changelog_min_gc_interval=2"; do
18152                 local MDT0=$(facet_svc $SINGLEMDS)
18153                 local var="${param%=*}"
18154                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18155
18156                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18157                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18158                         error "unable to set mdd.*.$param"
18159         done
18160
18161         local start=$SECONDS
18162         for i in $(seq $MDSCOUNT); do
18163                 cl_users=(${CL_USERS[mds$i]})
18164                 cl_user1[mds$i]="${cl_users[0]}"
18165
18166                 [[ -n "${cl_user1[mds$i]}" ]] ||
18167                         error "mds$i: no user registered"
18168         done
18169
18170         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18171         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18172
18173         # ensure we are past the previous changelog_min_gc_interval set above
18174         local sleep2=$((start + 2 - SECONDS))
18175         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18176
18177         # Generate one more changelog to trigger GC
18178         for ((i = 0; i < MDSCOUNT; i++)); do
18179                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18180                         error "create $DIR/$tdir/d$i.3 failed"
18181         done
18182
18183         # ensure gc thread is done
18184         for node in $(mdts_nodes); do
18185                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18186                         error "$node: GC-thread not done"
18187         done
18188
18189         do_nodes $mdts $LCTL set_param fail_loc=0
18190
18191         for (( i = 1; i <= MDSCOUNT; i++ )); do
18192                 # check cl_user1 is purged
18193                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18194                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18195         done
18196         return 0
18197 }
18198 run_test 160s "changelog garbage collect on idle records * time"
18199
18200 test_160t() {
18201         remote_mds_nodsh && skip "remote MDS with nodsh"
18202         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18203                 skip "Need MDS version at least 2.15.50"
18204
18205         local MDT0=$(facet_svc $SINGLEMDS)
18206         local cl_users
18207         local cl_user1
18208         local cl_user2
18209         local start
18210
18211         changelog_register --user user1 -m all ||
18212                 error "user1 failed to register"
18213
18214         mkdir_on_mdt0 $DIR/$tdir
18215         # create default overstripe to maximize changelog size
18216         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18217         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18218         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18219
18220         # user2 consumes less records so less space
18221         changelog_register --user user2 || error "user2 failed to register"
18222         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18223         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18224
18225         # check changelogs have been generated
18226         local nbcl=$(changelog_dump | wc -l)
18227         (( nbcl > 0 )) || error "no changelogs found"
18228
18229         # reduce the changelog_min_gc_interval to force check
18230         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18231                 local var="${param%=*}"
18232                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18233
18234                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18235                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18236                         error "unable to set mdd.*.$param"
18237         done
18238
18239         start=$SECONDS
18240         cl_users=(${CL_USERS[mds1]})
18241         cl_user1="${cl_users[0]}"
18242         cl_user2="${cl_users[1]}"
18243
18244         [[ -n $cl_user1 ]] ||
18245                 error "mds1: user #1 isn't registered"
18246         [[ -n $cl_user2 ]] ||
18247                 error "mds1: user #2 isn't registered"
18248
18249         # ensure we are past the previous changelog_min_gc_interval set above
18250         local sleep2=$((start + 2 - SECONDS))
18251         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18252
18253         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18254         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18255                         fail_val=$(((llog_size1 + llog_size2) / 2))
18256
18257         # Generate more changelog to trigger GC
18258         createmany -o $DIR/$tdir/u3_ 4 ||
18259                 error "create failed for more files"
18260
18261         # ensure gc thread is done
18262         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18263                 error "mds1: GC-thread not done"
18264
18265         do_facet mds1 $LCTL set_param fail_loc=0
18266
18267         # check cl_user1 is purged
18268         changelog_users mds1 | grep -q "$cl_user1" &&
18269                 error "User $cl_user1 is registered"
18270         # check cl_user2 is not purged
18271         changelog_users mds1 | grep -q "$cl_user2" ||
18272                 error "User $cl_user2 is not registered"
18273 }
18274 run_test 160t "changelog garbage collect on lack of space"
18275
18276 test_161a() {
18277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18278
18279         test_mkdir -c1 $DIR/$tdir
18280         cp /etc/hosts $DIR/$tdir/$tfile
18281         test_mkdir -c1 $DIR/$tdir/foo1
18282         test_mkdir -c1 $DIR/$tdir/foo2
18283         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18284         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18285         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18286         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18287         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18288         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18289                 $LFS fid2path $DIR $FID
18290                 error "bad link ea"
18291         fi
18292         # middle
18293         rm $DIR/$tdir/foo2/zachary
18294         # last
18295         rm $DIR/$tdir/foo2/thor
18296         # first
18297         rm $DIR/$tdir/$tfile
18298         # rename
18299         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18300         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18301                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18302         rm $DIR/$tdir/foo2/maggie
18303
18304         # overflow the EA
18305         local longname=$tfile.avg_len_is_thirty_two_
18306         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18307                 error_noexit 'failed to unlink many hardlinks'" EXIT
18308         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18309                 error "failed to hardlink many files"
18310         links=$($LFS fid2path $DIR $FID | wc -l)
18311         echo -n "${links}/1000 links in link EA"
18312         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18313 }
18314 run_test 161a "link ea sanity"
18315
18316 test_161b() {
18317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18318         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18319
18320         local MDTIDX=1
18321         local remote_dir=$DIR/$tdir/remote_dir
18322
18323         mkdir -p $DIR/$tdir
18324         $LFS mkdir -i $MDTIDX $remote_dir ||
18325                 error "create remote directory failed"
18326
18327         cp /etc/hosts $remote_dir/$tfile
18328         mkdir -p $remote_dir/foo1
18329         mkdir -p $remote_dir/foo2
18330         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18331         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18332         ln $remote_dir/$tfile $remote_dir/foo1/luna
18333         ln $remote_dir/$tfile $remote_dir/foo2/thor
18334
18335         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18336                      tr -d ']')
18337         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18338                 $LFS fid2path $DIR $FID
18339                 error "bad link ea"
18340         fi
18341         # middle
18342         rm $remote_dir/foo2/zachary
18343         # last
18344         rm $remote_dir/foo2/thor
18345         # first
18346         rm $remote_dir/$tfile
18347         # rename
18348         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18349         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18350         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18351                 $LFS fid2path $DIR $FID
18352                 error "bad link rename"
18353         fi
18354         rm $remote_dir/foo2/maggie
18355
18356         # overflow the EA
18357         local longname=filename_avg_len_is_thirty_two_
18358         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18359                 error "failed to hardlink many files"
18360         links=$($LFS fid2path $DIR $FID | wc -l)
18361         echo -n "${links}/1000 links in link EA"
18362         [[ ${links} -gt 60 ]] ||
18363                 error "expected at least 60 links in link EA"
18364         unlinkmany $remote_dir/foo2/$longname 1000 ||
18365         error "failed to unlink many hardlinks"
18366 }
18367 run_test 161b "link ea sanity under remote directory"
18368
18369 test_161c() {
18370         remote_mds_nodsh && skip "remote MDS with nodsh"
18371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18372         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18373                 skip "Need MDS version at least 2.1.5"
18374
18375         # define CLF_RENAME_LAST 0x0001
18376         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18377         changelog_register || error "changelog_register failed"
18378
18379         rm -rf $DIR/$tdir
18380         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18381         touch $DIR/$tdir/foo_161c
18382         touch $DIR/$tdir/bar_161c
18383         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18384         changelog_dump | grep RENME | tail -n 5
18385         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18386         changelog_clear 0 || error "changelog_clear failed"
18387         if [ x$flags != "x0x1" ]; then
18388                 error "flag $flags is not 0x1"
18389         fi
18390
18391         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18392         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18393         touch $DIR/$tdir/foo_161c
18394         touch $DIR/$tdir/bar_161c
18395         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18396         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18397         changelog_dump | grep RENME | tail -n 5
18398         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18399         changelog_clear 0 || error "changelog_clear failed"
18400         if [ x$flags != "x0x0" ]; then
18401                 error "flag $flags is not 0x0"
18402         fi
18403         echo "rename overwrite a target having nlink > 1," \
18404                 "changelog record has flags of $flags"
18405
18406         # rename doesn't overwrite a target (changelog flag 0x0)
18407         touch $DIR/$tdir/foo_161c
18408         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18409         changelog_dump | grep RENME | tail -n 5
18410         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18411         changelog_clear 0 || error "changelog_clear failed"
18412         if [ x$flags != "x0x0" ]; then
18413                 error "flag $flags is not 0x0"
18414         fi
18415         echo "rename doesn't overwrite a target," \
18416                 "changelog record has flags of $flags"
18417
18418         # define CLF_UNLINK_LAST 0x0001
18419         # unlink a file having nlink = 1 (changelog flag 0x1)
18420         rm -f $DIR/$tdir/foo2_161c
18421         changelog_dump | grep UNLNK | tail -n 5
18422         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18423         changelog_clear 0 || error "changelog_clear failed"
18424         if [ x$flags != "x0x1" ]; then
18425                 error "flag $flags is not 0x1"
18426         fi
18427         echo "unlink a file having nlink = 1," \
18428                 "changelog record has flags of $flags"
18429
18430         # unlink a file having nlink > 1 (changelog flag 0x0)
18431         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18432         rm -f $DIR/$tdir/foobar_161c
18433         changelog_dump | grep UNLNK | tail -n 5
18434         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18435         changelog_clear 0 || error "changelog_clear failed"
18436         if [ x$flags != "x0x0" ]; then
18437                 error "flag $flags is not 0x0"
18438         fi
18439         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18440 }
18441 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18442
18443 test_161d() {
18444         remote_mds_nodsh && skip "remote MDS with nodsh"
18445         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18446
18447         local pid
18448         local fid
18449
18450         changelog_register || error "changelog_register failed"
18451
18452         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18453         # interfer with $MOUNT/.lustre/fid/ access
18454         mkdir $DIR/$tdir
18455         [[ $? -eq 0 ]] || error "mkdir failed"
18456
18457         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18458         $LCTL set_param fail_loc=0x8000140c
18459         # 5s pause
18460         $LCTL set_param fail_val=5
18461
18462         # create file
18463         echo foofoo > $DIR/$tdir/$tfile &
18464         pid=$!
18465
18466         # wait for create to be delayed
18467         sleep 2
18468
18469         ps -p $pid
18470         [[ $? -eq 0 ]] || error "create should be blocked"
18471
18472         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18473         stack_trap "rm -f $tempfile"
18474         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18475         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18476         # some delay may occur during ChangeLog publishing and file read just
18477         # above, that could allow file write to happen finally
18478         [[ -s $tempfile ]] && echo "file should be empty"
18479
18480         $LCTL set_param fail_loc=0
18481
18482         wait $pid
18483         [[ $? -eq 0 ]] || error "create failed"
18484 }
18485 run_test 161d "create with concurrent .lustre/fid access"
18486
18487 check_path() {
18488         local expected="$1"
18489         shift
18490         local fid="$2"
18491
18492         local path
18493         path=$($LFS fid2path "$@")
18494         local rc=$?
18495
18496         if [ $rc -ne 0 ]; then
18497                 error "path looked up of '$expected' failed: rc=$rc"
18498         elif [ "$path" != "$expected" ]; then
18499                 error "path looked up '$path' instead of '$expected'"
18500         else
18501                 echo "FID '$fid' resolves to path '$path' as expected"
18502         fi
18503 }
18504
18505 test_162a() { # was test_162
18506         test_mkdir -p -c1 $DIR/$tdir/d2
18507         touch $DIR/$tdir/d2/$tfile
18508         touch $DIR/$tdir/d2/x1
18509         touch $DIR/$tdir/d2/x2
18510         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18511         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18512         # regular file
18513         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18514         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18515
18516         # softlink
18517         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18518         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18519         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18520
18521         # softlink to wrong file
18522         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18523         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18524         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18525
18526         # hardlink
18527         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18528         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18529         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18530         # fid2path dir/fsname should both work
18531         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18532         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18533
18534         # hardlink count: check that there are 2 links
18535         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18536         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18537
18538         # hardlink indexing: remove the first link
18539         rm $DIR/$tdir/d2/p/q/r/hlink
18540         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18541 }
18542 run_test 162a "path lookup sanity"
18543
18544 test_162b() {
18545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18546         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18547
18548         mkdir $DIR/$tdir
18549         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18550                                 error "create striped dir failed"
18551
18552         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18553                                         tail -n 1 | awk '{print $2}')
18554         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18555
18556         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18557         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18558
18559         # regular file
18560         for ((i=0;i<5;i++)); do
18561                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18562                         error "get fid for f$i failed"
18563                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18564
18565                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18566                         error "get fid for d$i failed"
18567                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18568         done
18569
18570         return 0
18571 }
18572 run_test 162b "striped directory path lookup sanity"
18573
18574 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18575 test_162c() {
18576         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18577                 skip "Need MDS version at least 2.7.51"
18578
18579         local lpath=$tdir.local
18580         local rpath=$tdir.remote
18581
18582         test_mkdir $DIR/$lpath
18583         test_mkdir $DIR/$rpath
18584
18585         for ((i = 0; i <= 101; i++)); do
18586                 lpath="$lpath/$i"
18587                 mkdir $DIR/$lpath
18588                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18589                         error "get fid for local directory $DIR/$lpath failed"
18590                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18591
18592                 rpath="$rpath/$i"
18593                 test_mkdir $DIR/$rpath
18594                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18595                         error "get fid for remote directory $DIR/$rpath failed"
18596                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18597         done
18598
18599         return 0
18600 }
18601 run_test 162c "fid2path works with paths 100 or more directories deep"
18602
18603 oalr_event_count() {
18604         local event="${1}"
18605         local trace="${2}"
18606
18607         awk -v name="${FSNAME}-OST0000" \
18608             -v event="${event}" \
18609             '$1 == "TRACE" && $2 == event && $3 == name' \
18610             "${trace}" |
18611         wc -l
18612 }
18613
18614 oalr_expect_event_count() {
18615         local event="${1}"
18616         local trace="${2}"
18617         local expect="${3}"
18618         local count
18619
18620         count=$(oalr_event_count "${event}" "${trace}")
18621         if ((count == expect)); then
18622                 return 0
18623         fi
18624
18625         error_noexit "${event} event count was '${count}', expected ${expect}"
18626         cat "${trace}" >&2
18627         exit 1
18628 }
18629
18630 cleanup_165() {
18631         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18632         stop ost1
18633         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18634 }
18635
18636 setup_165() {
18637         sync # Flush previous IOs so we can count log entries.
18638         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18639         stack_trap cleanup_165 EXIT
18640 }
18641
18642 test_165a() {
18643         local trace="/tmp/${tfile}.trace"
18644         local rc
18645         local count
18646
18647         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18648                 skip "OFD access log unsupported"
18649
18650         setup_165
18651         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18652         sleep 5
18653
18654         do_facet ost1 ofd_access_log_reader --list
18655         stop ost1
18656
18657         do_facet ost1 killall -TERM ofd_access_log_reader
18658         wait
18659         rc=$?
18660
18661         if ((rc != 0)); then
18662                 error "ofd_access_log_reader exited with rc = '${rc}'"
18663         fi
18664
18665         # Parse trace file for discovery events:
18666         oalr_expect_event_count alr_log_add "${trace}" 1
18667         oalr_expect_event_count alr_log_eof "${trace}" 1
18668         oalr_expect_event_count alr_log_free "${trace}" 1
18669 }
18670 run_test 165a "ofd access log discovery"
18671
18672 test_165b() {
18673         local trace="/tmp/${tfile}.trace"
18674         local file="${DIR}/${tfile}"
18675         local pfid1
18676         local pfid2
18677         local -a entry
18678         local rc
18679         local count
18680         local size
18681         local flags
18682
18683         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18684                 skip "OFD access log unsupported"
18685
18686         setup_165
18687         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18688         sleep 5
18689
18690         do_facet ost1 ofd_access_log_reader --list
18691
18692         lfs setstripe -c 1 -i 0 "${file}"
18693         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18694                 error "cannot create '${file}'"
18695
18696         sleep 5
18697         do_facet ost1 killall -TERM ofd_access_log_reader
18698         wait
18699         rc=$?
18700
18701         if ((rc != 0)); then
18702                 error "ofd_access_log_reader exited with rc = '${rc}'"
18703         fi
18704
18705         oalr_expect_event_count alr_log_entry "${trace}" 1
18706
18707         pfid1=$($LFS path2fid "${file}")
18708
18709         # 1     2             3   4    5     6   7    8    9     10
18710         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18711         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18712
18713         echo "entry = '${entry[*]}'" >&2
18714
18715         pfid2=${entry[4]}
18716         if [[ "${pfid1}" != "${pfid2}" ]]; then
18717                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18718         fi
18719
18720         size=${entry[8]}
18721         if ((size != 1048576)); then
18722                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18723         fi
18724
18725         flags=${entry[10]}
18726         if [[ "${flags}" != "w" ]]; then
18727                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18728         fi
18729
18730         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18731         sleep 5
18732
18733         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18734                 error "cannot read '${file}'"
18735         sleep 5
18736
18737         do_facet ost1 killall -TERM ofd_access_log_reader
18738         wait
18739         rc=$?
18740
18741         if ((rc != 0)); then
18742                 error "ofd_access_log_reader exited with rc = '${rc}'"
18743         fi
18744
18745         oalr_expect_event_count alr_log_entry "${trace}" 1
18746
18747         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18748         echo "entry = '${entry[*]}'" >&2
18749
18750         pfid2=${entry[4]}
18751         if [[ "${pfid1}" != "${pfid2}" ]]; then
18752                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18753         fi
18754
18755         size=${entry[8]}
18756         if ((size != 524288)); then
18757                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18758         fi
18759
18760         flags=${entry[10]}
18761         if [[ "${flags}" != "r" ]]; then
18762                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18763         fi
18764 }
18765 run_test 165b "ofd access log entries are produced and consumed"
18766
18767 test_165c() {
18768         local trace="/tmp/${tfile}.trace"
18769         local file="${DIR}/${tdir}/${tfile}"
18770
18771         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18772                 skip "OFD access log unsupported"
18773
18774         test_mkdir "${DIR}/${tdir}"
18775
18776         setup_165
18777         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18778         sleep 5
18779
18780         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18781
18782         # 4096 / 64 = 64. Create twice as many entries.
18783         for ((i = 0; i < 128; i++)); do
18784                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18785                         error "cannot create file"
18786         done
18787
18788         sync
18789
18790         do_facet ost1 killall -TERM ofd_access_log_reader
18791         wait
18792         rc=$?
18793         if ((rc != 0)); then
18794                 error "ofd_access_log_reader exited with rc = '${rc}'"
18795         fi
18796
18797         unlinkmany  "${file}-%d" 128
18798 }
18799 run_test 165c "full ofd access logs do not block IOs"
18800
18801 oal_get_read_count() {
18802         local stats="$1"
18803
18804         # STATS lustre-OST0001 alr_read_count 1
18805
18806         do_facet ost1 cat "${stats}" |
18807         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18808              END { print count; }'
18809 }
18810
18811 oal_expect_read_count() {
18812         local stats="$1"
18813         local count
18814         local expect="$2"
18815
18816         # Ask ofd_access_log_reader to write stats.
18817         do_facet ost1 killall -USR1 ofd_access_log_reader
18818
18819         # Allow some time for things to happen.
18820         sleep 1
18821
18822         count=$(oal_get_read_count "${stats}")
18823         if ((count == expect)); then
18824                 return 0
18825         fi
18826
18827         error_noexit "bad read count, got ${count}, expected ${expect}"
18828         do_facet ost1 cat "${stats}" >&2
18829         exit 1
18830 }
18831
18832 test_165d() {
18833         local stats="/tmp/${tfile}.stats"
18834         local file="${DIR}/${tdir}/${tfile}"
18835         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18836
18837         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18838                 skip "OFD access log unsupported"
18839
18840         test_mkdir "${DIR}/${tdir}"
18841
18842         setup_165
18843         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18844         sleep 5
18845
18846         lfs setstripe -c 1 -i 0 "${file}"
18847
18848         do_facet ost1 lctl set_param "${param}=rw"
18849         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18850                 error "cannot create '${file}'"
18851         oal_expect_read_count "${stats}" 1
18852
18853         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18854                 error "cannot read '${file}'"
18855         oal_expect_read_count "${stats}" 2
18856
18857         do_facet ost1 lctl set_param "${param}=r"
18858         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18859                 error "cannot create '${file}'"
18860         oal_expect_read_count "${stats}" 2
18861
18862         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18863                 error "cannot read '${file}'"
18864         oal_expect_read_count "${stats}" 3
18865
18866         do_facet ost1 lctl set_param "${param}=w"
18867         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18868                 error "cannot create '${file}'"
18869         oal_expect_read_count "${stats}" 4
18870
18871         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18872                 error "cannot read '${file}'"
18873         oal_expect_read_count "${stats}" 4
18874
18875         do_facet ost1 lctl set_param "${param}=0"
18876         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18877                 error "cannot create '${file}'"
18878         oal_expect_read_count "${stats}" 4
18879
18880         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18881                 error "cannot read '${file}'"
18882         oal_expect_read_count "${stats}" 4
18883
18884         do_facet ost1 killall -TERM ofd_access_log_reader
18885         wait
18886         rc=$?
18887         if ((rc != 0)); then
18888                 error "ofd_access_log_reader exited with rc = '${rc}'"
18889         fi
18890 }
18891 run_test 165d "ofd_access_log mask works"
18892
18893 test_165e() {
18894         local stats="/tmp/${tfile}.stats"
18895         local file0="${DIR}/${tdir}-0/${tfile}"
18896         local file1="${DIR}/${tdir}-1/${tfile}"
18897
18898         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18899                 skip "OFD access log unsupported"
18900
18901         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18902
18903         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18904         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18905
18906         lfs setstripe -c 1 -i 0 "${file0}"
18907         lfs setstripe -c 1 -i 0 "${file1}"
18908
18909         setup_165
18910         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18911         sleep 5
18912
18913         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18914                 error "cannot create '${file0}'"
18915         sync
18916         oal_expect_read_count "${stats}" 0
18917
18918         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18919                 error "cannot create '${file1}'"
18920         sync
18921         oal_expect_read_count "${stats}" 1
18922
18923         do_facet ost1 killall -TERM ofd_access_log_reader
18924         wait
18925         rc=$?
18926         if ((rc != 0)); then
18927                 error "ofd_access_log_reader exited with rc = '${rc}'"
18928         fi
18929 }
18930 run_test 165e "ofd_access_log MDT index filter works"
18931
18932 test_165f() {
18933         local trace="/tmp/${tfile}.trace"
18934         local rc
18935         local count
18936
18937         setup_165
18938         do_facet ost1 timeout 60 ofd_access_log_reader \
18939                 --exit-on-close --debug=- --trace=- > "${trace}" &
18940         sleep 5
18941         stop ost1
18942
18943         wait
18944         rc=$?
18945
18946         if ((rc != 0)); then
18947                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18948                 cat "${trace}"
18949                 exit 1
18950         fi
18951 }
18952 run_test 165f "ofd_access_log_reader --exit-on-close works"
18953
18954 test_169() {
18955         # do directio so as not to populate the page cache
18956         log "creating a 10 Mb file"
18957         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18958                 error "multiop failed while creating a file"
18959         log "starting reads"
18960         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18961         log "truncating the file"
18962         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18963                 error "multiop failed while truncating the file"
18964         log "killing dd"
18965         kill %+ || true # reads might have finished
18966         echo "wait until dd is finished"
18967         wait
18968         log "removing the temporary file"
18969         rm -rf $DIR/$tfile || error "tmp file removal failed"
18970 }
18971 run_test 169 "parallel read and truncate should not deadlock"
18972
18973 test_170() {
18974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18975
18976         $LCTL clear     # bug 18514
18977         $LCTL debug_daemon start $TMP/${tfile}_log_good
18978         touch $DIR/$tfile
18979         $LCTL debug_daemon stop
18980         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18981                 error "sed failed to read log_good"
18982
18983         $LCTL debug_daemon start $TMP/${tfile}_log_good
18984         rm -rf $DIR/$tfile
18985         $LCTL debug_daemon stop
18986
18987         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18988                error "lctl df log_bad failed"
18989
18990         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18991         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18992
18993         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18994         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18995
18996         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18997                 error "bad_line good_line1 good_line2 are empty"
18998
18999         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19000         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19001         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19002
19003         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19004         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19005         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19006
19007         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19008                 error "bad_line_new good_line_new are empty"
19009
19010         local expected_good=$((good_line1 + good_line2*2))
19011
19012         rm -f $TMP/${tfile}*
19013         # LU-231, short malformed line may not be counted into bad lines
19014         if [ $bad_line -ne $bad_line_new ] &&
19015                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19016                 error "expected $bad_line bad lines, but got $bad_line_new"
19017                 return 1
19018         fi
19019
19020         if [ $expected_good -ne $good_line_new ]; then
19021                 error "expected $expected_good good lines, but got $good_line_new"
19022                 return 2
19023         fi
19024         true
19025 }
19026 run_test 170 "test lctl df to handle corrupted log ====================="
19027
19028 test_171() { # bug20592
19029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19030
19031         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19032         $LCTL set_param fail_loc=0x50e
19033         $LCTL set_param fail_val=3000
19034         multiop_bg_pause $DIR/$tfile O_s || true
19035         local MULTIPID=$!
19036         kill -USR1 $MULTIPID
19037         # cause log dump
19038         sleep 3
19039         wait $MULTIPID
19040         if dmesg | grep "recursive fault"; then
19041                 error "caught a recursive fault"
19042         fi
19043         $LCTL set_param fail_loc=0
19044         true
19045 }
19046 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19047
19048 test_172() {
19049
19050         #define OBD_FAIL_OBD_CLEANUP  0x60e
19051         $LCTL set_param fail_loc=0x60e
19052         umount $MOUNT || error "umount $MOUNT failed"
19053         stack_trap "mount_client $MOUNT"
19054
19055         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19056                 error "no client OBDs are remained"
19057
19058         $LCTL dl | while read devno state type name foo; do
19059                 case $type in
19060                 lov|osc|lmv|mdc)
19061                         $LCTL --device $name cleanup
19062                         $LCTL --device $name detach
19063                         ;;
19064                 *)
19065                         # skip server devices
19066                         ;;
19067                 esac
19068         done
19069
19070         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19071                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19072                 error "some client OBDs are still remained"
19073         fi
19074
19075 }
19076 run_test 172 "manual device removal with lctl cleanup/detach ======"
19077
19078 # it would be good to share it with obdfilter-survey/iokit-libecho code
19079 setup_obdecho_osc () {
19080         local rc=0
19081         local ost_nid=$1
19082         local obdfilter_name=$2
19083         echo "Creating new osc for $obdfilter_name on $ost_nid"
19084         # make sure we can find loopback nid
19085         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19086
19087         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19088                            ${obdfilter_name}_osc_UUID || rc=2; }
19089         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19090                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19091         return $rc
19092 }
19093
19094 cleanup_obdecho_osc () {
19095         local obdfilter_name=$1
19096         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19097         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19098         return 0
19099 }
19100
19101 obdecho_test() {
19102         local OBD=$1
19103         local node=$2
19104         local pages=${3:-64}
19105         local rc=0
19106         local id
19107
19108         local count=10
19109         local obd_size=$(get_obd_size $node $OBD)
19110         local page_size=$(get_page_size $node)
19111         if [[ -n "$obd_size" ]]; then
19112                 local new_count=$((obd_size / (pages * page_size / 1024)))
19113                 [[ $new_count -ge $count ]] || count=$new_count
19114         fi
19115
19116         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19117         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19118                            rc=2; }
19119         if [ $rc -eq 0 ]; then
19120             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19121             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19122         fi
19123         echo "New object id is $id"
19124         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19125                            rc=4; }
19126         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19127                            "test_brw $count w v $pages $id" || rc=4; }
19128         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19129                            rc=4; }
19130         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19131                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19132         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19133                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19134         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19135         return $rc
19136 }
19137
19138 test_180a() {
19139         skip "obdecho on osc is no longer supported"
19140 }
19141 run_test 180a "test obdecho on osc"
19142
19143 test_180b() {
19144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19145         remote_ost_nodsh && skip "remote OST with nodsh"
19146
19147         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19148                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19149                 error "failed to load module obdecho"
19150
19151         local target=$(do_facet ost1 $LCTL dl |
19152                        awk '/obdfilter/ { print $4; exit; }')
19153
19154         if [ -n "$target" ]; then
19155                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19156         else
19157                 do_facet ost1 $LCTL dl
19158                 error "there is no obdfilter target on ost1"
19159         fi
19160 }
19161 run_test 180b "test obdecho directly on obdfilter"
19162
19163 test_180c() { # LU-2598
19164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19165         remote_ost_nodsh && skip "remote OST with nodsh"
19166         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19167                 skip "Need MDS version at least 2.4.0"
19168
19169         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19170                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19171                 error "failed to load module obdecho"
19172
19173         local target=$(do_facet ost1 $LCTL dl |
19174                        awk '/obdfilter/ { print $4; exit; }')
19175
19176         if [ -n "$target" ]; then
19177                 local pages=16384 # 64MB bulk I/O RPC size
19178
19179                 obdecho_test "$target" ost1 "$pages" ||
19180                         error "obdecho_test with pages=$pages failed with $?"
19181         else
19182                 do_facet ost1 $LCTL dl
19183                 error "there is no obdfilter target on ost1"
19184         fi
19185 }
19186 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19187
19188 test_181() { # bug 22177
19189         test_mkdir $DIR/$tdir
19190         # create enough files to index the directory
19191         createmany -o $DIR/$tdir/foobar 4000
19192         # print attributes for debug purpose
19193         lsattr -d .
19194         # open dir
19195         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19196         MULTIPID=$!
19197         # remove the files & current working dir
19198         unlinkmany $DIR/$tdir/foobar 4000
19199         rmdir $DIR/$tdir
19200         kill -USR1 $MULTIPID
19201         wait $MULTIPID
19202         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19203         return 0
19204 }
19205 run_test 181 "Test open-unlinked dir ========================"
19206
19207 test_182a() {
19208         local fcount=1000
19209         local tcount=10
19210
19211         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19212
19213         $LCTL set_param mdc.*.rpc_stats=clear
19214
19215         for (( i = 0; i < $tcount; i++ )) ; do
19216                 mkdir $DIR/$tdir/$i
19217         done
19218
19219         for (( i = 0; i < $tcount; i++ )) ; do
19220                 createmany -o $DIR/$tdir/$i/f- $fcount &
19221         done
19222         wait
19223
19224         for (( i = 0; i < $tcount; i++ )) ; do
19225                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19226         done
19227         wait
19228
19229         $LCTL get_param mdc.*.rpc_stats
19230
19231         rm -rf $DIR/$tdir
19232 }
19233 run_test 182a "Test parallel modify metadata operations from mdc"
19234
19235 test_182b() {
19236         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19237         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19238         local dcount=1000
19239         local tcount=10
19240         local stime
19241         local etime
19242         local delta
19243
19244         do_facet mds1 $LCTL list_param \
19245                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19246                 skip "MDS lacks parallel RPC handling"
19247
19248         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19249
19250         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19251                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19252
19253         stime=$(date +%s)
19254         createmany -i 0 -d $DIR/$tdir/t- $tcount
19255
19256         for (( i = 0; i < $tcount; i++ )) ; do
19257                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19258         done
19259         wait
19260         etime=$(date +%s)
19261         delta=$((etime - stime))
19262         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19263
19264         stime=$(date +%s)
19265         for (( i = 0; i < $tcount; i++ )) ; do
19266                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19267         done
19268         wait
19269         etime=$(date +%s)
19270         delta=$((etime - stime))
19271         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19272
19273         rm -rf $DIR/$tdir
19274
19275         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19276
19277         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19278
19279         stime=$(date +%s)
19280         createmany -i 0 -d $DIR/$tdir/t- $tcount
19281
19282         for (( i = 0; i < $tcount; i++ )) ; do
19283                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19284         done
19285         wait
19286         etime=$(date +%s)
19287         delta=$((etime - stime))
19288         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19289
19290         stime=$(date +%s)
19291         for (( i = 0; i < $tcount; i++ )) ; do
19292                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19293         done
19294         wait
19295         etime=$(date +%s)
19296         delta=$((etime - stime))
19297         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19298
19299         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19300 }
19301 run_test 182b "Test parallel modify metadata operations from osp"
19302
19303 test_183() { # LU-2275
19304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19305         remote_mds_nodsh && skip "remote MDS with nodsh"
19306         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19307                 skip "Need MDS version at least 2.3.56"
19308
19309         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19310         echo aaa > $DIR/$tdir/$tfile
19311
19312 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19313         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19314
19315         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19316         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19317
19318         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19319
19320         # Flush negative dentry cache
19321         touch $DIR/$tdir/$tfile
19322
19323         # We are not checking for any leaked references here, they'll
19324         # become evident next time we do cleanup with module unload.
19325         rm -rf $DIR/$tdir
19326 }
19327 run_test 183 "No crash or request leak in case of strange dispositions ========"
19328
19329 # test suite 184 is for LU-2016, LU-2017
19330 test_184a() {
19331         check_swap_layouts_support
19332
19333         dir0=$DIR/$tdir/$testnum
19334         test_mkdir -p -c1 $dir0
19335         ref1=/etc/passwd
19336         ref2=/etc/group
19337         file1=$dir0/f1
19338         file2=$dir0/f2
19339         $LFS setstripe -c1 $file1
19340         cp $ref1 $file1
19341         $LFS setstripe -c2 $file2
19342         cp $ref2 $file2
19343         gen1=$($LFS getstripe -g $file1)
19344         gen2=$($LFS getstripe -g $file2)
19345
19346         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19347         gen=$($LFS getstripe -g $file1)
19348         [[ $gen1 != $gen ]] ||
19349                 error "Layout generation on $file1 does not change"
19350         gen=$($LFS getstripe -g $file2)
19351         [[ $gen2 != $gen ]] ||
19352                 error "Layout generation on $file2 does not change"
19353
19354         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19355         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19356
19357         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19358 }
19359 run_test 184a "Basic layout swap"
19360
19361 test_184b() {
19362         check_swap_layouts_support
19363
19364         dir0=$DIR/$tdir/$testnum
19365         mkdir -p $dir0 || error "creating dir $dir0"
19366         file1=$dir0/f1
19367         file2=$dir0/f2
19368         file3=$dir0/f3
19369         dir1=$dir0/d1
19370         dir2=$dir0/d2
19371         mkdir $dir1 $dir2
19372         $LFS setstripe -c1 $file1
19373         $LFS setstripe -c2 $file2
19374         $LFS setstripe -c1 $file3
19375         chown $RUNAS_ID $file3
19376         gen1=$($LFS getstripe -g $file1)
19377         gen2=$($LFS getstripe -g $file2)
19378
19379         $LFS swap_layouts $dir1 $dir2 &&
19380                 error "swap of directories layouts should fail"
19381         $LFS swap_layouts $dir1 $file1 &&
19382                 error "swap of directory and file layouts should fail"
19383         $RUNAS $LFS swap_layouts $file1 $file2 &&
19384                 error "swap of file we cannot write should fail"
19385         $LFS swap_layouts $file1 $file3 &&
19386                 error "swap of file with different owner should fail"
19387         /bin/true # to clear error code
19388 }
19389 run_test 184b "Forbidden layout swap (will generate errors)"
19390
19391 test_184c() {
19392         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19393         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19394         check_swap_layouts_support
19395         check_swap_layout_no_dom $DIR
19396
19397         local dir0=$DIR/$tdir/$testnum
19398         mkdir -p $dir0 || error "creating dir $dir0"
19399
19400         local ref1=$dir0/ref1
19401         local ref2=$dir0/ref2
19402         local file1=$dir0/file1
19403         local file2=$dir0/file2
19404         # create a file large enough for the concurrent test
19405         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19406         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19407         echo "ref file size: ref1($(stat -c %s $ref1))," \
19408              "ref2($(stat -c %s $ref2))"
19409
19410         cp $ref2 $file2
19411         dd if=$ref1 of=$file1 bs=16k &
19412         local DD_PID=$!
19413
19414         # Make sure dd starts to copy file, but wait at most 5 seconds
19415         local loops=0
19416         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19417
19418         $LFS swap_layouts $file1 $file2
19419         local rc=$?
19420         wait $DD_PID
19421         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19422         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19423
19424         # how many bytes copied before swapping layout
19425         local copied=$(stat -c %s $file2)
19426         local remaining=$(stat -c %s $ref1)
19427         remaining=$((remaining - copied))
19428         echo "Copied $copied bytes before swapping layout..."
19429
19430         cmp -n $copied $file1 $ref2 | grep differ &&
19431                 error "Content mismatch [0, $copied) of ref2 and file1"
19432         cmp -n $copied $file2 $ref1 ||
19433                 error "Content mismatch [0, $copied) of ref1 and file2"
19434         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19435                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19436
19437         # clean up
19438         rm -f $ref1 $ref2 $file1 $file2
19439 }
19440 run_test 184c "Concurrent write and layout swap"
19441
19442 test_184d() {
19443         check_swap_layouts_support
19444         check_swap_layout_no_dom $DIR
19445         [ -z "$(which getfattr 2>/dev/null)" ] &&
19446                 skip_env "no getfattr command"
19447
19448         local file1=$DIR/$tdir/$tfile-1
19449         local file2=$DIR/$tdir/$tfile-2
19450         local file3=$DIR/$tdir/$tfile-3
19451         local lovea1
19452         local lovea2
19453
19454         mkdir -p $DIR/$tdir
19455         touch $file1 || error "create $file1 failed"
19456         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19457                 error "create $file2 failed"
19458         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19459                 error "create $file3 failed"
19460         lovea1=$(get_layout_param $file1)
19461
19462         $LFS swap_layouts $file2 $file3 ||
19463                 error "swap $file2 $file3 layouts failed"
19464         $LFS swap_layouts $file1 $file2 ||
19465                 error "swap $file1 $file2 layouts failed"
19466
19467         lovea2=$(get_layout_param $file2)
19468         echo "$lovea1"
19469         echo "$lovea2"
19470         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19471
19472         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19473         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19474 }
19475 run_test 184d "allow stripeless layouts swap"
19476
19477 test_184e() {
19478         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19479                 skip "Need MDS version at least 2.6.94"
19480         check_swap_layouts_support
19481         check_swap_layout_no_dom $DIR
19482         [ -z "$(which getfattr 2>/dev/null)" ] &&
19483                 skip_env "no getfattr command"
19484
19485         local file1=$DIR/$tdir/$tfile-1
19486         local file2=$DIR/$tdir/$tfile-2
19487         local file3=$DIR/$tdir/$tfile-3
19488         local lovea
19489
19490         mkdir -p $DIR/$tdir
19491         touch $file1 || error "create $file1 failed"
19492         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19493                 error "create $file2 failed"
19494         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19495                 error "create $file3 failed"
19496
19497         $LFS swap_layouts $file1 $file2 ||
19498                 error "swap $file1 $file2 layouts failed"
19499
19500         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19501         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19502
19503         echo 123 > $file1 || error "Should be able to write into $file1"
19504
19505         $LFS swap_layouts $file1 $file3 ||
19506                 error "swap $file1 $file3 layouts failed"
19507
19508         echo 123 > $file1 || error "Should be able to write into $file1"
19509
19510         rm -rf $file1 $file2 $file3
19511 }
19512 run_test 184e "Recreate layout after stripeless layout swaps"
19513
19514 test_184f() {
19515         # Create a file with name longer than sizeof(struct stat) ==
19516         # 144 to see if we can get chars from the file name to appear
19517         # in the returned striping. Note that 'f' == 0x66.
19518         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19519
19520         mkdir -p $DIR/$tdir
19521         mcreate $DIR/$tdir/$file
19522         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19523                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19524         fi
19525 }
19526 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19527
19528 test_185() { # LU-2441
19529         # LU-3553 - no volatile file support in old servers
19530         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19531                 skip "Need MDS version at least 2.3.60"
19532
19533         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19534         touch $DIR/$tdir/spoo
19535         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19536         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19537                 error "cannot create/write a volatile file"
19538         [ "$FILESET" == "" ] &&
19539         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19540                 error "FID is still valid after close"
19541
19542         multiop_bg_pause $DIR/$tdir Vw4096_c
19543         local multi_pid=$!
19544
19545         local OLD_IFS=$IFS
19546         IFS=":"
19547         local fidv=($fid)
19548         IFS=$OLD_IFS
19549         # assume that the next FID for this client is sequential, since stdout
19550         # is unfortunately eaten by multiop_bg_pause
19551         local n=$((${fidv[1]} + 1))
19552         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19553         if [ "$FILESET" == "" ]; then
19554                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19555                         error "FID is missing before close"
19556         fi
19557         kill -USR1 $multi_pid
19558         # 1 second delay, so if mtime change we will see it
19559         sleep 1
19560         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19561         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19562 }
19563 run_test 185 "Volatile file support"
19564
19565 function create_check_volatile() {
19566         local idx=$1
19567         local tgt
19568
19569         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19570         local PID=$!
19571         sleep 1
19572         local FID=$(cat /tmp/${tfile}.fid)
19573         [ "$FID" == "" ] && error "can't get FID for volatile"
19574         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19575         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19576         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19577         kill -USR1 $PID
19578         wait
19579         sleep 1
19580         cancel_lru_locks mdc # flush opencache
19581         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19582         return 0
19583 }
19584
19585 test_185a(){
19586         # LU-12516 - volatile creation via .lustre
19587         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19588                 skip "Need MDS version at least 2.3.55"
19589
19590         create_check_volatile 0
19591         [ $MDSCOUNT -lt 2 ] && return 0
19592
19593         # DNE case
19594         create_check_volatile 1
19595
19596         return 0
19597 }
19598 run_test 185a "Volatile file creation in .lustre/fid/"
19599
19600 test_187a() {
19601         remote_mds_nodsh && skip "remote MDS with nodsh"
19602         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19603                 skip "Need MDS version at least 2.3.0"
19604
19605         local dir0=$DIR/$tdir/$testnum
19606         mkdir -p $dir0 || error "creating dir $dir0"
19607
19608         local file=$dir0/file1
19609         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19610         stack_trap "rm -f $file"
19611         local dv1=$($LFS data_version $file)
19612         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19613         local dv2=$($LFS data_version $file)
19614         [[ $dv1 != $dv2 ]] ||
19615                 error "data version did not change on write $dv1 == $dv2"
19616 }
19617 run_test 187a "Test data version change"
19618
19619 test_187b() {
19620         remote_mds_nodsh && skip "remote MDS with nodsh"
19621         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19622                 skip "Need MDS version at least 2.3.0"
19623
19624         local dir0=$DIR/$tdir/$testnum
19625         mkdir -p $dir0 || error "creating dir $dir0"
19626
19627         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19628         [[ ${DV[0]} != ${DV[1]} ]] ||
19629                 error "data version did not change on write"\
19630                       " ${DV[0]} == ${DV[1]}"
19631
19632         # clean up
19633         rm -f $file1
19634 }
19635 run_test 187b "Test data version change on volatile file"
19636
19637 test_200() {
19638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19639         remote_mgs_nodsh && skip "remote MGS with nodsh"
19640         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19641
19642         local POOL=${POOL:-cea1}
19643         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19644         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19645         # Pool OST targets
19646         local first_ost=0
19647         local last_ost=$(($OSTCOUNT - 1))
19648         local ost_step=2
19649         local ost_list=$(seq $first_ost $ost_step $last_ost)
19650         local ost_range="$first_ost $last_ost $ost_step"
19651         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19652         local file_dir=$POOL_ROOT/file_tst
19653         local subdir=$test_path/subdir
19654         local rc=0
19655
19656         while : ; do
19657                 # former test_200a test_200b
19658                 pool_add $POOL                          || { rc=$? ; break; }
19659                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19660                 # former test_200c test_200d
19661                 mkdir -p $test_path
19662                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19663                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19664                 mkdir -p $subdir
19665                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19666                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19667                                                         || { rc=$? ; break; }
19668                 # former test_200e test_200f
19669                 local files=$((OSTCOUNT*3))
19670                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19671                                                         || { rc=$? ; break; }
19672                 pool_create_files $POOL $file_dir $files "$ost_list" \
19673                                                         || { rc=$? ; break; }
19674                 # former test_200g test_200h
19675                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19676                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19677
19678                 # former test_201a test_201b test_201c
19679                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19680
19681                 local f=$test_path/$tfile
19682                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19683                 pool_remove $POOL $f                    || { rc=$? ; break; }
19684                 break
19685         done
19686
19687         destroy_test_pools
19688
19689         return $rc
19690 }
19691 run_test 200 "OST pools"
19692
19693 # usage: default_attr <count | size | offset>
19694 default_attr() {
19695         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19696 }
19697
19698 # usage: check_default_stripe_attr
19699 check_default_stripe_attr() {
19700         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19701         case $1 in
19702         --stripe-count|-c)
19703                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19704         --stripe-size|-S)
19705                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19706         --stripe-index|-i)
19707                 EXPECTED=-1;;
19708         *)
19709                 error "unknown getstripe attr '$1'"
19710         esac
19711
19712         [ $ACTUAL == $EXPECTED ] ||
19713                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19714 }
19715
19716 test_204a() {
19717         test_mkdir $DIR/$tdir
19718         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19719
19720         check_default_stripe_attr --stripe-count
19721         check_default_stripe_attr --stripe-size
19722         check_default_stripe_attr --stripe-index
19723 }
19724 run_test 204a "Print default stripe attributes"
19725
19726 test_204b() {
19727         test_mkdir $DIR/$tdir
19728         $LFS setstripe --stripe-count 1 $DIR/$tdir
19729
19730         check_default_stripe_attr --stripe-size
19731         check_default_stripe_attr --stripe-index
19732 }
19733 run_test 204b "Print default stripe size and offset"
19734
19735 test_204c() {
19736         test_mkdir $DIR/$tdir
19737         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19738
19739         check_default_stripe_attr --stripe-count
19740         check_default_stripe_attr --stripe-index
19741 }
19742 run_test 204c "Print default stripe count and offset"
19743
19744 test_204d() {
19745         test_mkdir $DIR/$tdir
19746         $LFS setstripe --stripe-index 0 $DIR/$tdir
19747
19748         check_default_stripe_attr --stripe-count
19749         check_default_stripe_attr --stripe-size
19750 }
19751 run_test 204d "Print default stripe count and size"
19752
19753 test_204e() {
19754         test_mkdir $DIR/$tdir
19755         $LFS setstripe -d $DIR/$tdir
19756
19757         # LU-16904 check if root is set as PFL layout
19758         local numcomp=$($LFS getstripe --component-count $MOUNT)
19759
19760         if [[ $numcomp -gt 0 ]]; then
19761                 check_default_stripe_attr --stripe-count
19762         else
19763                 check_default_stripe_attr --stripe-count --raw
19764         fi
19765         check_default_stripe_attr --stripe-size --raw
19766         check_default_stripe_attr --stripe-index --raw
19767 }
19768 run_test 204e "Print raw stripe attributes"
19769
19770 test_204f() {
19771         test_mkdir $DIR/$tdir
19772         $LFS setstripe --stripe-count 1 $DIR/$tdir
19773
19774         check_default_stripe_attr --stripe-size --raw
19775         check_default_stripe_attr --stripe-index --raw
19776 }
19777 run_test 204f "Print raw stripe size and offset"
19778
19779 test_204g() {
19780         test_mkdir $DIR/$tdir
19781         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19782
19783         check_default_stripe_attr --stripe-count --raw
19784         check_default_stripe_attr --stripe-index --raw
19785 }
19786 run_test 204g "Print raw stripe count and offset"
19787
19788 test_204h() {
19789         test_mkdir $DIR/$tdir
19790         $LFS setstripe --stripe-index 0 $DIR/$tdir
19791
19792         check_default_stripe_attr --stripe-count --raw
19793         check_default_stripe_attr --stripe-size --raw
19794 }
19795 run_test 204h "Print raw stripe count and size"
19796
19797 # Figure out which job scheduler is being used, if any,
19798 # or use a fake one
19799 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19800         JOBENV=SLURM_JOB_ID
19801 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19802         JOBENV=LSB_JOBID
19803 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19804         JOBENV=PBS_JOBID
19805 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19806         JOBENV=LOADL_STEP_ID
19807 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19808         JOBENV=JOB_ID
19809 else
19810         $LCTL list_param jobid_name > /dev/null 2>&1
19811         if [ $? -eq 0 ]; then
19812                 JOBENV=nodelocal
19813         else
19814                 JOBENV=FAKE_JOBID
19815         fi
19816 fi
19817 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19818
19819 verify_jobstats() {
19820         local cmd=($1)
19821         shift
19822         local facets="$@"
19823
19824 # we don't really need to clear the stats for this test to work, since each
19825 # command has a unique jobid, but it makes debugging easier if needed.
19826 #       for facet in $facets; do
19827 #               local dev=$(convert_facet2label $facet)
19828 #               # clear old jobstats
19829 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19830 #       done
19831
19832         # use a new JobID for each test, or we might see an old one
19833         [ "$JOBENV" = "FAKE_JOBID" ] &&
19834                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19835
19836         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19837
19838         [ "$JOBENV" = "nodelocal" ] && {
19839                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19840                 $LCTL set_param jobid_name=$FAKE_JOBID
19841                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19842         }
19843
19844         log "Test: ${cmd[*]}"
19845         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19846
19847         if [ $JOBENV = "FAKE_JOBID" ]; then
19848                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19849         else
19850                 ${cmd[*]}
19851         fi
19852
19853         # all files are created on OST0000
19854         for facet in $facets; do
19855                 local stats="*.$(convert_facet2label $facet).job_stats"
19856
19857                 # strip out libtool wrappers for in-tree executables
19858                 if (( $(do_facet $facet lctl get_param $stats |
19859                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19860                         do_facet $facet lctl get_param $stats
19861                         error "No jobstats for $JOBVAL found on $facet::$stats"
19862                 fi
19863         done
19864 }
19865
19866 jobstats_set() {
19867         local new_jobenv=$1
19868
19869         set_persistent_param_and_check client "jobid_var" \
19870                 "$FSNAME.sys.jobid_var" $new_jobenv
19871 }
19872
19873 test_205a() { # Job stats
19874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19875         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19876                 skip "Need MDS version with at least 2.7.1"
19877         remote_mgs_nodsh && skip "remote MGS with nodsh"
19878         remote_mds_nodsh && skip "remote MDS with nodsh"
19879         remote_ost_nodsh && skip "remote OST with nodsh"
19880         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19881                 skip "Server doesn't support jobstats"
19882         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19883
19884         local old_jobenv=$($LCTL get_param -n jobid_var)
19885         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19886         stack_trap "jobstats_set $old_jobenv" EXIT
19887
19888         changelog_register
19889
19890         local old_jobid_name=$($LCTL get_param jobid_name)
19891         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19892
19893         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19894                                 mdt.*.job_cleanup_interval | head -n 1)
19895         local new_interval=5
19896         do_facet $SINGLEMDS \
19897                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19898         stack_trap "do_facet $SINGLEMDS \
19899                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19900         local start=$SECONDS
19901
19902         local cmd
19903         # mkdir
19904         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19905         verify_jobstats "$cmd" "$SINGLEMDS"
19906         # rmdir
19907         cmd="rmdir $DIR/$tdir"
19908         verify_jobstats "$cmd" "$SINGLEMDS"
19909         # mkdir on secondary MDT
19910         if [ $MDSCOUNT -gt 1 ]; then
19911                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19912                 verify_jobstats "$cmd" "mds2"
19913         fi
19914         # mknod
19915         cmd="mknod $DIR/$tfile c 1 3"
19916         verify_jobstats "$cmd" "$SINGLEMDS"
19917         # unlink
19918         cmd="rm -f $DIR/$tfile"
19919         verify_jobstats "$cmd" "$SINGLEMDS"
19920         # create all files on OST0000 so verify_jobstats can find OST stats
19921         # open & close
19922         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19923         verify_jobstats "$cmd" "$SINGLEMDS"
19924         # setattr
19925         cmd="touch $DIR/$tfile"
19926         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19927         # write
19928         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19929         verify_jobstats "$cmd" "ost1"
19930         # read
19931         cancel_lru_locks osc
19932         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19933         verify_jobstats "$cmd" "ost1"
19934         # truncate
19935         cmd="$TRUNCATE $DIR/$tfile 0"
19936         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19937         # rename
19938         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19939         verify_jobstats "$cmd" "$SINGLEMDS"
19940         # jobstats expiry - sleep until old stats should be expired
19941         local left=$((new_interval + 5 - (SECONDS - start)))
19942         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19943                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19944                         "0" $left
19945         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19946         verify_jobstats "$cmd" "$SINGLEMDS"
19947         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19948             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19949
19950         # Ensure that jobid are present in changelog (if supported by MDS)
19951         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19952                 changelog_dump | tail -10
19953                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19954                 [ $jobids -eq 9 ] ||
19955                         error "Wrong changelog jobid count $jobids != 9"
19956
19957                 # LU-5862
19958                 JOBENV="disable"
19959                 jobstats_set $JOBENV
19960                 touch $DIR/$tfile
19961                 changelog_dump | grep $tfile
19962                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19963                 [ $jobids -eq 0 ] ||
19964                         error "Unexpected jobids when jobid_var=$JOBENV"
19965         fi
19966
19967         # test '%j' access to environment variable - if supported
19968         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19969                 JOBENV="JOBCOMPLEX"
19970                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19971
19972                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19973         fi
19974
19975         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19976                 JOBENV="JOBCOMPLEX"
19977                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19978
19979                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19980         fi
19981
19982         # test '%j' access to per-session jobid - if supported
19983         if lctl list_param jobid_this_session > /dev/null 2>&1
19984         then
19985                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19986                 lctl set_param jobid_this_session=$USER
19987
19988                 JOBENV="JOBCOMPLEX"
19989                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19990
19991                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19992         fi
19993 }
19994 run_test 205a "Verify job stats"
19995
19996 # LU-13117, LU-13597, LU-16599
19997 test_205b() {
19998         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19999                 skip "Need MDS version at least 2.13.54.91"
20000
20001         local job_stats="mdt.*.job_stats"
20002         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20003
20004         do_facet mds1 $LCTL set_param $job_stats=clear
20005
20006         # Setting jobid_var to USER might not be supported
20007         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20008         $LCTL set_param jobid_var=USER || true
20009         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20010         $LCTL set_param jobid_name="%j.%e.%u"
20011
20012         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20013         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20014                 { do_facet mds1 $LCTL get_param $job_stats;
20015                   error "Unexpected jobid found"; }
20016         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20017                 { do_facet mds1 $LCTL get_param $job_stats;
20018                   error "wrong job_stats format found"; }
20019
20020         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20021                 echo "MDS does not yet escape jobid" && return 0
20022
20023         mkdir_on_mdt0 $DIR/$tdir
20024         $LCTL set_param jobid_var=TEST205b
20025         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20026         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20027                       awk '/has\\x20sp/ {print $3}')
20028         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20029                   error "jobid not escaped"; }
20030
20031         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20032                 # need to run such a command on mds1:
20033                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20034                 #
20035                 # there might be multiple MDTs on single mds server, so need to
20036                 # specifiy MDT0000. Or the command will fail due to other MDTs
20037                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20038                         error "cannot clear escaped jobid in job_stats";
20039         else
20040                 echo "MDS does not support clearing escaped jobid"
20041         fi
20042 }
20043 run_test 205b "Verify job stats jobid and output format"
20044
20045 # LU-13733
20046 test_205c() {
20047         $LCTL set_param llite.*.stats=0
20048         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20049         $LCTL get_param llite.*.stats
20050         $LCTL get_param llite.*.stats | grep \
20051                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20052                         error "wrong client stats format found"
20053 }
20054 run_test 205c "Verify client stats format"
20055
20056 test_205d() {
20057         local file=$DIR/$tdir/$tfile
20058
20059         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20060                 skip "need lustre >= 2.15.53 for lljobstat"
20061         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20062                 skip "need lustre >= 2.15.53 for lljobstat"
20063         verify_yaml_available || skip_env "YAML verification not installed"
20064
20065         test_mkdir -i 0 $DIR/$tdir
20066         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20067         stack_trap "rm -rf $DIR/$tdir"
20068
20069         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20070                 error "failed to write data to $file"
20071         mv $file $file.2
20072
20073         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20074         echo -n 'verify rename_stats...'
20075         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20076                 verify_yaml || error "rename_stats is not valid YAML"
20077         echo " OK"
20078
20079         echo -n 'verify mdt job_stats...'
20080         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20081                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20082         echo " OK"
20083
20084         echo -n 'verify ost job_stats...'
20085         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20086                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20087         echo " OK"
20088 }
20089 run_test 205d "verify the format of some stats files"
20090
20091 test_205e() {
20092         local ops_comma
20093         local file=$DIR/$tdir/$tfile
20094         local -a cli_params
20095
20096         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20097                 skip "need lustre >= 2.15.53 for lljobstat"
20098         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20099                 skip "need lustre >= 2.15.53 for lljobstat"
20100         verify_yaml_available || skip_env "YAML verification not installed"
20101
20102         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20103         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20104         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20105
20106         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20107         stack_trap "rm -rf $DIR/$tdir"
20108
20109         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20110                 error "failed to create $file on ost1"
20111         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20112                 error "failed to write data to $file"
20113
20114         do_facet mds1 "$LCTL get_param *.*.job_stats"
20115         do_facet ost1 "$LCTL get_param *.*.job_stats"
20116
20117         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20118         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20119                 error "The output of lljobstat is not an valid YAML"
20120
20121         # verify that job dd.0 does exist and has some ops on ost1
20122         # typically this line is like:
20123         # - 205e.dd.0:            {ops: 20, ...}
20124         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20125                     awk '$2=="205e.dd.0:" {print $4}')
20126
20127         (( ${ops_comma%,} >= 10 )) ||
20128                 error "cannot find job 205e.dd.0 with ops >= 10"
20129 }
20130 run_test 205e "verify the output of lljobstat"
20131
20132 test_205f() {
20133         verify_yaml_available || skip_env "YAML verification not installed"
20134
20135         # check both qos_ost_weights and qos_mdt_weights
20136         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20137         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20138                 error "qos_ost_weights is not valid YAML"
20139 }
20140 run_test 205f "verify qos_ost_weights YAML format "
20141
20142 __test_205_jobstats_dump() {
20143         local -a pids
20144         local nbr_instance=$1
20145
20146         while true; do
20147                 if (( ${#pids[@]} >= nbr_instance )); then
20148                         wait ${pids[@]}
20149                         pids=()
20150                 fi
20151
20152                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20153                 pids+=( $! )
20154         done
20155 }
20156
20157 __test_205_cleanup() {
20158         kill $@
20159         # Clear all job entries
20160         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20161 }
20162
20163 test_205g() {
20164         local -a mds1_params
20165         local -a cli_params
20166         local pids
20167         local interval=5
20168
20169         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20170         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20171         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20172
20173         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20174         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20175         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20176
20177         # start jobs loop
20178         export TEST205G_ID=205g
20179         stack_trap "unset TEST205G_ID" EXIT
20180         while true; do
20181                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20182         done & pids="$! "
20183
20184         __test_205_jobstats_dump 4 & pids+="$! "
20185         stack_trap "__test_205_cleanup $pids" EXIT INT
20186
20187         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20188 }
20189 run_test 205g "stress test for job_stats procfile"
20190
20191 test_205h() {
20192         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20193
20194         local dir=$DIR/$tdir
20195         local f=$dir/$tfile
20196         local f2=$dir/$tfile-2
20197         local f3=$dir/$tfile-3
20198         local subdir=$DIR/dir
20199         local val
20200
20201         local mdts=$(comma_list $(mdts_nodes))
20202         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20203         local client_saved=$($LCTL get_param -n jobid_var)
20204
20205         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20206         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20207
20208         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20209                 error "failed to set job_xattr parameter to user.job"
20210         $LCTL set_param jobid_var=procname.uid ||
20211                 error "failed to set jobid_var parameter"
20212
20213         test_mkdir $dir
20214
20215         touch $f
20216         val=$(getfattr -n user.job $f | grep user.job)
20217         [[ $val = user.job=\"touch.0\" ]] ||
20218                 error "expected user.job=\"touch.0\", got '$val'"
20219
20220         mkdir $subdir
20221         val=$(getfattr -n user.job $subdir | grep user.job)
20222         [[ $val = user.job=\"mkdir.0\" ]] ||
20223                 error "expected user.job=\"mkdir.0\", got '$val'"
20224
20225         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20226                 error "failed to set job_xattr parameter to NONE"
20227
20228         touch $f2
20229         val=$(getfattr -d $f2)
20230         [[ -z $val ]] ||
20231                 error "expected no user xattr, got '$val'"
20232
20233         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20234                 error "failed to set job_xattr parameter to trusted.job"
20235
20236         touch $f3
20237         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20238         [[ $val = trusted.job=\"touch.0\" ]] ||
20239                 error "expected trusted.job=\"touch.0\", got '$val'"
20240 }
20241 run_test 205h "check jobid xattr is stored correctly"
20242
20243 test_205i() {
20244         local mdts=$(comma_list $(mdts_nodes))
20245         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20246
20247         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20248
20249         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20250                 error "failed to set mdt.*.job_xattr to user.1234567"
20251
20252         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20253                 error "failed to reject too long job_xattr name"
20254
20255         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20256                 error "failed to reject job_xattr name in bad format"
20257
20258         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20259                 error "failed to reject job_xattr name with invalid character"
20260
20261         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20262                         xargs $LCTL set_param" &&
20263                 error "failed to reject job_xattr name with non-ascii character"
20264
20265         return 0
20266 }
20267 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20268
20269 # LU-1480, LU-1773 and LU-1657
20270 test_206() {
20271         mkdir -p $DIR/$tdir
20272         $LFS setstripe -c -1 $DIR/$tdir
20273 #define OBD_FAIL_LOV_INIT 0x1403
20274         $LCTL set_param fail_loc=0xa0001403
20275         $LCTL set_param fail_val=1
20276         touch $DIR/$tdir/$tfile || true
20277 }
20278 run_test 206 "fail lov_init_raid0() doesn't lbug"
20279
20280 test_207a() {
20281         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20282         local fsz=`stat -c %s $DIR/$tfile`
20283         cancel_lru_locks mdc
20284
20285         # do not return layout in getattr intent
20286 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20287         $LCTL set_param fail_loc=0x170
20288         local sz=`stat -c %s $DIR/$tfile`
20289
20290         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20291
20292         rm -rf $DIR/$tfile
20293 }
20294 run_test 207a "can refresh layout at glimpse"
20295
20296 test_207b() {
20297         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20298         local cksum=`md5sum $DIR/$tfile`
20299         local fsz=`stat -c %s $DIR/$tfile`
20300         cancel_lru_locks mdc
20301         cancel_lru_locks osc
20302
20303         # do not return layout in getattr intent
20304 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20305         $LCTL set_param fail_loc=0x171
20306
20307         # it will refresh layout after the file is opened but before read issues
20308         echo checksum is "$cksum"
20309         echo "$cksum" |md5sum -c --quiet || error "file differs"
20310
20311         rm -rf $DIR/$tfile
20312 }
20313 run_test 207b "can refresh layout at open"
20314
20315 test_208() {
20316         # FIXME: in this test suite, only RD lease is used. This is okay
20317         # for now as only exclusive open is supported. After generic lease
20318         # is done, this test suite should be revised. - Jinshan
20319
20320         remote_mds_nodsh && skip "remote MDS with nodsh"
20321         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20322                 skip "Need MDS version at least 2.4.52"
20323
20324         echo "==== test 1: verify get lease work"
20325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20326
20327         echo "==== test 2: verify lease can be broken by upcoming open"
20328         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20329         local PID=$!
20330         sleep 2
20331
20332         $MULTIOP $DIR/$tfile oO_RDWR:c
20333         kill -USR1 $PID && wait $PID || error "break lease error"
20334
20335         echo "==== test 3: verify lease can't be granted if an open already exists"
20336         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20337         local PID=$!
20338         sleep 2
20339
20340         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20341         kill -USR1 $PID && wait $PID || error "open file error"
20342
20343         echo "==== test 4: lease can sustain over recovery"
20344         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20345         PID=$!
20346         sleep 2
20347
20348         fail mds1
20349
20350         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20351
20352         echo "==== test 5: lease broken can't be regained by replay"
20353         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20354         PID=$!
20355         sleep 2
20356
20357         # open file to break lease and then recovery
20358         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20359         fail mds1
20360
20361         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20362
20363         rm -f $DIR/$tfile
20364 }
20365 run_test 208 "Exclusive open"
20366
20367 test_209() {
20368         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20369                 skip_env "must have disp_stripe"
20370
20371         touch $DIR/$tfile
20372         sync; sleep 5; sync;
20373
20374         echo 3 > /proc/sys/vm/drop_caches
20375         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20376                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20377         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20378
20379         # open/close 500 times
20380         for i in $(seq 500); do
20381                 cat $DIR/$tfile
20382         done
20383
20384         echo 3 > /proc/sys/vm/drop_caches
20385         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20386                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20387         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20388
20389         echo "before: $req_before, after: $req_after"
20390         [ $((req_after - req_before)) -ge 300 ] &&
20391                 error "open/close requests are not freed"
20392         return 0
20393 }
20394 run_test 209 "read-only open/close requests should be freed promptly"
20395
20396 test_210() {
20397         local pid
20398
20399         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20400         pid=$!
20401         sleep 1
20402
20403         $LFS getstripe $DIR/$tfile
20404         kill -USR1 $pid
20405         wait $pid || error "multiop failed"
20406
20407         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20408         pid=$!
20409         sleep 1
20410
20411         $LFS getstripe $DIR/$tfile
20412         kill -USR1 $pid
20413         wait $pid || error "multiop failed"
20414 }
20415 run_test 210 "lfs getstripe does not break leases"
20416
20417 function test_211() {
20418         local PID
20419         local id
20420         local rc
20421
20422         stack_trap "rm -f $DIR/$tfile" EXIT
20423         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20424                 error "can't create file"
20425         $LFS mirror extend -N $DIR/$tfile ||
20426                 error "can't create a replica"
20427         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20428         $LFS getstripe $DIR/$tfile
20429         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20430         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20431
20432         $MULTIOP $DIR/$tfile OeW_E+eUc &
20433         PID=$!
20434         sleep 0.3
20435
20436         id=$($LFS getstripe $DIR/$tfile |
20437                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20438         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20439                 error "removed last in-sync replica?"
20440
20441         kill -USR1 $PID
20442         wait $PID
20443         (( $? == 0 )) || error "failed split broke the lease"
20444 }
20445 run_test 211 "failed mirror split doesn't break write lease"
20446
20447 test_212() {
20448         size=`date +%s`
20449         size=$((size % 8192 + 1))
20450         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20451         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20452         rm -f $DIR/f212 $DIR/f212.xyz
20453 }
20454 run_test 212 "Sendfile test ============================================"
20455
20456 test_213() {
20457         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20458         cancel_lru_locks osc
20459         lctl set_param fail_loc=0x8000040f
20460         # generate a read lock
20461         cat $DIR/$tfile > /dev/null
20462         # write to the file, it will try to cancel the above read lock.
20463         cat /etc/hosts >> $DIR/$tfile
20464 }
20465 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20466
20467 test_214() { # for bug 20133
20468         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20469         for (( i=0; i < 340; i++ )) ; do
20470                 touch $DIR/$tdir/d214c/a$i
20471         done
20472
20473         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20474         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20475         ls $DIR/d214c || error "ls $DIR/d214c failed"
20476         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20477         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20478 }
20479 run_test 214 "hash-indexed directory test - bug 20133"
20480
20481 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20482 create_lnet_proc_files() {
20483         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20484 }
20485
20486 # counterpart of create_lnet_proc_files
20487 remove_lnet_proc_files() {
20488         rm -f $TMP/lnet_$1.sys
20489 }
20490
20491 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20492 # 3rd arg as regexp for body
20493 check_lnet_proc_stats() {
20494         local l=$(cat "$TMP/lnet_$1" |wc -l)
20495         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20496
20497         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20498 }
20499
20500 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20501 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20502 # optional and can be regexp for 2nd line (lnet.routes case)
20503 check_lnet_proc_entry() {
20504         local blp=2          # blp stands for 'position of 1st line of body'
20505         [ -z "$5" ] || blp=3 # lnet.routes case
20506
20507         local l=$(cat "$TMP/lnet_$1" |wc -l)
20508         # subtracting one from $blp because the body can be empty
20509         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20510
20511         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20512                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20513
20514         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20515                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20516
20517         # bail out if any unexpected line happened
20518         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20519         [ "$?" != 0 ] || error "$2 misformatted"
20520 }
20521
20522 test_215() { # for bugs 18102, 21079, 21517
20523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20524
20525         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20526         local P='[1-9][0-9]*'           # positive numeric
20527         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20528         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20529         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20530         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20531
20532         local L1 # regexp for 1st line
20533         local L2 # regexp for 2nd line (optional)
20534         local BR # regexp for the rest (body)
20535
20536         # lnet.stats should look as 11 space-separated non-negative numerics
20537         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20538         create_lnet_proc_files "stats"
20539         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20540         remove_lnet_proc_files "stats"
20541
20542         # lnet.routes should look like this:
20543         # Routing disabled/enabled
20544         # net hops priority state router
20545         # where net is a string like tcp0, hops > 0, priority >= 0,
20546         # state is up/down,
20547         # router is a string like 192.168.1.1@tcp2
20548         L1="^Routing (disabled|enabled)$"
20549         L2="^net +hops +priority +state +router$"
20550         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20551         create_lnet_proc_files "routes"
20552         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20553         remove_lnet_proc_files "routes"
20554
20555         # lnet.routers should look like this:
20556         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20557         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20558         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20559         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20560         L1="^ref +rtr_ref +alive +router$"
20561         BR="^$P +$P +(up|down) +$NID$"
20562         create_lnet_proc_files "routers"
20563         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20564         remove_lnet_proc_files "routers"
20565
20566         # lnet.peers should look like this:
20567         # nid refs state last max rtr min tx min queue
20568         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20569         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20570         # numeric (0 or >0 or <0), queue >= 0.
20571         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20572         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20573         create_lnet_proc_files "peers"
20574         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20575         remove_lnet_proc_files "peers"
20576
20577         # lnet.buffers  should look like this:
20578         # pages count credits min
20579         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20580         L1="^pages +count +credits +min$"
20581         BR="^ +$N +$N +$I +$I$"
20582         create_lnet_proc_files "buffers"
20583         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20584         remove_lnet_proc_files "buffers"
20585
20586         # lnet.nis should look like this:
20587         # nid status alive refs peer rtr max tx min
20588         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20589         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20590         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20591         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20592         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20593         create_lnet_proc_files "nis"
20594         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20595         remove_lnet_proc_files "nis"
20596
20597         # can we successfully write to lnet.stats?
20598         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20599 }
20600 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20601
20602 test_216() { # bug 20317
20603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20604         remote_ost_nodsh && skip "remote OST with nodsh"
20605
20606         local node
20607         local facets=$(get_facets OST)
20608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20609
20610         save_lustre_params client "osc.*.contention_seconds" > $p
20611         save_lustre_params $facets \
20612                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20613         save_lustre_params $facets \
20614                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20615         save_lustre_params $facets \
20616                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20617         clear_stats osc.*.osc_stats
20618
20619         # agressive lockless i/o settings
20620         do_nodes $(comma_list $(osts_nodes)) \
20621                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20622                         ldlm.namespaces.filter-*.contended_locks=0 \
20623                         ldlm.namespaces.filter-*.contention_seconds=60"
20624         lctl set_param -n osc.*.contention_seconds=60
20625
20626         $DIRECTIO write $DIR/$tfile 0 10 4096
20627         $CHECKSTAT -s 40960 $DIR/$tfile
20628
20629         # disable lockless i/o
20630         do_nodes $(comma_list $(osts_nodes)) \
20631                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20632                         ldlm.namespaces.filter-*.contended_locks=32 \
20633                         ldlm.namespaces.filter-*.contention_seconds=0"
20634         lctl set_param -n osc.*.contention_seconds=0
20635         clear_stats osc.*.osc_stats
20636
20637         dd if=/dev/zero of=$DIR/$tfile count=0
20638         $CHECKSTAT -s 0 $DIR/$tfile
20639
20640         restore_lustre_params <$p
20641         rm -f $p
20642         rm $DIR/$tfile
20643 }
20644 run_test 216 "check lockless direct write updates file size and kms correctly"
20645
20646 test_217() { # bug 22430
20647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20648
20649         local node
20650
20651         for node in $(nodes_list); do
20652                 local nid=$(host_nids_address $node $NETTYPE)
20653                 local node_ip=$(do_node $node getent ahostsv4 $node |
20654                                 awk '{ print $1; exit; }')
20655
20656                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20657                 # if hostname matches any NID, use hostname for better testing
20658                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20659                         echo "lctl ping node $node@$NETTYPE"
20660                         lctl ping $node@$NETTYPE
20661                 else # otherwise, at least test 'lctl ping' is working
20662                         echo "lctl ping nid $(h2nettype $nid)"
20663                         lctl ping $(h2nettype $nid)
20664                         echo "skipping $node (no hyphen detected)"
20665                 fi
20666         done
20667 }
20668 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20669
20670 test_218() {
20671         # do directio so as not to populate the page cache
20672         log "creating a 10 Mb file"
20673         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20674                 error "multiop failed while creating a file"
20675         log "starting reads"
20676         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20677         log "truncating the file"
20678         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20679                 error "multiop failed while truncating the file"
20680         log "killing dd"
20681         kill %+ || true # reads might have finished
20682         echo "wait until dd is finished"
20683         wait
20684         log "removing the temporary file"
20685         rm -rf $DIR/$tfile || error "tmp file removal failed"
20686 }
20687 run_test 218 "parallel read and truncate should not deadlock"
20688
20689 test_219() {
20690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20691
20692         # write one partial page
20693         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20694         # set no grant so vvp_io_commit_write will do sync write
20695         $LCTL set_param fail_loc=0x411
20696         # write a full page at the end of file
20697         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20698
20699         $LCTL set_param fail_loc=0
20700         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20701         $LCTL set_param fail_loc=0x411
20702         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20703
20704         # LU-4201
20705         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20706         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20707 }
20708 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20709
20710 test_220() { #LU-325
20711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20712         remote_ost_nodsh && skip "remote OST with nodsh"
20713         remote_mds_nodsh && skip "remote MDS with nodsh"
20714         remote_mgs_nodsh && skip "remote MGS with nodsh"
20715
20716         local OSTIDX=0
20717
20718         # create on MDT0000 so the last_id and next_id are correct
20719         mkdir_on_mdt0 $DIR/$tdir
20720         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20721         OST=${OST%_UUID}
20722
20723         # on the mdt's osc
20724         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20725         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20726                         osp.$mdtosc_proc1.prealloc_last_id)
20727         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20728                         osp.$mdtosc_proc1.prealloc_next_id)
20729
20730         $LFS df -i
20731
20732         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20733         #define OBD_FAIL_OST_ENOINO              0x229
20734         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20735         create_pool $FSNAME.$TESTNAME || return 1
20736         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20737
20738         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20739
20740         MDSOBJS=$((last_id - next_id))
20741         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20742
20743         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20744         echo "OST still has $count kbytes free"
20745
20746         echo "create $MDSOBJS files @next_id..."
20747         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20748
20749         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20750                         osp.$mdtosc_proc1.prealloc_last_id)
20751         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20752                         osp.$mdtosc_proc1.prealloc_next_id)
20753
20754         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20755         $LFS df -i
20756
20757         echo "cleanup..."
20758
20759         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20760         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20761
20762         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20763                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20764         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20765                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20766         echo "unlink $MDSOBJS files @$next_id..."
20767         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20768 }
20769 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20770
20771 test_221() {
20772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20773
20774         dd if=`which date` of=$MOUNT/date oflag=sync
20775         chmod +x $MOUNT/date
20776
20777         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20778         $LCTL set_param fail_loc=0x80001401
20779
20780         $MOUNT/date > /dev/null
20781         rm -f $MOUNT/date
20782 }
20783 run_test 221 "make sure fault and truncate race to not cause OOM"
20784
20785 test_222a () {
20786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20787
20788         rm -rf $DIR/$tdir
20789         test_mkdir $DIR/$tdir
20790         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20791         createmany -o $DIR/$tdir/$tfile 10
20792         cancel_lru_locks mdc
20793         cancel_lru_locks osc
20794         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20795         $LCTL set_param fail_loc=0x31a
20796         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20797         $LCTL set_param fail_loc=0
20798         rm -r $DIR/$tdir
20799 }
20800 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20801
20802 test_222b () {
20803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20804
20805         rm -rf $DIR/$tdir
20806         test_mkdir $DIR/$tdir
20807         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20808         createmany -o $DIR/$tdir/$tfile 10
20809         cancel_lru_locks mdc
20810         cancel_lru_locks osc
20811         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20812         $LCTL set_param fail_loc=0x31a
20813         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20814         $LCTL set_param fail_loc=0
20815 }
20816 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20817
20818 test_223 () {
20819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20820
20821         rm -rf $DIR/$tdir
20822         test_mkdir $DIR/$tdir
20823         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20824         createmany -o $DIR/$tdir/$tfile 10
20825         cancel_lru_locks mdc
20826         cancel_lru_locks osc
20827         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20828         $LCTL set_param fail_loc=0x31b
20829         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20830         $LCTL set_param fail_loc=0
20831         rm -r $DIR/$tdir
20832 }
20833 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20834
20835 test_224a() { # LU-1039, MRP-303
20836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20837         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20838         $LCTL set_param fail_loc=0x508
20839         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20840         $LCTL set_param fail_loc=0
20841         df $DIR
20842 }
20843 run_test 224a "Don't panic on bulk IO failure"
20844
20845 test_224bd_sub() { # LU-1039, MRP-303
20846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20847         local timeout=$1
20848
20849         shift
20850         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20851
20852         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20853
20854         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20855         cancel_lru_locks osc
20856         set_checksums 0
20857         stack_trap "set_checksums $ORIG_CSUM" EXIT
20858         local at_max_saved=0
20859
20860         # adaptive timeouts may prevent seeing the issue
20861         if at_is_enabled; then
20862                 at_max_saved=$(at_max_get mds)
20863                 at_max_set 0 mds client
20864                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20865         fi
20866
20867         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20868         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20869         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20870
20871         do_facet ost1 $LCTL set_param fail_loc=0
20872         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20873         df $DIR
20874 }
20875
20876 test_224b() {
20877         test_224bd_sub 3 error "dd failed"
20878 }
20879 run_test 224b "Don't panic on bulk IO failure"
20880
20881 test_224c() { # LU-6441
20882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20883         remote_mds_nodsh && skip "remote MDS with nodsh"
20884
20885         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20886         save_writethrough $p
20887         set_cache writethrough on
20888
20889         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20890         local at_max=$($LCTL get_param -n at_max)
20891         local timeout=$($LCTL get_param -n timeout)
20892         local test_at="at_max"
20893         local param_at="$FSNAME.sys.at_max"
20894         local test_timeout="timeout"
20895         local param_timeout="$FSNAME.sys.timeout"
20896
20897         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20898
20899         set_persistent_param_and_check client "$test_at" "$param_at" 0
20900         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20901
20902         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20903         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20904         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20905         stack_trap "rm -f $DIR/$tfile"
20906         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20907         sync
20908         do_facet ost1 "$LCTL set_param fail_loc=0"
20909
20910         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20911         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20912                 $timeout
20913
20914         $LCTL set_param -n $pages_per_rpc
20915         restore_lustre_params < $p
20916         rm -f $p
20917 }
20918 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20919
20920 test_224d() { # LU-11169
20921         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20922 }
20923 run_test 224d "Don't corrupt data on bulk IO timeout"
20924
20925 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20926 test_225a () {
20927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20928         if [ -z ${MDSSURVEY} ]; then
20929                 skip_env "mds-survey not found"
20930         fi
20931         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20932                 skip "Need MDS version at least 2.2.51"
20933
20934         local mds=$(facet_host $SINGLEMDS)
20935         local target=$(do_nodes $mds 'lctl dl' |
20936                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20937
20938         local cmd1="file_count=1000 thrhi=4"
20939         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20940         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20941         local cmd="$cmd1 $cmd2 $cmd3"
20942
20943         rm -f ${TMP}/mds_survey*
20944         echo + $cmd
20945         eval $cmd || error "mds-survey with zero-stripe failed"
20946         cat ${TMP}/mds_survey*
20947         rm -f ${TMP}/mds_survey*
20948 }
20949 run_test 225a "Metadata survey sanity with zero-stripe"
20950
20951 test_225b () {
20952         if [ -z ${MDSSURVEY} ]; then
20953                 skip_env "mds-survey not found"
20954         fi
20955         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20956                 skip "Need MDS version at least 2.2.51"
20957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20958         remote_mds_nodsh && skip "remote MDS with nodsh"
20959         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20960                 skip_env "Need to mount OST to test"
20961         fi
20962
20963         local mds=$(facet_host $SINGLEMDS)
20964         local target=$(do_nodes $mds 'lctl dl' |
20965                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20966
20967         local cmd1="file_count=1000 thrhi=4"
20968         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20969         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20970         local cmd="$cmd1 $cmd2 $cmd3"
20971
20972         rm -f ${TMP}/mds_survey*
20973         echo + $cmd
20974         eval $cmd || error "mds-survey with stripe_count failed"
20975         cat ${TMP}/mds_survey*
20976         rm -f ${TMP}/mds_survey*
20977 }
20978 run_test 225b "Metadata survey sanity with stripe_count = 1"
20979
20980 mcreate_path2fid () {
20981         local mode=$1
20982         local major=$2
20983         local minor=$3
20984         local name=$4
20985         local desc=$5
20986         local path=$DIR/$tdir/$name
20987         local fid
20988         local rc
20989         local fid_path
20990
20991         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20992                 error "cannot create $desc"
20993
20994         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20995         rc=$?
20996         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20997
20998         fid_path=$($LFS fid2path $MOUNT $fid)
20999         rc=$?
21000         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21001
21002         [ "$path" == "$fid_path" ] ||
21003                 error "fid2path returned $fid_path, expected $path"
21004
21005         echo "pass with $path and $fid"
21006 }
21007
21008 test_226a () {
21009         rm -rf $DIR/$tdir
21010         mkdir -p $DIR/$tdir
21011
21012         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21013         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21014         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21015         mcreate_path2fid 0040666 0 0 dir "directory"
21016         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21017         mcreate_path2fid 0100666 0 0 file "regular file"
21018         mcreate_path2fid 0120666 0 0 link "symbolic link"
21019         mcreate_path2fid 0140666 0 0 sock "socket"
21020 }
21021 run_test 226a "call path2fid and fid2path on files of all type"
21022
21023 test_226b () {
21024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21025
21026         local MDTIDX=1
21027
21028         rm -rf $DIR/$tdir
21029         mkdir -p $DIR/$tdir
21030         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21031                 error "create remote directory failed"
21032         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21033         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21034                                 "character special file (null)"
21035         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21036                                 "character special file (no device)"
21037         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21038         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21039                                 "block special file (loop)"
21040         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21041         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21042         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21043 }
21044 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21045
21046 test_226c () {
21047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21048         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21049                 skip "Need MDS version at least 2.13.55"
21050
21051         local submnt=/mnt/submnt
21052         local srcfile=/etc/passwd
21053         local dstfile=$submnt/passwd
21054         local path
21055         local fid
21056
21057         rm -rf $DIR/$tdir
21058         rm -rf $submnt
21059         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21060                 error "create remote directory failed"
21061         mkdir -p $submnt || error "create $submnt failed"
21062         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21063                 error "mount $submnt failed"
21064         stack_trap "umount $submnt" EXIT
21065
21066         cp $srcfile $dstfile
21067         fid=$($LFS path2fid $dstfile)
21068         path=$($LFS fid2path $submnt "$fid")
21069         [ "$path" = "$dstfile" ] ||
21070                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21071 }
21072 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21073
21074 test_226e () {
21075         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21076                 skip "Need client at least version 2.15.56"
21077
21078         # Define filename with 'newline' and a space
21079         local testfile="Test"$'\n'"file 01"
21080         # Define link name with multiple 'newline' and a space
21081         local linkfile="Link"$'\n'"file "$'\n'"01"
21082         # Remove prior hard link
21083         rm -f $DIR/"$linkfile"
21084
21085         # Create file
21086         touch $DIR/"$testfile"
21087         # Create link
21088         ln $DIR/"$testfile" $DIR/"$linkfile"
21089
21090         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21091                 error "getstripe failed on $DIR/$testfile"
21092
21093         # Call with -0 option
21094         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21095                 echo "FILE:" | grep -c "FILE:")
21096
21097         # With -0 option the output should be exactly 2 lines.
21098         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21099 }
21100 run_test 226e "Verify path2fid -0 option with newline and space"
21101
21102 # LU-1299 Executing or running ldd on a truncated executable does not
21103 # cause an out-of-memory condition.
21104 test_227() {
21105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21106         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21107
21108         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21109         chmod +x $MOUNT/date
21110
21111         $MOUNT/date > /dev/null
21112         ldd $MOUNT/date > /dev/null
21113         rm -f $MOUNT/date
21114 }
21115 run_test 227 "running truncated executable does not cause OOM"
21116
21117 # LU-1512 try to reuse idle OI blocks
21118 test_228a() {
21119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21120         remote_mds_nodsh && skip "remote MDS with nodsh"
21121         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21122
21123         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21124         local myDIR=$DIR/$tdir
21125
21126         mkdir -p $myDIR
21127         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21128         $LCTL set_param fail_loc=0x80001002
21129         createmany -o $myDIR/t- 10000
21130         $LCTL set_param fail_loc=0
21131         # The guard is current the largest FID holder
21132         touch $myDIR/guard
21133         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21134                     tr -d '[')
21135         local IDX=$(($SEQ % 64))
21136
21137         do_facet $SINGLEMDS sync
21138         # Make sure journal flushed.
21139         sleep 6
21140         local blk1=$(do_facet $SINGLEMDS \
21141                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21142                      grep Blockcount | awk '{print $4}')
21143
21144         # Remove old files, some OI blocks will become idle.
21145         unlinkmany $myDIR/t- 10000
21146         # Create new files, idle OI blocks should be reused.
21147         createmany -o $myDIR/t- 2000
21148         do_facet $SINGLEMDS sync
21149         # Make sure journal flushed.
21150         sleep 6
21151         local blk2=$(do_facet $SINGLEMDS \
21152                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21153                      grep Blockcount | awk '{print $4}')
21154
21155         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21156 }
21157 run_test 228a "try to reuse idle OI blocks"
21158
21159 test_228b() {
21160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21161         remote_mds_nodsh && skip "remote MDS with nodsh"
21162         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21163
21164         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21165         local myDIR=$DIR/$tdir
21166
21167         mkdir -p $myDIR
21168         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21169         $LCTL set_param fail_loc=0x80001002
21170         createmany -o $myDIR/t- 10000
21171         $LCTL set_param fail_loc=0
21172         # The guard is current the largest FID holder
21173         touch $myDIR/guard
21174         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21175                     tr -d '[')
21176         local IDX=$(($SEQ % 64))
21177
21178         do_facet $SINGLEMDS sync
21179         # Make sure journal flushed.
21180         sleep 6
21181         local blk1=$(do_facet $SINGLEMDS \
21182                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21183                      grep Blockcount | awk '{print $4}')
21184
21185         # Remove old files, some OI blocks will become idle.
21186         unlinkmany $myDIR/t- 10000
21187
21188         # stop the MDT
21189         stop $SINGLEMDS || error "Fail to stop MDT."
21190         # remount the MDT
21191         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21192                 error "Fail to start MDT."
21193
21194         client_up || error "Fail to df."
21195         # Create new files, idle OI blocks should be reused.
21196         createmany -o $myDIR/t- 2000
21197         do_facet $SINGLEMDS sync
21198         # Make sure journal flushed.
21199         sleep 6
21200         local blk2=$(do_facet $SINGLEMDS \
21201                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21202                      grep Blockcount | awk '{print $4}')
21203
21204         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21205 }
21206 run_test 228b "idle OI blocks can be reused after MDT restart"
21207
21208 #LU-1881
21209 test_228c() {
21210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21211         remote_mds_nodsh && skip "remote MDS with nodsh"
21212         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21213
21214         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21215         local myDIR=$DIR/$tdir
21216
21217         mkdir -p $myDIR
21218         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21219         $LCTL set_param fail_loc=0x80001002
21220         # 20000 files can guarantee there are index nodes in the OI file
21221         createmany -o $myDIR/t- 20000
21222         $LCTL set_param fail_loc=0
21223         # The guard is current the largest FID holder
21224         touch $myDIR/guard
21225         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21226                     tr -d '[')
21227         local IDX=$(($SEQ % 64))
21228
21229         do_facet $SINGLEMDS sync
21230         # Make sure journal flushed.
21231         sleep 6
21232         local blk1=$(do_facet $SINGLEMDS \
21233                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21234                      grep Blockcount | awk '{print $4}')
21235
21236         # Remove old files, some OI blocks will become idle.
21237         unlinkmany $myDIR/t- 20000
21238         rm -f $myDIR/guard
21239         # The OI file should become empty now
21240
21241         # Create new files, idle OI blocks should be reused.
21242         createmany -o $myDIR/t- 2000
21243         do_facet $SINGLEMDS sync
21244         # Make sure journal flushed.
21245         sleep 6
21246         local blk2=$(do_facet $SINGLEMDS \
21247                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21248                      grep Blockcount | awk '{print $4}')
21249
21250         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21251 }
21252 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21253
21254 test_229() { # LU-2482, LU-3448
21255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21256         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21257         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21258                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21259
21260         rm -f $DIR/$tfile
21261
21262         # Create a file with a released layout and stripe count 2.
21263         $MULTIOP $DIR/$tfile H2c ||
21264                 error "failed to create file with released layout"
21265
21266         $LFS getstripe -v $DIR/$tfile
21267
21268         local pattern=$($LFS getstripe -L $DIR/$tfile)
21269         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21270
21271         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21272                 error "getstripe"
21273         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21274         stat $DIR/$tfile || error "failed to stat released file"
21275
21276         chown $RUNAS_ID $DIR/$tfile ||
21277                 error "chown $RUNAS_ID $DIR/$tfile failed"
21278
21279         chgrp $RUNAS_ID $DIR/$tfile ||
21280                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21281
21282         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21283         rm $DIR/$tfile || error "failed to remove released file"
21284 }
21285 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21286
21287 test_230a() {
21288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21289         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21290         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21291                 skip "Need MDS version at least 2.11.52"
21292
21293         local MDTIDX=1
21294
21295         test_mkdir $DIR/$tdir
21296         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21297         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21298         [ $mdt_idx -ne 0 ] &&
21299                 error "create local directory on wrong MDT $mdt_idx"
21300
21301         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21302                         error "create remote directory failed"
21303         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21304         [ $mdt_idx -ne $MDTIDX ] &&
21305                 error "create remote directory on wrong MDT $mdt_idx"
21306
21307         createmany -o $DIR/$tdir/test_230/t- 10 ||
21308                 error "create files on remote directory failed"
21309         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21310         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21311         rm -r $DIR/$tdir || error "unlink remote directory failed"
21312 }
21313 run_test 230a "Create remote directory and files under the remote directory"
21314
21315 test_230b() {
21316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21317         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21318         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21319                 skip "Need MDS version at least 2.11.52"
21320
21321         local MDTIDX=1
21322         local mdt_index
21323         local i
21324         local file
21325         local pid
21326         local stripe_count
21327         local migrate_dir=$DIR/$tdir/migrate_dir
21328         local other_dir=$DIR/$tdir/other_dir
21329
21330         test_mkdir $DIR/$tdir
21331         test_mkdir -i0 -c1 $migrate_dir
21332         test_mkdir -i0 -c1 $other_dir
21333         for ((i=0; i<10; i++)); do
21334                 mkdir -p $migrate_dir/dir_${i}
21335                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21336                         error "create files under remote dir failed $i"
21337         done
21338
21339         cp /etc/passwd $migrate_dir/$tfile
21340         cp /etc/passwd $other_dir/$tfile
21341         chattr +SAD $migrate_dir
21342         chattr +SAD $migrate_dir/$tfile
21343
21344         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21345         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21346         local old_dir_mode=$(stat -c%f $migrate_dir)
21347         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21348
21349         mkdir -p $migrate_dir/dir_default_stripe2
21350         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21351         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21352
21353         mkdir -p $other_dir
21354         ln $migrate_dir/$tfile $other_dir/luna
21355         ln $migrate_dir/$tfile $migrate_dir/sofia
21356         ln $other_dir/$tfile $migrate_dir/david
21357         ln -s $migrate_dir/$tfile $other_dir/zachary
21358         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21359         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21360
21361         local len
21362         local lnktgt
21363
21364         # inline symlink
21365         for len in 58 59 60; do
21366                 lnktgt=$(str_repeat 'l' $len)
21367                 touch $migrate_dir/$lnktgt
21368                 ln -s $lnktgt $migrate_dir/${len}char_ln
21369         done
21370
21371         # PATH_MAX
21372         for len in 4094 4095; do
21373                 lnktgt=$(str_repeat 'l' $len)
21374                 ln -s $lnktgt $migrate_dir/${len}char_ln
21375         done
21376
21377         # NAME_MAX
21378         for len in 254 255; do
21379                 touch $migrate_dir/$(str_repeat 'l' $len)
21380         done
21381
21382         $LFS migrate -m $MDTIDX $migrate_dir ||
21383                 error "fails on migrating remote dir to MDT1"
21384
21385         echo "migratate to MDT1, then checking.."
21386         for ((i = 0; i < 10; i++)); do
21387                 for file in $(find $migrate_dir/dir_${i}); do
21388                         mdt_index=$($LFS getstripe -m $file)
21389                         # broken symlink getstripe will fail
21390                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21391                                 error "$file is not on MDT${MDTIDX}"
21392                 done
21393         done
21394
21395         # the multiple link file should still in MDT0
21396         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21397         [ $mdt_index == 0 ] ||
21398                 error "$file is not on MDT${MDTIDX}"
21399
21400         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21401         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21402                 error " expect $old_dir_flag get $new_dir_flag"
21403
21404         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21405         [ "$old_file_flag" = "$new_file_flag" ] ||
21406                 error " expect $old_file_flag get $new_file_flag"
21407
21408         local new_dir_mode=$(stat -c%f $migrate_dir)
21409         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21410                 error "expect mode $old_dir_mode get $new_dir_mode"
21411
21412         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21413         [ "$old_file_mode" = "$new_file_mode" ] ||
21414                 error "expect mode $old_file_mode get $new_file_mode"
21415
21416         diff /etc/passwd $migrate_dir/$tfile ||
21417                 error "$tfile different after migration"
21418
21419         diff /etc/passwd $other_dir/luna ||
21420                 error "luna different after migration"
21421
21422         diff /etc/passwd $migrate_dir/sofia ||
21423                 error "sofia different after migration"
21424
21425         diff /etc/passwd $migrate_dir/david ||
21426                 error "david different after migration"
21427
21428         diff /etc/passwd $other_dir/zachary ||
21429                 error "zachary different after migration"
21430
21431         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21432                 error "${tfile}_ln different after migration"
21433
21434         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21435                 error "${tfile}_ln_other different after migration"
21436
21437         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21438         [ $stripe_count = 2 ] ||
21439                 error "dir strpe_count $d != 2 after migration."
21440
21441         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21442         [ $stripe_count = 2 ] ||
21443                 error "file strpe_count $d != 2 after migration."
21444
21445         #migrate back to MDT0
21446         MDTIDX=0
21447
21448         $LFS migrate -m $MDTIDX $migrate_dir ||
21449                 error "fails on migrating remote dir to MDT0"
21450
21451         echo "migrate back to MDT0, checking.."
21452         for file in $(find $migrate_dir); do
21453                 mdt_index=$($LFS getstripe -m $file)
21454                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21455                         error "$file is not on MDT${MDTIDX}"
21456         done
21457
21458         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21459         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21460                 error " expect $old_dir_flag get $new_dir_flag"
21461
21462         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21463         [ "$old_file_flag" = "$new_file_flag" ] ||
21464                 error " expect $old_file_flag get $new_file_flag"
21465
21466         local new_dir_mode=$(stat -c%f $migrate_dir)
21467         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21468                 error "expect mode $old_dir_mode get $new_dir_mode"
21469
21470         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21471         [ "$old_file_mode" = "$new_file_mode" ] ||
21472                 error "expect mode $old_file_mode get $new_file_mode"
21473
21474         diff /etc/passwd ${migrate_dir}/$tfile ||
21475                 error "$tfile different after migration"
21476
21477         diff /etc/passwd ${other_dir}/luna ||
21478                 error "luna different after migration"
21479
21480         diff /etc/passwd ${migrate_dir}/sofia ||
21481                 error "sofia different after migration"
21482
21483         diff /etc/passwd ${other_dir}/zachary ||
21484                 error "zachary different after migration"
21485
21486         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21487                 error "${tfile}_ln different after migration"
21488
21489         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21490                 error "${tfile}_ln_other different after migration"
21491
21492         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21493         [ $stripe_count = 2 ] ||
21494                 error "dir strpe_count $d != 2 after migration."
21495
21496         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21497         [ $stripe_count = 2 ] ||
21498                 error "file strpe_count $d != 2 after migration."
21499
21500         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21501 }
21502 run_test 230b "migrate directory"
21503
21504 test_230c() {
21505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21507         remote_mds_nodsh && skip "remote MDS with nodsh"
21508         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21509                 skip "Need MDS version at least 2.11.52"
21510
21511         local MDTIDX=1
21512         local total=3
21513         local mdt_index
21514         local file
21515         local migrate_dir=$DIR/$tdir/migrate_dir
21516
21517         #If migrating directory fails in the middle, all entries of
21518         #the directory is still accessiable.
21519         test_mkdir $DIR/$tdir
21520         test_mkdir -i0 -c1 $migrate_dir
21521         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21522         stat $migrate_dir
21523         createmany -o $migrate_dir/f $total ||
21524                 error "create files under ${migrate_dir} failed"
21525
21526         # fail after migrating top dir, and this will fail only once, so the
21527         # first sub file migration will fail (currently f3), others succeed.
21528         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21529         do_facet mds1 lctl set_param fail_loc=0x1801
21530         local t=$(ls $migrate_dir | wc -l)
21531         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21532                 error "migrate should fail"
21533         local u=$(ls $migrate_dir | wc -l)
21534         [ "$u" == "$t" ] || error "$u != $t during migration"
21535
21536         # add new dir/file should succeed
21537         mkdir $migrate_dir/dir ||
21538                 error "mkdir failed under migrating directory"
21539         touch $migrate_dir/file ||
21540                 error "create file failed under migrating directory"
21541
21542         # add file with existing name should fail
21543         for file in $migrate_dir/f*; do
21544                 stat $file > /dev/null || error "stat $file failed"
21545                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21546                         error "open(O_CREAT|O_EXCL) $file should fail"
21547                 $MULTIOP $file m && error "create $file should fail"
21548                 touch $DIR/$tdir/remote_dir/$tfile ||
21549                         error "touch $tfile failed"
21550                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21551                         error "link $file should fail"
21552                 mdt_index=$($LFS getstripe -m $file)
21553                 if [ $mdt_index == 0 ]; then
21554                         # file failed to migrate is not allowed to rename to
21555                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21556                                 error "rename to $file should fail"
21557                 else
21558                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21559                                 error "rename to $file failed"
21560                 fi
21561                 echo hello >> $file || error "write $file failed"
21562         done
21563
21564         # resume migration with different options should fail
21565         $LFS migrate -m 0 $migrate_dir &&
21566                 error "migrate -m 0 $migrate_dir should fail"
21567
21568         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21569                 error "migrate -c 2 $migrate_dir should fail"
21570
21571         # resume migration should succeed
21572         $LFS migrate -m $MDTIDX $migrate_dir ||
21573                 error "migrate $migrate_dir failed"
21574
21575         echo "Finish migration, then checking.."
21576         for file in $(find $migrate_dir); do
21577                 mdt_index=$($LFS getstripe -m $file)
21578                 [ $mdt_index == $MDTIDX ] ||
21579                         error "$file is not on MDT${MDTIDX}"
21580         done
21581
21582         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21583 }
21584 run_test 230c "check directory accessiblity if migration failed"
21585
21586 test_230d() {
21587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21589         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21590                 skip "Need MDS version at least 2.11.52"
21591         # LU-11235
21592         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21593
21594         local migrate_dir=$DIR/$tdir/migrate_dir
21595         local old_index
21596         local new_index
21597         local old_count
21598         local new_count
21599         local new_hash
21600         local mdt_index
21601         local i
21602         local j
21603
21604         old_index=$((RANDOM % MDSCOUNT))
21605         old_count=$((MDSCOUNT - old_index))
21606         new_index=$((RANDOM % MDSCOUNT))
21607         new_count=$((MDSCOUNT - new_index))
21608         new_hash=1 # for all_char
21609
21610         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21611         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21612
21613         test_mkdir $DIR/$tdir
21614         test_mkdir -i $old_index -c $old_count $migrate_dir
21615
21616         for ((i=0; i<100; i++)); do
21617                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21618                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21619                         error "create files under remote dir failed $i"
21620         done
21621
21622         echo -n "Migrate from MDT$old_index "
21623         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21624         echo -n "to MDT$new_index"
21625         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21626         echo
21627
21628         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21629         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21630                 error "migrate remote dir error"
21631
21632         echo "Finish migration, then checking.."
21633         for file in $(find $migrate_dir -maxdepth 1); do
21634                 mdt_index=$($LFS getstripe -m $file)
21635                 if [ $mdt_index -lt $new_index ] ||
21636                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21637                         error "$file is on MDT$mdt_index"
21638                 fi
21639         done
21640
21641         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21642 }
21643 run_test 230d "check migrate big directory"
21644
21645 test_230e() {
21646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21648         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21649                 skip "Need MDS version at least 2.11.52"
21650
21651         local i
21652         local j
21653         local a_fid
21654         local b_fid
21655
21656         mkdir_on_mdt0 $DIR/$tdir
21657         mkdir $DIR/$tdir/migrate_dir
21658         mkdir $DIR/$tdir/other_dir
21659         touch $DIR/$tdir/migrate_dir/a
21660         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21661         ls $DIR/$tdir/other_dir
21662
21663         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21664                 error "migrate dir fails"
21665
21666         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21667         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21668
21669         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21670         [ $mdt_index == 0 ] || error "a is not on MDT0"
21671
21672         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21673                 error "migrate dir fails"
21674
21675         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21676         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21677
21678         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21679         [ $mdt_index == 1 ] || error "a is not on MDT1"
21680
21681         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21682         [ $mdt_index == 1 ] || error "b is not on MDT1"
21683
21684         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21685         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21686
21687         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21688
21689         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21690 }
21691 run_test 230e "migrate mulitple local link files"
21692
21693 test_230f() {
21694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21695         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21697                 skip "Need MDS version at least 2.11.52"
21698
21699         local a_fid
21700         local ln_fid
21701
21702         mkdir -p $DIR/$tdir
21703         mkdir $DIR/$tdir/migrate_dir
21704         $LFS mkdir -i1 $DIR/$tdir/other_dir
21705         touch $DIR/$tdir/migrate_dir/a
21706         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21707         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21708         ls $DIR/$tdir/other_dir
21709
21710         # a should be migrated to MDT1, since no other links on MDT0
21711         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21712                 error "#1 migrate dir fails"
21713         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21714         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21715         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21716         [ $mdt_index == 1 ] || error "a is not on MDT1"
21717
21718         # a should stay on MDT1, because it is a mulitple link file
21719         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21720                 error "#2 migrate dir fails"
21721         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21722         [ $mdt_index == 1 ] || error "a is not on MDT1"
21723
21724         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21725                 error "#3 migrate dir fails"
21726
21727         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21728         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21729         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21730
21731         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21732         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21733
21734         # a should be migrated to MDT0, since no other links on MDT1
21735         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21736                 error "#4 migrate dir fails"
21737         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21738         [ $mdt_index == 0 ] || error "a is not on MDT0"
21739
21740         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21741 }
21742 run_test 230f "migrate mulitple remote link files"
21743
21744 test_230g() {
21745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21747         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21748                 skip "Need MDS version at least 2.11.52"
21749
21750         mkdir -p $DIR/$tdir/migrate_dir
21751
21752         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21753                 error "migrating dir to non-exist MDT succeeds"
21754         true
21755 }
21756 run_test 230g "migrate dir to non-exist MDT"
21757
21758 test_230h() {
21759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21760         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21761         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21762                 skip "Need MDS version at least 2.11.52"
21763
21764         local mdt_index
21765
21766         mkdir -p $DIR/$tdir/migrate_dir
21767
21768         $LFS migrate -m1 $DIR &&
21769                 error "migrating mountpoint1 should fail"
21770
21771         $LFS migrate -m1 $DIR/$tdir/.. &&
21772                 error "migrating mountpoint2 should fail"
21773
21774         # same as mv
21775         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21776                 error "migrating $tdir/migrate_dir/.. should fail"
21777
21778         true
21779 }
21780 run_test 230h "migrate .. and root"
21781
21782 test_230i() {
21783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21784         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21785         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21786                 skip "Need MDS version at least 2.11.52"
21787
21788         mkdir -p $DIR/$tdir/migrate_dir
21789
21790         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21791                 error "migration fails with a tailing slash"
21792
21793         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21794                 error "migration fails with two tailing slashes"
21795 }
21796 run_test 230i "lfs migrate -m tolerates trailing slashes"
21797
21798 test_230j() {
21799         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21800         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21801                 skip "Need MDS version at least 2.11.52"
21802
21803         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21804         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21805                 error "create $tfile failed"
21806         cat /etc/passwd > $DIR/$tdir/$tfile
21807
21808         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21809
21810         cmp /etc/passwd $DIR/$tdir/$tfile ||
21811                 error "DoM file mismatch after migration"
21812 }
21813 run_test 230j "DoM file data not changed after dir migration"
21814
21815 test_230k() {
21816         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21817         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21818                 skip "Need MDS version at least 2.11.56"
21819
21820         local total=20
21821         local files_on_starting_mdt=0
21822
21823         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21824         $LFS getdirstripe $DIR/$tdir
21825         for i in $(seq $total); do
21826                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21827                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21828                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21829         done
21830
21831         echo "$files_on_starting_mdt files on MDT0"
21832
21833         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21834         $LFS getdirstripe $DIR/$tdir
21835
21836         files_on_starting_mdt=0
21837         for i in $(seq $total); do
21838                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21839                         error "file $tfile.$i mismatch after migration"
21840                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21841                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21842         done
21843
21844         echo "$files_on_starting_mdt files on MDT1 after migration"
21845         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21846
21847         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21848         $LFS getdirstripe $DIR/$tdir
21849
21850         files_on_starting_mdt=0
21851         for i in $(seq $total); do
21852                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21853                         error "file $tfile.$i mismatch after 2nd migration"
21854                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21855                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21856         done
21857
21858         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21859         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21860
21861         true
21862 }
21863 run_test 230k "file data not changed after dir migration"
21864
21865 test_230l() {
21866         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21867         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21868                 skip "Need MDS version at least 2.11.56"
21869
21870         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21871         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21872                 error "create files under remote dir failed $i"
21873         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21874 }
21875 run_test 230l "readdir between MDTs won't crash"
21876
21877 test_230m() {
21878         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21879         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21880                 skip "Need MDS version at least 2.11.56"
21881
21882         local MDTIDX=1
21883         local mig_dir=$DIR/$tdir/migrate_dir
21884         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21885         local shortstr="b"
21886         local val
21887
21888         echo "Creating files and dirs with xattrs"
21889         test_mkdir $DIR/$tdir
21890         test_mkdir -i0 -c1 $mig_dir
21891         mkdir $mig_dir/dir
21892         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21893                 error "cannot set xattr attr1 on dir"
21894         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21895                 error "cannot set xattr attr2 on dir"
21896         touch $mig_dir/dir/f0
21897         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21898                 error "cannot set xattr attr1 on file"
21899         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21900                 error "cannot set xattr attr2 on file"
21901         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21902         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21903         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21904         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21905         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21906         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21907         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21908         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21909         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21910
21911         echo "Migrating to MDT1"
21912         $LFS migrate -m $MDTIDX $mig_dir ||
21913                 error "fails on migrating dir to MDT1"
21914
21915         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21916         echo "Checking xattrs"
21917         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21918         [ "$val" = $longstr ] ||
21919                 error "expecting xattr1 $longstr on dir, found $val"
21920         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21921         [ "$val" = $shortstr ] ||
21922                 error "expecting xattr2 $shortstr on dir, found $val"
21923         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21924         [ "$val" = $longstr ] ||
21925                 error "expecting xattr1 $longstr on file, found $val"
21926         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21927         [ "$val" = $shortstr ] ||
21928                 error "expecting xattr2 $shortstr on file, found $val"
21929 }
21930 run_test 230m "xattrs not changed after dir migration"
21931
21932 test_230n() {
21933         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21934         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21935                 skip "Need MDS version at least 2.13.53"
21936
21937         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21938         cat /etc/hosts > $DIR/$tdir/$tfile
21939         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21940         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21941
21942         cmp /etc/hosts $DIR/$tdir/$tfile ||
21943                 error "File data mismatch after migration"
21944 }
21945 run_test 230n "Dir migration with mirrored file"
21946
21947 test_230o() {
21948         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21949         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21950                 skip "Need MDS version at least 2.13.52"
21951
21952         local mdts=$(comma_list $(mdts_nodes))
21953         local timeout=100
21954         local restripe_status
21955         local delta
21956         local i
21957
21958         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21959
21960         # in case "crush" hash type is not set
21961         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21962
21963         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21964                            mdt.*MDT0000.enable_dir_restripe)
21965         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21966         stack_trap "do_nodes $mdts $LCTL set_param \
21967                     mdt.*.enable_dir_restripe=$restripe_status"
21968
21969         mkdir $DIR/$tdir
21970         createmany -m $DIR/$tdir/f 100 ||
21971                 error "create files under remote dir failed $i"
21972         createmany -d $DIR/$tdir/d 100 ||
21973                 error "create dirs under remote dir failed $i"
21974
21975         for i in $(seq 2 $MDSCOUNT); do
21976                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21977                 $LFS setdirstripe -c $i $DIR/$tdir ||
21978                         error "split -c $i $tdir failed"
21979                 wait_update $HOSTNAME \
21980                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21981                         error "dir split not finished"
21982                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21983                         awk '/migrate/ {sum += $2} END { print sum }')
21984                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21985                 # delta is around total_files/stripe_count
21986                 (( $delta < 200 / (i - 1) + 4 )) ||
21987                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21988         done
21989 }
21990 run_test 230o "dir split"
21991
21992 test_230p() {
21993         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21994         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21995                 skip "Need MDS version at least 2.13.52"
21996
21997         local mdts=$(comma_list $(mdts_nodes))
21998         local timeout=100
21999         local restripe_status
22000         local delta
22001         local c
22002
22003         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22004
22005         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22006
22007         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22008                            mdt.*MDT0000.enable_dir_restripe)
22009         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22010         stack_trap "do_nodes $mdts $LCTL set_param \
22011                     mdt.*.enable_dir_restripe=$restripe_status"
22012
22013         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22014         createmany -m $DIR/$tdir/f 100 ||
22015                 error "create files under remote dir failed"
22016         createmany -d $DIR/$tdir/d 100 ||
22017                 error "create dirs under remote dir failed"
22018
22019         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22020                 local mdt_hash="crush"
22021
22022                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22023                 $LFS setdirstripe -c $c $DIR/$tdir ||
22024                         error "split -c $c $tdir failed"
22025                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22026                         mdt_hash="$mdt_hash,fixed"
22027                 elif [ $c -eq 1 ]; then
22028                         mdt_hash="none"
22029                 fi
22030                 wait_update $HOSTNAME \
22031                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22032                         error "dir merge not finished"
22033                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22034                         awk '/migrate/ {sum += $2} END { print sum }')
22035                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22036                 # delta is around total_files/stripe_count
22037                 (( delta < 200 / c + 4 )) ||
22038                         error "$delta files migrated >= $((200 / c + 4))"
22039         done
22040 }
22041 run_test 230p "dir merge"
22042
22043 test_230q() {
22044         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22045         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22046                 skip "Need MDS version at least 2.13.52"
22047
22048         local mdts=$(comma_list $(mdts_nodes))
22049         local saved_threshold=$(do_facet mds1 \
22050                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22051         local saved_delta=$(do_facet mds1 \
22052                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22053         local threshold=100
22054         local delta=2
22055         local total=0
22056         local stripe_count=0
22057         local stripe_index
22058         local nr_files
22059         local create
22060
22061         # test with fewer files on ZFS
22062         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22063
22064         stack_trap "do_nodes $mdts $LCTL set_param \
22065                     mdt.*.dir_split_count=$saved_threshold"
22066         stack_trap "do_nodes $mdts $LCTL set_param \
22067                     mdt.*.dir_split_delta=$saved_delta"
22068         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22069         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22070         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22071         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22072         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22073         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22074
22075         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22076         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22077
22078         create=$((threshold * 3 / 2))
22079         while [ $stripe_count -lt $MDSCOUNT ]; do
22080                 createmany -m $DIR/$tdir/f $total $create ||
22081                         error "create sub files failed"
22082                 stat $DIR/$tdir > /dev/null
22083                 total=$((total + create))
22084                 stripe_count=$((stripe_count + delta))
22085                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22086
22087                 wait_update $HOSTNAME \
22088                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22089                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22090
22091                 wait_update $HOSTNAME \
22092                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22093                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22094
22095                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22096                 echo "$nr_files/$total files on MDT$stripe_index after split"
22097                 # allow 10% margin of imbalance with crush hash
22098                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22099                         error "$nr_files files on MDT$stripe_index after split"
22100
22101                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22102                 [ $nr_files -eq $total ] ||
22103                         error "total sub files $nr_files != $total"
22104         done
22105
22106         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22107
22108         echo "fixed layout directory won't auto split"
22109         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22110         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22111                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22112         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22113                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22114 }
22115 run_test 230q "dir auto split"
22116
22117 test_230r() {
22118         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22119         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22120         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22121                 skip "Need MDS version at least 2.13.54"
22122
22123         # maximum amount of local locks:
22124         # parent striped dir - 2 locks
22125         # new stripe in parent to migrate to - 1 lock
22126         # source and target - 2 locks
22127         # Total 5 locks for regular file
22128         mkdir -p $DIR/$tdir
22129         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22130         touch $DIR/$tdir/dir1/eee
22131
22132         # create 4 hardlink for 4 more locks
22133         # Total: 9 locks > RS_MAX_LOCKS (8)
22134         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22135         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22136         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22137         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22138         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22139         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22140         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22141         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22142
22143         cancel_lru_locks mdc
22144
22145         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22146                 error "migrate dir fails"
22147
22148         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22149 }
22150 run_test 230r "migrate with too many local locks"
22151
22152 test_230s() {
22153         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22154                 skip "Need MDS version at least 2.14.52"
22155
22156         local mdts=$(comma_list $(mdts_nodes))
22157         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22158                                 mdt.*MDT0000.enable_dir_restripe)
22159
22160         stack_trap "do_nodes $mdts $LCTL set_param \
22161                     mdt.*.enable_dir_restripe=$restripe_status"
22162
22163         local st
22164         for st in 0 1; do
22165                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22166                 test_mkdir $DIR/$tdir
22167                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22168                         error "$LFS mkdir should return EEXIST if target exists"
22169                 rmdir $DIR/$tdir
22170         done
22171 }
22172 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22173
22174 test_230t()
22175 {
22176         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22177         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22178                 skip "Need MDS version at least 2.14.50"
22179
22180         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22181         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22182         $LFS project -p 1 -s $DIR/$tdir ||
22183                 error "set $tdir project id failed"
22184         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22185                 error "set subdir project id failed"
22186         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22187 }
22188 run_test 230t "migrate directory with project ID set"
22189
22190 test_230u()
22191 {
22192         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22193         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22194                 skip "Need MDS version at least 2.14.53"
22195
22196         local count
22197
22198         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22199         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22200         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22201         for i in $(seq 0 $((MDSCOUNT - 1))); do
22202                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22203                 echo "$count dirs migrated to MDT$i"
22204         done
22205         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22206         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22207 }
22208 run_test 230u "migrate directory by QOS"
22209
22210 test_230v()
22211 {
22212         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22213         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22214                 skip "Need MDS version at least 2.14.53"
22215
22216         local count
22217
22218         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22219         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22220         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22221         for i in $(seq 0 $((MDSCOUNT - 1))); do
22222                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22223                 echo "$count subdirs migrated to MDT$i"
22224                 (( i == 3 )) && (( count > 0 )) &&
22225                         error "subdir shouldn't be migrated to MDT3"
22226         done
22227         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22228         (( count == 3 )) || error "dirs migrated to $count MDTs"
22229 }
22230 run_test 230v "subdir migrated to the MDT where its parent is located"
22231
22232 test_230w() {
22233         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22234         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22235                 skip "Need MDS version at least 2.15.0"
22236
22237         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22238         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22239         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22240
22241         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22242                 error "migrate failed"
22243
22244         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22245                 error "$tdir stripe count mismatch"
22246
22247         for i in $(seq 0 9); do
22248                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22249                         error "d$i is striped"
22250         done
22251 }
22252 run_test 230w "non-recursive mode dir migration"
22253
22254 test_230x() {
22255         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22256         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22257                 skip "Need MDS version at least 2.15.0"
22258
22259         mkdir -p $DIR/$tdir || error "mkdir failed"
22260         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22261
22262         local mdt_name=$(mdtname_from_index 0)
22263         local low=$(do_facet mds2 $LCTL get_param -n \
22264                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22265         local high=$(do_facet mds2 $LCTL get_param -n \
22266                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22267         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22268         local maxage=$(do_facet mds2 $LCTL get_param -n \
22269                 osp.*$mdt_name-osp-MDT0001.maxage)
22270
22271         stack_trap "do_facet mds2 $LCTL set_param -n \
22272                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22273                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22274         stack_trap "do_facet mds2 $LCTL set_param -n \
22275                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22276
22277         do_facet mds2 $LCTL set_param -n \
22278                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22279         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22280         sleep 4
22281         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22282                 error "migrate $tdir should fail"
22283
22284         do_facet mds2 $LCTL set_param -n \
22285                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22286         do_facet mds2 $LCTL set_param -n \
22287                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22288         sleep 4
22289         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22290                 error "migrate failed"
22291         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22292                 error "$tdir stripe count mismatch"
22293 }
22294 run_test 230x "dir migration check space"
22295
22296 test_230y() {
22297         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22298         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22299                 skip "Need MDS version at least 2.15.55.45"
22300
22301         local pid
22302
22303         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22304         $LFS getdirstripe $DIR/$tdir
22305         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22306         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22307         pid=$!
22308         sleep 1
22309
22310         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22311         do_facet mds2 lctl set_param fail_loc=0x1802
22312
22313         wait $pid
22314         do_facet mds2 lctl set_param fail_loc=0
22315         $LFS getdirstripe $DIR/$tdir
22316         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22317         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22318 }
22319 run_test 230y "unlink dir with bad hash type"
22320
22321 test_230z() {
22322         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22323         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22324                 skip "Need MDS version at least 2.15.55.45"
22325
22326         local pid
22327
22328         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22329         $LFS getdirstripe $DIR/$tdir
22330         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22331         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22332         pid=$!
22333         sleep 1
22334
22335         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22336         do_facet mds2 lctl set_param fail_loc=0x1802
22337
22338         wait $pid
22339         do_facet mds2 lctl set_param fail_loc=0
22340         $LFS getdirstripe $DIR/$tdir
22341
22342         # resume migration
22343         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22344                 error "resume migration failed"
22345         $LFS getdirstripe $DIR/$tdir
22346         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22347                 error "migration is not finished"
22348 }
22349 run_test 230z "resume dir migration with bad hash type"
22350
22351 test_231a()
22352 {
22353         # For simplicity this test assumes that max_pages_per_rpc
22354         # is the same across all OSCs
22355         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22356         local bulk_size=$((max_pages * PAGE_SIZE))
22357         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22358                                        head -n 1)
22359
22360         mkdir -p $DIR/$tdir
22361         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22362                 error "failed to set stripe with -S ${brw_size}M option"
22363         stack_trap "rm -rf $DIR/$tdir"
22364
22365         # clear the OSC stats
22366         $LCTL set_param osc.*.stats=0 &>/dev/null
22367         stop_writeback
22368
22369         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22370         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22371                 oflag=direct &>/dev/null || error "dd failed"
22372
22373         sync; sleep 1; sync # just to be safe
22374         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22375         if [ x$nrpcs != "x1" ]; then
22376                 $LCTL get_param osc.*.stats
22377                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22378         fi
22379
22380         start_writeback
22381         # Drop the OSC cache, otherwise we will read from it
22382         cancel_lru_locks osc
22383
22384         # clear the OSC stats
22385         $LCTL set_param osc.*.stats=0 &>/dev/null
22386
22387         # Client reads $bulk_size.
22388         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22389                 iflag=direct &>/dev/null || error "dd failed"
22390
22391         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22392         if [ x$nrpcs != "x1" ]; then
22393                 $LCTL get_param osc.*.stats
22394                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22395         fi
22396 }
22397 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22398
22399 test_231b() {
22400         mkdir -p $DIR/$tdir
22401         stack_trap "rm -rf $DIR/$tdir"
22402         local i
22403         for i in {0..1023}; do
22404                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22405                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22406                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22407         done
22408         sync
22409 }
22410 run_test 231b "must not assert on fully utilized OST request buffer"
22411
22412 test_232a() {
22413         mkdir -p $DIR/$tdir
22414         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22415
22416         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22417         do_facet ost1 $LCTL set_param fail_loc=0x31c
22418
22419         # ignore dd failure
22420         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22421         stack_trap "rm -f $DIR/$tdir/$tfile"
22422
22423         do_facet ost1 $LCTL set_param fail_loc=0
22424         umount_client $MOUNT || error "umount failed"
22425         mount_client $MOUNT || error "mount failed"
22426         stop ost1 || error "cannot stop ost1"
22427         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22428 }
22429 run_test 232a "failed lock should not block umount"
22430
22431 test_232b() {
22432         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22433                 skip "Need MDS version at least 2.10.58"
22434
22435         mkdir -p $DIR/$tdir
22436         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22437         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22438         stack_trap "rm -f $DIR/$tdir/$tfile"
22439         sync
22440         cancel_lru_locks osc
22441
22442         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22443         do_facet ost1 $LCTL set_param fail_loc=0x31c
22444
22445         # ignore failure
22446         $LFS data_version $DIR/$tdir/$tfile || true
22447
22448         do_facet ost1 $LCTL set_param fail_loc=0
22449         umount_client $MOUNT || error "umount failed"
22450         mount_client $MOUNT || error "mount failed"
22451         stop ost1 || error "cannot stop ost1"
22452         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22453 }
22454 run_test 232b "failed data version lock should not block umount"
22455
22456 test_233a() {
22457         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22458                 skip "Need MDS version at least 2.3.64"
22459         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22460
22461         local fid=$($LFS path2fid $MOUNT)
22462
22463         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22464                 error "cannot access $MOUNT using its FID '$fid'"
22465 }
22466 run_test 233a "checking that OBF of the FS root succeeds"
22467
22468 test_233b() {
22469         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22470                 skip "Need MDS version at least 2.5.90"
22471         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22472
22473         local fid=$($LFS path2fid $MOUNT/.lustre)
22474
22475         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22476                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22477
22478         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22479         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22480                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22481 }
22482 run_test 233b "checking that OBF of the FS .lustre succeeds"
22483
22484 test_234() {
22485         local p="$TMP/sanityN-$TESTNAME.parameters"
22486         save_lustre_params client "llite.*.xattr_cache" > $p
22487         lctl set_param llite.*.xattr_cache 1 ||
22488                 skip_env "xattr cache is not supported"
22489
22490         mkdir -p $DIR/$tdir || error "mkdir failed"
22491         touch $DIR/$tdir/$tfile || error "touch failed"
22492         # OBD_FAIL_LLITE_XATTR_ENOMEM
22493         $LCTL set_param fail_loc=0x1405
22494         getfattr -n user.attr $DIR/$tdir/$tfile &&
22495                 error "getfattr should have failed with ENOMEM"
22496         $LCTL set_param fail_loc=0x0
22497         rm -rf $DIR/$tdir
22498
22499         restore_lustre_params < $p
22500         rm -f $p
22501 }
22502 run_test 234 "xattr cache should not crash on ENOMEM"
22503
22504 test_235() {
22505         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22506                 skip "Need MDS version at least 2.4.52"
22507
22508         flock_deadlock $DIR/$tfile
22509         local RC=$?
22510         case $RC in
22511                 0)
22512                 ;;
22513                 124) error "process hangs on a deadlock"
22514                 ;;
22515                 *) error "error executing flock_deadlock $DIR/$tfile"
22516                 ;;
22517         esac
22518 }
22519 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22520
22521 #LU-2935
22522 test_236() {
22523         check_swap_layouts_support
22524
22525         local ref1=/etc/passwd
22526         local ref2=/etc/group
22527         local file1=$DIR/$tdir/f1
22528         local file2=$DIR/$tdir/f2
22529
22530         test_mkdir -c1 $DIR/$tdir
22531         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22532         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22533         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22534         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22535         local fd=$(free_fd)
22536         local cmd="exec $fd<>$file2"
22537         eval $cmd
22538         rm $file2
22539         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22540                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22541         cmd="exec $fd>&-"
22542         eval $cmd
22543         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22544
22545         #cleanup
22546         rm -rf $DIR/$tdir
22547 }
22548 run_test 236 "Layout swap on open unlinked file"
22549
22550 # LU-4659 linkea consistency
22551 test_238() {
22552         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22553                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22554                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22555                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22556
22557         touch $DIR/$tfile
22558         ln $DIR/$tfile $DIR/$tfile.lnk
22559         touch $DIR/$tfile.new
22560         mv $DIR/$tfile.new $DIR/$tfile
22561         local fid1=$($LFS path2fid $DIR/$tfile)
22562         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22563         local path1=$($LFS fid2path $FSNAME "$fid1")
22564         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22565         local path2=$($LFS fid2path $FSNAME "$fid2")
22566         [ $tfile.lnk == $path2 ] ||
22567                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22568         rm -f $DIR/$tfile*
22569 }
22570 run_test 238 "Verify linkea consistency"
22571
22572 test_239A() { # was test_239
22573         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22574                 skip "Need MDS version at least 2.5.60"
22575
22576         local list=$(comma_list $(mdts_nodes))
22577
22578         mkdir -p $DIR/$tdir
22579         createmany -o $DIR/$tdir/f- 5000
22580         unlinkmany $DIR/$tdir/f- 5000
22581         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22582                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22583         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22584                         osp.*MDT*.sync_in_flight" | calc_sum)
22585         [ "$changes" -eq 0 ] || error "$changes not synced"
22586 }
22587 run_test 239A "osp_sync test"
22588
22589 test_239a() { #LU-5297
22590         remote_mds_nodsh && skip "remote MDS with nodsh"
22591
22592         touch $DIR/$tfile
22593         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22594         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22595         chgrp $RUNAS_GID $DIR/$tfile
22596         wait_delete_completed
22597 }
22598 run_test 239a "process invalid osp sync record correctly"
22599
22600 test_239b() { #LU-5297
22601         remote_mds_nodsh && skip "remote MDS with nodsh"
22602
22603         touch $DIR/$tfile1
22604         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22605         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22606         chgrp $RUNAS_GID $DIR/$tfile1
22607         wait_delete_completed
22608         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22609         touch $DIR/$tfile2
22610         chgrp $RUNAS_GID $DIR/$tfile2
22611         wait_delete_completed
22612 }
22613 run_test 239b "process osp sync record with ENOMEM error correctly"
22614
22615 test_240() {
22616         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22617         remote_mds_nodsh && skip "remote MDS with nodsh"
22618
22619         mkdir -p $DIR/$tdir
22620
22621         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22622                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22623         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22624                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22625
22626         umount_client $MOUNT || error "umount failed"
22627         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22628         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22629         mount_client $MOUNT || error "failed to mount client"
22630
22631         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22632         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22633 }
22634 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22635
22636 test_241_bio() {
22637         local count=$1
22638         local bsize=$2
22639
22640         for LOOP in $(seq $count); do
22641                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22642                 cancel_lru_locks $OSC || true
22643         done
22644 }
22645
22646 test_241_dio() {
22647         local count=$1
22648         local bsize=$2
22649
22650         for LOOP in $(seq $1); do
22651                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22652                         2>/dev/null
22653         done
22654 }
22655
22656 test_241a() { # was test_241
22657         local bsize=$PAGE_SIZE
22658
22659         (( bsize < 40960 )) && bsize=40960
22660         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22661         ls -la $DIR/$tfile
22662         cancel_lru_locks $OSC
22663         test_241_bio 1000 $bsize &
22664         PID=$!
22665         test_241_dio 1000 $bsize
22666         wait $PID
22667 }
22668 run_test 241a "bio vs dio"
22669
22670 test_241b() {
22671         local bsize=$PAGE_SIZE
22672
22673         (( bsize < 40960 )) && bsize=40960
22674         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22675         ls -la $DIR/$tfile
22676         test_241_dio 1000 $bsize &
22677         PID=$!
22678         test_241_dio 1000 $bsize
22679         wait $PID
22680 }
22681 run_test 241b "dio vs dio"
22682
22683 test_242() {
22684         remote_mds_nodsh && skip "remote MDS with nodsh"
22685
22686         mkdir_on_mdt0 $DIR/$tdir
22687         touch $DIR/$tdir/$tfile
22688
22689         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22690         do_facet mds1 lctl set_param fail_loc=0x105
22691         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22692
22693         do_facet mds1 lctl set_param fail_loc=0
22694         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22695 }
22696 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22697
22698 test_243()
22699 {
22700         test_mkdir $DIR/$tdir
22701         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22702 }
22703 run_test 243 "various group lock tests"
22704
22705 test_244a()
22706 {
22707         test_mkdir $DIR/$tdir
22708         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22709         sendfile_grouplock $DIR/$tdir/$tfile || \
22710                 error "sendfile+grouplock failed"
22711         rm -rf $DIR/$tdir
22712 }
22713 run_test 244a "sendfile with group lock tests"
22714
22715 test_244b()
22716 {
22717         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22718
22719         local threads=50
22720         local size=$((1024*1024))
22721
22722         test_mkdir $DIR/$tdir
22723         for i in $(seq 1 $threads); do
22724                 local file=$DIR/$tdir/file_$((i / 10))
22725                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22726                 local pids[$i]=$!
22727         done
22728         for i in $(seq 1 $threads); do
22729                 wait ${pids[$i]}
22730         done
22731 }
22732 run_test 244b "multi-threaded write with group lock"
22733
22734 test_245a() {
22735         local flagname="multi_mod_rpcs"
22736         local connect_data_name="max_mod_rpcs"
22737         local out
22738
22739         # check if multiple modify RPCs flag is set
22740         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22741                 grep "connect_flags:")
22742         echo "$out"
22743
22744         echo "$out" | grep -qw $flagname
22745         if [ $? -ne 0 ]; then
22746                 echo "connect flag $flagname is not set"
22747                 return
22748         fi
22749
22750         # check if multiple modify RPCs data is set
22751         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22752         echo "$out"
22753
22754         echo "$out" | grep -qw $connect_data_name ||
22755                 error "import should have connect data $connect_data_name"
22756 }
22757 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22758
22759 test_245b() {
22760         local flagname="multi_mod_rpcs"
22761         local connect_data_name="max_mod_rpcs"
22762         local out
22763
22764         remote_mds_nodsh && skip "remote MDS with nodsh"
22765         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22766
22767         # check if multiple modify RPCs flag is set
22768         out=$(do_facet mds1 \
22769               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22770               grep "connect_flags:")
22771         echo "$out"
22772
22773         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22774
22775         # check if multiple modify RPCs data is set
22776         out=$(do_facet mds1 \
22777               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22778
22779         [[ "$out" =~ $connect_data_name ]] ||
22780                 {
22781                         echo "$out"
22782                         error "missing connect data $connect_data_name"
22783                 }
22784 }
22785 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22786
22787 cleanup_247() {
22788         local submount=$1
22789
22790         trap 0
22791         umount_client $submount
22792         rmdir $submount
22793 }
22794
22795 test_247a() {
22796         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22797                 grep -q subtree ||
22798                 skip_env "Fileset feature is not supported"
22799
22800         local submount=${MOUNT}_$tdir
22801
22802         mkdir $MOUNT/$tdir
22803         mkdir -p $submount || error "mkdir $submount failed"
22804         FILESET="$FILESET/$tdir" mount_client $submount ||
22805                 error "mount $submount failed"
22806         trap "cleanup_247 $submount" EXIT
22807         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22808         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22809                 error "read $MOUNT/$tdir/$tfile failed"
22810         cleanup_247 $submount
22811 }
22812 run_test 247a "mount subdir as fileset"
22813
22814 test_247b() {
22815         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22816                 skip_env "Fileset feature is not supported"
22817
22818         local submount=${MOUNT}_$tdir
22819
22820         rm -rf $MOUNT/$tdir
22821         mkdir -p $submount || error "mkdir $submount failed"
22822         SKIP_FILESET=1
22823         FILESET="$FILESET/$tdir" mount_client $submount &&
22824                 error "mount $submount should fail"
22825         rmdir $submount
22826 }
22827 run_test 247b "mount subdir that dose not exist"
22828
22829 test_247c() {
22830         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22831                 skip_env "Fileset feature is not supported"
22832
22833         local submount=${MOUNT}_$tdir
22834
22835         mkdir -p $MOUNT/$tdir/dir1
22836         mkdir -p $submount || error "mkdir $submount failed"
22837         trap "cleanup_247 $submount" EXIT
22838         FILESET="$FILESET/$tdir" mount_client $submount ||
22839                 error "mount $submount failed"
22840         local fid=$($LFS path2fid $MOUNT/)
22841         $LFS fid2path $submount $fid && error "fid2path should fail"
22842         cleanup_247 $submount
22843 }
22844 run_test 247c "running fid2path outside subdirectory root"
22845
22846 test_247d() {
22847         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22848                 skip "Fileset feature is not supported"
22849
22850         local submount=${MOUNT}_$tdir
22851
22852         mkdir -p $MOUNT/$tdir/dir1
22853         mkdir -p $submount || error "mkdir $submount failed"
22854         FILESET="$FILESET/$tdir" mount_client $submount ||
22855                 error "mount $submount failed"
22856         trap "cleanup_247 $submount" EXIT
22857
22858         local td=$submount/dir1
22859         local fid=$($LFS path2fid $td)
22860         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22861
22862         # check that we get the same pathname back
22863         local rootpath
22864         local found
22865         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22866                 echo "$rootpath $fid"
22867                 found=$($LFS fid2path $rootpath "$fid")
22868                 [ -n "$found" ] || error "fid2path should succeed"
22869                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22870         done
22871         # check wrong root path format
22872         rootpath=$submount"_wrong"
22873         found=$($LFS fid2path $rootpath "$fid")
22874         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22875
22876         cleanup_247 $submount
22877 }
22878 run_test 247d "running fid2path inside subdirectory root"
22879
22880 # LU-8037
22881 test_247e() {
22882         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22883                 grep -q subtree ||
22884                 skip "Fileset feature is not supported"
22885
22886         local submount=${MOUNT}_$tdir
22887
22888         mkdir $MOUNT/$tdir
22889         mkdir -p $submount || error "mkdir $submount failed"
22890         FILESET="$FILESET/.." mount_client $submount &&
22891                 error "mount $submount should fail"
22892         rmdir $submount
22893 }
22894 run_test 247e "mount .. as fileset"
22895
22896 test_247f() {
22897         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22898         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22899                 skip "Need at least version 2.14.50.162"
22900         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22901                 skip "Fileset feature is not supported"
22902
22903         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22904         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22905                 error "mkdir remote failed"
22906         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22907                 error "mkdir remote/subdir failed"
22908         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22909                 error "mkdir striped failed"
22910         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22911
22912         local submount=${MOUNT}_$tdir
22913
22914         mkdir -p $submount || error "mkdir $submount failed"
22915         stack_trap "rmdir $submount"
22916
22917         local dir
22918         local fileset=$FILESET
22919         local mdts=$(comma_list $(mdts_nodes))
22920
22921         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22922         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22923                 $tdir/striped/subdir $tdir/striped/.; do
22924                 FILESET="$fileset/$dir" mount_client $submount ||
22925                         error "mount $dir failed"
22926                 umount_client $submount
22927         done
22928 }
22929 run_test 247f "mount striped or remote directory as fileset"
22930
22931 test_subdir_mount_lock()
22932 {
22933         local testdir=$1
22934         local submount=${MOUNT}_$(basename $testdir)
22935
22936         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22937
22938         mkdir -p $submount || error "mkdir $submount failed"
22939         stack_trap "rmdir $submount"
22940
22941         FILESET="$fileset/$testdir" mount_client $submount ||
22942                 error "mount $FILESET failed"
22943         stack_trap "umount $submount"
22944
22945         local mdts=$(comma_list $(mdts_nodes))
22946
22947         local nrpcs
22948
22949         stat $submount > /dev/null || error "stat $submount failed"
22950         cancel_lru_locks $MDC
22951         stat $submount > /dev/null || error "stat $submount failed"
22952         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22953         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22954         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22955         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22956                 awk '/getattr/ {sum += $2} END {print sum}')
22957
22958         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22959 }
22960
22961 test_247g() {
22962         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22963
22964         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22965                 error "mkdir $tdir failed"
22966         test_subdir_mount_lock $tdir
22967 }
22968 run_test 247g "striped directory submount revalidate ROOT from cache"
22969
22970 test_247h() {
22971         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22972         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22973                 skip "Need MDS version at least 2.15.51"
22974
22975         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22976         test_subdir_mount_lock $tdir
22977         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22978         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22979                 error "mkdir $tdir.1 failed"
22980         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22981 }
22982 run_test 247h "remote directory submount revalidate ROOT from cache"
22983
22984 test_248a() {
22985         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22986         [ -z "$fast_read_sav" ] && skip "no fast read support"
22987
22988         # create a large file for fast read verification
22989         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22990
22991         # make sure the file is created correctly
22992         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22993                 { rm -f $DIR/$tfile; skip "file creation error"; }
22994
22995         echo "Test 1: verify that fast read is 4 times faster on cache read"
22996
22997         # small read with fast read enabled
22998         $LCTL set_param -n llite.*.fast_read=1
22999         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23000                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23001                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23002         # small read with fast read disabled
23003         $LCTL set_param -n llite.*.fast_read=0
23004         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23005                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23006                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23007
23008         # verify that fast read is 4 times faster for cache read
23009         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23010                 error_not_in_vm "fast read was not 4 times faster: " \
23011                            "$t_fast vs $t_slow"
23012
23013         echo "Test 2: verify the performance between big and small read"
23014         $LCTL set_param -n llite.*.fast_read=1
23015
23016         # 1k non-cache read
23017         cancel_lru_locks osc
23018         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23019                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23020                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23021
23022         # 1M non-cache read
23023         cancel_lru_locks osc
23024         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23025                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23026                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23027
23028         # verify that big IO is not 4 times faster than small IO
23029         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23030                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23031
23032         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23033         rm -f $DIR/$tfile
23034 }
23035 run_test 248a "fast read verification"
23036
23037 test_248b() {
23038         # Default short_io_bytes=16384, try both smaller and larger sizes.
23039         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23040         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23041         echo "bs=53248 count=113 normal buffered write"
23042         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23043                 error "dd of initial data file failed"
23044         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23045
23046         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23047         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23048                 error "dd with sync normal writes failed"
23049         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23050
23051         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23052         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23053                 error "dd with sync small writes failed"
23054         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23055
23056         cancel_lru_locks osc
23057
23058         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23059         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23060         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23061         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23062                 iflag=direct || error "dd with O_DIRECT small read failed"
23063         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23064         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23065                 error "compare $TMP/$tfile.1 failed"
23066
23067         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23068         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23069
23070         # just to see what the maximum tunable value is, and test parsing
23071         echo "test invalid parameter 2MB"
23072         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23073                 error "too-large short_io_bytes allowed"
23074         echo "test maximum parameter 512KB"
23075         # if we can set a larger short_io_bytes, run test regardless of version
23076         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23077                 # older clients may not allow setting it this large, that's OK
23078                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23079                         skip "Need at least client version 2.13.50"
23080                 error "medium short_io_bytes failed"
23081         fi
23082         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23083         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23084
23085         echo "test large parameter 64KB"
23086         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23087         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23088
23089         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23090         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23091                 error "dd with sync large writes failed"
23092         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23093
23094         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23095         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23096         num=$((113 * 4096 / PAGE_SIZE))
23097         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23098         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23099                 error "dd with O_DIRECT large writes failed"
23100         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23101                 error "compare $DIR/$tfile.3 failed"
23102
23103         cancel_lru_locks osc
23104
23105         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23106         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23107                 error "dd with O_DIRECT large read failed"
23108         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23109                 error "compare $TMP/$tfile.2 failed"
23110
23111         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23112         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23113                 error "dd with O_DIRECT large read failed"
23114         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23115                 error "compare $TMP/$tfile.3 failed"
23116 }
23117 run_test 248b "test short_io read and write for both small and large sizes"
23118
23119 test_249() { # LU-7890
23120         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23121                 skip "Need at least version 2.8.54"
23122
23123         rm -f $DIR/$tfile
23124         $LFS setstripe -c 1 $DIR/$tfile
23125         # Offset 2T == 4k * 512M
23126         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23127                 error "dd to 2T offset failed"
23128 }
23129 run_test 249 "Write above 2T file size"
23130
23131 test_250() {
23132         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23133          && skip "no 16TB file size limit on ZFS"
23134
23135         $LFS setstripe -c 1 $DIR/$tfile
23136         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23137         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23138         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23139         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23140                 conv=notrunc,fsync && error "append succeeded"
23141         return 0
23142 }
23143 run_test 250 "Write above 16T limit"
23144
23145 test_251() {
23146         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23147
23148         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23149         #Skip once - writing the first stripe will succeed
23150         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23151         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23152                 error "short write happened"
23153
23154         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23155         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23156                 error "short read happened"
23157
23158         rm -f $DIR/$tfile
23159 }
23160 run_test 251 "Handling short read and write correctly"
23161
23162 test_252() {
23163         remote_mds_nodsh && skip "remote MDS with nodsh"
23164         remote_ost_nodsh && skip "remote OST with nodsh"
23165         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23166                 skip_env "ldiskfs only test"
23167         fi
23168
23169         local tgt
23170         local dev
23171         local out
23172         local uuid
23173         local num
23174         local gen
23175
23176         # check lr_reader on OST0000
23177         tgt=ost1
23178         dev=$(facet_device $tgt)
23179         out=$(do_facet $tgt $LR_READER $dev)
23180         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23181         echo "$out"
23182         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23183         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23184                 error "Invalid uuid returned by $LR_READER on target $tgt"
23185         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23186
23187         # check lr_reader -c on MDT0000
23188         tgt=mds1
23189         dev=$(facet_device $tgt)
23190         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23191                 skip "$LR_READER does not support additional options"
23192         fi
23193         out=$(do_facet $tgt $LR_READER -c $dev)
23194         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23195         echo "$out"
23196         num=$(echo "$out" | grep -c "mdtlov")
23197         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23198                 error "Invalid number of mdtlov clients returned by $LR_READER"
23199         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23200
23201         # check lr_reader -cr on MDT0000
23202         out=$(do_facet $tgt $LR_READER -cr $dev)
23203         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23204         echo "$out"
23205         echo "$out" | grep -q "^reply_data:$" ||
23206                 error "$LR_READER should have returned 'reply_data' section"
23207         num=$(echo "$out" | grep -c "client_generation")
23208         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23209 }
23210 run_test 252 "check lr_reader tool"
23211
23212 test_253() {
23213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23214         remote_mds_nodsh && skip "remote MDS with nodsh"
23215         remote_mgs_nodsh && skip "remote MGS with nodsh"
23216
23217         local ostidx=0
23218         local rc=0
23219         local ost_name=$(ostname_from_index $ostidx)
23220
23221         # on the mdt's osc
23222         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23223         do_facet $SINGLEMDS $LCTL get_param -n \
23224                 osp.$mdtosc_proc1.reserved_mb_high ||
23225                 skip  "remote MDS does not support reserved_mb_high"
23226
23227         rm -rf $DIR/$tdir
23228         wait_mds_ost_sync
23229         wait_delete_completed
23230         mkdir $DIR/$tdir
23231         stack_trap "rm -rf $DIR/$tdir"
23232
23233         pool_add $TESTNAME || error "Pool creation failed"
23234         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23235
23236         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23237                 error "Setstripe failed"
23238
23239         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23240
23241         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23242                     grep "watermarks")
23243         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23244
23245         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23246                         osp.$mdtosc_proc1.prealloc_status)
23247         echo "prealloc_status $oa_status"
23248
23249         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23250                 error "File creation should fail"
23251
23252         #object allocation was stopped, but we still able to append files
23253         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23254                 oflag=append || error "Append failed"
23255
23256         rm -f $DIR/$tdir/$tfile.0
23257
23258         # For this test, we want to delete the files we created to go out of
23259         # space but leave the watermark, so we remain nearly out of space
23260         ost_watermarks_enospc_delete_files $tfile $ostidx
23261
23262         wait_delete_completed
23263
23264         sleep_maxage
23265
23266         for i in $(seq 10 12); do
23267                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23268                         2>/dev/null || error "File creation failed after rm"
23269         done
23270
23271         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23272                         osp.$mdtosc_proc1.prealloc_status)
23273         echo "prealloc_status $oa_status"
23274
23275         if (( oa_status != 0 )); then
23276                 error "Object allocation still disable after rm"
23277         fi
23278 }
23279 run_test 253 "Check object allocation limit"
23280
23281 test_254() {
23282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23283         remote_mds_nodsh && skip "remote MDS with nodsh"
23284
23285         local mdt=$(facet_svc $SINGLEMDS)
23286
23287         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23288                 skip "MDS does not support changelog_size"
23289
23290         local cl_user
23291
23292         changelog_register || error "changelog_register failed"
23293
23294         changelog_clear 0 || error "changelog_clear failed"
23295
23296         local size1=$(do_facet $SINGLEMDS \
23297                       $LCTL get_param -n mdd.$mdt.changelog_size)
23298         echo "Changelog size $size1"
23299
23300         rm -rf $DIR/$tdir
23301         $LFS mkdir -i 0 $DIR/$tdir
23302         # change something
23303         mkdir -p $DIR/$tdir/pics/2008/zachy
23304         touch $DIR/$tdir/pics/2008/zachy/timestamp
23305         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23306         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23307         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23308         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23309         rm $DIR/$tdir/pics/desktop.jpg
23310
23311         local size2=$(do_facet $SINGLEMDS \
23312                       $LCTL get_param -n mdd.$mdt.changelog_size)
23313         echo "Changelog size after work $size2"
23314
23315         (( $size2 > $size1 )) ||
23316                 error "new Changelog size=$size2 less than old size=$size1"
23317 }
23318 run_test 254 "Check changelog size"
23319
23320 ladvise_no_type()
23321 {
23322         local type=$1
23323         local file=$2
23324
23325         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23326                 awk -F: '{print $2}' | grep $type > /dev/null
23327         if [ $? -ne 0 ]; then
23328                 return 0
23329         fi
23330         return 1
23331 }
23332
23333 ladvise_no_ioctl()
23334 {
23335         local file=$1
23336
23337         lfs ladvise -a willread $file > /dev/null 2>&1
23338         if [ $? -eq 0 ]; then
23339                 return 1
23340         fi
23341
23342         lfs ladvise -a willread $file 2>&1 |
23343                 grep "Inappropriate ioctl for device" > /dev/null
23344         if [ $? -eq 0 ]; then
23345                 return 0
23346         fi
23347         return 1
23348 }
23349
23350 percent() {
23351         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23352 }
23353
23354 # run a random read IO workload
23355 # usage: random_read_iops <filename> <filesize> <iosize>
23356 random_read_iops() {
23357         local file=$1
23358         local fsize=$2
23359         local iosize=${3:-4096}
23360
23361         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23362                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23363 }
23364
23365 drop_file_oss_cache() {
23366         local file="$1"
23367         local nodes="$2"
23368
23369         $LFS ladvise -a dontneed $file 2>/dev/null ||
23370                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23371 }
23372
23373 ladvise_willread_performance()
23374 {
23375         local repeat=10
23376         local average_origin=0
23377         local average_cache=0
23378         local average_ladvise=0
23379
23380         for ((i = 1; i <= $repeat; i++)); do
23381                 echo "Iter $i/$repeat: reading without willread hint"
23382                 cancel_lru_locks osc
23383                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23384                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23385                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23386                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23387
23388                 cancel_lru_locks osc
23389                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23390                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23391                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23392
23393                 cancel_lru_locks osc
23394                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23395                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23396                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23397                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23398                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23399         done
23400         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23401         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23402         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23403
23404         speedup_cache=$(percent $average_cache $average_origin)
23405         speedup_ladvise=$(percent $average_ladvise $average_origin)
23406
23407         echo "Average uncached read: $average_origin"
23408         echo "Average speedup with OSS cached read: " \
23409                 "$average_cache = +$speedup_cache%"
23410         echo "Average speedup with ladvise willread: " \
23411                 "$average_ladvise = +$speedup_ladvise%"
23412
23413         local lowest_speedup=20
23414         if (( ${average_cache%.*} < $lowest_speedup )); then
23415                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23416                      " got $average_cache%. Skipping ladvise willread check."
23417                 return 0
23418         fi
23419
23420         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23421         # it is still good to run until then to exercise 'ladvise willread'
23422         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23423                 [ "$ost1_FSTYPE" = "zfs" ] &&
23424                 echo "osd-zfs does not support dontneed or drop_caches" &&
23425                 return 0
23426
23427         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23428         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23429                 error_not_in_vm "Speedup with willread is less than " \
23430                         "$lowest_speedup%, got $average_ladvise%"
23431 }
23432
23433 test_255a() {
23434         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23435                 skip "lustre < 2.8.54 does not support ladvise "
23436         remote_ost_nodsh && skip "remote OST with nodsh"
23437
23438         stack_trap "rm -f $DIR/$tfile"
23439         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23440
23441         ladvise_no_type willread $DIR/$tfile &&
23442                 skip "willread ladvise is not supported"
23443
23444         ladvise_no_ioctl $DIR/$tfile &&
23445                 skip "ladvise ioctl is not supported"
23446
23447         local size_mb=100
23448         local size=$((size_mb * 1048576))
23449         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23450                 error "dd to $DIR/$tfile failed"
23451
23452         lfs ladvise -a willread $DIR/$tfile ||
23453                 error "Ladvise failed with no range argument"
23454
23455         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23456                 error "Ladvise failed with no -l or -e argument"
23457
23458         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23459                 error "Ladvise failed with only -e argument"
23460
23461         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23462                 error "Ladvise failed with only -l argument"
23463
23464         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23465                 error "End offset should not be smaller than start offset"
23466
23467         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23468                 error "End offset should not be equal to start offset"
23469
23470         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23471                 error "Ladvise failed with overflowing -s argument"
23472
23473         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23474                 error "Ladvise failed with overflowing -e argument"
23475
23476         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23477                 error "Ladvise failed with overflowing -l argument"
23478
23479         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23480                 error "Ladvise succeeded with conflicting -l and -e arguments"
23481
23482         echo "Synchronous ladvise should wait"
23483         local delay=8
23484 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23485         do_nodes $(comma_list $(osts_nodes)) \
23486                 $LCTL set_param fail_val=$delay fail_loc=0x237
23487         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23488                 $LCTL set_param fail_loc=0"
23489
23490         local start_ts=$SECONDS
23491         lfs ladvise -a willread $DIR/$tfile ||
23492                 error "Ladvise failed with no range argument"
23493         local end_ts=$SECONDS
23494         local inteval_ts=$((end_ts - start_ts))
23495
23496         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23497                 error "Synchronous advice didn't wait reply"
23498         fi
23499
23500         echo "Asynchronous ladvise shouldn't wait"
23501         local start_ts=$SECONDS
23502         lfs ladvise -a willread -b $DIR/$tfile ||
23503                 error "Ladvise failed with no range argument"
23504         local end_ts=$SECONDS
23505         local inteval_ts=$((end_ts - start_ts))
23506
23507         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23508                 error "Asynchronous advice blocked"
23509         fi
23510
23511         ladvise_willread_performance
23512 }
23513 run_test 255a "check 'lfs ladvise -a willread'"
23514
23515 facet_meminfo() {
23516         local facet=$1
23517         local info=$2
23518
23519         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23520 }
23521
23522 test_255b() {
23523         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23524                 skip "lustre < 2.8.54 does not support ladvise "
23525         remote_ost_nodsh && skip "remote OST with nodsh"
23526
23527         stack_trap "rm -f $DIR/$tfile"
23528         lfs setstripe -c 1 -i 0 $DIR/$tfile
23529
23530         ladvise_no_type dontneed $DIR/$tfile &&
23531                 skip "dontneed ladvise is not supported"
23532
23533         ladvise_no_ioctl $DIR/$tfile &&
23534                 skip "ladvise ioctl is not supported"
23535
23536         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23537                 [ "$ost1_FSTYPE" = "zfs" ] &&
23538                 skip "zfs-osd does not support 'ladvise dontneed'"
23539
23540         local size_mb=100
23541         local size=$((size_mb * 1048576))
23542         # In order to prevent disturbance of other processes, only check 3/4
23543         # of the memory usage
23544         local kibibytes=$((size_mb * 1024 * 3 / 4))
23545
23546         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23547                 error "dd to $DIR/$tfile failed"
23548
23549         #force write to complete before dropping OST cache & checking memory
23550         sync
23551
23552         local total=$(facet_meminfo ost1 MemTotal)
23553         echo "Total memory: $total KiB"
23554
23555         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23556         local before_read=$(facet_meminfo ost1 Cached)
23557         echo "Cache used before read: $before_read KiB"
23558
23559         lfs ladvise -a willread $DIR/$tfile ||
23560                 error "Ladvise willread failed"
23561         local after_read=$(facet_meminfo ost1 Cached)
23562         echo "Cache used after read: $after_read KiB"
23563
23564         lfs ladvise -a dontneed $DIR/$tfile ||
23565                 error "Ladvise dontneed again failed"
23566         local no_read=$(facet_meminfo ost1 Cached)
23567         echo "Cache used after dontneed ladvise: $no_read KiB"
23568
23569         if [ $total -lt $((before_read + kibibytes)) ]; then
23570                 echo "Memory is too small, abort checking"
23571                 return 0
23572         fi
23573
23574         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23575                 error "Ladvise willread should use more memory" \
23576                         "than $kibibytes KiB"
23577         fi
23578
23579         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23580                 error "Ladvise dontneed should release more memory" \
23581                         "than $kibibytes KiB"
23582         fi
23583 }
23584 run_test 255b "check 'lfs ladvise -a dontneed'"
23585
23586 test_255c() {
23587         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23588                 skip "lustre < 2.10.50 does not support lockahead"
23589
23590         local ost1_imp=$(get_osc_import_name client ost1)
23591         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23592                          cut -d'.' -f2)
23593         local count
23594         local new_count
23595         local difference
23596         local i
23597         local rc
23598
23599         test_mkdir -p $DIR/$tdir
23600         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23601
23602         #test 10 returns only success/failure
23603         i=10
23604         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23605         rc=$?
23606         if [ $rc -eq 255 ]; then
23607                 error "Ladvise test${i} failed, ${rc}"
23608         fi
23609
23610         #test 11 counts lock enqueue requests, all others count new locks
23611         i=11
23612         count=$(do_facet ost1 \
23613                 $LCTL get_param -n ost.OSS.ost.stats)
23614         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23615
23616         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23617         rc=$?
23618         if [ $rc -eq 255 ]; then
23619                 error "Ladvise test${i} failed, ${rc}"
23620         fi
23621
23622         new_count=$(do_facet ost1 \
23623                 $LCTL get_param -n ost.OSS.ost.stats)
23624         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23625                    awk '{ print $2 }')
23626
23627         difference="$((new_count - count))"
23628         if [ $difference -ne $rc ]; then
23629                 error "Ladvise test${i}, bad enqueue count, returned " \
23630                       "${rc}, actual ${difference}"
23631         fi
23632
23633         for i in $(seq 12 21); do
23634                 # If we do not do this, we run the risk of having too many
23635                 # locks and starting lock cancellation while we are checking
23636                 # lock counts.
23637                 cancel_lru_locks osc
23638
23639                 count=$($LCTL get_param -n \
23640                        ldlm.namespaces.$imp_name.lock_unused_count)
23641
23642                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23643                 rc=$?
23644                 if [ $rc -eq 255 ]; then
23645                         error "Ladvise test ${i} failed, ${rc}"
23646                 fi
23647
23648                 new_count=$($LCTL get_param -n \
23649                        ldlm.namespaces.$imp_name.lock_unused_count)
23650                 difference="$((new_count - count))"
23651
23652                 # Test 15 output is divided by 100 to map down to valid return
23653                 if [ $i -eq 15 ]; then
23654                         rc="$((rc * 100))"
23655                 fi
23656
23657                 if [ $difference -ne $rc ]; then
23658                         error "Ladvise test ${i}, bad lock count, returned " \
23659                               "${rc}, actual ${difference}"
23660                 fi
23661         done
23662
23663         #test 22 returns only success/failure
23664         i=22
23665         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23666         rc=$?
23667         if [ $rc -eq 255 ]; then
23668                 error "Ladvise test${i} failed, ${rc}"
23669         fi
23670 }
23671 run_test 255c "suite of ladvise lockahead tests"
23672
23673 test_256() {
23674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23675         remote_mds_nodsh && skip "remote MDS with nodsh"
23676         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23677         changelog_users $SINGLEMDS | grep "^cl" &&
23678                 skip "active changelog user"
23679
23680         local cl_user
23681         local cat_sl
23682         local mdt_dev
23683
23684         mdt_dev=$(facet_device $SINGLEMDS)
23685         echo $mdt_dev
23686
23687         changelog_register || error "changelog_register failed"
23688
23689         rm -rf $DIR/$tdir
23690         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23691
23692         changelog_clear 0 || error "changelog_clear failed"
23693
23694         # change something
23695         touch $DIR/$tdir/{1..10}
23696
23697         # stop the MDT
23698         stop $SINGLEMDS || error "Fail to stop MDT"
23699
23700         # remount the MDT
23701         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23702                 error "Fail to start MDT"
23703
23704         #after mount new plainllog is used
23705         touch $DIR/$tdir/{11..19}
23706         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23707         stack_trap "rm -f $tmpfile"
23708         cat_sl=$(do_facet $SINGLEMDS "sync; \
23709                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23710                  llog_reader $tmpfile | grep -c type=1064553b")
23711         do_facet $SINGLEMDS llog_reader $tmpfile
23712
23713         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23714
23715         changelog_clear 0 || error "changelog_clear failed"
23716
23717         cat_sl=$(do_facet $SINGLEMDS "sync; \
23718                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23719                  llog_reader $tmpfile | grep -c type=1064553b")
23720
23721         if (( cat_sl == 2 )); then
23722                 error "Empty plain llog was not deleted from changelog catalog"
23723         elif (( cat_sl != 1 )); then
23724                 error "Active plain llog shouldn't be deleted from catalog"
23725         fi
23726 }
23727 run_test 256 "Check llog delete for empty and not full state"
23728
23729 test_257() {
23730         remote_mds_nodsh && skip "remote MDS with nodsh"
23731         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23732                 skip "Need MDS version at least 2.8.55"
23733
23734         test_mkdir $DIR/$tdir
23735
23736         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23737                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23738         stat $DIR/$tdir
23739
23740 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23741         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23742         local facet=mds$((mdtidx + 1))
23743         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23744         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23745
23746         stop $facet || error "stop MDS failed"
23747         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23748                 error "start MDS fail"
23749         wait_recovery_complete $facet
23750 }
23751 run_test 257 "xattr locks are not lost"
23752
23753 # Verify we take the i_mutex when security requires it
23754 test_258a() {
23755 #define OBD_FAIL_IMUTEX_SEC 0x141c
23756         $LCTL set_param fail_loc=0x141c
23757         touch $DIR/$tfile
23758         chmod u+s $DIR/$tfile
23759         chmod a+rwx $DIR/$tfile
23760         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23761         RC=$?
23762         if [ $RC -ne 0 ]; then
23763                 error "error, failed to take i_mutex, rc=$?"
23764         fi
23765         rm -f $DIR/$tfile
23766 }
23767 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23768
23769 # Verify we do NOT take the i_mutex in the normal case
23770 test_258b() {
23771 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23772         $LCTL set_param fail_loc=0x141d
23773         touch $DIR/$tfile
23774         chmod a+rwx $DIR
23775         chmod a+rw $DIR/$tfile
23776         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23777         RC=$?
23778         if [ $RC -ne 0 ]; then
23779                 error "error, took i_mutex unnecessarily, rc=$?"
23780         fi
23781         rm -f $DIR/$tfile
23782
23783 }
23784 run_test 258b "verify i_mutex security behavior"
23785
23786 test_259() {
23787         local file=$DIR/$tfile
23788         local before
23789         local after
23790
23791         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23792
23793         stack_trap "rm -f $file" EXIT
23794
23795         wait_delete_completed
23796         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23797         echo "before: $before"
23798
23799         $LFS setstripe -i 0 -c 1 $file
23800         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23801         sync_all_data
23802         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23803         echo "after write: $after"
23804
23805 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23806         do_facet ost1 $LCTL set_param fail_loc=0x2301
23807         $TRUNCATE $file 0
23808         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23809         echo "after truncate: $after"
23810
23811         stop ost1
23812         do_facet ost1 $LCTL set_param fail_loc=0
23813         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23814         sleep 2
23815         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23816         echo "after restart: $after"
23817         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23818                 error "missing truncate?"
23819
23820         return 0
23821 }
23822 run_test 259 "crash at delayed truncate"
23823
23824 test_260() {
23825 #define OBD_FAIL_MDC_CLOSE               0x806
23826         $LCTL set_param fail_loc=0x80000806
23827         touch $DIR/$tfile
23828
23829 }
23830 run_test 260 "Check mdc_close fail"
23831
23832 ### Data-on-MDT sanity tests ###
23833 test_270a() {
23834         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23835                 skip "Need MDS version at least 2.10.55 for DoM"
23836
23837         # create DoM file
23838         local dom=$DIR/$tdir/dom_file
23839         local tmp=$DIR/$tdir/tmp_file
23840
23841         mkdir_on_mdt0 $DIR/$tdir
23842
23843         # basic checks for DoM component creation
23844         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23845                 error "Can set MDT layout to non-first entry"
23846
23847         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23848                 error "Can define multiple entries as MDT layout"
23849
23850         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23851
23852         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23853         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23854         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23855
23856         local mdtidx=$($LFS getstripe -m $dom)
23857         local mdtname=MDT$(printf %04x $mdtidx)
23858         local facet=mds$((mdtidx + 1))
23859         local space_check=1
23860
23861         # Skip free space checks with ZFS
23862         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23863
23864         # write
23865         sync
23866         local size_tmp=$((65536 * 3))
23867         local mdtfree1=$(do_facet $facet \
23868                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23869
23870         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23871         # check also direct IO along write
23872         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23873         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23874         sync
23875         cmp $tmp $dom || error "file data is different"
23876         [ $(stat -c%s $dom) == $size_tmp ] ||
23877                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23878         if [ $space_check == 1 ]; then
23879                 local mdtfree2=$(do_facet $facet \
23880                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23881
23882                 # increase in usage from by $size_tmp
23883                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23884                         error "MDT free space wrong after write: " \
23885                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23886         fi
23887
23888         # truncate
23889         local size_dom=10000
23890
23891         $TRUNCATE $dom $size_dom
23892         [ $(stat -c%s $dom) == $size_dom ] ||
23893                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23894         if [ $space_check == 1 ]; then
23895                 mdtfree1=$(do_facet $facet \
23896                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23897                 # decrease in usage from $size_tmp to new $size_dom
23898                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23899                   $(((size_tmp - size_dom) / 1024)) ] ||
23900                         error "MDT free space is wrong after truncate: " \
23901                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23902         fi
23903
23904         # append
23905         cat $tmp >> $dom
23906         sync
23907         size_dom=$((size_dom + size_tmp))
23908         [ $(stat -c%s $dom) == $size_dom ] ||
23909                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23910         if [ $space_check == 1 ]; then
23911                 mdtfree2=$(do_facet $facet \
23912                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23913                 # increase in usage by $size_tmp from previous
23914                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23915                         error "MDT free space is wrong after append: " \
23916                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23917         fi
23918
23919         # delete
23920         rm $dom
23921         if [ $space_check == 1 ]; then
23922                 mdtfree1=$(do_facet $facet \
23923                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23924                 # decrease in usage by $size_dom from previous
23925                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23926                         error "MDT free space is wrong after removal: " \
23927                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23928         fi
23929
23930         # combined striping
23931         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23932                 error "Can't create DoM + OST striping"
23933
23934         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23935         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23936         # check also direct IO along write
23937         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23938         sync
23939         cmp $tmp $dom || error "file data is different"
23940         [ $(stat -c%s $dom) == $size_tmp ] ||
23941                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23942         rm $dom $tmp
23943
23944         return 0
23945 }
23946 run_test 270a "DoM: basic functionality tests"
23947
23948 test_270b() {
23949         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23950                 skip "Need MDS version at least 2.10.55"
23951
23952         local dom=$DIR/$tdir/dom_file
23953         local max_size=1048576
23954
23955         mkdir -p $DIR/$tdir
23956         $LFS setstripe -E $max_size -L mdt $dom
23957
23958         # truncate over the limit
23959         $TRUNCATE $dom $(($max_size + 1)) &&
23960                 error "successful truncate over the maximum size"
23961         # write over the limit
23962         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23963                 error "successful write over the maximum size"
23964         # append over the limit
23965         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23966         echo "12345" >> $dom && error "successful append over the maximum size"
23967         rm $dom
23968
23969         return 0
23970 }
23971 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23972
23973 test_270c() {
23974         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23975                 skip "Need MDS version at least 2.10.55"
23976
23977         mkdir -p $DIR/$tdir
23978         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23979
23980         # check files inherit DoM EA
23981         touch $DIR/$tdir/first
23982         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23983                 error "bad pattern"
23984         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23985                 error "bad stripe count"
23986         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23987                 error "bad stripe size"
23988
23989         # check directory inherits DoM EA and uses it as default
23990         mkdir $DIR/$tdir/subdir
23991         touch $DIR/$tdir/subdir/second
23992         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23993                 error "bad pattern in sub-directory"
23994         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23995                 error "bad stripe count in sub-directory"
23996         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23997                 error "bad stripe size in sub-directory"
23998         return 0
23999 }
24000 run_test 270c "DoM: DoM EA inheritance tests"
24001
24002 test_270d() {
24003         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24004                 skip "Need MDS version at least 2.10.55"
24005
24006         mkdir -p $DIR/$tdir
24007         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24008
24009         # inherit default DoM striping
24010         mkdir $DIR/$tdir/subdir
24011         touch $DIR/$tdir/subdir/f1
24012
24013         # change default directory striping
24014         $LFS setstripe -c 1 $DIR/$tdir/subdir
24015         touch $DIR/$tdir/subdir/f2
24016         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24017                 error "wrong default striping in file 2"
24018         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24019                 error "bad pattern in file 2"
24020         return 0
24021 }
24022 run_test 270d "DoM: change striping from DoM to RAID0"
24023
24024 test_270e() {
24025         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24026                 skip "Need MDS version at least 2.10.55"
24027
24028         mkdir -p $DIR/$tdir/dom
24029         mkdir -p $DIR/$tdir/norm
24030         DOMFILES=20
24031         NORMFILES=10
24032         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24033         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24034
24035         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24036         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24037
24038         # find DoM files by layout
24039         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24040         [ $NUM -eq  $DOMFILES ] ||
24041                 error "lfs find -L: found $NUM, expected $DOMFILES"
24042         echo "Test 1: lfs find 20 DOM files by layout: OK"
24043
24044         # there should be 1 dir with default DOM striping
24045         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24046         [ $NUM -eq  1 ] ||
24047                 error "lfs find -L: found $NUM, expected 1 dir"
24048         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24049
24050         # find DoM files by stripe size
24051         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24052         [ $NUM -eq  $DOMFILES ] ||
24053                 error "lfs find -S: found $NUM, expected $DOMFILES"
24054         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24055
24056         # find files by stripe offset except DoM files
24057         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24058         [ $NUM -eq  $NORMFILES ] ||
24059                 error "lfs find -i: found $NUM, expected $NORMFILES"
24060         echo "Test 5: lfs find no DOM files by stripe index: OK"
24061         return 0
24062 }
24063 run_test 270e "DoM: lfs find with DoM files test"
24064
24065 test_270f() {
24066         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24067                 skip "Need MDS version at least 2.10.55"
24068
24069         local mdtname=${FSNAME}-MDT0000-mdtlov
24070         local dom=$DIR/$tdir/dom_file
24071         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24072                                                 lod.$mdtname.dom_stripesize)
24073         local dom_limit=131072
24074
24075         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24076         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24077                                                 lod.$mdtname.dom_stripesize)
24078         [ ${dom_limit} -eq ${dom_current} ] ||
24079                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24080
24081         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24082         $LFS setstripe -d $DIR/$tdir
24083         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24084                 error "Can't set directory default striping"
24085
24086         # exceed maximum stripe size
24087         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24088                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24089         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24090                 error "Able to create DoM component size more than LOD limit"
24091
24092         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24093         dom_current=$(do_facet mds1 $LCTL get_param -n \
24094                                                 lod.$mdtname.dom_stripesize)
24095         [ 0 -eq ${dom_current} ] ||
24096                 error "Can't set zero DoM stripe limit"
24097         rm $dom
24098
24099         # attempt to create DoM file on server with disabled DoM should
24100         # remove DoM entry from layout and be succeed
24101         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24102                 error "Can't create DoM file (DoM is disabled)"
24103         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24104                 error "File has DoM component while DoM is disabled"
24105         rm $dom
24106
24107         # attempt to create DoM file with only DoM stripe should return error
24108         $LFS setstripe -E $dom_limit -L mdt $dom &&
24109                 error "Able to create DoM-only file while DoM is disabled"
24110
24111         # too low values to be aligned with smallest stripe size 64K
24112         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24113         dom_current=$(do_facet mds1 $LCTL get_param -n \
24114                                                 lod.$mdtname.dom_stripesize)
24115         [ 30000 -eq ${dom_current} ] &&
24116                 error "Can set too small DoM stripe limit"
24117
24118         # 64K is a minimal stripe size in Lustre, expect limit of that size
24119         [ 65536 -eq ${dom_current} ] ||
24120                 error "Limit is not set to 64K but ${dom_current}"
24121
24122         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24123         dom_current=$(do_facet mds1 $LCTL get_param -n \
24124                                                 lod.$mdtname.dom_stripesize)
24125         echo $dom_current
24126         [ 2147483648 -eq ${dom_current} ] &&
24127                 error "Can set too large DoM stripe limit"
24128
24129         do_facet mds1 $LCTL set_param -n \
24130                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24131         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24132                 error "Can't create DoM component size after limit change"
24133         do_facet mds1 $LCTL set_param -n \
24134                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24135         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24136                 error "Can't create DoM file after limit decrease"
24137         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24138                 error "Can create big DoM component after limit decrease"
24139         touch ${dom}_def ||
24140                 error "Can't create file with old default layout"
24141
24142         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24143         return 0
24144 }
24145 run_test 270f "DoM: maximum DoM stripe size checks"
24146
24147 test_270g() {
24148         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24149                 skip "Need MDS version at least 2.13.52"
24150         local dom=$DIR/$tdir/$tfile
24151
24152         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24153         local lodname=${FSNAME}-MDT0000-mdtlov
24154
24155         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24156         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24157         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24158         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24159
24160         local dom_limit=1024
24161         local dom_threshold="50%"
24162
24163         $LFS setstripe -d $DIR/$tdir
24164         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24165                 error "Can't set directory default striping"
24166
24167         do_facet mds1 $LCTL set_param -n \
24168                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24169         # set 0 threshold and create DOM file to change tunable stripesize
24170         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24171         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24172                 error "Failed to create $dom file"
24173         # now tunable dom_cur_stripesize should reach maximum
24174         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24175                                         lod.${lodname}.dom_stripesize_cur_kb)
24176         [[ $dom_current == $dom_limit ]] ||
24177                 error "Current DOM stripesize is not maximum"
24178         rm $dom
24179
24180         # set threshold for further tests
24181         do_facet mds1 $LCTL set_param -n \
24182                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24183         echo "DOM threshold is $dom_threshold free space"
24184         local dom_def
24185         local dom_set
24186         # Spoof bfree to exceed threshold
24187         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24188         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24189         for spfree in 40 20 0 15 30 55; do
24190                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24191                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24192                         error "Failed to create $dom file"
24193                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24194                                         lod.${lodname}.dom_stripesize_cur_kb)
24195                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24196                 [[ $dom_def != $dom_current ]] ||
24197                         error "Default stripe size was not changed"
24198                 if (( spfree > 0 )) ; then
24199                         dom_set=$($LFS getstripe -S $dom)
24200                         (( dom_set == dom_def * 1024 )) ||
24201                                 error "DOM component size is still old"
24202                 else
24203                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24204                                 error "DoM component is set with no free space"
24205                 fi
24206                 rm $dom
24207                 dom_current=$dom_def
24208         done
24209 }
24210 run_test 270g "DoM: default DoM stripe size depends on free space"
24211
24212 test_270h() {
24213         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24214                 skip "Need MDS version at least 2.13.53"
24215
24216         local mdtname=${FSNAME}-MDT0000-mdtlov
24217         local dom=$DIR/$tdir/$tfile
24218         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24219
24220         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24221         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24222
24223         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24224         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24225                 error "can't create OST file"
24226         # mirrored file with DOM entry in the second mirror
24227         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24228                 error "can't create mirror with DoM component"
24229
24230         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24231
24232         # DOM component in the middle and has other enries in the same mirror,
24233         # should succeed but lost DoM component
24234         $LFS setstripe --copy=${dom}_1 $dom ||
24235                 error "Can't create file from OST|DOM mirror layout"
24236         # check new file has no DoM layout after all
24237         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24238                 error "File has DoM component while DoM is disabled"
24239 }
24240 run_test 270h "DoM: DoM stripe removal when disabled on server"
24241
24242 test_270i() {
24243         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24244                 skip "Need MDS version at least 2.14.54"
24245
24246         mkdir $DIR/$tdir
24247         # DoM with plain layout
24248         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24249                 error "default plain layout with DoM must fail"
24250         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24251                 error "setstripe plain file layout with DoM must fail"
24252         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24253                 error "default DoM layout with bad striping must fail"
24254         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24255                 error "setstripe to DoM layout with bad striping must fail"
24256         return 0
24257 }
24258 run_test 270i "DoM: setting invalid DoM striping should fail"
24259
24260 test_270j() {
24261         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24262                 skip "Need MDS version at least 2.15.55.203"
24263
24264         local dom=$DIR/$tdir/$tfile
24265         local odv
24266         local ndv
24267
24268         mkdir -p $DIR/$tdir
24269
24270         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24271
24272         odv=$($LFS data_version $dom)
24273         chmod 666 $dom
24274         mv $dom ${dom}_moved
24275         link ${dom}_moved $dom
24276         setfattr -n user.attrx -v "some_attr" $dom
24277         ndv=$($LFS data_version $dom)
24278         (( $ndv == $odv )) ||
24279                 error "data version was changed by metadata operations"
24280
24281         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24282                 error "failed to write data into $dom"
24283         cancel_lru_locks mdc
24284         ndv=$($LFS data_version $dom)
24285         (( $ndv != $odv )) ||
24286                 error "data version wasn't changed on write"
24287
24288         odv=$ndv
24289         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24290         ndv=$($LFS data_version $dom)
24291         (( $ndv != $odv )) ||
24292                 error "data version wasn't changed on truncate down"
24293
24294         odv=$ndv
24295         $TRUNCATE $dom 25000
24296         ndv=$($LFS data_version $dom)
24297         (( $ndv != $odv )) ||
24298                 error "data version wasn't changed on truncate up"
24299
24300         # check also fallocate for ldiskfs
24301         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24302                 odv=$ndv
24303                 fallocate -l 1048576 $dom
24304                 ndv=$($LFS data_version $dom)
24305                 (( $ndv != $odv )) ||
24306                         error "data version wasn't changed on fallocate"
24307
24308                 odv=$ndv
24309                 fallocate -p --offset 4096 -l 4096 $dom
24310                 ndv=$($LFS data_version $dom)
24311                 (( $ndv != $odv )) ||
24312                         error "data version wasn't changed on fallocate punch"
24313         fi
24314 }
24315 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24316
24317 test_271a() {
24318         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24319                 skip "Need MDS version at least 2.10.55"
24320
24321         local dom=$DIR/$tdir/dom
24322
24323         mkdir -p $DIR/$tdir
24324
24325         $LFS setstripe -E 1024K -L mdt $dom
24326
24327         lctl set_param -n mdc.*.stats=clear
24328         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24329         cat $dom > /dev/null
24330         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24331         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24332         ls $dom
24333         rm -f $dom
24334 }
24335 run_test 271a "DoM: data is cached for read after write"
24336
24337 test_271b() {
24338         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24339                 skip "Need MDS version at least 2.10.55"
24340
24341         local dom=$DIR/$tdir/dom
24342
24343         mkdir -p $DIR/$tdir
24344
24345         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24346
24347         lctl set_param -n mdc.*.stats=clear
24348         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24349         cancel_lru_locks mdc
24350         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24351         # second stat to check size is cached on client
24352         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24353         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24354         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24355         rm -f $dom
24356 }
24357 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24358
24359 test_271ba() {
24360         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24361                 skip "Need MDS version at least 2.10.55"
24362
24363         local dom=$DIR/$tdir/dom
24364
24365         mkdir -p $DIR/$tdir
24366
24367         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24368
24369         lctl set_param -n mdc.*.stats=clear
24370         lctl set_param -n osc.*.stats=clear
24371         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24372         cancel_lru_locks mdc
24373         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24374         # second stat to check size is cached on client
24375         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24376         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24377         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24378         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24379         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24380         rm -f $dom
24381 }
24382 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24383
24384
24385 get_mdc_stats() {
24386         local mdtidx=$1
24387         local param=$2
24388         local mdt=MDT$(printf %04x $mdtidx)
24389
24390         if [ -z $param ]; then
24391                 lctl get_param -n mdc.*$mdt*.stats
24392         else
24393                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24394         fi
24395 }
24396
24397 test_271c() {
24398         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24399                 skip "Need MDS version at least 2.10.55"
24400
24401         local dom=$DIR/$tdir/dom
24402
24403         mkdir -p $DIR/$tdir
24404
24405         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24406
24407         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24408         local facet=mds$((mdtidx + 1))
24409
24410         cancel_lru_locks mdc
24411         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24412         createmany -o $dom 1000
24413         lctl set_param -n mdc.*.stats=clear
24414         smalliomany -w $dom 1000 200
24415         get_mdc_stats $mdtidx
24416         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24417         # Each file has 1 open, 1 IO enqueues, total 2000
24418         # but now we have also +1 getxattr for security.capability, total 3000
24419         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24420         unlinkmany $dom 1000
24421
24422         cancel_lru_locks mdc
24423         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24424         createmany -o $dom 1000
24425         lctl set_param -n mdc.*.stats=clear
24426         smalliomany -w $dom 1000 200
24427         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24428         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24429         # for OPEN and IO lock.
24430         [ $((enq - enq_2)) -ge 1000 ] ||
24431                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24432         unlinkmany $dom 1000
24433         return 0
24434 }
24435 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24436
24437 cleanup_271def_tests() {
24438         trap 0
24439         rm -f $1
24440 }
24441
24442 test_271d() {
24443         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24444                 skip "Need MDS version at least 2.10.57"
24445
24446         local dom=$DIR/$tdir/dom
24447         local tmp=$TMP/$tfile
24448         trap "cleanup_271def_tests $tmp" EXIT
24449
24450         mkdir -p $DIR/$tdir
24451
24452         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24453
24454         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24455
24456         cancel_lru_locks mdc
24457         dd if=/dev/urandom of=$tmp bs=1000 count=1
24458         dd if=$tmp of=$dom bs=1000 count=1
24459         cancel_lru_locks mdc
24460
24461         cat /etc/hosts >> $tmp
24462         lctl set_param -n mdc.*.stats=clear
24463
24464         # append data to the same file it should update local page
24465         echo "Append to the same page"
24466         cat /etc/hosts >> $dom
24467         local num=$(get_mdc_stats $mdtidx ost_read)
24468         local ra=$(get_mdc_stats $mdtidx req_active)
24469         local rw=$(get_mdc_stats $mdtidx req_waittime)
24470
24471         [ -z $num ] || error "$num READ RPC occured"
24472         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24473         echo "... DONE"
24474
24475         # compare content
24476         cmp $tmp $dom || error "file miscompare"
24477
24478         cancel_lru_locks mdc
24479         lctl set_param -n mdc.*.stats=clear
24480
24481         echo "Open and read file"
24482         cat $dom > /dev/null
24483         local num=$(get_mdc_stats $mdtidx ost_read)
24484         local ra=$(get_mdc_stats $mdtidx req_active)
24485         local rw=$(get_mdc_stats $mdtidx req_waittime)
24486
24487         [ -z $num ] || error "$num READ RPC occured"
24488         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24489         echo "... DONE"
24490
24491         # compare content
24492         cmp $tmp $dom || error "file miscompare"
24493
24494         return 0
24495 }
24496 run_test 271d "DoM: read on open (1K file in reply buffer)"
24497
24498 test_271f() {
24499         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24500                 skip "Need MDS version at least 2.10.57"
24501
24502         local dom=$DIR/$tdir/dom
24503         local tmp=$TMP/$tfile
24504         trap "cleanup_271def_tests $tmp" EXIT
24505
24506         mkdir -p $DIR/$tdir
24507
24508         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24509
24510         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24511
24512         cancel_lru_locks mdc
24513         dd if=/dev/urandom of=$tmp bs=265000 count=1
24514         dd if=$tmp of=$dom bs=265000 count=1
24515         cancel_lru_locks mdc
24516         cat /etc/hosts >> $tmp
24517         lctl set_param -n mdc.*.stats=clear
24518
24519         echo "Append to the same page"
24520         cat /etc/hosts >> $dom
24521         local num=$(get_mdc_stats $mdtidx ost_read)
24522         local ra=$(get_mdc_stats $mdtidx req_active)
24523         local rw=$(get_mdc_stats $mdtidx req_waittime)
24524
24525         [ -z $num ] || error "$num READ RPC occured"
24526         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24527         echo "... DONE"
24528
24529         # compare content
24530         cmp $tmp $dom || error "file miscompare"
24531
24532         cancel_lru_locks mdc
24533         lctl set_param -n mdc.*.stats=clear
24534
24535         echo "Open and read file"
24536         cat $dom > /dev/null
24537         local num=$(get_mdc_stats $mdtidx ost_read)
24538         local ra=$(get_mdc_stats $mdtidx req_active)
24539         local rw=$(get_mdc_stats $mdtidx req_waittime)
24540
24541         [ -z $num ] && num=0
24542         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24543         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24544         echo "... DONE"
24545
24546         # compare content
24547         cmp $tmp $dom || error "file miscompare"
24548
24549         return 0
24550 }
24551 run_test 271f "DoM: read on open (200K file and read tail)"
24552
24553 test_271g() {
24554         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24555                 skip "Skipping due to old client or server version"
24556
24557         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24558         # to get layout
24559         $CHECKSTAT -t file $DIR1/$tfile
24560
24561         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24562         MULTIOP_PID=$!
24563         sleep 1
24564         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24565         $LCTL set_param fail_loc=0x80000314
24566         rm $DIR1/$tfile || error "Unlink fails"
24567         RC=$?
24568         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24569         [ $RC -eq 0 ] || error "Failed write to stale object"
24570 }
24571 run_test 271g "Discard DoM data vs client flush race"
24572
24573 test_272a() {
24574         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24575                 skip "Need MDS version at least 2.11.50"
24576
24577         local dom=$DIR/$tdir/dom
24578         mkdir -p $DIR/$tdir
24579
24580         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24581         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24582                 error "failed to write data into $dom"
24583         local old_md5=$(md5sum $dom)
24584
24585         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24586                 error "failed to migrate to the same DoM component"
24587
24588         local new_md5=$(md5sum $dom)
24589
24590         [ "$old_md5" == "$new_md5" ] ||
24591                 error "md5sum differ: $old_md5, $new_md5"
24592
24593         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24594                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24595 }
24596 run_test 272a "DoM migration: new layout with the same DOM component"
24597
24598 test_272b() {
24599         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24600                 skip "Need MDS version at least 2.11.50"
24601
24602         local dom=$DIR/$tdir/dom
24603         mkdir -p $DIR/$tdir
24604         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24605         stack_trap "rm -rf $DIR/$tdir"
24606
24607         local mdtidx=$($LFS getstripe -m $dom)
24608         local mdtname=MDT$(printf %04x $mdtidx)
24609         local facet=mds$((mdtidx + 1))
24610
24611         local mdtfree1=$(do_facet $facet \
24612                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24613         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24614                 error "failed to write data into $dom"
24615         local old_md5=$(md5sum $dom)
24616         cancel_lru_locks mdc
24617         local mdtfree1=$(do_facet $facet \
24618                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24619
24620         $LFS migrate -c2 $dom ||
24621                 error "failed to migrate to the new composite layout"
24622         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24623                 error "MDT stripe was not removed"
24624         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24625                 error "$dir1 shouldn't have DATAVER EA"
24626
24627         cancel_lru_locks mdc
24628         local new_md5=$(md5sum $dom)
24629         [ "$old_md5" == "$new_md5" ] ||
24630                 error "$old_md5 != $new_md5"
24631
24632         # Skip free space checks with ZFS
24633         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24634                 local mdtfree2=$(do_facet $facet \
24635                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24636                 [ $mdtfree2 -gt $mdtfree1 ] ||
24637                         error "MDT space is not freed after migration"
24638         fi
24639         return 0
24640 }
24641 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24642
24643 test_272c() {
24644         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24645                 skip "Need MDS version at least 2.11.50"
24646
24647         local dom=$DIR/$tdir/$tfile
24648         mkdir -p $DIR/$tdir
24649         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24650         stack_trap "rm -rf $DIR/$tdir"
24651
24652         local mdtidx=$($LFS getstripe -m $dom)
24653         local mdtname=MDT$(printf %04x $mdtidx)
24654         local facet=mds$((mdtidx + 1))
24655
24656         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24657                 error "failed to write data into $dom"
24658         local old_md5=$(md5sum $dom)
24659         cancel_lru_locks mdc
24660         local mdtfree1=$(do_facet $facet \
24661                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24662
24663         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24664                 error "failed to migrate to the new composite layout"
24665         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24666                 error "MDT stripe was not removed"
24667
24668         cancel_lru_locks mdc
24669         local new_md5=$(md5sum $dom)
24670         [ "$old_md5" == "$new_md5" ] ||
24671                 error "$old_md5 != $new_md5"
24672
24673         # Skip free space checks with ZFS
24674         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24675                 local mdtfree2=$(do_facet $facet \
24676                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24677                 [ $mdtfree2 -gt $mdtfree1 ] ||
24678                         error "MDS space is not freed after migration"
24679         fi
24680         return 0
24681 }
24682 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24683
24684 test_272d() {
24685         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24686                 skip "Need MDS version at least 2.12.55"
24687
24688         local dom=$DIR/$tdir/$tfile
24689         mkdir -p $DIR/$tdir
24690         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24691
24692         local mdtidx=$($LFS getstripe -m $dom)
24693         local mdtname=MDT$(printf %04x $mdtidx)
24694         local facet=mds$((mdtidx + 1))
24695
24696         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24697                 error "failed to write data into $dom"
24698         local old_md5=$(md5sum $dom)
24699         cancel_lru_locks mdc
24700         local mdtfree1=$(do_facet $facet \
24701                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24702
24703         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24704                 error "failed mirroring to the new composite layout"
24705         $LFS mirror resync $dom ||
24706                 error "failed mirror resync"
24707         $LFS mirror split --mirror-id 1 -d $dom ||
24708                 error "failed mirror split"
24709
24710         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24711                 error "MDT stripe was not removed"
24712
24713         cancel_lru_locks mdc
24714         local new_md5=$(md5sum $dom)
24715         [ "$old_md5" == "$new_md5" ] ||
24716                 error "$old_md5 != $new_md5"
24717
24718         # Skip free space checks with ZFS
24719         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24720                 local mdtfree2=$(do_facet $facet \
24721                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24722                 [ $mdtfree2 -gt $mdtfree1 ] ||
24723                         error "MDS space is not freed after DOM mirror deletion"
24724         fi
24725         return 0
24726 }
24727 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24728
24729 test_272e() {
24730         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24731                 skip "Need MDS version at least 2.12.55"
24732
24733         local dom=$DIR/$tdir/$tfile
24734         mkdir -p $DIR/$tdir
24735         $LFS setstripe -c 2 $dom
24736
24737         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24738                 error "failed to write data into $dom"
24739         local old_md5=$(md5sum $dom)
24740         cancel_lru_locks
24741
24742         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24743                 error "failed mirroring to the DOM layout"
24744         $LFS mirror resync $dom ||
24745                 error "failed mirror resync"
24746         $LFS mirror split --mirror-id 1 -d $dom ||
24747                 error "failed mirror split"
24748
24749         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24750                 error "MDT stripe wasn't set"
24751
24752         cancel_lru_locks
24753         local new_md5=$(md5sum $dom)
24754         [ "$old_md5" == "$new_md5" ] ||
24755                 error "$old_md5 != $new_md5"
24756
24757         return 0
24758 }
24759 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24760
24761 test_272f() {
24762         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24763                 skip "Need MDS version at least 2.12.55"
24764
24765         local dom=$DIR/$tdir/$tfile
24766         mkdir -p $DIR/$tdir
24767         $LFS setstripe -c 2 $dom
24768
24769         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24770                 error "failed to write data into $dom"
24771         local old_md5=$(md5sum $dom)
24772         cancel_lru_locks
24773
24774         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24775                 error "failed migrating to the DOM file"
24776
24777         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24778                 error "MDT stripe wasn't set"
24779
24780         cancel_lru_locks
24781         local new_md5=$(md5sum $dom)
24782         [ "$old_md5" != "$new_md5" ] &&
24783                 error "$old_md5 != $new_md5"
24784
24785         return 0
24786 }
24787 run_test 272f "DoM migration: OST-striped file to DOM file"
24788
24789 test_273a() {
24790         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24791                 skip "Need MDS version at least 2.11.50"
24792
24793         # Layout swap cannot be done if either file has DOM component,
24794         # this will never be supported, migration should be used instead
24795
24796         local dom=$DIR/$tdir/$tfile
24797         mkdir -p $DIR/$tdir
24798
24799         $LFS setstripe -c2 ${dom}_plain
24800         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24801         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24802                 error "can swap layout with DoM component"
24803         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24804                 error "can swap layout with DoM component"
24805
24806         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24807         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24808                 error "can swap layout with DoM component"
24809         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24810                 error "can swap layout with DoM component"
24811         return 0
24812 }
24813 run_test 273a "DoM: layout swapping should fail with DOM"
24814
24815 test_273b() {
24816         mkdir -p $DIR/$tdir
24817         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24818
24819 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24820         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24821
24822         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24823 }
24824 run_test 273b "DoM: race writeback and object destroy"
24825
24826 test_273c() {
24827         mkdir -p $DIR/$tdir
24828         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24829
24830         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24831         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24832
24833         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24834 }
24835 run_test 273c "race writeback and object destroy"
24836
24837 test_275() {
24838         remote_ost_nodsh && skip "remote OST with nodsh"
24839         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24840                 skip "Need OST version >= 2.10.57"
24841
24842         local file=$DIR/$tfile
24843         local oss
24844
24845         oss=$(comma_list $(osts_nodes))
24846
24847         dd if=/dev/urandom of=$file bs=1M count=2 ||
24848                 error "failed to create a file"
24849         stack_trap "rm -f $file"
24850         cancel_lru_locks osc
24851
24852         #lock 1
24853         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24854                 error "failed to read a file"
24855
24856 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24857         $LCTL set_param fail_loc=0x8000031f
24858
24859         cancel_lru_locks osc &
24860         sleep 1
24861
24862 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24863         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24864         #IO takes another lock, but matches the PENDING one
24865         #and places it to the IO RPC
24866         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24867                 error "failed to read a file with PENDING lock"
24868 }
24869 run_test 275 "Read on a canceled duplicate lock"
24870
24871 test_276() {
24872         remote_ost_nodsh && skip "remote OST with nodsh"
24873         local pid
24874
24875         do_facet ost1 "(while true; do \
24876                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24877                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24878         pid=$!
24879
24880         for LOOP in $(seq 20); do
24881                 stop ost1
24882                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24883         done
24884         kill -9 $pid
24885         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24886                 rm $TMP/sanity_276_pid"
24887 }
24888 run_test 276 "Race between mount and obd_statfs"
24889
24890 test_277() {
24891         $LCTL set_param ldlm.namespaces.*.lru_size=0
24892         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24893         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24894                         grep ^used_mb | awk '{print $2}')
24895         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24896         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24897                 oflag=direct conv=notrunc
24898         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24899                         grep ^used_mb | awk '{print $2}')
24900         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24901 }
24902 run_test 277 "Direct IO shall drop page cache"
24903
24904 test_278() {
24905         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24906         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24907         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24908                 skip "needs the same host for mdt1 mdt2" && return
24909
24910         local pid1
24911         local pid2
24912
24913 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24914         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24915         stop mds2 &
24916         pid2=$!
24917
24918         stop mds1
24919
24920         echo "Starting MDTs"
24921         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24922         wait $pid2
24923 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24924 #will return NULL
24925         do_facet mds2 $LCTL set_param fail_loc=0
24926
24927         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24928         wait_recovery_complete mds2
24929 }
24930 run_test 278 "Race starting MDS between MDTs stop/start"
24931
24932 test_280() {
24933         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24934                 skip "Need MGS version at least 2.13.52"
24935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24936         combined_mgs_mds || skip "needs combined MGS/MDT"
24937
24938         umount_client $MOUNT
24939 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24940         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24941
24942         mount_client $MOUNT &
24943         sleep 1
24944         stop mgs || error "stop mgs failed"
24945         #for a race mgs would crash
24946         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24947         # make sure we unmount client before remounting
24948         wait
24949         umount_client $MOUNT
24950         mount_client $MOUNT || error "mount client failed"
24951 }
24952 run_test 280 "Race between MGS umount and client llog processing"
24953
24954 cleanup_test_300() {
24955         trap 0
24956         umask $SAVE_UMASK
24957 }
24958 test_striped_dir() {
24959         local mdt_index=$1
24960         local stripe_count
24961         local stripe_index
24962
24963         mkdir -p $DIR/$tdir
24964
24965         SAVE_UMASK=$(umask)
24966         trap cleanup_test_300 RETURN EXIT
24967
24968         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24969                                                 $DIR/$tdir/striped_dir ||
24970                 error "set striped dir error"
24971
24972         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24973         [ "$mode" = "755" ] || error "expect 755 got $mode"
24974
24975         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24976                 error "getdirstripe failed"
24977         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24978         if [ "$stripe_count" != "2" ]; then
24979                 error "1:stripe_count is $stripe_count, expect 2"
24980         fi
24981         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24982         if [ "$stripe_count" != "2" ]; then
24983                 error "2:stripe_count is $stripe_count, expect 2"
24984         fi
24985
24986         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24987         if [ "$stripe_index" != "$mdt_index" ]; then
24988                 error "stripe_index is $stripe_index, expect $mdt_index"
24989         fi
24990
24991         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24992                 error "nlink error after create striped dir"
24993
24994         mkdir $DIR/$tdir/striped_dir/a
24995         mkdir $DIR/$tdir/striped_dir/b
24996
24997         stat $DIR/$tdir/striped_dir/a ||
24998                 error "create dir under striped dir failed"
24999         stat $DIR/$tdir/striped_dir/b ||
25000                 error "create dir under striped dir failed"
25001
25002         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25003                 error "nlink error after mkdir"
25004
25005         rmdir $DIR/$tdir/striped_dir/a
25006         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25007                 error "nlink error after rmdir"
25008
25009         rmdir $DIR/$tdir/striped_dir/b
25010         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25011                 error "nlink error after rmdir"
25012
25013         chattr +i $DIR/$tdir/striped_dir
25014         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25015                 error "immutable flags not working under striped dir!"
25016         chattr -i $DIR/$tdir/striped_dir
25017
25018         rmdir $DIR/$tdir/striped_dir ||
25019                 error "rmdir striped dir error"
25020
25021         cleanup_test_300
25022
25023         true
25024 }
25025
25026 test_300a() {
25027         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25028                 skip "skipped for lustre < 2.7.0"
25029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25030         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25031
25032         test_striped_dir 0 || error "failed on striped dir on MDT0"
25033         test_striped_dir 1 || error "failed on striped dir on MDT0"
25034 }
25035 run_test 300a "basic striped dir sanity test"
25036
25037 test_300b() {
25038         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25039                 skip "skipped for lustre < 2.7.0"
25040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25042
25043         local i
25044         local mtime1
25045         local mtime2
25046         local mtime3
25047
25048         test_mkdir $DIR/$tdir || error "mkdir fail"
25049         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25050                 error "set striped dir error"
25051         for i in {0..9}; do
25052                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25053                 sleep 1
25054                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25055                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25056                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25057                 sleep 1
25058                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25059                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25060                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25061         done
25062         true
25063 }
25064 run_test 300b "check ctime/mtime for striped dir"
25065
25066 test_300c() {
25067         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25068                 skip "skipped for lustre < 2.7.0"
25069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25070         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25071
25072         local file_count
25073
25074         mkdir_on_mdt0 $DIR/$tdir
25075         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25076                 error "set striped dir error"
25077
25078         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25079                 error "chown striped dir failed"
25080
25081         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25082                 error "create 5k files failed"
25083
25084         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25085
25086         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25087
25088         rm -rf $DIR/$tdir
25089 }
25090 run_test 300c "chown && check ls under striped directory"
25091
25092 test_300d() {
25093         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25094                 skip "skipped for lustre < 2.7.0"
25095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25097
25098         local stripe_count
25099         local file
25100
25101         mkdir -p $DIR/$tdir
25102         $LFS setstripe -c 2 $DIR/$tdir
25103
25104         #local striped directory
25105         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25106                 error "set striped dir error"
25107         #look at the directories for debug purposes
25108         ls -l $DIR/$tdir
25109         $LFS getdirstripe $DIR/$tdir
25110         ls -l $DIR/$tdir/striped_dir
25111         $LFS getdirstripe $DIR/$tdir/striped_dir
25112         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25113                 error "create 10 files failed"
25114
25115         #remote striped directory
25116         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25117                 error "set striped dir error"
25118         #look at the directories for debug purposes
25119         ls -l $DIR/$tdir
25120         $LFS getdirstripe $DIR/$tdir
25121         ls -l $DIR/$tdir/remote_striped_dir
25122         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25123         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25124                 error "create 10 files failed"
25125
25126         for file in $(find $DIR/$tdir); do
25127                 stripe_count=$($LFS getstripe -c $file)
25128                 [ $stripe_count -eq 2 ] ||
25129                         error "wrong stripe $stripe_count for $file"
25130         done
25131
25132         rm -rf $DIR/$tdir
25133 }
25134 run_test 300d "check default stripe under striped directory"
25135
25136 test_300e() {
25137         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25138                 skip "Need MDS version at least 2.7.55"
25139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25140         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25141
25142         local stripe_count
25143         local file
25144
25145         mkdir -p $DIR/$tdir
25146
25147         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25148                 error "set striped dir error"
25149
25150         touch $DIR/$tdir/striped_dir/a
25151         touch $DIR/$tdir/striped_dir/b
25152         touch $DIR/$tdir/striped_dir/c
25153
25154         mkdir $DIR/$tdir/striped_dir/dir_a
25155         mkdir $DIR/$tdir/striped_dir/dir_b
25156         mkdir $DIR/$tdir/striped_dir/dir_c
25157
25158         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25159                 error "set striped adir under striped dir error"
25160
25161         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25162                 error "set striped bdir under striped dir error"
25163
25164         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25165                 error "set striped cdir under striped dir error"
25166
25167         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25168                 error "rename dir under striped dir fails"
25169
25170         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25171                 error "rename dir under different stripes fails"
25172
25173         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25174                 error "rename file under striped dir should succeed"
25175
25176         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25177                 error "rename dir under striped dir should succeed"
25178
25179         rm -rf $DIR/$tdir
25180 }
25181 run_test 300e "check rename under striped directory"
25182
25183 test_300f() {
25184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25186         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25187                 skip "Need MDS version at least 2.7.55"
25188
25189         local stripe_count
25190         local file
25191
25192         rm -rf $DIR/$tdir
25193         mkdir -p $DIR/$tdir
25194
25195         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25196                 error "set striped dir error"
25197
25198         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25199                 error "set striped dir error"
25200
25201         touch $DIR/$tdir/striped_dir/a
25202         mkdir $DIR/$tdir/striped_dir/dir_a
25203         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25204                 error "create striped dir under striped dir fails"
25205
25206         touch $DIR/$tdir/striped_dir1/b
25207         mkdir $DIR/$tdir/striped_dir1/dir_b
25208         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25209                 error "create striped dir under striped dir fails"
25210
25211         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25212                 error "rename dir under different striped dir should fail"
25213
25214         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25215                 error "rename striped dir under diff striped dir should fail"
25216
25217         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25218                 error "rename file under diff striped dirs fails"
25219
25220         rm -rf $DIR/$tdir
25221 }
25222 run_test 300f "check rename cross striped directory"
25223
25224 test_300_check_default_striped_dir()
25225 {
25226         local dirname=$1
25227         local default_count=$2
25228         local default_index=$3
25229         local stripe_count
25230         local stripe_index
25231         local dir_stripe_index
25232         local dir
25233
25234         echo "checking $dirname $default_count $default_index"
25235         $LFS setdirstripe -D -c $default_count -i $default_index \
25236                                 -H all_char $DIR/$tdir/$dirname ||
25237                 error "set default stripe on striped dir error"
25238         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25239         [ $stripe_count -eq $default_count ] ||
25240                 error "expect $default_count get $stripe_count for $dirname"
25241
25242         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25243         [ $stripe_index -eq $default_index ] ||
25244                 error "expect $default_index get $stripe_index for $dirname"
25245
25246         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25247                                                 error "create dirs failed"
25248
25249         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25250         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25251         for dir in $(find $DIR/$tdir/$dirname/*); do
25252                 stripe_count=$($LFS getdirstripe -c $dir)
25253                 (( $stripe_count == $default_count )) ||
25254                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25255                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25256                 error "stripe count $default_count != $stripe_count for $dir"
25257
25258                 stripe_index=$($LFS getdirstripe -i $dir)
25259                 [ $default_index -eq -1 ] ||
25260                         [ $stripe_index -eq $default_index ] ||
25261                         error "$stripe_index != $default_index for $dir"
25262
25263                 #check default stripe
25264                 stripe_count=$($LFS getdirstripe -D -c $dir)
25265                 [ $stripe_count -eq $default_count ] ||
25266                 error "default count $default_count != $stripe_count for $dir"
25267
25268                 stripe_index=$($LFS getdirstripe -D -i $dir)
25269                 [ $stripe_index -eq $default_index ] ||
25270                 error "default index $default_index != $stripe_index for $dir"
25271         done
25272         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25273 }
25274
25275 test_300g() {
25276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25277         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25278                 skip "Need MDS version at least 2.7.55"
25279
25280         local dir
25281         local stripe_count
25282         local stripe_index
25283
25284         mkdir_on_mdt0 $DIR/$tdir
25285         mkdir $DIR/$tdir/normal_dir
25286
25287         #Checking when client cache stripe index
25288         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25289         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25290                 error "create striped_dir failed"
25291
25292         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25293                 error "create dir0 fails"
25294         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25295         [ $stripe_index -eq 0 ] ||
25296                 error "dir0 expect index 0 got $stripe_index"
25297
25298         mkdir $DIR/$tdir/striped_dir/dir1 ||
25299                 error "create dir1 fails"
25300         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25301         [ $stripe_index -eq 1 ] ||
25302                 error "dir1 expect index 1 got $stripe_index"
25303
25304         #check default stripe count/stripe index
25305         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25306         test_300_check_default_striped_dir normal_dir 1 0
25307         test_300_check_default_striped_dir normal_dir -1 1
25308         test_300_check_default_striped_dir normal_dir 2 -1
25309
25310         #delete default stripe information
25311         echo "delete default stripeEA"
25312         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25313                 error "set default stripe on striped dir error"
25314
25315         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25316         for dir in $(find $DIR/$tdir/normal_dir/*); do
25317                 stripe_count=$($LFS getdirstripe -c $dir)
25318                 [ $stripe_count -eq 0 ] ||
25319                         error "expect 1 get $stripe_count for $dir"
25320         done
25321 }
25322 run_test 300g "check default striped directory for normal directory"
25323
25324 test_300h() {
25325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25326         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25327                 skip "Need MDS version at least 2.7.55"
25328
25329         local dir
25330         local stripe_count
25331
25332         mkdir $DIR/$tdir
25333         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25334                 error "set striped dir error"
25335
25336         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25337         test_300_check_default_striped_dir striped_dir 1 0
25338         test_300_check_default_striped_dir striped_dir -1 1
25339         test_300_check_default_striped_dir striped_dir 2 -1
25340
25341         #delete default stripe information
25342         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25343                 error "set default stripe on striped dir error"
25344
25345         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25346         for dir in $(find $DIR/$tdir/striped_dir/*); do
25347                 stripe_count=$($LFS getdirstripe -c $dir)
25348                 [ $stripe_count -eq 0 ] ||
25349                         error "expect 1 get $stripe_count for $dir"
25350         done
25351 }
25352 run_test 300h "check default striped directory for striped directory"
25353
25354 test_300i() {
25355         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25356         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25357         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25358                 skip "Need MDS version at least 2.7.55"
25359
25360         local stripe_count
25361         local file
25362
25363         mkdir $DIR/$tdir
25364
25365         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25366                 error "set striped dir error"
25367
25368         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25369                 error "create files under striped dir failed"
25370
25371         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25372                 error "set striped hashdir error"
25373
25374         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25375                 error "create dir0 under hash dir failed"
25376         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25377                 error "create dir1 under hash dir failed"
25378         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25379                 error "create dir2 under hash dir failed"
25380
25381         # unfortunately, we need to umount to clear dir layout cache for now
25382         # once we fully implement dir layout, we can drop this
25383         umount_client $MOUNT || error "umount failed"
25384         mount_client $MOUNT || error "mount failed"
25385
25386         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25387         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25388         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25389
25390         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25391                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25392                         error "create crush2 dir $tdir/hashdir/d3 failed"
25393                 $LFS find -H crush2 $DIR/$tdir/hashdir
25394                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25395                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25396
25397                 # mkdir with an invalid hash type (hash=fail_val) from client
25398                 # should be replaced on MDS with a valid (default) hash type
25399                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25400                 $LCTL set_param fail_loc=0x1901 fail_val=99
25401                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25402
25403                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25404                 local expect=$(do_facet mds1 \
25405                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25406                 [[ $hash == $expect ]] ||
25407                         error "d99 hash '$hash' != expected hash '$expect'"
25408         fi
25409
25410         #set the stripe to be unknown hash type on read
25411         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25412         $LCTL set_param fail_loc=0x1901 fail_val=99
25413         for ((i = 0; i < 10; i++)); do
25414                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25415                         error "stat f-$i failed"
25416                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25417         done
25418
25419         touch $DIR/$tdir/striped_dir/f0 &&
25420                 error "create under striped dir with unknown hash should fail"
25421
25422         $LCTL set_param fail_loc=0
25423
25424         umount_client $MOUNT || error "umount failed"
25425         mount_client $MOUNT || error "mount failed"
25426
25427         return 0
25428 }
25429 run_test 300i "client handle unknown hash type striped directory"
25430
25431 test_300j() {
25432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25434         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25435                 skip "Need MDS version at least 2.7.55"
25436
25437         local stripe_count
25438         local file
25439
25440         mkdir $DIR/$tdir
25441
25442         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25443         $LCTL set_param fail_loc=0x1702
25444         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25445                 error "set striped dir error"
25446
25447         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25448                 error "create files under striped dir failed"
25449
25450         $LCTL set_param fail_loc=0
25451
25452         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25453
25454         return 0
25455 }
25456 run_test 300j "test large update record"
25457
25458 test_300k() {
25459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25460         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25461         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25462                 skip "Need MDS version at least 2.7.55"
25463
25464         # this test needs a huge transaction
25465         local kb
25466         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25467              osd*.$FSNAME-MDT0000.kbytestotal")
25468         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25469
25470         local stripe_count
25471         local file
25472
25473         mkdir $DIR/$tdir
25474
25475         #define OBD_FAIL_LARGE_STRIPE   0x1703
25476         $LCTL set_param fail_loc=0x1703
25477         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25478                 error "set striped dir error"
25479         $LCTL set_param fail_loc=0
25480
25481         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25482                 error "getstripeddir fails"
25483         rm -rf $DIR/$tdir/striped_dir ||
25484                 error "unlink striped dir fails"
25485
25486         return 0
25487 }
25488 run_test 300k "test large striped directory"
25489
25490 test_300l() {
25491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25493         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25494                 skip "Need MDS version at least 2.7.55"
25495
25496         local stripe_index
25497
25498         test_mkdir -p $DIR/$tdir/striped_dir
25499         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25500                         error "chown $RUNAS_ID failed"
25501         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25502                 error "set default striped dir failed"
25503
25504         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25505         $LCTL set_param fail_loc=0x80000158
25506         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25507
25508         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25509         [ $stripe_index -eq 1 ] ||
25510                 error "expect 1 get $stripe_index for $dir"
25511 }
25512 run_test 300l "non-root user to create dir under striped dir with stale layout"
25513
25514 test_300m() {
25515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25516         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25517         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25518                 skip "Need MDS version at least 2.7.55"
25519
25520         mkdir -p $DIR/$tdir/striped_dir
25521         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25522                 error "set default stripes dir error"
25523
25524         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25525
25526         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25527         [ $stripe_count -eq 0 ] ||
25528                         error "expect 0 get $stripe_count for a"
25529
25530         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25531                 error "set default stripes dir error"
25532
25533         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25534
25535         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25536         [ $stripe_count -eq 0 ] ||
25537                         error "expect 0 get $stripe_count for b"
25538
25539         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25540                 error "set default stripes dir error"
25541
25542         mkdir $DIR/$tdir/striped_dir/c &&
25543                 error "default stripe_index is invalid, mkdir c should fails"
25544
25545         rm -rf $DIR/$tdir || error "rmdir fails"
25546 }
25547 run_test 300m "setstriped directory on single MDT FS"
25548
25549 cleanup_300n() {
25550         local list=$(comma_list $(mdts_nodes))
25551
25552         trap 0
25553         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25554 }
25555
25556 test_300n() {
25557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25559         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25560                 skip "Need MDS version at least 2.7.55"
25561         remote_mds_nodsh && skip "remote MDS with nodsh"
25562
25563         local stripe_index
25564         local list=$(comma_list $(mdts_nodes))
25565
25566         trap cleanup_300n RETURN EXIT
25567         mkdir -p $DIR/$tdir
25568         chmod 777 $DIR/$tdir
25569         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25570                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25571                 error "create striped dir succeeds with gid=0"
25572
25573         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25574         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25575                 error "create striped dir fails with gid=-1"
25576
25577         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25578         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25579                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25580                 error "set default striped dir succeeds with gid=0"
25581
25582
25583         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25584         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25585                 error "set default striped dir fails with gid=-1"
25586
25587
25588         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25589         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25590                                         error "create test_dir fails"
25591         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25592                                         error "create test_dir1 fails"
25593         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25594                                         error "create test_dir2 fails"
25595         cleanup_300n
25596 }
25597 run_test 300n "non-root user to create dir under striped dir with default EA"
25598
25599 test_300o() {
25600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25602         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25603                 skip "Need MDS version at least 2.7.55"
25604
25605         local numfree1
25606         local numfree2
25607
25608         mkdir -p $DIR/$tdir
25609
25610         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25611         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25612         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25613                 skip "not enough free inodes $numfree1 $numfree2"
25614         fi
25615
25616         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25617         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25618         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25619                 skip "not enough free space $numfree1 $numfree2"
25620         fi
25621
25622         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25623                 error "setdirstripe fails"
25624
25625         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25626                 error "create dirs fails"
25627
25628         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25629         ls $DIR/$tdir/striped_dir > /dev/null ||
25630                 error "ls striped dir fails"
25631         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25632                 error "unlink big striped dir fails"
25633 }
25634 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25635
25636 test_300p() {
25637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25639         remote_mds_nodsh && skip "remote MDS with nodsh"
25640
25641         mkdir_on_mdt0 $DIR/$tdir
25642
25643         #define OBD_FAIL_OUT_ENOSPC     0x1704
25644         do_facet mds2 lctl set_param fail_loc=0x80001704
25645         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25646                  && error "create striped directory should fail"
25647
25648         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25649
25650         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25651         true
25652 }
25653 run_test 300p "create striped directory without space"
25654
25655 test_300q() {
25656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25658
25659         local fd=$(free_fd)
25660         local cmd="exec $fd<$tdir"
25661         cd $DIR
25662         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25663         eval $cmd
25664         cmd="exec $fd<&-"
25665         trap "eval $cmd" EXIT
25666         cd $tdir || error "cd $tdir fails"
25667         rmdir  ../$tdir || error "rmdir $tdir fails"
25668         mkdir local_dir && error "create dir succeeds"
25669         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25670         eval $cmd
25671         return 0
25672 }
25673 run_test 300q "create remote directory under orphan directory"
25674
25675 test_300r() {
25676         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25677                 skip "Need MDS version at least 2.7.55" && return
25678         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25679
25680         mkdir $DIR/$tdir
25681
25682         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25683                 error "set striped dir error"
25684
25685         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25686                 error "getstripeddir fails"
25687
25688         local stripe_count
25689         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25690                       awk '/lmv_stripe_count:/ { print $2 }')
25691
25692         [ $MDSCOUNT -ne $stripe_count ] &&
25693                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25694
25695         rm -rf $DIR/$tdir/striped_dir ||
25696                 error "unlink striped dir fails"
25697 }
25698 run_test 300r "test -1 striped directory"
25699
25700 test_300s_helper() {
25701         local count=$1
25702
25703         local stripe_dir=$DIR/$tdir/striped_dir.$count
25704
25705         $LFS mkdir -c $count $stripe_dir ||
25706                 error "lfs mkdir -c error"
25707
25708         $LFS getdirstripe $stripe_dir ||
25709                 error "lfs getdirstripe fails"
25710
25711         local stripe_count
25712         stripe_count=$($LFS getdirstripe $stripe_dir |
25713                       awk '/lmv_stripe_count:/ { print $2 }')
25714
25715         [ $count -ne $stripe_count ] &&
25716                 error_noexit "bad stripe count $stripe_count expected $count"
25717
25718         local dupe_stripes
25719         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25720                 awk '/0x/ {count[$1] += 1}; END {
25721                         for (idx in count) {
25722                                 if (count[idx]>1) {
25723                                         print "index " idx " count " count[idx]
25724                                 }
25725                         }
25726                 }')
25727
25728         if [[ -n "$dupe_stripes" ]] ; then
25729                 lfs getdirstripe $stripe_dir
25730                 error_noexit "Dupe MDT above: $dupe_stripes "
25731         fi
25732
25733         rm -rf $stripe_dir ||
25734                 error_noexit "unlink $stripe_dir fails"
25735 }
25736
25737 test_300s() {
25738         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25739                 skip "Need MDS version at least 2.7.55" && return
25740         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25741
25742         mkdir $DIR/$tdir
25743         for count in $(seq 2 $MDSCOUNT); do
25744                 test_300s_helper $count
25745         done
25746 }
25747 run_test 300s "test lfs mkdir -c without -i"
25748
25749 test_300t() {
25750         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25751                 skip "need MDS 2.14.55 or later"
25752         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25753
25754         local testdir="$DIR/$tdir/striped_dir"
25755         local dir1=$testdir/dir1
25756         local dir2=$testdir/dir2
25757
25758         mkdir -p $testdir
25759
25760         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25761                 error "failed to set default stripe count for $testdir"
25762
25763         mkdir $dir1
25764         local stripe_count=$($LFS getdirstripe -c $dir1)
25765
25766         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25767
25768         local max_count=$((MDSCOUNT - 1))
25769         local mdts=$(comma_list $(mdts_nodes))
25770
25771         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25772         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25773
25774         mkdir $dir2
25775         stripe_count=$($LFS getdirstripe -c $dir2)
25776
25777         (( $stripe_count == $max_count )) || error "wrong stripe count"
25778 }
25779 run_test 300t "test max_mdt_stripecount"
25780
25781 prepare_remote_file() {
25782         mkdir $DIR/$tdir/src_dir ||
25783                 error "create remote source failed"
25784
25785         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25786                  error "cp to remote source failed"
25787         touch $DIR/$tdir/src_dir/a
25788
25789         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25790                 error "create remote target dir failed"
25791
25792         touch $DIR/$tdir/tgt_dir/b
25793
25794         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25795                 error "rename dir cross MDT failed!"
25796
25797         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25798                 error "src_child still exists after rename"
25799
25800         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25801                 error "missing file(a) after rename"
25802
25803         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25804                 error "diff after rename"
25805 }
25806
25807 test_310a() {
25808         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25810
25811         local remote_file=$DIR/$tdir/tgt_dir/b
25812
25813         mkdir -p $DIR/$tdir
25814
25815         prepare_remote_file || error "prepare remote file failed"
25816
25817         #open-unlink file
25818         $OPENUNLINK $remote_file $remote_file ||
25819                 error "openunlink $remote_file failed"
25820         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25821 }
25822 run_test 310a "open unlink remote file"
25823
25824 test_310b() {
25825         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25827
25828         local remote_file=$DIR/$tdir/tgt_dir/b
25829
25830         mkdir -p $DIR/$tdir
25831
25832         prepare_remote_file || error "prepare remote file failed"
25833
25834         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25835         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25836         $CHECKSTAT -t file $remote_file || error "check file failed"
25837 }
25838 run_test 310b "unlink remote file with multiple links while open"
25839
25840 test_310c() {
25841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25842         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25843
25844         local remote_file=$DIR/$tdir/tgt_dir/b
25845
25846         mkdir -p $DIR/$tdir
25847
25848         prepare_remote_file || error "prepare remote file failed"
25849
25850         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25851         multiop_bg_pause $remote_file O_uc ||
25852                         error "mulitop failed for remote file"
25853         MULTIPID=$!
25854         $MULTIOP $DIR/$tfile Ouc
25855         kill -USR1 $MULTIPID
25856         wait $MULTIPID
25857 }
25858 run_test 310c "open-unlink remote file with multiple links"
25859
25860 #LU-4825
25861 test_311() {
25862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25863         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25864         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25865                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25866         remote_mds_nodsh && skip "remote MDS with nodsh"
25867
25868         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25869         local mdts=$(comma_list $(mdts_nodes))
25870
25871         mkdir -p $DIR/$tdir
25872         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25873         createmany -o $DIR/$tdir/$tfile. 1000
25874
25875         # statfs data is not real time, let's just calculate it
25876         old_iused=$((old_iused + 1000))
25877
25878         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25879                         osp.*OST0000*MDT0000.create_count")
25880         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25881                                 osp.*OST0000*MDT0000.max_create_count")
25882         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25883
25884         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25885         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25886         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25887
25888         unlinkmany $DIR/$tdir/$tfile. 1000
25889
25890         do_nodes $mdts "$LCTL set_param -n \
25891                         osp.*OST0000*.max_create_count=$max_count"
25892         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25893                 do_nodes $mdts "$LCTL set_param -n \
25894                                 osp.*OST0000*.create_count=$count"
25895         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25896                         grep "=0" && error "create_count is zero"
25897
25898         local new_iused
25899         for i in $(seq 120); do
25900                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25901                 # system may be too busy to destroy all objs in time, use
25902                 # a somewhat small value to not fail autotest
25903                 [ $((old_iused - new_iused)) -gt 400 ] && break
25904                 sleep 1
25905         done
25906
25907         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25908         [ $((old_iused - new_iused)) -gt 400 ] ||
25909                 error "objs not destroyed after unlink"
25910 }
25911 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25912
25913 zfs_get_objid()
25914 {
25915         local ost=$1
25916         local tf=$2
25917         local fid=($($LFS getstripe $tf | grep 0x))
25918         local seq=${fid[3]#0x}
25919         local objid=${fid[1]}
25920
25921         local vdevdir=$(dirname $(facet_vdevice $ost))
25922         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25923         local zfs_zapid=$(do_facet $ost $cmd |
25924                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25925                           awk '/Object/{getline; print $1}')
25926         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25927                           awk "/$objid = /"'{printf $3}')
25928
25929         echo $zfs_objid
25930 }
25931
25932 zfs_object_blksz() {
25933         local ost=$1
25934         local objid=$2
25935
25936         local vdevdir=$(dirname $(facet_vdevice $ost))
25937         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25938         local blksz=$(do_facet $ost $cmd $objid |
25939                       awk '/dblk/{getline; printf $4}')
25940
25941         case "${blksz: -1}" in
25942                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25943                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25944                 *) ;;
25945         esac
25946
25947         echo $blksz
25948 }
25949
25950 test_312() { # LU-4856
25951         remote_ost_nodsh && skip "remote OST with nodsh"
25952         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25953
25954         local max_blksz=$(do_facet ost1 \
25955                           $ZFS get -p recordsize $(facet_device ost1) |
25956                           awk '!/VALUE/{print $3}')
25957         local tf=$DIR/$tfile
25958
25959         $LFS setstripe -c1 $tf
25960         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25961
25962         # Get ZFS object id
25963         local zfs_objid=$(zfs_get_objid $facet $tf)
25964         # block size change by sequential overwrite
25965         local bs
25966
25967         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25968                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25969
25970                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25971                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25972         done
25973         rm -f $tf
25974
25975         $LFS setstripe -c1 $tf
25976         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25977
25978         # block size change by sequential append write
25979         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25980         zfs_objid=$(zfs_get_objid $facet $tf)
25981         local count
25982
25983         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25984                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25985                         oflag=sync conv=notrunc
25986
25987                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25988                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25989                         error "blksz error, actual $blksz, " \
25990                                 "expected: 2 * $count * $PAGE_SIZE"
25991         done
25992         rm -f $tf
25993
25994         # random write
25995         $LFS setstripe -c1 $tf
25996         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25997         zfs_objid=$(zfs_get_objid $facet $tf)
25998
25999         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26000         blksz=$(zfs_object_blksz $facet $zfs_objid)
26001         (( blksz == PAGE_SIZE )) ||
26002                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26003
26004         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26005         blksz=$(zfs_object_blksz $facet $zfs_objid)
26006         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26007
26008         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26009         blksz=$(zfs_object_blksz $facet $zfs_objid)
26010         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26011 }
26012 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26013
26014 test_313() {
26015         remote_ost_nodsh && skip "remote OST with nodsh"
26016
26017         local file=$DIR/$tfile
26018
26019         rm -f $file
26020         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26021
26022         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26023         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26024         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26025                 error "write should failed"
26026         do_facet ost1 "$LCTL set_param fail_loc=0"
26027         rm -f $file
26028 }
26029 run_test 313 "io should fail after last_rcvd update fail"
26030
26031 test_314() {
26032         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26033
26034         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26035         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26036         rm -f $DIR/$tfile
26037         wait_delete_completed
26038         do_facet ost1 "$LCTL set_param fail_loc=0"
26039 }
26040 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26041
26042 test_315() { # LU-618
26043         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26044
26045         local file=$DIR/$tfile
26046         rm -f $file
26047
26048         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26049                 error "multiop file write failed"
26050         $MULTIOP $file oO_RDONLY:r4063232_c &
26051         PID=$!
26052
26053         sleep 2
26054
26055         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26056         kill -USR1 $PID
26057
26058         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26059         rm -f $file
26060 }
26061 run_test 315 "read should be accounted"
26062
26063 test_316() {
26064         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26065         large_xattr_enabled || skip "ea_inode feature disabled"
26066
26067         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26068         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26069         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26070         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26071
26072         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26073 }
26074 run_test 316 "lfs migrate of file with large_xattr enabled"
26075
26076 test_317() {
26077         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26078                 skip "Need MDS version at least 2.11.53"
26079         if [ "$ost1_FSTYPE" == "zfs" ]; then
26080                 skip "LU-10370: no implementation for ZFS"
26081         fi
26082
26083         local trunc_sz
26084         local grant_blk_size
26085
26086         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26087                         awk '/grant_block_size:/ { print $2; exit; }')
26088         #
26089         # Create File of size 5M. Truncate it to below size's and verify
26090         # blocks count.
26091         #
26092         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26093                 error "Create file $DIR/$tfile failed"
26094         stack_trap "rm -f $DIR/$tfile" EXIT
26095
26096         for trunc_sz in 2097152 4097 4000 509 0; do
26097                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26098                         error "truncate $tfile to $trunc_sz failed"
26099                 local sz=$(stat --format=%s $DIR/$tfile)
26100                 local blk=$(stat --format=%b $DIR/$tfile)
26101                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26102                                      grant_blk_size) * 8))
26103
26104                 if [[ $blk -ne $trunc_blk ]]; then
26105                         $(which stat) $DIR/$tfile
26106                         error "Expected Block $trunc_blk got $blk for $tfile"
26107                 fi
26108
26109                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26110                         error "Expected Size $trunc_sz got $sz for $tfile"
26111         done
26112
26113         #
26114         # sparse file test
26115         # Create file with a hole and write actual 65536 bytes which aligned
26116         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26117         #
26118         local bs=65536
26119         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26120                 error "Create file : $DIR/$tfile"
26121
26122         #
26123         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26124         # blocks. The block count must drop to 8.
26125         #
26126         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26127                 ((bs - grant_blk_size) + 1)))
26128         $TRUNCATE $DIR/$tfile $trunc_sz ||
26129                 error "truncate $tfile to $trunc_sz failed"
26130
26131         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26132         sz=$(stat --format=%s $DIR/$tfile)
26133         blk=$(stat --format=%b $DIR/$tfile)
26134
26135         if [[ $blk -ne $trunc_bsz ]]; then
26136                 $(which stat) $DIR/$tfile
26137                 error "Expected Block $trunc_bsz got $blk for $tfile"
26138         fi
26139
26140         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26141                 error "Expected Size $trunc_sz got $sz for $tfile"
26142 }
26143 run_test 317 "Verify blocks get correctly update after truncate"
26144
26145 test_318() {
26146         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26147         local old_max_active=$($LCTL get_param -n \
26148                             ${llite_name}.max_read_ahead_async_active \
26149                             2>/dev/null)
26150
26151         $LCTL set_param llite.*.max_read_ahead_async_active=256
26152         local max_active=$($LCTL get_param -n \
26153                            ${llite_name}.max_read_ahead_async_active \
26154                            2>/dev/null)
26155         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26156
26157         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26158                 error "set max_read_ahead_async_active should succeed"
26159
26160         $LCTL set_param llite.*.max_read_ahead_async_active=512
26161         max_active=$($LCTL get_param -n \
26162                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26163         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26164
26165         # restore @max_active
26166         [ $old_max_active -ne 0 ] && $LCTL set_param \
26167                 llite.*.max_read_ahead_async_active=$old_max_active
26168
26169         local old_threshold=$($LCTL get_param -n \
26170                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26171         local max_per_file_mb=$($LCTL get_param -n \
26172                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26173
26174         local invalid=$(($max_per_file_mb + 1))
26175         $LCTL set_param \
26176                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26177                         && error "set $invalid should fail"
26178
26179         local valid=$(($invalid - 1))
26180         $LCTL set_param \
26181                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26182                         error "set $valid should succeed"
26183         local threshold=$($LCTL get_param -n \
26184                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26185         [ $threshold -eq $valid ] || error \
26186                 "expect threshold $valid got $threshold"
26187         $LCTL set_param \
26188                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26189 }
26190 run_test 318 "Verify async readahead tunables"
26191
26192 test_319() {
26193         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26194
26195         local before=$(date +%s)
26196         local evict
26197         local mdir=$DIR/$tdir
26198         local file=$mdir/xxx
26199
26200         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26201         touch $file
26202
26203 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26204         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26205         $LFS migrate -m1 $mdir &
26206
26207         sleep 1
26208         dd if=$file of=/dev/null
26209         wait
26210         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26211           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26212
26213         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26214 }
26215 run_test 319 "lost lease lock on migrate error"
26216
26217 test_398a() { # LU-4198
26218         local ost1_imp=$(get_osc_import_name client ost1)
26219         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26220                          cut -d'.' -f2)
26221
26222         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26223         stack_trap "rm -f $DIR/$tfile"
26224         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26225
26226         # request a new lock on client
26227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26228
26229         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26230         local lock_count=$($LCTL get_param -n \
26231                            ldlm.namespaces.$imp_name.lru_size)
26232         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26233
26234         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26235
26236         # no lock cached, should use lockless DIO and not enqueue new lock
26237         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26238         lock_count=$($LCTL get_param -n \
26239                      ldlm.namespaces.$imp_name.lru_size)
26240         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26241
26242         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
26243
26244         # no lock cached, should use locked DIO append
26245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26246                 conv=notrunc || error "DIO append failed"
26247         lock_count=$($LCTL get_param -n \
26248                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
26249         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26250 }
26251 run_test 398a "direct IO should cancel lock otherwise lockless"
26252
26253 test_398b() { # LU-4198
26254         local before=$(date +%s)
26255         local njobs=4
26256         local size=48
26257
26258         which fio || skip_env "no fio installed"
26259         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26260         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26261
26262         # Single page, multiple pages, stripe size, 4*stripe size
26263         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26264                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26265                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26266                         --numjobs=$njobs --fallocate=none \
26267                         --iodepth=16 --allow_file_create=0 \
26268                         --size=$((size/njobs))M \
26269                         --filename=$DIR/$tfile &
26270                 bg_pid=$!
26271
26272                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26273                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26274                         --numjobs=$njobs --fallocate=none \
26275                         --iodepth=16 --allow_file_create=0 \
26276                         --size=$((size/njobs))M \
26277                         --filename=$DIR/$tfile || true
26278                 wait $bg_pid
26279         done
26280
26281         evict=$(do_facet client $LCTL get_param \
26282                 osc.$FSNAME-OST*-osc-*/state |
26283             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26284
26285         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26286                 (do_facet client $LCTL get_param \
26287                         osc.$FSNAME-OST*-osc-*/state;
26288                     error "eviction happened: $evict before:$before")
26289
26290         rm -f $DIR/$tfile
26291 }
26292 run_test 398b "DIO and buffer IO race"
26293
26294 test_398c() { # LU-4198
26295         local ost1_imp=$(get_osc_import_name client ost1)
26296         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26297                          cut -d'.' -f2)
26298
26299         which fio || skip_env "no fio installed"
26300
26301         saved_debug=$($LCTL get_param -n debug)
26302         $LCTL set_param debug=0
26303
26304         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26305         ((size /= 1024)) # by megabytes
26306         ((size /= 2)) # write half of the OST at most
26307         [ $size -gt 40 ] && size=40 #reduce test time anyway
26308
26309         $LFS setstripe -c 1 $DIR/$tfile
26310
26311         # it seems like ldiskfs reserves more space than necessary if the
26312         # writing blocks are not mapped, so it extends the file firstly
26313         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26314         cancel_lru_locks osc
26315
26316         # clear and verify rpc_stats later
26317         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26318
26319         local njobs=4
26320         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26321         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26322                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26323                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26324                 --filename=$DIR/$tfile
26325         [ $? -eq 0 ] || error "fio write error"
26326
26327         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26328                 error "Locks were requested while doing AIO"
26329
26330         # get the percentage of 1-page I/O
26331         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26332                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26333                 awk '{print $7}')
26334         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26335
26336         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26337         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26338                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26339                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26340                 --filename=$DIR/$tfile
26341         [ $? -eq 0 ] || error "fio mixed read write error"
26342
26343         echo "AIO with large block size ${size}M"
26344         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26345                 --numjobs=1 --fallocate=none --ioengine=libaio \
26346                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26347                 --filename=$DIR/$tfile
26348         [ $? -eq 0 ] || error "fio large block size failed"
26349
26350         rm -f $DIR/$tfile
26351         $LCTL set_param debug="$saved_debug"
26352 }
26353 run_test 398c "run fio to test AIO"
26354
26355 test_398d() { #  LU-13846
26356         which aiocp || skip_env "no aiocp installed"
26357         local aio_file=$DIR/$tfile.aio
26358
26359         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26360
26361         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26362         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26363         stack_trap "rm -f $DIR/$tfile $aio_file"
26364
26365         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26366
26367         # make sure we don't crash and fail properly
26368         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26369                 error "aio not aligned with PAGE SIZE should fail"
26370
26371         rm -f $DIR/$tfile $aio_file
26372 }
26373 run_test 398d "run aiocp to verify block size > stripe size"
26374
26375 test_398e() {
26376         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26377         touch $DIR/$tfile.new
26378         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26379 }
26380 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26381
26382 test_398f() { #  LU-14687
26383         which aiocp || skip_env "no aiocp installed"
26384         local aio_file=$DIR/$tfile.aio
26385
26386         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26387
26388         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26389         stack_trap "rm -f $DIR/$tfile $aio_file"
26390
26391         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26392         $LCTL set_param fail_loc=0x1418
26393         # make sure we don't crash and fail properly
26394         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26395                 error "aio with page allocation failure succeeded"
26396         $LCTL set_param fail_loc=0
26397         diff $DIR/$tfile $aio_file
26398         [[ $? != 0 ]] || error "no diff after failed aiocp"
26399 }
26400 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26401
26402 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26403 # stripe and i/o size must be > stripe size
26404 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26405 # single RPC in flight.  This test shows async DIO submission is working by
26406 # showing multiple RPCs in flight.
26407 test_398g() { #  LU-13798
26408         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26409
26410         # We need to do some i/o first to acquire enough grant to put our RPCs
26411         # in flight; otherwise a new connection may not have enough grant
26412         # available
26413         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26414                 error "parallel dio failed"
26415         stack_trap "rm -f $DIR/$tfile"
26416
26417         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26418         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26419         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26420         stack_trap "$LCTL set_param -n $pages_per_rpc"
26421
26422         # Recreate file so it's empty
26423         rm -f $DIR/$tfile
26424         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26425         #Pause rpc completion to guarantee we see multiple rpcs in flight
26426         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26427         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26428         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26429
26430         # Clear rpc stats
26431         $LCTL set_param osc.*.rpc_stats=c
26432
26433         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26434                 error "parallel dio failed"
26435         stack_trap "rm -f $DIR/$tfile"
26436
26437         $LCTL get_param osc.*-OST0000-*.rpc_stats
26438         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26439                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26440                 grep "8:" | awk '{print $8}')
26441         # We look at the "8 rpcs in flight" field, and verify A) it is present
26442         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26443         # as expected for an 8M DIO to a file with 1M stripes.
26444         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26445
26446         # Verify turning off parallel dio works as expected
26447         # Clear rpc stats
26448         $LCTL set_param osc.*.rpc_stats=c
26449         $LCTL set_param llite.*.parallel_dio=0
26450         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26451
26452         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26453                 error "dio with parallel dio disabled failed"
26454
26455         # Ideally, we would see only one RPC in flight here, but there is an
26456         # unavoidable race between i/o completion and RPC in flight counting,
26457         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26458         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26459         # So instead we just verify it's always < 8.
26460         $LCTL get_param osc.*-OST0000-*.rpc_stats
26461         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26462                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26463                 grep '^$' -B1 | grep . | awk '{print $1}')
26464         [ $ret != "8:" ] ||
26465                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26466 }
26467 run_test 398g "verify parallel dio async RPC submission"
26468
26469 test_398h() { #  LU-13798
26470         local dio_file=$DIR/$tfile.dio
26471
26472         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26473
26474         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26475         stack_trap "rm -f $DIR/$tfile $dio_file"
26476
26477         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26478                 error "parallel dio failed"
26479         diff $DIR/$tfile $dio_file
26480         [[ $? == 0 ]] || error "file diff after aiocp"
26481 }
26482 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26483
26484 test_398i() { #  LU-13798
26485         local dio_file=$DIR/$tfile.dio
26486
26487         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26488
26489         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26490         stack_trap "rm -f $DIR/$tfile $dio_file"
26491
26492         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26493         $LCTL set_param fail_loc=0x1418
26494         # make sure we don't crash and fail properly
26495         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26496                 error "parallel dio page allocation failure succeeded"
26497         diff $DIR/$tfile $dio_file
26498         [[ $? != 0 ]] || error "no diff after failed aiocp"
26499 }
26500 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26501
26502 test_398j() { #  LU-13798
26503         # Stripe size > RPC size but less than i/o size tests split across
26504         # stripes and RPCs for individual i/o op
26505         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26506
26507         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26508         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26509         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26510         stack_trap "$LCTL set_param -n $pages_per_rpc"
26511
26512         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26513                 error "parallel dio write failed"
26514         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26515
26516         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26517                 error "parallel dio read failed"
26518         diff $DIR/$tfile $DIR/$tfile.2
26519         [[ $? == 0 ]] || error "file diff after parallel dio read"
26520 }
26521 run_test 398j "test parallel dio where stripe size > rpc_size"
26522
26523 test_398k() { #  LU-13798
26524         wait_delete_completed
26525         wait_mds_ost_sync
26526
26527         # 4 stripe file; we will cause out of space on OST0
26528         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26529
26530         # Fill OST0 (if it's not too large)
26531         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26532                    head -n1)
26533         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26534                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26535         fi
26536         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26537         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26538                 error "dd should fill OST0"
26539         stack_trap "rm -f $DIR/$tfile.1"
26540
26541         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26542         err=$?
26543
26544         ls -la $DIR/$tfile
26545         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26546                 error "file is not 0 bytes in size"
26547
26548         # dd above should not succeed, but don't error until here so we can
26549         # get debug info above
26550         [[ $err != 0 ]] ||
26551                 error "parallel dio write with enospc succeeded"
26552         stack_trap "rm -f $DIR/$tfile"
26553 }
26554 run_test 398k "test enospc on first stripe"
26555
26556 test_398l() { #  LU-13798
26557         wait_delete_completed
26558         wait_mds_ost_sync
26559
26560         # 4 stripe file; we will cause out of space on OST0
26561         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26562         # happens on the second i/o chunk we issue
26563         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26564
26565         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26566         stack_trap "rm -f $DIR/$tfile"
26567
26568         # Fill OST0 (if it's not too large)
26569         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26570                    head -n1)
26571         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26572                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26573         fi
26574         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26575         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26576                 error "dd should fill OST0"
26577         stack_trap "rm -f $DIR/$tfile.1"
26578
26579         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26580         err=$?
26581         stack_trap "rm -f $DIR/$tfile.2"
26582
26583         # Check that short write completed as expected
26584         ls -la $DIR/$tfile.2
26585         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26586                 error "file is not 1M in size"
26587
26588         # dd above should not succeed, but don't error until here so we can
26589         # get debug info above
26590         [[ $err != 0 ]] ||
26591                 error "parallel dio write with enospc succeeded"
26592
26593         # Truncate source file to same length as output file and diff them
26594         $TRUNCATE $DIR/$tfile 1048576
26595         diff $DIR/$tfile $DIR/$tfile.2
26596         [[ $? == 0 ]] || error "data incorrect after short write"
26597 }
26598 run_test 398l "test enospc on intermediate stripe/RPC"
26599
26600 test_398m() { #  LU-13798
26601         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26602
26603         # Set up failure on OST0, the first stripe:
26604         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26605         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26606         # OST0 is on ost1, OST1 is on ost2.
26607         # So this fail_val specifies OST0
26608         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26609         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26610
26611         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26612                 error "parallel dio write with failure on first stripe succeeded"
26613         stack_trap "rm -f $DIR/$tfile"
26614         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26615
26616         # Place data in file for read
26617         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26618                 error "parallel dio write failed"
26619
26620         # Fail read on OST0, first stripe
26621         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26622         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26623         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26624                 error "parallel dio read with error on first stripe succeeded"
26625         rm -f $DIR/$tfile.2
26626         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26627
26628         # Switch to testing on OST1, second stripe
26629         # Clear file contents, maintain striping
26630         echo > $DIR/$tfile
26631         # Set up failure on OST1, second stripe:
26632         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26633         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26634
26635         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26636                 error "parallel dio write with failure on second stripe succeeded"
26637         stack_trap "rm -f $DIR/$tfile"
26638         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26639
26640         # Place data in file for read
26641         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26642                 error "parallel dio write failed"
26643
26644         # Fail read on OST1, second stripe
26645         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26646         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26647         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26648                 error "parallel dio read with error on second stripe succeeded"
26649         rm -f $DIR/$tfile.2
26650         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26651 }
26652 run_test 398m "test RPC failures with parallel dio"
26653
26654 # Parallel submission of DIO should not cause problems for append, but it's
26655 # important to verify.
26656 test_398n() { #  LU-13798
26657         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26658
26659         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26660                 error "dd to create source file failed"
26661         stack_trap "rm -f $DIR/$tfile"
26662
26663         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26664                 error "parallel dio write with failure on second stripe succeeded"
26665         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26666         diff $DIR/$tfile $DIR/$tfile.1
26667         [[ $? == 0 ]] || error "data incorrect after append"
26668
26669 }
26670 run_test 398n "test append with parallel DIO"
26671
26672 test_398o() {
26673         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26674 }
26675 run_test 398o "right kms with DIO"
26676
26677 test_398p()
26678 {
26679         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26680         which aiocp || skip_env "no aiocp installed"
26681
26682         local stripe_size=$((1024 * 1024)) #1 MiB
26683         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26684         local file_size=$((25 * stripe_size))
26685
26686         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26687         stack_trap "rm -f $DIR/$tfile*"
26688         # Just a bit bigger than the largest size in the test set below
26689         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26690                 error "buffered i/o to create file failed"
26691
26692         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26693                 $((stripe_size * 4)); do
26694
26695                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26696
26697                 echo "bs: $bs, file_size $file_size"
26698                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
26699                         $DIR/$tfile.1 $DIR/$tfile.2 &
26700                 pid_dio1=$!
26701                 # Buffered I/O with similar but not the same block size
26702                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26703                         conv=notrunc &
26704                 pid_bio2=$!
26705                 wait $pid_dio1
26706                 rc1=$?
26707                 wait $pid_bio2
26708                 rc2=$?
26709                 if (( rc1 != 0 )); then
26710                         error "aio copy 1 w/bsize $bs failed: $rc1"
26711                 fi
26712                 if (( rc2 != 0 )); then
26713                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26714                 fi
26715
26716                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26717                         error "size incorrect"
26718                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
26719                         error "files differ, bsize $bs"
26720                 rm -f $DIR/$tfile.2
26721         done
26722 }
26723 run_test 398p "race aio with buffered i/o"
26724
26725 test_398q()
26726 {
26727         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
26728
26729         local stripe_size=$((1024 * 1024)) #1 MiB
26730         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
26731         local file_size=$((25 * stripe_size))
26732
26733         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
26734         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
26735
26736         # Just a bit bigger than the largest size in the test set below
26737         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
26738                 error "buffered i/o to create file failed"
26739
26740         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
26741                 $((stripe_size * 4)); do
26742
26743                 echo "bs: $bs, file_size $file_size"
26744                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
26745                         conv=notrunc oflag=direct iflag=direct &
26746                 pid_dio1=$!
26747                 # Buffered I/O with similar but not the same block size
26748                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
26749                         conv=notrunc &
26750                 pid_bio2=$!
26751                 wait $pid_dio1
26752                 rc1=$?
26753                 wait $pid_bio2
26754                 rc2=$?
26755                 if (( rc1 != 0 )); then
26756                         error "dio copy 1 w/bsize $bs failed: $rc1"
26757                 fi
26758                 if (( rc2 != 0 )); then
26759                         error "buffered copy 2 w/bsize $bs failed: $rc2"
26760                 fi
26761
26762                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
26763                         error "size incorrect"
26764                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
26765                         error "files differ, bsize $bs"
26766         done
26767
26768         rm -f $DIR/$tfile*
26769 }
26770 run_test 398q "race dio with buffered i/o"
26771
26772 test_fake_rw() {
26773         local read_write=$1
26774         if [ "$read_write" = "write" ]; then
26775                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26776         elif [ "$read_write" = "read" ]; then
26777                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26778         else
26779                 error "argument error"
26780         fi
26781
26782         # turn off debug for performance testing
26783         local saved_debug=$($LCTL get_param -n debug)
26784         $LCTL set_param debug=0
26785
26786         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26787
26788         # get ost1 size - $FSNAME-OST0000
26789         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26790         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26791         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26792
26793         if [ "$read_write" = "read" ]; then
26794                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26795         fi
26796
26797         local start_time=$(date +%s.%N)
26798         $dd_cmd bs=1M count=$blocks oflag=sync ||
26799                 error "real dd $read_write error"
26800         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26801
26802         if [ "$read_write" = "write" ]; then
26803                 rm -f $DIR/$tfile
26804         fi
26805
26806         # define OBD_FAIL_OST_FAKE_RW           0x238
26807         do_facet ost1 $LCTL set_param fail_loc=0x238
26808
26809         local start_time=$(date +%s.%N)
26810         $dd_cmd bs=1M count=$blocks oflag=sync ||
26811                 error "fake dd $read_write error"
26812         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26813
26814         if [ "$read_write" = "write" ]; then
26815                 # verify file size
26816                 cancel_lru_locks osc
26817                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26818                         error "$tfile size not $blocks MB"
26819         fi
26820         do_facet ost1 $LCTL set_param fail_loc=0
26821
26822         echo "fake $read_write $duration_fake vs. normal $read_write" \
26823                 "$duration in seconds"
26824         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26825                 error_not_in_vm "fake write is slower"
26826
26827         $LCTL set_param -n debug="$saved_debug"
26828         rm -f $DIR/$tfile
26829 }
26830 test_399a() { # LU-7655 for OST fake write
26831         remote_ost_nodsh && skip "remote OST with nodsh"
26832
26833         test_fake_rw write
26834 }
26835 run_test 399a "fake write should not be slower than normal write"
26836
26837 test_399b() { # LU-8726 for OST fake read
26838         remote_ost_nodsh && skip "remote OST with nodsh"
26839         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26840                 skip_env "ldiskfs only test"
26841         fi
26842
26843         test_fake_rw read
26844 }
26845 run_test 399b "fake read should not be slower than normal read"
26846
26847 test_400a() { # LU-1606, was conf-sanity test_74
26848         if ! which $CC > /dev/null 2>&1; then
26849                 skip_env "$CC is not installed"
26850         fi
26851
26852         local extra_flags=''
26853         local out=$TMP/$tfile
26854         local prefix=/usr/include/lustre
26855         local prog
26856
26857         # Oleg removes .c files in his test rig so test if any c files exist
26858         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26859                 skip_env "Needed .c test files are missing"
26860
26861         if ! [[ -d $prefix ]]; then
26862                 # Assume we're running in tree and fixup the include path.
26863                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26864                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26865                 extra_flags+=" -L$LUSTRE/utils/.libs"
26866         fi
26867
26868         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26869                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26870                         error "client api broken"
26871         done
26872         rm -f $out
26873 }
26874 run_test 400a "Lustre client api program can compile and link"
26875
26876 test_400b() { # LU-1606, LU-5011
26877         local header
26878         local out=$TMP/$tfile
26879         local prefix=/usr/include/linux/lustre
26880
26881         # We use a hard coded prefix so that this test will not fail
26882         # when run in tree. There are headers in lustre/include/lustre/
26883         # that are not packaged (like lustre_idl.h) and have more
26884         # complicated include dependencies (like config.h and lnet/types.h).
26885         # Since this test about correct packaging we just skip them when
26886         # they don't exist (see below) rather than try to fixup cppflags.
26887
26888         if ! which $CC > /dev/null 2>&1; then
26889                 skip_env "$CC is not installed"
26890         fi
26891
26892         for header in $prefix/*.h; do
26893                 if ! [[ -f "$header" ]]; then
26894                         continue
26895                 fi
26896
26897                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26898                         continue # lustre_ioctl.h is internal header
26899                 fi
26900
26901                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26902                         error "cannot compile '$header'"
26903         done
26904         rm -f $out
26905 }
26906 run_test 400b "packaged headers can be compiled"
26907
26908 test_401a() { #LU-7437
26909         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26910         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26911
26912         #count the number of parameters by "list_param -R"
26913         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26914         #count the number of parameters by listing proc files
26915         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26916         echo "proc_dirs='$proc_dirs'"
26917         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26918         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26919                       sort -u | wc -l)
26920
26921         [ $params -eq $procs ] ||
26922                 error "found $params parameters vs. $procs proc files"
26923
26924         # test the list_param -D option only returns directories
26925         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26926         #count the number of parameters by listing proc directories
26927         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26928                 sort -u | wc -l)
26929
26930         [ $params -eq $procs ] ||
26931                 error "found $params parameters vs. $procs proc files"
26932 }
26933 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26934
26935 test_401b() {
26936         # jobid_var may not allow arbitrary values, so use jobid_name
26937         # if available
26938         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26939                 local testname=jobid_name tmp='testing%p'
26940         else
26941                 local testname=jobid_var tmp=testing
26942         fi
26943
26944         local save=$($LCTL get_param -n $testname)
26945
26946         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26947                 error "no error returned when setting bad parameters"
26948
26949         local jobid_new=$($LCTL get_param -n foe $testname baz)
26950         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26951
26952         $LCTL set_param -n fog=bam $testname=$save bat=fog
26953         local jobid_old=$($LCTL get_param -n foe $testname bag)
26954         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26955 }
26956 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26957
26958 test_401c() {
26959         # jobid_var may not allow arbitrary values, so use jobid_name
26960         # if available
26961         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26962                 local testname=jobid_name
26963         else
26964                 local testname=jobid_var
26965         fi
26966
26967         local jobid_var_old=$($LCTL get_param -n $testname)
26968         local jobid_var_new
26969
26970         $LCTL set_param $testname= &&
26971                 error "no error returned for 'set_param a='"
26972
26973         jobid_var_new=$($LCTL get_param -n $testname)
26974         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26975                 error "$testname was changed by setting without value"
26976
26977         $LCTL set_param $testname &&
26978                 error "no error returned for 'set_param a'"
26979
26980         jobid_var_new=$($LCTL get_param -n $testname)
26981         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26982                 error "$testname was changed by setting without value"
26983 }
26984 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26985
26986 test_401d() {
26987         # jobid_var may not allow arbitrary values, so use jobid_name
26988         # if available
26989         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26990                 local testname=jobid_name new_value='foo=bar%p'
26991         else
26992                 local testname=jobid_var new_valuie=foo=bar
26993         fi
26994
26995         local jobid_var_old=$($LCTL get_param -n $testname)
26996         local jobid_var_new
26997
26998         $LCTL set_param $testname=$new_value ||
26999                 error "'set_param a=b' did not accept a value containing '='"
27000
27001         jobid_var_new=$($LCTL get_param -n $testname)
27002         [[ "$jobid_var_new" == "$new_value" ]] ||
27003                 error "'set_param a=b' failed on a value containing '='"
27004
27005         # Reset the $testname to test the other format
27006         $LCTL set_param $testname=$jobid_var_old
27007         jobid_var_new=$($LCTL get_param -n $testname)
27008         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27009                 error "failed to reset $testname"
27010
27011         $LCTL set_param $testname $new_value ||
27012                 error "'set_param a b' did not accept a value containing '='"
27013
27014         jobid_var_new=$($LCTL get_param -n $testname)
27015         [[ "$jobid_var_new" == "$new_value" ]] ||
27016                 error "'set_param a b' failed on a value containing '='"
27017
27018         $LCTL set_param $testname $jobid_var_old
27019         jobid_var_new=$($LCTL get_param -n $testname)
27020         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27021                 error "failed to reset $testname"
27022 }
27023 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27024
27025 test_401e() { # LU-14779
27026         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27027                 error "lctl list_param MGC* failed"
27028         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27029         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27030                 error "lctl get_param lru_size failed"
27031 }
27032 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27033
27034 test_402() {
27035         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27036         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27037                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27038         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27039                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27040                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27041         remote_mds_nodsh && skip "remote MDS with nodsh"
27042
27043         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27044 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27045         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27046         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27047                 echo "Touch failed - OK"
27048 }
27049 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27050
27051 test_403() {
27052         local file1=$DIR/$tfile.1
27053         local file2=$DIR/$tfile.2
27054         local tfile=$TMP/$tfile
27055
27056         rm -f $file1 $file2 $tfile
27057
27058         touch $file1
27059         ln $file1 $file2
27060
27061         # 30 sec OBD_TIMEOUT in ll_getattr()
27062         # right before populating st_nlink
27063         $LCTL set_param fail_loc=0x80001409
27064         stat -c %h $file1 > $tfile &
27065
27066         # create an alias, drop all locks and reclaim the dentry
27067         < $file2
27068         cancel_lru_locks mdc
27069         cancel_lru_locks osc
27070         sysctl -w vm.drop_caches=2
27071
27072         wait
27073
27074         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27075
27076         rm -f $tfile $file1 $file2
27077 }
27078 run_test 403 "i_nlink should not drop to zero due to aliasing"
27079
27080 test_404() { # LU-6601
27081         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27082                 skip "Need server version newer than 2.8.52"
27083         remote_mds_nodsh && skip "remote MDS with nodsh"
27084
27085         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27086                 awk '/osp .*-osc-MDT/ { print $4}')
27087
27088         local osp
27089         for osp in $mosps; do
27090                 echo "Deactivate: " $osp
27091                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27092                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27093                         awk -vp=$osp '$4 == p { print $2 }')
27094                 [ $stat = IN ] || {
27095                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27096                         error "deactivate error"
27097                 }
27098                 echo "Activate: " $osp
27099                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27100                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27101                         awk -vp=$osp '$4 == p { print $2 }')
27102                 [ $stat = UP ] || {
27103                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27104                         error "activate error"
27105                 }
27106         done
27107 }
27108 run_test 404 "validate manual {de}activated works properly for OSPs"
27109
27110 test_405() {
27111         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27112         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27113                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27114                         skip "Layout swap lock is not supported"
27115
27116         check_swap_layouts_support
27117         check_swap_layout_no_dom $DIR
27118
27119         test_mkdir $DIR/$tdir
27120         swap_lock_test -d $DIR/$tdir ||
27121                 error "One layout swap locked test failed"
27122 }
27123 run_test 405 "Various layout swap lock tests"
27124
27125 test_406() {
27126         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27127         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27128         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27130         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27131                 skip "Need MDS version at least 2.8.50"
27132
27133         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27134         local test_pool=$TESTNAME
27135
27136         pool_add $test_pool || error "pool_add failed"
27137         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27138                 error "pool_add_targets failed"
27139
27140         save_layout_restore_at_exit $MOUNT
27141
27142         # parent set default stripe count only, child will stripe from both
27143         # parent and fs default
27144         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27145                 error "setstripe $MOUNT failed"
27146         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27147         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27148         for i in $(seq 10); do
27149                 local f=$DIR/$tdir/$tfile.$i
27150                 touch $f || error "touch failed"
27151                 local count=$($LFS getstripe -c $f)
27152                 [ $count -eq $OSTCOUNT ] ||
27153                         error "$f stripe count $count != $OSTCOUNT"
27154                 local offset=$($LFS getstripe -i $f)
27155                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27156                 local size=$($LFS getstripe -S $f)
27157                 [ $size -eq $((def_stripe_size * 2)) ] ||
27158                         error "$f stripe size $size != $((def_stripe_size * 2))"
27159                 local pool=$($LFS getstripe -p $f)
27160                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27161         done
27162
27163         # change fs default striping, delete parent default striping, now child
27164         # will stripe from new fs default striping only
27165         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27166                 error "change $MOUNT default stripe failed"
27167         $LFS setstripe -c 0 $DIR/$tdir ||
27168                 error "delete $tdir default stripe failed"
27169         for i in $(seq 11 20); do
27170                 local f=$DIR/$tdir/$tfile.$i
27171                 touch $f || error "touch $f failed"
27172                 local count=$($LFS getstripe -c $f)
27173                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27174                 local offset=$($LFS getstripe -i $f)
27175                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27176                 local size=$($LFS getstripe -S $f)
27177                 [ $size -eq $def_stripe_size ] ||
27178                         error "$f stripe size $size != $def_stripe_size"
27179                 local pool=$($LFS getstripe -p $f)
27180                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27181         done
27182
27183         unlinkmany $DIR/$tdir/$tfile. 1 20
27184
27185         local f=$DIR/$tdir/$tfile
27186         pool_remove_all_targets $test_pool $f
27187         pool_remove $test_pool $f
27188 }
27189 run_test 406 "DNE support fs default striping"
27190
27191 test_407() {
27192         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27193         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27194                 skip "Need MDS version at least 2.8.55"
27195         remote_mds_nodsh && skip "remote MDS with nodsh"
27196
27197         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27198                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27199         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27200                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27201         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27202
27203         #define OBD_FAIL_DT_TXN_STOP    0x2019
27204         for idx in $(seq $MDSCOUNT); do
27205                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27206         done
27207         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27208         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27209                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27210         true
27211 }
27212 run_test 407 "transaction fail should cause operation fail"
27213
27214 test_408() {
27215         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27216
27217         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27218         lctl set_param fail_loc=0x8000040a
27219         # let ll_prepare_partial_page() fail
27220         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27221
27222         rm -f $DIR/$tfile
27223
27224         # create at least 100 unused inodes so that
27225         # shrink_icache_memory(0) should not return 0
27226         touch $DIR/$tfile-{0..100}
27227         rm -f $DIR/$tfile-{0..100}
27228         sync
27229
27230         echo 2 > /proc/sys/vm/drop_caches
27231 }
27232 run_test 408 "drop_caches should not hang due to page leaks"
27233
27234 test_409()
27235 {
27236         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27237
27238         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27239         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27240         touch $DIR/$tdir/guard || error "(2) Fail to create"
27241
27242         local PREFIX=$(str_repeat 'A' 128)
27243         echo "Create 1K hard links start at $(date)"
27244         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27245                 error "(3) Fail to hard link"
27246
27247         echo "Links count should be right although linkEA overflow"
27248         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27249         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27250         [ $linkcount -eq 1001 ] ||
27251                 error "(5) Unexpected hard links count: $linkcount"
27252
27253         echo "List all links start at $(date)"
27254         ls -l $DIR/$tdir/foo > /dev/null ||
27255                 error "(6) Fail to list $DIR/$tdir/foo"
27256
27257         echo "Unlink hard links start at $(date)"
27258         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27259                 error "(7) Fail to unlink"
27260         echo "Unlink hard links finished at $(date)"
27261 }
27262 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27263
27264 test_410()
27265 {
27266         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27267                 skip "Need client version at least 2.9.59"
27268         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27269                 skip "Need MODULES build"
27270
27271         # Create a file, and stat it from the kernel
27272         local testfile=$DIR/$tfile
27273         touch $testfile
27274
27275         local run_id=$RANDOM
27276         local my_ino=$(stat --format "%i" $testfile)
27277
27278         # Try to insert the module. This will always fail as the
27279         # module is designed to not be inserted.
27280         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27281             &> /dev/null
27282
27283         # Anything but success is a test failure
27284         dmesg | grep -q \
27285             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27286             error "no inode match"
27287 }
27288 run_test 410 "Test inode number returned from kernel thread"
27289
27290 cleanup_test411_cgroup() {
27291         trap 0
27292         rmdir "$1"
27293 }
27294
27295 test_411() {
27296         local cg_basedir=/sys/fs/cgroup/memory
27297         # LU-9966
27298         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27299                 skip "no setup for cgroup"
27300
27301         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27302                 error "test file creation failed"
27303         cancel_lru_locks osc
27304
27305         # Create a very small memory cgroup to force a slab allocation error
27306         local cgdir=$cg_basedir/osc_slab_alloc
27307         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27308         trap "cleanup_test411_cgroup $cgdir" EXIT
27309         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27310         echo 1M > $cgdir/memory.limit_in_bytes
27311
27312         # Should not LBUG, just be killed by oom-killer
27313         # dd will return 0 even allocation failure in some environment.
27314         # So don't check return value
27315         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27316         cleanup_test411_cgroup $cgdir
27317
27318         return 0
27319 }
27320 run_test 411 "Slab allocation error with cgroup does not LBUG"
27321
27322 test_412() {
27323         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27324         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27325                 skip "Need server version at least 2.10.55"
27326
27327         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27328                 error "mkdir failed"
27329         $LFS getdirstripe $DIR/$tdir
27330         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27331         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27332                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27333         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27334         [ $stripe_count -eq 2 ] ||
27335                 error "expect 2 get $stripe_count"
27336
27337         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27338
27339         local index
27340         local index2
27341
27342         # subdirs should be on the same MDT as parent
27343         for i in $(seq 0 $((MDSCOUNT - 1))); do
27344                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27345                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27346                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27347                 (( index == i )) || error "mdt$i/sub on MDT$index"
27348         done
27349
27350         # stripe offset -1, ditto
27351         for i in {1..10}; do
27352                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27353                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27354                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27355                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27356                 (( index == index2 )) ||
27357                         error "qos$i on MDT$index, sub on MDT$index2"
27358         done
27359
27360         local testdir=$DIR/$tdir/inherit
27361
27362         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27363         # inherit 2 levels
27364         for i in 1 2; do
27365                 testdir=$testdir/s$i
27366                 mkdir $testdir || error "mkdir $testdir failed"
27367                 index=$($LFS getstripe -m $testdir)
27368                 (( index == 1 )) ||
27369                         error "$testdir on MDT$index"
27370         done
27371
27372         # not inherit any more
27373         testdir=$testdir/s3
27374         mkdir $testdir || error "mkdir $testdir failed"
27375         getfattr -d -m dmv $testdir | grep dmv &&
27376                 error "default LMV set on $testdir" || true
27377 }
27378 run_test 412 "mkdir on specific MDTs"
27379
27380 TEST413_COUNT=${TEST413_COUNT:-200}
27381
27382 #
27383 # set_maxage() is used by test_413 only.
27384 # This is a helper function to set maxage. Does not return any value.
27385 # Input: maxage to set
27386 #
27387 set_maxage() {
27388         local lmv_qos_maxage
27389         local lod_qos_maxage
27390         local new_maxage=$1
27391
27392         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27393         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27394         stack_trap "$LCTL set_param \
27395                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27396         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27397                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27398         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27399                 lod.*.mdt_qos_maxage=$new_maxage
27400         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27401                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27402 }
27403
27404 generate_uneven_mdts() {
27405         local threshold=$1
27406         local ffree
27407         local bavail
27408         local max
27409         local min
27410         local max_index
27411         local min_index
27412         local tmp
27413         local i
27414
27415         echo
27416         echo "Check for uneven MDTs: "
27417
27418         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27419         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27420         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27421
27422         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27423         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27424         max_index=0
27425         min_index=0
27426         for ((i = 1; i < ${#ffree[@]}; i++)); do
27427                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27428                 if [ $tmp -gt $max ]; then
27429                         max=$tmp
27430                         max_index=$i
27431                 fi
27432                 if [ $tmp -lt $min ]; then
27433                         min=$tmp
27434                         min_index=$i
27435                 fi
27436         done
27437
27438         (( min > 0 )) || skip "low space on MDT$min_index"
27439         (( ${ffree[min_index]} > 0 )) ||
27440                 skip "no free files on MDT$min_index"
27441         (( ${ffree[min_index]} < 10000000 )) ||
27442                 skip "too many free files on MDT$min_index"
27443
27444         # Check if we need to generate uneven MDTs
27445         local diff=$(((max - min) * 100 / min))
27446         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27447         local testdir # individual folder within $testdirp
27448         local start
27449         local cmd
27450
27451         # fallocate is faster to consume space on MDT, if available
27452         if check_fallocate_supported mds$((min_index + 1)); then
27453                 cmd="fallocate -l 128K "
27454         else
27455                 cmd="dd if=/dev/zero bs=128K count=1 of="
27456         fi
27457
27458         echo "using cmd $cmd"
27459         for (( i = 0; diff < threshold; i++ )); do
27460                 testdir=${testdirp}/$i
27461                 [ -d $testdir ] && continue
27462
27463                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27464
27465                 mkdir -p $testdirp
27466                 # generate uneven MDTs, create till $threshold% diff
27467                 echo -n "weight diff=$diff% must be > $threshold% ..."
27468                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27469                 $LFS mkdir -i $min_index $testdir ||
27470                         error "mkdir $testdir failed"
27471                 $LFS setstripe -E 1M -L mdt $testdir ||
27472                         error "setstripe $testdir failed"
27473                 start=$SECONDS
27474                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27475                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27476                 done
27477                 sync; sleep 1; sync
27478
27479                 # wait for QOS to update
27480                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27481
27482                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27483                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27484                 max=$(((${ffree[max_index]} >> 8) *
27485                         (${bavail[max_index]} * bsize >> 16)))
27486                 min=$(((${ffree[min_index]} >> 8) *
27487                         (${bavail[min_index]} * bsize >> 16)))
27488                 (( min > 0 )) || skip "low space on MDT$min_index"
27489                 diff=$(((max - min) * 100 / min))
27490         done
27491
27492         echo "MDT filesfree available: ${ffree[*]}"
27493         echo "MDT blocks available: ${bavail[*]}"
27494         echo "weight diff=$diff%"
27495 }
27496
27497 test_qos_mkdir() {
27498         local mkdir_cmd=$1
27499         local stripe_count=$2
27500         local mdts=$(comma_list $(mdts_nodes))
27501
27502         local testdir
27503         local lmv_qos_prio_free
27504         local lmv_qos_threshold_rr
27505         local lod_qos_prio_free
27506         local lod_qos_threshold_rr
27507         local total
27508         local count
27509         local i
27510
27511         # @total is total directories created if it's testing plain
27512         # directories, otherwise it's total stripe object count for
27513         # striped directories test.
27514         # remote/striped directory unlinking is slow on zfs and may
27515         # timeout, test with fewer directories
27516         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27517
27518         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27519         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27520         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27521                 head -n1)
27522         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
27523         stack_trap "$LCTL set_param \
27524                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
27525         stack_trap "$LCTL set_param \
27526                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
27527
27528         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
27529                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
27530         lod_qos_prio_free=${lod_qos_prio_free%%%}
27531         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
27532                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
27533         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
27534         stack_trap "do_nodes $mdts $LCTL set_param \
27535                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
27536         stack_trap "do_nodes $mdts $LCTL set_param \
27537                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
27538
27539         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27540         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
27541
27542         testdir=$DIR/$tdir-s$stripe_count/rr
27543
27544         local stripe_index=$($LFS getstripe -m $testdir)
27545         local test_mkdir_rr=true
27546
27547         getfattr -d -m dmv -e hex $testdir | grep dmv
27548         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
27549                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
27550                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
27551                         test_mkdir_rr=false
27552         fi
27553
27554         echo
27555         $test_mkdir_rr &&
27556                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
27557                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
27558
27559         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27560         for (( i = 0; i < total / stripe_count; i++ )); do
27561                 eval $mkdir_cmd $testdir/subdir$i ||
27562                         error "$mkdir_cmd subdir$i failed"
27563         done
27564
27565         for (( i = 0; i < $MDSCOUNT; i++ )); do
27566                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27567                 echo "$count directories created on MDT$i"
27568                 if $test_mkdir_rr; then
27569                         (( count == total / stripe_count / MDSCOUNT )) ||
27570                                 error "subdirs are not evenly distributed"
27571                 elif (( i == stripe_index )); then
27572                         (( count == total / stripe_count )) ||
27573                                 error "$count subdirs created on MDT$i"
27574                 else
27575                         (( count == 0 )) ||
27576                                 error "$count subdirs created on MDT$i"
27577                 fi
27578
27579                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
27580                         count=$($LFS getdirstripe $testdir/* |
27581                                 grep -c -P "^\s+$i\t")
27582                         echo "$count stripes created on MDT$i"
27583                         # deviation should < 5% of average
27584                         delta=$((count - total / MDSCOUNT))
27585                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
27586                                 error "stripes are not evenly distributed"
27587                 fi
27588         done
27589
27590         echo
27591         echo "Check for uneven MDTs: "
27592
27593         local ffree
27594         local bavail
27595         local max
27596         local min
27597         local max_index
27598         local min_index
27599         local tmp
27600
27601         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27602         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27603         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27604
27605         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27606         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27607         max_index=0
27608         min_index=0
27609         for ((i = 1; i < ${#ffree[@]}; i++)); do
27610                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27611                 if [ $tmp -gt $max ]; then
27612                         max=$tmp
27613                         max_index=$i
27614                 fi
27615                 if [ $tmp -lt $min ]; then
27616                         min=$tmp
27617                         min_index=$i
27618                 fi
27619         done
27620         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
27621
27622         (( min > 0 )) || skip "low space on MDT$min_index"
27623         (( ${ffree[min_index]} < 10000000 )) ||
27624                 skip "too many free files on MDT$min_index"
27625
27626         generate_uneven_mdts 120
27627
27628         echo "MDT filesfree available: ${ffree[*]}"
27629         echo "MDT blocks available: ${bavail[*]}"
27630         echo "weight diff=$(((max - min) * 100 / min))%"
27631         echo
27632         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
27633
27634         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
27635         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
27636         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
27637         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
27638         # decrease statfs age, so that it can be updated in time
27639         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
27640         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
27641
27642         sleep 1
27643
27644         testdir=$DIR/$tdir-s$stripe_count/qos
27645
27646         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
27647         for (( i = 0; i < total / stripe_count; i++ )); do
27648                 eval $mkdir_cmd $testdir/subdir$i ||
27649                         error "$mkdir_cmd subdir$i failed"
27650         done
27651
27652         max=0
27653         for (( i = 0; i < $MDSCOUNT; i++ )); do
27654                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
27655                 (( count > max )) && max=$count
27656                 echo "$count directories created on MDT$i : curmax=$max"
27657         done
27658
27659         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
27660
27661         # D-value should > 10% of average
27662         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
27663                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
27664
27665         # ditto for stripes
27666         if (( stripe_count > 1 )); then
27667                 max=0
27668                 for (( i = 0; i < $MDSCOUNT; i++ )); do
27669                         count=$($LFS getdirstripe $testdir/* |
27670                                 grep -c -P "^\s+$i\t")
27671                         (( count > max )) && max=$count
27672                         echo "$count stripes created on MDT$i"
27673                 done
27674
27675                 min=$($LFS getdirstripe $testdir/* |
27676                         grep -c -P "^\s+$min_index\t")
27677                 (( max - min > total / MDSCOUNT / 10 )) ||
27678                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
27679         fi
27680 }
27681
27682 most_full_mdt() {
27683         local ffree
27684         local bavail
27685         local bsize
27686         local min
27687         local min_index
27688         local tmp
27689
27690         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27691         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27692         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27693
27694         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27695         min_index=0
27696         for ((i = 1; i < ${#ffree[@]}; i++)); do
27697                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27698                 (( tmp < min )) && min=$tmp && min_index=$i
27699         done
27700
27701         echo -n $min_index
27702 }
27703
27704 test_413a() {
27705         [ $MDSCOUNT -lt 2 ] &&
27706                 skip "We need at least 2 MDTs for this test"
27707
27708         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27709                 skip "Need server version at least 2.12.52"
27710
27711         local stripe_max=$((MDSCOUNT - 1))
27712         local stripe_count
27713
27714         # let caller set maxage for latest result
27715         set_maxage 1
27716
27717         # fill MDT unevenly
27718         generate_uneven_mdts 120
27719
27720         # test 4-stripe directory at most, otherwise it's too slow
27721         # We are being very defensive. Although Autotest uses 4 MDTs.
27722         # We make sure stripe_max does not go over 4.
27723         (( stripe_max > 4 )) && stripe_max=4
27724         # unlinking striped directory is slow on zfs, and may timeout, only test
27725         # plain directory
27726         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27727         for stripe_count in $(seq 1 $stripe_max); do
27728                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27729                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27730                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27731                         error "mkdir failed"
27732                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27733         done
27734 }
27735 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27736
27737 test_413b() {
27738         [ $MDSCOUNT -lt 2 ] &&
27739                 skip "We need at least 2 MDTs for this test"
27740
27741         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27742                 skip "Need server version at least 2.12.52"
27743
27744         local stripe_max=$((MDSCOUNT - 1))
27745         local testdir
27746         local stripe_count
27747
27748         # let caller set maxage for latest result
27749         set_maxage 1
27750
27751         # fill MDT unevenly
27752         generate_uneven_mdts 120
27753
27754         # test 4-stripe directory at most, otherwise it's too slow
27755         # We are being very defensive. Although Autotest uses 4 MDTs.
27756         # We make sure stripe_max does not go over 4.
27757         (( stripe_max > 4 )) && stripe_max=4
27758         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27759         for stripe_count in $(seq 1 $stripe_max); do
27760                 testdir=$DIR/$tdir-s$stripe_count
27761                 mkdir $testdir || error "mkdir $testdir failed"
27762                 mkdir $testdir/rr || error "mkdir rr failed"
27763                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27764                         error "mkdir qos failed"
27765                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27766                         $testdir/rr || error "setdirstripe rr failed"
27767                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27768                         error "setdirstripe failed"
27769                 test_qos_mkdir "mkdir" $stripe_count
27770         done
27771 }
27772 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27773
27774 test_413c() {
27775         (( $MDSCOUNT >= 2 )) ||
27776                 skip "We need at least 2 MDTs for this test"
27777
27778         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27779                 skip "Need server version at least 2.14.51"
27780
27781         local testdir
27782         local inherit
27783         local inherit_rr
27784         local lmv_qos_maxage
27785         local lod_qos_maxage
27786
27787         # let caller set maxage for latest result
27788         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27789         $LCTL set_param lmv.*.qos_maxage=1
27790         stack_trap "$LCTL set_param \
27791                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27792         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27793                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27794         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27795                 lod.*.mdt_qos_maxage=1
27796         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27797                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27798
27799         # fill MDT unevenly
27800         generate_uneven_mdts 120
27801
27802         testdir=$DIR/${tdir}-s1
27803         mkdir $testdir || error "mkdir $testdir failed"
27804         mkdir $testdir/rr || error "mkdir rr failed"
27805         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27806         # default max_inherit is -1, default max_inherit_rr is 0
27807         $LFS setdirstripe -D -c 1 $testdir/rr ||
27808                 error "setdirstripe rr failed"
27809         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27810                 error "setdirstripe qos failed"
27811         test_qos_mkdir "mkdir" 1
27812
27813         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27814         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27815         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27816         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27817         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27818
27819         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27820         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27821         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27822         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27823         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27824         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27825         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27826                 error "level2 shouldn't have default LMV" || true
27827 }
27828 run_test 413c "mkdir with default LMV max inherit rr"
27829
27830 test_413d() {
27831         (( MDSCOUNT >= 2 )) ||
27832                 skip "We need at least 2 MDTs for this test"
27833
27834         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27835                 skip "Need server version at least 2.14.51"
27836
27837         local lmv_qos_threshold_rr
27838
27839         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27840                 head -n1)
27841         stack_trap "$LCTL set_param \
27842                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27843
27844         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27845         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27846         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27847                 error "$tdir shouldn't have default LMV"
27848         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27849                 error "mkdir sub failed"
27850
27851         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27852
27853         (( count == 100 )) || error "$count subdirs on MDT0"
27854 }
27855 run_test 413d "inherit ROOT default LMV"
27856
27857 test_413e() {
27858         (( MDSCOUNT >= 2 )) ||
27859                 skip "We need at least 2 MDTs for this test"
27860         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27861                 skip "Need server version at least 2.14.55"
27862
27863         local testdir=$DIR/$tdir
27864         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27865         local max_inherit
27866         local sub_max_inherit
27867
27868         mkdir -p $testdir || error "failed to create $testdir"
27869
27870         # set default max-inherit to -1 if stripe count is 0 or 1
27871         $LFS setdirstripe -D -c 1 $testdir ||
27872                 error "failed to set default LMV"
27873         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27874         (( max_inherit == -1 )) ||
27875                 error "wrong max_inherit value $max_inherit"
27876
27877         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27878         $LFS setdirstripe -D -c -1 $testdir ||
27879                 error "failed to set default LMV"
27880         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27881         (( max_inherit > 0 )) ||
27882                 error "wrong max_inherit value $max_inherit"
27883
27884         # and the subdir will decrease the max_inherit by 1
27885         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27886         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27887         (( sub_max_inherit == max_inherit - 1)) ||
27888                 error "wrong max-inherit of subdir $sub_max_inherit"
27889
27890         # check specified --max-inherit and warning message
27891         stack_trap "rm -f $tmpfile"
27892         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27893                 error "failed to set default LMV"
27894         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27895         (( max_inherit == -1 )) ||
27896                 error "wrong max_inherit value $max_inherit"
27897
27898         # check the warning messages
27899         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27900                 error "failed to detect warning string"
27901         fi
27902 }
27903 run_test 413e "check default max-inherit value"
27904
27905 test_fs_dmv_inherit()
27906 {
27907         local testdir=$DIR/$tdir
27908
27909         local count
27910         local inherit
27911         local inherit_rr
27912
27913         for i in 1 2; do
27914                 mkdir $testdir || error "mkdir $testdir failed"
27915                 count=$($LFS getdirstripe -D -c $testdir)
27916                 (( count == 1 )) ||
27917                         error "$testdir default LMV count mismatch $count != 1"
27918                 inherit=$($LFS getdirstripe -D -X $testdir)
27919                 (( inherit == 3 - i )) ||
27920                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27921                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27922                 (( inherit_rr == 3 - i )) ||
27923                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27924                 testdir=$testdir/sub
27925         done
27926
27927         mkdir $testdir || error "mkdir $testdir failed"
27928         count=$($LFS getdirstripe -D -c $testdir)
27929         (( count == 0 )) ||
27930                 error "$testdir default LMV count not zero: $count"
27931 }
27932
27933 test_413f() {
27934         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27935
27936         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27937                 skip "Need server version at least 2.14.55"
27938
27939         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27940                 error "dump $DIR default LMV failed"
27941         stack_trap "setfattr --restore=$TMP/dmv.ea"
27942
27943         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27944                 error "set $DIR default LMV failed"
27945
27946         test_fs_dmv_inherit
27947 }
27948 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27949
27950 test_413g() {
27951         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27952
27953         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27954         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27955                 error "dump $DIR default LMV failed"
27956         stack_trap "setfattr --restore=$TMP/dmv.ea"
27957
27958         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27959                 error "set $DIR default LMV failed"
27960
27961         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27962                 error "mount $MOUNT2 failed"
27963         stack_trap "umount_client $MOUNT2"
27964
27965         local saved_DIR=$DIR
27966
27967         export DIR=$MOUNT2
27968
27969         stack_trap "export DIR=$saved_DIR"
27970
27971         # first check filesystem-wide default LMV inheritance
27972         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27973
27974         # then check subdirs are spread to all MDTs
27975         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27976
27977         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27978
27979         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27980 }
27981 run_test 413g "enforce ROOT default LMV on subdir mount"
27982
27983 test_413h() {
27984         (( MDSCOUNT >= 2 )) ||
27985                 skip "We need at least 2 MDTs for this test"
27986
27987         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27988                 skip "Need server version at least 2.15.50.6"
27989
27990         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27991
27992         stack_trap "$LCTL set_param \
27993                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27994         $LCTL set_param lmv.*.qos_maxage=1
27995
27996         local depth=5
27997         local rr_depth=4
27998         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27999         local count=$((MDSCOUNT * 20))
28000
28001         generate_uneven_mdts 50
28002
28003         mkdir -p $dir || error "mkdir $dir failed"
28004         stack_trap "rm -rf $dir"
28005         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28006                 --max-inherit-rr=$rr_depth $dir
28007
28008         for ((d=0; d < depth + 2; d++)); do
28009                 log "dir=$dir:"
28010                 for ((sub=0; sub < count; sub++)); do
28011                         mkdir $dir/d$sub
28012                 done
28013                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28014                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28015                 # subdirs within $rr_depth should be created round-robin
28016                 if (( d < rr_depth )); then
28017                         (( ${num[0]} != count )) ||
28018                                 error "all objects created on MDT ${num[1]}"
28019                 fi
28020
28021                 dir=$dir/d0
28022         done
28023 }
28024 run_test 413h "don't stick to parent for round-robin dirs"
28025
28026 test_413i() {
28027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28028
28029         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28030                 skip "Need server version at least 2.14.55"
28031
28032         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28033                 error "dump $DIR default LMV failed"
28034         stack_trap "setfattr --restore=$TMP/dmv.ea"
28035
28036         local testdir=$DIR/$tdir
28037         local def_max_rr=1
28038         local def_max=3
28039         local count
28040
28041         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28042                 --max-inherit-rr=$def_max_rr $DIR ||
28043                 error "set $DIR default LMV failed"
28044
28045         for i in $(seq 2 3); do
28046                 def_max=$((def_max - 1))
28047                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28048
28049                 mkdir $testdir
28050                 # RR is decremented and keeps zeroed once exhausted
28051                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28052                 (( count == def_max_rr )) ||
28053                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28054
28055                 # max-inherit is decremented
28056                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28057                 (( count == def_max )) ||
28058                         error_noexit "$testdir: max-inherit $count != $def_max"
28059
28060                 testdir=$testdir/d$i
28061         done
28062
28063         # d3 is the last inherited from ROOT, no inheritance anymore
28064         # i.e. no the default layout anymore
28065         mkdir -p $testdir/d4/d5
28066         count=$($LFS getdirstripe -D --max-inherit $testdir)
28067         (( count == -1 )) ||
28068                 error_noexit "$testdir: max-inherit $count != -1"
28069
28070         local p_count=$($LFS getdirstripe -i $testdir)
28071
28072         for i in $(seq 4 5); do
28073                 testdir=$testdir/d$i
28074
28075                 # the root default layout is not applied once exhausted
28076                 count=$($LFS getdirstripe -i $testdir)
28077                 (( count == p_count )) ||
28078                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28079         done
28080
28081         $LFS setdirstripe -i 0 $DIR/d2
28082         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28083         (( count == -1 )) ||
28084                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28085 }
28086 run_test 413i "check default layout inheritance"
28087
28088 test_413z() {
28089         local pids=""
28090         local subdir
28091         local pid
28092
28093         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28094                 unlinkmany $subdir/f. $TEST413_COUNT &
28095                 pids="$pids $!"
28096         done
28097
28098         for pid in $pids; do
28099                 wait $pid
28100         done
28101
28102         true
28103 }
28104 run_test 413z "413 test cleanup"
28105
28106 test_414() {
28107 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28108         $LCTL set_param fail_loc=0x80000521
28109         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28110         rm -f $DIR/$tfile
28111 }
28112 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28113
28114 test_415() {
28115         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28116         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28117                 skip "Need server version at least 2.11.52"
28118
28119         # LU-11102
28120         local total=500
28121         local max=120
28122
28123         # this test may be slow on ZFS
28124         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28125
28126         # though this test is designed for striped directory, let's test normal
28127         # directory too since lock is always saved as CoS lock.
28128         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28129         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28130         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28131         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28132         wait_delete_completed_mds
28133
28134         # run a loop without concurrent touch to measure rename duration.
28135         # only for test debug/robustness, NOT part of COS functional test.
28136         local start_time=$SECONDS
28137         for ((i = 0; i < total; i++)); do
28138                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28139                         > /dev/null
28140         done
28141         local baseline=$((SECONDS - start_time))
28142         echo "rename $total files without 'touch' took $baseline sec"
28143
28144         (
28145                 while true; do
28146                         touch $DIR/$tdir
28147                 done
28148         ) &
28149         local setattr_pid=$!
28150
28151         # rename files back to original name so unlinkmany works
28152         start_time=$SECONDS
28153         for ((i = 0; i < total; i++)); do
28154                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28155                         > /dev/null
28156         done
28157         local duration=$((SECONDS - start_time))
28158
28159         kill -9 $setattr_pid
28160
28161         echo "rename $total files with 'touch' took $duration sec"
28162         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28163         (( duration <= max )) ||
28164                 error_not_in_vm "rename took $duration > $max sec"
28165 }
28166 run_test 415 "lock revoke is not missing"
28167
28168 test_416() {
28169         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28170                 skip "Need server version at least 2.11.55"
28171
28172         # define OBD_FAIL_OSD_TXN_START    0x19a
28173         do_facet mds1 lctl set_param fail_loc=0x19a
28174
28175         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28176
28177         true
28178 }
28179 run_test 416 "transaction start failure won't cause system hung"
28180
28181 cleanup_417() {
28182         trap 0
28183         do_nodes $(comma_list $(mdts_nodes)) \
28184                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28185         do_nodes $(comma_list $(mdts_nodes)) \
28186                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28187         do_nodes $(comma_list $(mdts_nodes)) \
28188                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28189 }
28190
28191 test_417() {
28192         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28193         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28194                 skip "Need MDS version at least 2.11.56"
28195
28196         trap cleanup_417 RETURN EXIT
28197
28198         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28199         do_nodes $(comma_list $(mdts_nodes)) \
28200                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28201         $LFS migrate -m 0 $DIR/$tdir.1 &&
28202                 error "migrate dir $tdir.1 should fail"
28203
28204         do_nodes $(comma_list $(mdts_nodes)) \
28205                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28206         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28207                 error "create remote dir $tdir.2 should fail"
28208
28209         do_nodes $(comma_list $(mdts_nodes)) \
28210                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28211         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28212                 error "create striped dir $tdir.3 should fail"
28213         true
28214 }
28215 run_test 417 "disable remote dir, striped dir and dir migration"
28216
28217 # Checks that the outputs of df [-i] and lfs df [-i] match
28218 #
28219 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28220 check_lfs_df() {
28221         local dir=$2
28222         local inodes
28223         local df_out
28224         local lfs_df_out
28225         local count
28226         local passed=false
28227
28228         # blocks or inodes
28229         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28230
28231         for count in {1..100}; do
28232                 do_nodes "$CLIENTS" \
28233                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28234                 sync; sleep 0.2
28235
28236                 # read the lines of interest
28237                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28238                         error "df $inodes $dir | tail -n +2 failed"
28239                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28240                         error "lfs df $inodes $dir | grep summary: failed"
28241
28242                 # skip first substrings of each output as they are different
28243                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28244                 # compare the two outputs
28245                 passed=true
28246                 #  skip "available" on MDT until LU-13997 is fixed.
28247                 #for i in {1..5}; do
28248                 for i in 1 2 4 5; do
28249                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28250                 done
28251                 $passed && break
28252         done
28253
28254         if ! $passed; then
28255                 df -P $inodes $dir
28256                 echo
28257                 lfs df $inodes $dir
28258                 error "df and lfs df $1 output mismatch: "      \
28259                       "df ${inodes}: ${df_out[*]}, "            \
28260                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28261         fi
28262 }
28263
28264 test_418() {
28265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28266
28267         local dir=$DIR/$tdir
28268         local numfiles=$((RANDOM % 4096 + 2))
28269         local numblocks=$((RANDOM % 256 + 1))
28270
28271         wait_delete_completed
28272         test_mkdir $dir
28273
28274         # check block output
28275         check_lfs_df blocks $dir
28276         # check inode output
28277         check_lfs_df inodes $dir
28278
28279         # create a single file and retest
28280         echo "Creating a single file and testing"
28281         createmany -o $dir/$tfile- 1 &>/dev/null ||
28282                 error "creating 1 file in $dir failed"
28283         check_lfs_df blocks $dir
28284         check_lfs_df inodes $dir
28285
28286         # create a random number of files
28287         echo "Creating $((numfiles - 1)) files and testing"
28288         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28289                 error "creating $((numfiles - 1)) files in $dir failed"
28290
28291         # write a random number of blocks to the first test file
28292         echo "Writing $numblocks 4K blocks and testing"
28293         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28294                 count=$numblocks &>/dev/null ||
28295                 error "dd to $dir/${tfile}-0 failed"
28296
28297         # retest
28298         check_lfs_df blocks $dir
28299         check_lfs_df inodes $dir
28300
28301         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28302                 error "unlinking $numfiles files in $dir failed"
28303 }
28304 run_test 418 "df and lfs df outputs match"
28305
28306 test_419()
28307 {
28308         local dir=$DIR/$tdir
28309
28310         mkdir -p $dir
28311         touch $dir/file
28312
28313         cancel_lru_locks mdc
28314
28315         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28316         $LCTL set_param fail_loc=0x1410
28317         cat $dir/file
28318         $LCTL set_param fail_loc=0
28319         rm -rf $dir
28320 }
28321 run_test 419 "Verify open file by name doesn't crash kernel"
28322
28323 test_420()
28324 {
28325         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28326                 skip "Need MDS version at least 2.12.53"
28327
28328         local SAVE_UMASK=$(umask)
28329         local dir=$DIR/$tdir
28330         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28331
28332         mkdir -p $dir
28333         umask 0000
28334         mkdir -m03777 $dir/testdir
28335         ls -dn $dir/testdir
28336         # Need to remove trailing '.' when SELinux is enabled
28337         local dirperms=$(ls -dn $dir/testdir |
28338                          awk '{ sub(/\.$/, "", $1); print $1}')
28339         [ $dirperms == "drwxrwsrwt" ] ||
28340                 error "incorrect perms on $dir/testdir"
28341
28342         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28343                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28344         ls -n $dir/testdir/testfile
28345         local fileperms=$(ls -n $dir/testdir/testfile |
28346                           awk '{ sub(/\.$/, "", $1); print $1}')
28347         [ $fileperms == "-rwxr-xr-x" ] ||
28348                 error "incorrect perms on $dir/testdir/testfile"
28349
28350         umask $SAVE_UMASK
28351 }
28352 run_test 420 "clear SGID bit on non-directories for non-members"
28353
28354 test_421a() {
28355         local cnt
28356         local fid1
28357         local fid2
28358
28359         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28360                 skip "Need MDS version at least 2.12.54"
28361
28362         test_mkdir $DIR/$tdir
28363         createmany -o $DIR/$tdir/f 3
28364         cnt=$(ls -1 $DIR/$tdir | wc -l)
28365         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28366
28367         fid1=$(lfs path2fid $DIR/$tdir/f1)
28368         fid2=$(lfs path2fid $DIR/$tdir/f2)
28369         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28370
28371         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28372         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28373
28374         cnt=$(ls -1 $DIR/$tdir | wc -l)
28375         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28376
28377         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28378         createmany -o $DIR/$tdir/f 3
28379         cnt=$(ls -1 $DIR/$tdir | wc -l)
28380         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28381
28382         fid1=$(lfs path2fid $DIR/$tdir/f1)
28383         fid2=$(lfs path2fid $DIR/$tdir/f2)
28384         echo "remove using fsname $FSNAME"
28385         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28386
28387         cnt=$(ls -1 $DIR/$tdir | wc -l)
28388         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28389 }
28390 run_test 421a "simple rm by fid"
28391
28392 test_421b() {
28393         local cnt
28394         local FID1
28395         local FID2
28396
28397         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28398                 skip "Need MDS version at least 2.12.54"
28399
28400         test_mkdir $DIR/$tdir
28401         createmany -o $DIR/$tdir/f 3
28402         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28403         MULTIPID=$!
28404
28405         FID1=$(lfs path2fid $DIR/$tdir/f1)
28406         FID2=$(lfs path2fid $DIR/$tdir/f2)
28407         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28408
28409         kill -USR1 $MULTIPID
28410         wait
28411
28412         cnt=$(ls $DIR/$tdir | wc -l)
28413         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28414 }
28415 run_test 421b "rm by fid on open file"
28416
28417 test_421c() {
28418         local cnt
28419         local FIDS
28420
28421         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28422                 skip "Need MDS version at least 2.12.54"
28423
28424         test_mkdir $DIR/$tdir
28425         createmany -o $DIR/$tdir/f 3
28426         touch $DIR/$tdir/$tfile
28427         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28428         cnt=$(ls -1 $DIR/$tdir | wc -l)
28429         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28430
28431         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28432         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28433
28434         cnt=$(ls $DIR/$tdir | wc -l)
28435         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28436 }
28437 run_test 421c "rm by fid against hardlinked files"
28438
28439 test_421d() {
28440         local cnt
28441         local FIDS
28442
28443         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28444                 skip "Need MDS version at least 2.12.54"
28445
28446         test_mkdir $DIR/$tdir
28447         createmany -o $DIR/$tdir/f 4097
28448         cnt=$(ls -1 $DIR/$tdir | wc -l)
28449         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28450
28451         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28452         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28453
28454         cnt=$(ls $DIR/$tdir | wc -l)
28455         rm -rf $DIR/$tdir
28456         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28457 }
28458 run_test 421d "rmfid en masse"
28459
28460 test_421e() {
28461         local cnt
28462         local FID
28463
28464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28465         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28466                 skip "Need MDS version at least 2.12.54"
28467
28468         mkdir -p $DIR/$tdir
28469         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28470         createmany -o $DIR/$tdir/striped_dir/f 512
28471         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28472         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28473
28474         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28475                 sed "s/[/][^:]*://g")
28476         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28477
28478         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28479         rm -rf $DIR/$tdir
28480         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28481 }
28482 run_test 421e "rmfid in DNE"
28483
28484 test_421f() {
28485         local cnt
28486         local FID
28487
28488         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28489                 skip "Need MDS version at least 2.12.54"
28490
28491         test_mkdir $DIR/$tdir
28492         touch $DIR/$tdir/f
28493         cnt=$(ls -1 $DIR/$tdir | wc -l)
28494         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28495
28496         FID=$(lfs path2fid $DIR/$tdir/f)
28497         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28498         # rmfid should fail
28499         cnt=$(ls -1 $DIR/$tdir | wc -l)
28500         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28501
28502         chmod a+rw $DIR/$tdir
28503         ls -la $DIR/$tdir
28504         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28505         # rmfid should fail
28506         cnt=$(ls -1 $DIR/$tdir | wc -l)
28507         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28508
28509         rm -f $DIR/$tdir/f
28510         $RUNAS touch $DIR/$tdir/f
28511         FID=$(lfs path2fid $DIR/$tdir/f)
28512         echo "rmfid as root"
28513         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28514         cnt=$(ls -1 $DIR/$tdir | wc -l)
28515         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28516
28517         rm -f $DIR/$tdir/f
28518         $RUNAS touch $DIR/$tdir/f
28519         cnt=$(ls -1 $DIR/$tdir | wc -l)
28520         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28521         FID=$(lfs path2fid $DIR/$tdir/f)
28522         # rmfid w/o user_fid2path mount option should fail
28523         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
28524         cnt=$(ls -1 $DIR/$tdir | wc -l)
28525         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
28526
28527         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
28528         stack_trap "rmdir $tmpdir"
28529         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
28530                 error "failed to mount client'"
28531         stack_trap "umount_client $tmpdir"
28532
28533         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
28534         # rmfid should succeed
28535         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
28536         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
28537
28538         # rmfid shouldn't allow to remove files due to dir's permission
28539         chmod a+rwx $tmpdir/$tdir
28540         touch $tmpdir/$tdir/f
28541         ls -la $tmpdir/$tdir
28542         FID=$(lfs path2fid $tmpdir/$tdir/f)
28543         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
28544         return 0
28545 }
28546 run_test 421f "rmfid checks permissions"
28547
28548 test_421g() {
28549         local cnt
28550         local FIDS
28551
28552         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28553         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28554                 skip "Need MDS version at least 2.12.54"
28555
28556         mkdir -p $DIR/$tdir
28557         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28558         createmany -o $DIR/$tdir/striped_dir/f 512
28559         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28560         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28561
28562         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28563                 sed "s/[/][^:]*://g")
28564
28565         rm -f $DIR/$tdir/striped_dir/f1*
28566         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28567         removed=$((512 - cnt))
28568
28569         # few files have been just removed, so we expect
28570         # rmfid to fail on their fids
28571         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
28572         [ $removed != $errors ] && error "$errors != $removed"
28573
28574         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28575         rm -rf $DIR/$tdir
28576         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28577 }
28578 run_test 421g "rmfid to return errors properly"
28579
28580 test_421h() {
28581         local mount_other
28582         local mount_ret
28583         local rmfid_ret
28584         local old_fid
28585         local fidA
28586         local fidB
28587         local fidC
28588         local fidD
28589
28590         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
28591                 skip "Need MDS version at least 2.15.53"
28592
28593         test_mkdir $DIR/$tdir
28594         test_mkdir $DIR/$tdir/subdir
28595         touch $DIR/$tdir/subdir/file0
28596         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
28597         echo File $DIR/$tdir/subdir/file0 FID $old_fid
28598         rm -f $DIR/$tdir/subdir/file0
28599         touch $DIR/$tdir/subdir/fileA
28600         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
28601         echo File $DIR/$tdir/subdir/fileA FID $fidA
28602         touch $DIR/$tdir/subdir/fileB
28603         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
28604         echo File $DIR/$tdir/subdir/fileB FID $fidB
28605         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
28606         touch $DIR/$tdir/subdir/fileC
28607         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
28608         echo File $DIR/$tdir/subdir/fileC FID $fidC
28609         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
28610         touch $DIR/$tdir/fileD
28611         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
28612         echo File $DIR/$tdir/fileD FID $fidD
28613
28614         # mount another client mount point with subdirectory mount
28615         export FILESET=/$tdir/subdir
28616         mount_other=${MOUNT}_other
28617         mount_client $mount_other ${MOUNT_OPTS}
28618         mount_ret=$?
28619         export FILESET=""
28620         (( mount_ret == 0 )) || error "mount $mount_other failed"
28621
28622         echo Removing FIDs:
28623         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28624         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
28625         rmfid_ret=$?
28626
28627         umount_client $mount_other || error "umount $mount_other failed"
28628
28629         (( rmfid_ret != 0 )) || error "rmfid should have failed"
28630
28631         # fileA should have been deleted
28632         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
28633
28634         # fileB should have been deleted
28635         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
28636
28637         # fileC should not have been deleted, fid also exists outside of fileset
28638         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
28639
28640         # fileD should not have been deleted, it exists outside of fileset
28641         stat $DIR/$tdir/fileD || error "fileD deleted"
28642 }
28643 run_test 421h "rmfid with fileset mount"
28644
28645 test_422() {
28646         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
28647         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
28648         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
28649         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
28650         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
28651
28652         local amc=$(at_max_get client)
28653         local amo=$(at_max_get mds1)
28654         local timeout=`lctl get_param -n timeout`
28655
28656         at_max_set 0 client
28657         at_max_set 0 mds1
28658
28659 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
28660         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
28661                         fail_val=$(((2*timeout + 10)*1000))
28662         touch $DIR/$tdir/d3/file &
28663         sleep 2
28664 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
28665         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
28666                         fail_val=$((2*timeout + 5))
28667         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
28668         local pid=$!
28669         sleep 1
28670         kill -9 $pid
28671         sleep $((2 * timeout))
28672         echo kill $pid
28673         kill -9 $pid
28674         lctl mark touch
28675         touch $DIR/$tdir/d2/file3
28676         touch $DIR/$tdir/d2/file4
28677         touch $DIR/$tdir/d2/file5
28678
28679         wait
28680         at_max_set $amc client
28681         at_max_set $amo mds1
28682
28683         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
28684         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
28685                 error "Watchdog is always throttled"
28686 }
28687 run_test 422 "kill a process with RPC in progress"
28688
28689 stat_test() {
28690     df -h $MOUNT &
28691     df -h $MOUNT &
28692     df -h $MOUNT &
28693     df -h $MOUNT &
28694     df -h $MOUNT &
28695     df -h $MOUNT &
28696 }
28697
28698 test_423() {
28699     local _stats
28700     # ensure statfs cache is expired
28701     sleep 2;
28702
28703     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
28704     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
28705
28706     return 0
28707 }
28708 run_test 423 "statfs should return a right data"
28709
28710 test_424() {
28711 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
28712         $LCTL set_param fail_loc=0x80000522
28713         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28714         rm -f $DIR/$tfile
28715 }
28716 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28717
28718 test_425() {
28719         test_mkdir -c -1 $DIR/$tdir
28720         $LFS setstripe -c -1 $DIR/$tdir
28721
28722         lru_resize_disable "" 100
28723         stack_trap "lru_resize_enable" EXIT
28724
28725         sleep 5
28726
28727         for i in $(seq $((MDSCOUNT * 125))); do
28728                 local t=$DIR/$tdir/$tfile_$i
28729
28730                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28731                         error_noexit "Create file $t"
28732         done
28733         stack_trap "rm -rf $DIR/$tdir" EXIT
28734
28735         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28736                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28737                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28738
28739                 [ $lock_count -le $lru_size ] ||
28740                         error "osc lock count $lock_count > lru size $lru_size"
28741         done
28742
28743         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28744                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28745                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28746
28747                 [ $lock_count -le $lru_size ] ||
28748                         error "mdc lock count $lock_count > lru size $lru_size"
28749         done
28750 }
28751 run_test 425 "lock count should not exceed lru size"
28752
28753 test_426() {
28754         splice-test -r $DIR/$tfile
28755         splice-test -rd $DIR/$tfile
28756         splice-test $DIR/$tfile
28757         splice-test -d $DIR/$tfile
28758 }
28759 run_test 426 "splice test on Lustre"
28760
28761 test_427() {
28762         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28763         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28764                 skip "Need MDS version at least 2.12.4"
28765         local log
28766
28767         mkdir $DIR/$tdir
28768         mkdir $DIR/$tdir/1
28769         mkdir $DIR/$tdir/2
28770         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28771         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28772
28773         $LFS getdirstripe $DIR/$tdir/1/dir
28774
28775         #first setfattr for creating updatelog
28776         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28777
28778 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28779         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28780         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28781         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28782
28783         sleep 2
28784         fail mds2
28785         wait_recovery_complete mds2 $((2*TIMEOUT))
28786
28787         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28788         echo $log | grep "get update log failed" &&
28789                 error "update log corruption is detected" || true
28790 }
28791 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28792
28793 test_428() {
28794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28795         local cache_limit=$CACHE_MAX
28796
28797         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28798         $LCTL set_param -n llite.*.max_cached_mb=64
28799
28800         mkdir $DIR/$tdir
28801         $LFS setstripe -c 1 $DIR/$tdir
28802         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28803         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28804         #test write
28805         for f in $(seq 4); do
28806                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28807         done
28808         wait
28809
28810         cancel_lru_locks osc
28811         # Test read
28812         for f in $(seq 4); do
28813                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28814         done
28815         wait
28816 }
28817 run_test 428 "large block size IO should not hang"
28818
28819 test_429() { # LU-7915 / LU-10948
28820         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28821         local testfile=$DIR/$tfile
28822         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28823         local new_flag=1
28824         local first_rpc
28825         local second_rpc
28826         local third_rpc
28827
28828         $LCTL get_param $ll_opencache_threshold_count ||
28829                 skip "client does not have opencache parameter"
28830
28831         set_opencache $new_flag
28832         stack_trap "restore_opencache"
28833         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28834                 error "enable opencache failed"
28835         touch $testfile
28836         # drop MDC DLM locks
28837         cancel_lru_locks mdc
28838         # clear MDC RPC stats counters
28839         $LCTL set_param $mdc_rpcstats=clear
28840
28841         # According to the current implementation, we need to run 3 times
28842         # open & close file to verify if opencache is enabled correctly.
28843         # 1st, RPCs are sent for lookup/open and open handle is released on
28844         #      close finally.
28845         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28846         #      so open handle won't be released thereafter.
28847         # 3rd, No RPC is sent out.
28848         $MULTIOP $testfile oc || error "multiop failed"
28849         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28850         echo "1st: $first_rpc RPCs in flight"
28851
28852         $MULTIOP $testfile oc || error "multiop failed"
28853         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28854         echo "2nd: $second_rpc RPCs in flight"
28855
28856         $MULTIOP $testfile oc || error "multiop failed"
28857         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28858         echo "3rd: $third_rpc RPCs in flight"
28859
28860         #verify no MDC RPC is sent
28861         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28862 }
28863 run_test 429 "verify if opencache flag on client side does work"
28864
28865 lseek_test_430() {
28866         local offset
28867         local file=$1
28868
28869         # data at [200K, 400K)
28870         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28871                 error "256K->512K dd fails"
28872         # data at [2M, 3M)
28873         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28874                 error "2M->3M dd fails"
28875         # data at [4M, 5M)
28876         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28877                 error "4M->5M dd fails"
28878         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28879         # start at first component hole #1
28880         printf "Seeking hole from 1000 ... "
28881         offset=$(lseek_test -l 1000 $file)
28882         echo $offset
28883         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28884         printf "Seeking data from 1000 ... "
28885         offset=$(lseek_test -d 1000 $file)
28886         echo $offset
28887         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28888
28889         # start at first component data block
28890         printf "Seeking hole from 300000 ... "
28891         offset=$(lseek_test -l 300000 $file)
28892         echo $offset
28893         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28894         printf "Seeking data from 300000 ... "
28895         offset=$(lseek_test -d 300000 $file)
28896         echo $offset
28897         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28898
28899         # start at the first component but beyond end of object size
28900         printf "Seeking hole from 1000000 ... "
28901         offset=$(lseek_test -l 1000000 $file)
28902         echo $offset
28903         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28904         printf "Seeking data from 1000000 ... "
28905         offset=$(lseek_test -d 1000000 $file)
28906         echo $offset
28907         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28908
28909         # start at second component stripe 2 (empty file)
28910         printf "Seeking hole from 1500000 ... "
28911         offset=$(lseek_test -l 1500000 $file)
28912         echo $offset
28913         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28914         printf "Seeking data from 1500000 ... "
28915         offset=$(lseek_test -d 1500000 $file)
28916         echo $offset
28917         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28918
28919         # start at second component stripe 1 (all data)
28920         printf "Seeking hole from 3000000 ... "
28921         offset=$(lseek_test -l 3000000 $file)
28922         echo $offset
28923         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28924         printf "Seeking data from 3000000 ... "
28925         offset=$(lseek_test -d 3000000 $file)
28926         echo $offset
28927         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28928
28929         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28930                 error "2nd dd fails"
28931         echo "Add data block at 640K...1280K"
28932
28933         # start at before new data block, in hole
28934         printf "Seeking hole from 600000 ... "
28935         offset=$(lseek_test -l 600000 $file)
28936         echo $offset
28937         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28938         printf "Seeking data from 600000 ... "
28939         offset=$(lseek_test -d 600000 $file)
28940         echo $offset
28941         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28942
28943         # start at the first component new data block
28944         printf "Seeking hole from 1000000 ... "
28945         offset=$(lseek_test -l 1000000 $file)
28946         echo $offset
28947         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28948         printf "Seeking data from 1000000 ... "
28949         offset=$(lseek_test -d 1000000 $file)
28950         echo $offset
28951         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28952
28953         # start at second component stripe 2, new data
28954         printf "Seeking hole from 1200000 ... "
28955         offset=$(lseek_test -l 1200000 $file)
28956         echo $offset
28957         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28958         printf "Seeking data from 1200000 ... "
28959         offset=$(lseek_test -d 1200000 $file)
28960         echo $offset
28961         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28962
28963         # start beyond file end
28964         printf "Using offset > filesize ... "
28965         lseek_test -l 4000000 $file && error "lseek should fail"
28966         printf "Using offset > filesize ... "
28967         lseek_test -d 4000000 $file && error "lseek should fail"
28968
28969         printf "Done\n\n"
28970 }
28971
28972 test_430a() {
28973         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28974                 skip "MDT does not support SEEK_HOLE"
28975
28976         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28977                 skip "OST does not support SEEK_HOLE"
28978
28979         local file=$DIR/$tdir/$tfile
28980
28981         mkdir -p $DIR/$tdir
28982
28983         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28984         # OST stripe #1 will have continuous data at [1M, 3M)
28985         # OST stripe #2 is empty
28986         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28987         lseek_test_430 $file
28988         rm $file
28989         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28990         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28991         lseek_test_430 $file
28992         rm $file
28993         $LFS setstripe -c2 -S 512K $file
28994         echo "Two stripes, stripe size 512K"
28995         lseek_test_430 $file
28996         rm $file
28997         # FLR with stale mirror
28998         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28999                        -N -c2 -S 1M $file
29000         echo "Mirrored file:"
29001         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29002         echo "Plain 2 stripes 1M"
29003         lseek_test_430 $file
29004         rm $file
29005 }
29006 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29007
29008 test_430b() {
29009         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29010                 skip "OST does not support SEEK_HOLE"
29011
29012         local offset
29013         local file=$DIR/$tdir/$tfile
29014
29015         mkdir -p $DIR/$tdir
29016         # Empty layout lseek should fail
29017         $MCREATE $file
29018         # seek from 0
29019         printf "Seeking hole from 0 ... "
29020         lseek_test -l 0 $file && error "lseek should fail"
29021         printf "Seeking data from 0 ... "
29022         lseek_test -d 0 $file && error "lseek should fail"
29023         rm $file
29024
29025         # 1M-hole file
29026         $LFS setstripe -E 1M -c2 -E eof $file
29027         $TRUNCATE $file 1048576
29028         printf "Seeking hole from 1000000 ... "
29029         offset=$(lseek_test -l 1000000 $file)
29030         echo $offset
29031         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29032         printf "Seeking data from 1000000 ... "
29033         lseek_test -d 1000000 $file && error "lseek should fail"
29034         rm $file
29035
29036         # full component followed by non-inited one
29037         $LFS setstripe -E 1M -c2 -E eof $file
29038         dd if=/dev/urandom of=$file bs=1M count=1
29039         printf "Seeking hole from 1000000 ... "
29040         offset=$(lseek_test -l 1000000 $file)
29041         echo $offset
29042         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29043         printf "Seeking hole from 1048576 ... "
29044         lseek_test -l 1048576 $file && error "lseek should fail"
29045         # init second component and truncate back
29046         echo "123" >> $file
29047         $TRUNCATE $file 1048576
29048         printf "Seeking hole from 1000000 ... "
29049         offset=$(lseek_test -l 1000000 $file)
29050         echo $offset
29051         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29052         printf "Seeking hole from 1048576 ... "
29053         lseek_test -l 1048576 $file && error "lseek should fail"
29054         # boundary checks for big values
29055         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29056         offset=$(lseek_test -d 0 $file.10g)
29057         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29058         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29059         offset=$(lseek_test -d 0 $file.100g)
29060         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29061         return 0
29062 }
29063 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29064
29065 test_430c() {
29066         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29067                 skip "OST does not support SEEK_HOLE"
29068
29069         local file=$DIR/$tdir/$tfile
29070         local start
29071
29072         mkdir -p $DIR/$tdir
29073         stack_trap "rm -f $file $file.tmp"
29074         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29075
29076         # cp version 8.33+ prefers lseek over fiemap
29077         local ver=$(cp --version | awk '{ print $4; exit; }')
29078
29079         echo "cp $ver installed"
29080         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29081                 start=$SECONDS
29082                 time cp -v $file $file.tmp || error "cp $file failed"
29083                 (( SECONDS - start < 5 )) || {
29084                         strace cp $file $file.tmp |&
29085                                 grep -E "open|read|seek|FIEMAP" |
29086                                 grep -A 100 $file
29087                         error "cp: too long runtime $((SECONDS - start))"
29088                 }
29089         else
29090                 echo "cp test skipped due to $ver < 8.33"
29091         fi
29092
29093         # tar version 1.29+ supports SEEK_HOLE/DATA
29094         ver=$(tar --version | awk '{ print $4; exit; }')
29095         echo "tar $ver installed"
29096         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29097                 start=$SECONDS
29098                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29099                 (( SECONDS - start < 5 )) || {
29100                         strace tar cf $file.tmp --sparse $file |&
29101                                 grep -E "open|read|seek|FIEMAP" |
29102                                 grep -A 100 $file
29103                         error "tar: too long runtime $((SECONDS - start))"
29104                 }
29105         else
29106                 echo "tar test skipped due to $ver < 1.29"
29107         fi
29108 }
29109 run_test 430c "lseek: external tools check"
29110
29111 test_431() { # LU-14187
29112         local file=$DIR/$tdir/$tfile
29113
29114         mkdir -p $DIR/$tdir
29115         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29116         dd if=/dev/urandom of=$file bs=4k count=1
29117         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29118         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29119         #define OBD_FAIL_OST_RESTART_IO 0x251
29120         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29121         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29122         cp $file $file.0
29123         cancel_lru_locks
29124         sync_all_data
29125         echo 3 > /proc/sys/vm/drop_caches
29126         diff  $file $file.0 || error "data diff"
29127 }
29128 run_test 431 "Restart transaction for IO"
29129
29130 cleanup_test_432() {
29131         do_facet mgs $LCTL nodemap_activate 0
29132         wait_nm_sync active
29133 }
29134
29135 test_432() {
29136         local tmpdir=$TMP/dir432
29137
29138         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29139                 skip "Need MDS version at least 2.14.52"
29140
29141         stack_trap cleanup_test_432 EXIT
29142         mkdir $DIR/$tdir
29143         mkdir $tmpdir
29144
29145         do_facet mgs $LCTL nodemap_activate 1
29146         wait_nm_sync active
29147         do_facet mgs $LCTL nodemap_modify --name default \
29148                 --property admin --value 1
29149         do_facet mgs $LCTL nodemap_modify --name default \
29150                 --property trusted --value 1
29151         cancel_lru_locks mdc
29152         wait_nm_sync default admin_nodemap
29153         wait_nm_sync default trusted_nodemap
29154
29155         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29156                grep -ci "Operation not permitted") -ne 0 ]; then
29157                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29158         fi
29159 }
29160 run_test 432 "mv dir from outside Lustre"
29161
29162 test_433() {
29163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29164
29165         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29166                 skip "inode cache not supported"
29167
29168         $LCTL set_param llite.*.inode_cache=0
29169         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29170
29171         local count=256
29172         local before
29173         local after
29174
29175         cancel_lru_locks mdc
29176         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29177         createmany -m $DIR/$tdir/f $count
29178         createmany -d $DIR/$tdir/d $count
29179         ls -l $DIR/$tdir > /dev/null
29180         stack_trap "rm -rf $DIR/$tdir"
29181
29182         before=$(num_objects)
29183         cancel_lru_locks mdc
29184         after=$(num_objects)
29185
29186         # sometimes even @before is less than 2 * count
29187         while (( before - after < count )); do
29188                 sleep 1
29189                 after=$(num_objects)
29190                 wait=$((wait + 1))
29191                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29192                 if (( wait > 60 )); then
29193                         error "inode slab grew from $before to $after"
29194                 fi
29195         done
29196
29197         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29198 }
29199 run_test 433 "ldlm lock cancel releases dentries and inodes"
29200
29201 test_434() {
29202         local file
29203         local getxattr_count
29204         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29206
29207         [[ $(getenforce) == "Disabled" ]] ||
29208                 skip "lsm selinux module have to be disabled for this test"
29209
29210         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29211                 error "fail to create $DIR/$tdir/ on MDT0000"
29212
29213         touch $DIR/$tdir/$tfile-{001..100}
29214
29215         # disable the xattr cache
29216         save_lustre_params client "llite.*.xattr_cache" > $p
29217         lctl set_param llite.*.xattr_cache=0
29218         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29219
29220         # clear clients mdc stats
29221         clear_stats $mdc_stat_param ||
29222                 error "fail to clear stats on mdc MDT0000"
29223
29224         for file in $DIR/$tdir/$tfile-{001..100}; do
29225                 getfattr -n security.selinux $file |&
29226                         grep -q "Operation not supported" ||
29227                         error "getxattr on security.selinux should return EOPNOTSUPP"
29228         done
29229
29230         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29231         (( getxattr_count < 100 )) ||
29232                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29233 }
29234 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29235
29236 test_440() {
29237         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29238                 source $LUSTRE/scripts/bash-completion/lustre
29239         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29240                 source /usr/share/bash-completion/completions/lustre
29241         else
29242                 skip "bash completion scripts not found"
29243         fi
29244
29245         local lctl_completions
29246         local lfs_completions
29247
29248         lctl_completions=$(_lustre_cmds lctl)
29249         if [[ ! $lctl_completions =~ "get_param" ]]; then
29250                 error "lctl bash completion failed"
29251         fi
29252
29253         lfs_completions=$(_lustre_cmds lfs)
29254         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29255                 error "lfs bash completion failed"
29256         fi
29257 }
29258 run_test 440 "bash completion for lfs, lctl"
29259
29260 prep_801() {
29261         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29262         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29263                 skip "Need server version at least 2.9.55"
29264
29265         start_full_debug_logging
29266 }
29267
29268 post_801() {
29269         stop_full_debug_logging
29270 }
29271
29272 barrier_stat() {
29273         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29274                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29275                            awk '/The barrier for/ { print $7 }')
29276                 echo $st
29277         else
29278                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29279                 echo \'$st\'
29280         fi
29281 }
29282
29283 barrier_expired() {
29284         local expired
29285
29286         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29287                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29288                           awk '/will be expired/ { print $7 }')
29289         else
29290                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29291         fi
29292
29293         echo $expired
29294 }
29295
29296 test_801a() {
29297         prep_801
29298
29299         echo "Start barrier_freeze at: $(date)"
29300         #define OBD_FAIL_BARRIER_DELAY          0x2202
29301         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29302         # Do not reduce barrier time - See LU-11873
29303         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29304
29305         sleep 2
29306         local b_status=$(barrier_stat)
29307         echo "Got barrier status at: $(date)"
29308         [ "$b_status" = "'freezing_p1'" ] ||
29309                 error "(1) unexpected barrier status $b_status"
29310
29311         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29312         wait
29313         b_status=$(barrier_stat)
29314         [ "$b_status" = "'frozen'" ] ||
29315                 error "(2) unexpected barrier status $b_status"
29316
29317         local expired=$(barrier_expired)
29318         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29319         sleep $((expired + 3))
29320
29321         b_status=$(barrier_stat)
29322         [ "$b_status" = "'expired'" ] ||
29323                 error "(3) unexpected barrier status $b_status"
29324
29325         # Do not reduce barrier time - See LU-11873
29326         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29327                 error "(4) fail to freeze barrier"
29328
29329         b_status=$(barrier_stat)
29330         [ "$b_status" = "'frozen'" ] ||
29331                 error "(5) unexpected barrier status $b_status"
29332
29333         echo "Start barrier_thaw at: $(date)"
29334         #define OBD_FAIL_BARRIER_DELAY          0x2202
29335         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29336         do_facet mgs $LCTL barrier_thaw $FSNAME &
29337
29338         sleep 2
29339         b_status=$(barrier_stat)
29340         echo "Got barrier status at: $(date)"
29341         [ "$b_status" = "'thawing'" ] ||
29342                 error "(6) unexpected barrier status $b_status"
29343
29344         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29345         wait
29346         b_status=$(barrier_stat)
29347         [ "$b_status" = "'thawed'" ] ||
29348                 error "(7) unexpected barrier status $b_status"
29349
29350         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29351         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29352         do_facet mgs $LCTL barrier_freeze $FSNAME
29353
29354         b_status=$(barrier_stat)
29355         [ "$b_status" = "'failed'" ] ||
29356                 error "(8) unexpected barrier status $b_status"
29357
29358         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29359         do_facet mgs $LCTL barrier_thaw $FSNAME
29360
29361         post_801
29362 }
29363 run_test 801a "write barrier user interfaces and stat machine"
29364
29365 test_801b() {
29366         prep_801
29367
29368         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29369         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29370         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29371         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29372         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29373
29374         cancel_lru_locks mdc
29375
29376         # 180 seconds should be long enough
29377         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29378
29379         local b_status=$(barrier_stat)
29380         [ "$b_status" = "'frozen'" ] ||
29381                 error "(6) unexpected barrier status $b_status"
29382
29383         mkdir $DIR/$tdir/d0/d10 &
29384         mkdir_pid=$!
29385
29386         touch $DIR/$tdir/d1/f13 &
29387         touch_pid=$!
29388
29389         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29390         ln_pid=$!
29391
29392         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29393         mv_pid=$!
29394
29395         rm -f $DIR/$tdir/d4/f12 &
29396         rm_pid=$!
29397
29398         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29399
29400         # To guarantee taht the 'stat' is not blocked
29401         b_status=$(barrier_stat)
29402         [ "$b_status" = "'frozen'" ] ||
29403                 error "(8) unexpected barrier status $b_status"
29404
29405         # let above commands to run at background
29406         sleep 5
29407
29408         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29409         ps -p $touch_pid || error "(10) touch should be blocked"
29410         ps -p $ln_pid || error "(11) link should be blocked"
29411         ps -p $mv_pid || error "(12) rename should be blocked"
29412         ps -p $rm_pid || error "(13) unlink should be blocked"
29413
29414         b_status=$(barrier_stat)
29415         [ "$b_status" = "'frozen'" ] ||
29416                 error "(14) unexpected barrier status $b_status"
29417
29418         do_facet mgs $LCTL barrier_thaw $FSNAME
29419         b_status=$(barrier_stat)
29420         [ "$b_status" = "'thawed'" ] ||
29421                 error "(15) unexpected barrier status $b_status"
29422
29423         wait $mkdir_pid || error "(16) mkdir should succeed"
29424         wait $touch_pid || error "(17) touch should succeed"
29425         wait $ln_pid || error "(18) link should succeed"
29426         wait $mv_pid || error "(19) rename should succeed"
29427         wait $rm_pid || error "(20) unlink should succeed"
29428
29429         post_801
29430 }
29431 run_test 801b "modification will be blocked by write barrier"
29432
29433 test_801c() {
29434         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29435
29436         prep_801
29437
29438         stop mds2 || error "(1) Fail to stop mds2"
29439
29440         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29441
29442         local b_status=$(barrier_stat)
29443         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29444                 do_facet mgs $LCTL barrier_thaw $FSNAME
29445                 error "(2) unexpected barrier status $b_status"
29446         }
29447
29448         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29449                 error "(3) Fail to rescan barrier bitmap"
29450
29451         # Do not reduce barrier time - See LU-11873
29452         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29453
29454         b_status=$(barrier_stat)
29455         [ "$b_status" = "'frozen'" ] ||
29456                 error "(4) unexpected barrier status $b_status"
29457
29458         do_facet mgs $LCTL barrier_thaw $FSNAME
29459         b_status=$(barrier_stat)
29460         [ "$b_status" = "'thawed'" ] ||
29461                 error "(5) unexpected barrier status $b_status"
29462
29463         local devname=$(mdsdevname 2)
29464
29465         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29466
29467         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29468                 error "(7) Fail to rescan barrier bitmap"
29469
29470         post_801
29471 }
29472 run_test 801c "rescan barrier bitmap"
29473
29474 test_802b() {
29475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29476         remote_mds_nodsh && skip "remote MDS with nodsh"
29477
29478         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29479                 skip "readonly option not available"
29480
29481         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29482
29483         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29484                 error "(2) Fail to copy"
29485
29486         # write back all cached data before setting MDT to readonly
29487         cancel_lru_locks
29488         sync_all_data
29489
29490         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29491         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29492
29493         echo "Modify should be refused"
29494         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29495
29496         echo "Read should be allowed"
29497         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29498                 error "(7) Read should succeed under ro mode"
29499
29500         # disable readonly
29501         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29502 }
29503 run_test 802b "be able to set MDTs to readonly"
29504
29505 test_803a() {
29506         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29507         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29508                 skip "MDS needs to be newer than 2.10.54"
29509
29510         mkdir_on_mdt0 $DIR/$tdir
29511         # Create some objects on all MDTs to trigger related logs objects
29512         for idx in $(seq $MDSCOUNT); do
29513                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29514                         $DIR/$tdir/dir${idx} ||
29515                         error "Fail to create $DIR/$tdir/dir${idx}"
29516         done
29517
29518         wait_delete_completed # ensure old test cleanups are finished
29519         sleep 3
29520         echo "before create:"
29521         $LFS df -i $MOUNT
29522         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29523
29524         for i in {1..10}; do
29525                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
29526                         error "Fail to create $DIR/$tdir/foo$i"
29527         done
29528
29529         # sync ZFS-on-MDS to refresh statfs data
29530         wait_zfs_commit mds1
29531         sleep 3
29532         echo "after create:"
29533         $LFS df -i $MOUNT
29534         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29535
29536         # allow for an llog to be cleaned up during the test
29537         [ $after_used -ge $((before_used + 10 - 1)) ] ||
29538                 error "before ($before_used) + 10 > after ($after_used)"
29539
29540         for i in {1..10}; do
29541                 rm -rf $DIR/$tdir/foo$i ||
29542                         error "Fail to remove $DIR/$tdir/foo$i"
29543         done
29544
29545         # sync ZFS-on-MDS to refresh statfs data
29546         wait_zfs_commit mds1
29547         wait_delete_completed
29548         sleep 3 # avoid MDT return cached statfs
29549         echo "after unlink:"
29550         $LFS df -i $MOUNT
29551         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
29552
29553         # allow for an llog to be created during the test
29554         [ $after_used -le $((before_used + 1)) ] ||
29555                 error "after ($after_used) > before ($before_used) + 1"
29556 }
29557 run_test 803a "verify agent object for remote object"
29558
29559 test_803b() {
29560         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29561         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
29562                 skip "MDS needs to be newer than 2.13.56"
29563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29564
29565         for i in $(seq 0 $((MDSCOUNT - 1))); do
29566                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
29567         done
29568
29569         local before=0
29570         local after=0
29571
29572         local tmp
29573
29574         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29575         for i in $(seq 0 $((MDSCOUNT - 1))); do
29576                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29577                         awk '/getattr/ { print $2 }')
29578                 before=$((before + tmp))
29579         done
29580         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
29581         for i in $(seq 0 $((MDSCOUNT - 1))); do
29582                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
29583                         awk '/getattr/ { print $2 }')
29584                 after=$((after + tmp))
29585         done
29586
29587         [ $before -eq $after ] || error "getattr count $before != $after"
29588 }
29589 run_test 803b "remote object can getattr from cache"
29590
29591 test_804() {
29592         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29593         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29594                 skip "MDS needs to be newer than 2.10.54"
29595         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
29596
29597         mkdir -p $DIR/$tdir
29598         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
29599                 error "Fail to create $DIR/$tdir/dir0"
29600
29601         local fid=$($LFS path2fid $DIR/$tdir/dir0)
29602         local dev=$(mdsdevname 2)
29603
29604         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29605                 grep ${fid} || error "NOT found agent entry for dir0"
29606
29607         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
29608                 error "Fail to create $DIR/$tdir/dir1"
29609
29610         touch $DIR/$tdir/dir1/foo0 ||
29611                 error "Fail to create $DIR/$tdir/dir1/foo0"
29612         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
29613         local rc=0
29614
29615         for idx in $(seq $MDSCOUNT); do
29616                 dev=$(mdsdevname $idx)
29617                 do_facet mds${idx} \
29618                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29619                         grep ${fid} && rc=$idx
29620         done
29621
29622         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
29623                 error "Fail to rename foo0 to foo1"
29624         if [ $rc -eq 0 ]; then
29625                 for idx in $(seq $MDSCOUNT); do
29626                         dev=$(mdsdevname $idx)
29627                         do_facet mds${idx} \
29628                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29629                         grep ${fid} && rc=$idx
29630                 done
29631         fi
29632
29633         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
29634                 error "Fail to rename foo1 to foo2"
29635         if [ $rc -eq 0 ]; then
29636                 for idx in $(seq $MDSCOUNT); do
29637                         dev=$(mdsdevname $idx)
29638                         do_facet mds${idx} \
29639                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
29640                         grep ${fid} && rc=$idx
29641                 done
29642         fi
29643
29644         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
29645
29646         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
29647                 error "Fail to link to $DIR/$tdir/dir1/foo2"
29648         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
29649                 error "Fail to rename foo2 to foo0"
29650         unlink $DIR/$tdir/dir1/foo0 ||
29651                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
29652         rm -rf $DIR/$tdir/dir0 ||
29653                 error "Fail to rm $DIR/$tdir/dir0"
29654
29655         for idx in $(seq $MDSCOUNT); do
29656                 rc=0
29657
29658                 stop mds${idx}
29659                 dev=$(mdsdevname $idx)
29660                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
29661                         rc=$?
29662                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
29663                         error "mount mds$idx failed"
29664                 df $MOUNT > /dev/null 2>&1
29665
29666                 # e2fsck should not return error
29667                 [ $rc -eq 0 ] ||
29668                         error "e2fsck detected error on MDT${idx}: rc=$rc"
29669         done
29670 }
29671 run_test 804 "verify agent entry for remote entry"
29672
29673 cleanup_805() {
29674         do_facet $SINGLEMDS zfs set quota=$old $fsset
29675         unlinkmany $DIR/$tdir/f- 1000000
29676         trap 0
29677 }
29678
29679 test_805() {
29680         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
29681         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
29682         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
29683                 skip "netfree not implemented before 0.7"
29684         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
29685                 skip "Need MDS version at least 2.10.57"
29686
29687         local fsset
29688         local freekb
29689         local usedkb
29690         local old
29691         local quota
29692         local pref="osd-zfs.$FSNAME-MDT0000."
29693
29694         # limit available space on MDS dataset to meet nospace issue
29695         # quickly. then ZFS 0.7.2 can use reserved space if asked
29696         # properly (using netfree flag in osd_declare_destroy()
29697         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
29698         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
29699                 gawk '{print $3}')
29700         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
29701         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
29702         let "usedkb=usedkb-freekb"
29703         let "freekb=freekb/2"
29704         if let "freekb > 5000"; then
29705                 let "freekb=5000"
29706         fi
29707         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
29708         trap cleanup_805 EXIT
29709         mkdir_on_mdt0 $DIR/$tdir
29710         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
29711                 error "Can't set PFL layout"
29712         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29713         rm -rf $DIR/$tdir || error "not able to remove"
29714         do_facet $SINGLEMDS zfs set quota=$old $fsset
29715         trap 0
29716 }
29717 run_test 805 "ZFS can remove from full fs"
29718
29719 # Size-on-MDS test
29720 check_lsom_data()
29721 {
29722         local file=$1
29723         local expect=$(stat -c %s $file)
29724
29725         check_lsom_size $1 $expect
29726
29727         local blocks=$($LFS getsom -b $file)
29728         expect=$(stat -c %b $file)
29729         [[ $blocks == $expect ]] ||
29730                 error "$file expected blocks: $expect, got: $blocks"
29731 }
29732
29733 check_lsom_size()
29734 {
29735         local size
29736         local expect=$2
29737
29738         cancel_lru_locks mdc
29739
29740         size=$($LFS getsom -s $1)
29741         [[ $size == $expect ]] ||
29742                 error "$file expected size: $expect, got: $size"
29743 }
29744
29745 test_806() {
29746         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29747                 skip "Need MDS version at least 2.11.52"
29748
29749         local bs=1048576
29750
29751         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29752
29753         disable_opencache
29754         stack_trap "restore_opencache"
29755
29756         # single-threaded write
29757         echo "Test SOM for single-threaded write"
29758         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29759                 error "write $tfile failed"
29760         check_lsom_size $DIR/$tfile $bs
29761
29762         local num=32
29763         local size=$(($num * $bs))
29764         local offset=0
29765         local i
29766
29767         echo "Test SOM for single client multi-threaded($num) write"
29768         $TRUNCATE $DIR/$tfile 0
29769         for ((i = 0; i < $num; i++)); do
29770                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29771                 local pids[$i]=$!
29772                 offset=$((offset + $bs))
29773         done
29774         for (( i=0; i < $num; i++ )); do
29775                 wait ${pids[$i]}
29776         done
29777         check_lsom_size $DIR/$tfile $size
29778
29779         $TRUNCATE $DIR/$tfile 0
29780         for ((i = 0; i < $num; i++)); do
29781                 offset=$((offset - $bs))
29782                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29783                 local pids[$i]=$!
29784         done
29785         for (( i=0; i < $num; i++ )); do
29786                 wait ${pids[$i]}
29787         done
29788         check_lsom_size $DIR/$tfile $size
29789
29790         # multi-client writes
29791         num=$(get_node_count ${CLIENTS//,/ })
29792         size=$(($num * $bs))
29793         offset=0
29794         i=0
29795
29796         echo "Test SOM for multi-client ($num) writes"
29797         $TRUNCATE $DIR/$tfile 0
29798         for client in ${CLIENTS//,/ }; do
29799                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29800                 local pids[$i]=$!
29801                 i=$((i + 1))
29802                 offset=$((offset + $bs))
29803         done
29804         for (( i=0; i < $num; i++ )); do
29805                 wait ${pids[$i]}
29806         done
29807         check_lsom_size $DIR/$tfile $offset
29808
29809         i=0
29810         $TRUNCATE $DIR/$tfile 0
29811         for client in ${CLIENTS//,/ }; do
29812                 offset=$((offset - $bs))
29813                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29814                 local pids[$i]=$!
29815                 i=$((i + 1))
29816         done
29817         for (( i=0; i < $num; i++ )); do
29818                 wait ${pids[$i]}
29819         done
29820         check_lsom_size $DIR/$tfile $size
29821
29822         # verify SOM blocks count
29823         echo "Verify SOM block count"
29824         $TRUNCATE $DIR/$tfile 0
29825         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29826                 error "failed to write file $tfile with fdatasync and fstat"
29827         check_lsom_data $DIR/$tfile
29828
29829         $TRUNCATE $DIR/$tfile 0
29830         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29831                 error "failed to write file $tfile with fdatasync"
29832         check_lsom_data $DIR/$tfile
29833
29834         $TRUNCATE $DIR/$tfile 0
29835         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29836                 error "failed to write file $tfile with sync IO"
29837         check_lsom_data $DIR/$tfile
29838
29839         # verify truncate
29840         echo "Test SOM for truncate"
29841         # use ftruncate to sync blocks on close request
29842         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29843         check_lsom_size $DIR/$tfile 16384
29844         check_lsom_data $DIR/$tfile
29845
29846         $TRUNCATE $DIR/$tfile 1234
29847         check_lsom_size $DIR/$tfile 1234
29848         # sync blocks on the MDT
29849         $MULTIOP $DIR/$tfile oc
29850         check_lsom_data $DIR/$tfile
29851 }
29852 run_test 806 "Verify Lazy Size on MDS"
29853
29854 test_807() {
29855         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29856         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29857                 skip "Need MDS version at least 2.11.52"
29858
29859         # Registration step
29860         changelog_register || error "changelog_register failed"
29861         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29862         changelog_users $SINGLEMDS | grep -q $cl_user ||
29863                 error "User $cl_user not found in changelog_users"
29864
29865         rm -rf $DIR/$tdir || error "rm $tdir failed"
29866         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29867         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29868         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29869         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29870                 error "truncate $tdir/trunc failed"
29871
29872         local bs=1048576
29873         echo "Test SOM for single-threaded write with fsync"
29874         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29875                 error "write $tfile failed"
29876         sync;sync;sync
29877
29878         # multi-client wirtes
29879         local num=$(get_node_count ${CLIENTS//,/ })
29880         local offset=0
29881         local i=0
29882
29883         echo "Test SOM for multi-client ($num) writes"
29884         touch $DIR/$tfile || error "touch $tfile failed"
29885         $TRUNCATE $DIR/$tfile 0
29886         for client in ${CLIENTS//,/ }; do
29887                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29888                 local pids[$i]=$!
29889                 i=$((i + 1))
29890                 offset=$((offset + $bs))
29891         done
29892         for (( i=0; i < $num; i++ )); do
29893                 wait ${pids[$i]}
29894         done
29895
29896         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29897         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29898         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29899         check_lsom_data $DIR/$tdir/trunc
29900         check_lsom_data $DIR/$tdir/single_dd
29901         check_lsom_data $DIR/$tfile
29902
29903         rm -rf $DIR/$tdir
29904         # Deregistration step
29905         changelog_deregister || error "changelog_deregister failed"
29906 }
29907 run_test 807 "verify LSOM syncing tool"
29908
29909 check_som_nologged()
29910 {
29911         local lines=$($LFS changelog $FSNAME-MDT0000 |
29912                 grep 'x=trusted.som' | wc -l)
29913         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29914 }
29915
29916 test_808() {
29917         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29918                 skip "Need MDS version at least 2.11.55"
29919
29920         # Registration step
29921         changelog_register || error "changelog_register failed"
29922
29923         touch $DIR/$tfile || error "touch $tfile failed"
29924         check_som_nologged
29925
29926         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29927                 error "write $tfile failed"
29928         check_som_nologged
29929
29930         $TRUNCATE $DIR/$tfile 1234
29931         check_som_nologged
29932
29933         $TRUNCATE $DIR/$tfile 1048576
29934         check_som_nologged
29935
29936         # Deregistration step
29937         changelog_deregister || error "changelog_deregister failed"
29938 }
29939 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29940
29941 check_som_nodata()
29942 {
29943         $LFS getsom $1
29944         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29945 }
29946
29947 test_809() {
29948         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29949                 skip "Need MDS version at least 2.11.56"
29950
29951         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29952                 error "failed to create DoM-only file $DIR/$tfile"
29953         touch $DIR/$tfile || error "touch $tfile failed"
29954         check_som_nodata $DIR/$tfile
29955
29956         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29957                 error "write $tfile failed"
29958         check_som_nodata $DIR/$tfile
29959
29960         $TRUNCATE $DIR/$tfile 1234
29961         check_som_nodata $DIR/$tfile
29962
29963         $TRUNCATE $DIR/$tfile 4097
29964         check_som_nodata $DIR/$file
29965 }
29966 run_test 809 "Verify no SOM xattr store for DoM-only files"
29967
29968 test_810() {
29969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29970         $GSS && skip_env "could not run with gss"
29971         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29972                 skip "OST < 2.12.58 doesn't align checksum"
29973
29974         set_checksums 1
29975         stack_trap "set_checksums $ORIG_CSUM" EXIT
29976         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29977
29978         local csum
29979         local before
29980         local after
29981         for csum in $CKSUM_TYPES; do
29982                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29983                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29984                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29985                         eval set -- $i
29986                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29987                         before=$(md5sum $DIR/$tfile)
29988                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29989                         after=$(md5sum $DIR/$tfile)
29990                         [ "$before" == "$after" ] ||
29991                                 error "$csum: $before != $after bs=$1 seek=$2"
29992                 done
29993         done
29994 }
29995 run_test 810 "partial page writes on ZFS (LU-11663)"
29996
29997 test_812a() {
29998         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29999                 skip "OST < 2.12.51 doesn't support this fail_loc"
30000
30001         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30002         # ensure ost1 is connected
30003         stat $DIR/$tfile >/dev/null || error "can't stat"
30004         wait_osc_import_state client ost1 FULL
30005         # no locks, no reqs to let the connection idle
30006         cancel_lru_locks osc
30007
30008         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30009 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30010         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30011         wait_osc_import_state client ost1 CONNECTING
30012         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30013
30014         stat $DIR/$tfile >/dev/null || error "can't stat file"
30015 }
30016 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30017
30018 test_812b() { # LU-12378
30019         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30020                 skip "OST < 2.12.51 doesn't support this fail_loc"
30021
30022         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30023         # ensure ost1 is connected
30024         stat $DIR/$tfile >/dev/null || error "can't stat"
30025         wait_osc_import_state client ost1 FULL
30026         # no locks, no reqs to let the connection idle
30027         cancel_lru_locks osc
30028
30029         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30030 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30031         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30032         wait_osc_import_state client ost1 CONNECTING
30033         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30034
30035         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30036         wait_osc_import_state client ost1 IDLE
30037 }
30038 run_test 812b "do not drop no resend request for idle connect"
30039
30040 test_812c() {
30041         local old
30042
30043         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30044
30045         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30046         $LFS getstripe $DIR/$tfile
30047         $LCTL set_param osc.*.idle_timeout=10
30048         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30049         # ensure ost1 is connected
30050         stat $DIR/$tfile >/dev/null || error "can't stat"
30051         wait_osc_import_state client ost1 FULL
30052         # no locks, no reqs to let the connection idle
30053         cancel_lru_locks osc
30054
30055 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30056         $LCTL set_param fail_loc=0x80000533
30057         sleep 15
30058         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30059 }
30060 run_test 812c "idle import vs lock enqueue race"
30061
30062 test_813() {
30063         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30064         [ -z "$file_heat_sav" ] && skip "no file heat support"
30065
30066         local readsample
30067         local writesample
30068         local readbyte
30069         local writebyte
30070         local readsample1
30071         local writesample1
30072         local readbyte1
30073         local writebyte1
30074
30075         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30076         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30077
30078         $LCTL set_param -n llite.*.file_heat=1
30079         echo "Turn on file heat"
30080         echo "Period second: $period_second, Decay percentage: $decay_pct"
30081
30082         echo "QQQQ" > $DIR/$tfile
30083         echo "QQQQ" > $DIR/$tfile
30084         echo "QQQQ" > $DIR/$tfile
30085         cat $DIR/$tfile > /dev/null
30086         cat $DIR/$tfile > /dev/null
30087         cat $DIR/$tfile > /dev/null
30088         cat $DIR/$tfile > /dev/null
30089
30090         local out=$($LFS heat_get $DIR/$tfile)
30091
30092         $LFS heat_get $DIR/$tfile
30093         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30094         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30095         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30096         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30097
30098         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30099         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30100         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30101         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30102
30103         sleep $((period_second + 3))
30104         echo "Sleep $((period_second + 3)) seconds..."
30105         # The recursion formula to calculate the heat of the file f is as
30106         # follow:
30107         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30108         # Where Hi is the heat value in the period between time points i*I and
30109         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30110         # to the weight of Ci.
30111         out=$($LFS heat_get $DIR/$tfile)
30112         $LFS heat_get $DIR/$tfile
30113         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30114         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30115         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30116         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30117
30118         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30119                 error "read sample ($readsample) is wrong"
30120         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30121                 error "write sample ($writesample) is wrong"
30122         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30123                 error "read bytes ($readbyte) is wrong"
30124         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30125                 error "write bytes ($writebyte) is wrong"
30126
30127         echo "QQQQ" > $DIR/$tfile
30128         echo "QQQQ" > $DIR/$tfile
30129         echo "QQQQ" > $DIR/$tfile
30130         cat $DIR/$tfile > /dev/null
30131         cat $DIR/$tfile > /dev/null
30132         cat $DIR/$tfile > /dev/null
30133         cat $DIR/$tfile > /dev/null
30134
30135         sleep $((period_second + 3))
30136         echo "Sleep $((period_second + 3)) seconds..."
30137
30138         out=$($LFS heat_get $DIR/$tfile)
30139         $LFS heat_get $DIR/$tfile
30140         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30141         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30142         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30143         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30144
30145         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30146                 4 * $decay_pct) / 100") -eq 1 ] ||
30147                 error "read sample ($readsample1) is wrong"
30148         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30149                 3 * $decay_pct) / 100") -eq 1 ] ||
30150                 error "write sample ($writesample1) is wrong"
30151         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30152                 20 * $decay_pct) / 100") -eq 1 ] ||
30153                 error "read bytes ($readbyte1) is wrong"
30154         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30155                 15 * $decay_pct) / 100") -eq 1 ] ||
30156                 error "write bytes ($writebyte1) is wrong"
30157
30158         echo "Turn off file heat for the file $DIR/$tfile"
30159         $LFS heat_set -o $DIR/$tfile
30160
30161         echo "QQQQ" > $DIR/$tfile
30162         echo "QQQQ" > $DIR/$tfile
30163         echo "QQQQ" > $DIR/$tfile
30164         cat $DIR/$tfile > /dev/null
30165         cat $DIR/$tfile > /dev/null
30166         cat $DIR/$tfile > /dev/null
30167         cat $DIR/$tfile > /dev/null
30168
30169         out=$($LFS heat_get $DIR/$tfile)
30170         $LFS heat_get $DIR/$tfile
30171         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30172         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30173         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30174         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30175
30176         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30177         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30178         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30179         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30180
30181         echo "Trun on file heat for the file $DIR/$tfile"
30182         $LFS heat_set -O $DIR/$tfile
30183
30184         echo "QQQQ" > $DIR/$tfile
30185         echo "QQQQ" > $DIR/$tfile
30186         echo "QQQQ" > $DIR/$tfile
30187         cat $DIR/$tfile > /dev/null
30188         cat $DIR/$tfile > /dev/null
30189         cat $DIR/$tfile > /dev/null
30190         cat $DIR/$tfile > /dev/null
30191
30192         out=$($LFS heat_get $DIR/$tfile)
30193         $LFS heat_get $DIR/$tfile
30194         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30195         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30196         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30197         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30198
30199         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30200         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30201         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30202         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30203
30204         $LFS heat_set -c $DIR/$tfile
30205         $LCTL set_param -n llite.*.file_heat=0
30206         echo "Turn off file heat support for the Lustre filesystem"
30207
30208         echo "QQQQ" > $DIR/$tfile
30209         echo "QQQQ" > $DIR/$tfile
30210         echo "QQQQ" > $DIR/$tfile
30211         cat $DIR/$tfile > /dev/null
30212         cat $DIR/$tfile > /dev/null
30213         cat $DIR/$tfile > /dev/null
30214         cat $DIR/$tfile > /dev/null
30215
30216         out=$($LFS heat_get $DIR/$tfile)
30217         $LFS heat_get $DIR/$tfile
30218         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30219         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30220         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30221         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30222
30223         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30224         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30225         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30226         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30227
30228         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30229         rm -f $DIR/$tfile
30230 }
30231 run_test 813 "File heat verfication"
30232
30233 test_814()
30234 {
30235         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30236         echo -n y >> $DIR/$tfile
30237         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30238         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30239 }
30240 run_test 814 "sparse cp works as expected (LU-12361)"
30241
30242 test_815()
30243 {
30244         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30245         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30246 }
30247 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30248
30249 test_816() {
30250         local ost1_imp=$(get_osc_import_name client ost1)
30251         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30252                          cut -d'.' -f2)
30253
30254         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30255         # ensure ost1 is connected
30256
30257         stat $DIR/$tfile >/dev/null || error "can't stat"
30258         wait_osc_import_state client ost1 FULL
30259         # no locks, no reqs to let the connection idle
30260         cancel_lru_locks osc
30261         lru_resize_disable osc
30262         local before
30263         local now
30264         before=$($LCTL get_param -n \
30265                  ldlm.namespaces.$imp_name.lru_size)
30266
30267         wait_osc_import_state client ost1 IDLE
30268         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30269         now=$($LCTL get_param -n \
30270               ldlm.namespaces.$imp_name.lru_size)
30271         [ $before == $now ] || error "lru_size changed $before != $now"
30272 }
30273 run_test 816 "do not reset lru_resize on idle reconnect"
30274
30275 cleanup_817() {
30276         umount $tmpdir
30277         exportfs -u localhost:$DIR/nfsexp
30278         rm -rf $DIR/nfsexp
30279 }
30280
30281 test_817() {
30282         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30283
30284         mkdir -p $DIR/nfsexp
30285         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30286                 error "failed to export nfs"
30287
30288         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30289         stack_trap cleanup_817 EXIT
30290
30291         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30292                 error "failed to mount nfs to $tmpdir"
30293
30294         cp /bin/true $tmpdir
30295         $DIR/nfsexp/true || error "failed to execute 'true' command"
30296 }
30297 run_test 817 "nfsd won't cache write lock for exec file"
30298
30299 test_818() {
30300         test_mkdir -i0 -c1 $DIR/$tdir
30301         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30302         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30303         stop $SINGLEMDS
30304
30305         # restore osp-syn threads
30306         stack_trap "fail $SINGLEMDS"
30307
30308         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30309         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30310         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30311                 error "start $SINGLEMDS failed"
30312         rm -rf $DIR/$tdir
30313
30314         local testid=$(echo $TESTNAME | tr '_' ' ')
30315
30316         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30317                 grep "run LFSCK" || error "run LFSCK is not suggested"
30318 }
30319 run_test 818 "unlink with failed llog"
30320
30321 test_819a() {
30322         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30323         cancel_lru_locks osc
30324         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30325         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30326         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30327         rm -f $TDIR/$tfile
30328 }
30329 run_test 819a "too big niobuf in read"
30330
30331 test_819b() {
30332         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30333         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30334         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30335         cancel_lru_locks osc
30336         sleep 1
30337         rm -f $TDIR/$tfile
30338 }
30339 run_test 819b "too big niobuf in write"
30340
30341
30342 function test_820_start_ost() {
30343         sleep 5
30344
30345         for num in $(seq $OSTCOUNT); do
30346                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30347         done
30348 }
30349
30350 test_820() {
30351         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30352
30353         mkdir $DIR/$tdir
30354         umount_client $MOUNT || error "umount failed"
30355         for num in $(seq $OSTCOUNT); do
30356                 stop ost$num
30357         done
30358
30359         # mount client with no active OSTs
30360         # so that the client can't initialize max LOV EA size
30361         # from OSC notifications
30362         mount_client $MOUNT || error "mount failed"
30363         # delay OST starting to keep this 0 max EA size for a while
30364         test_820_start_ost &
30365
30366         # create a directory on MDS2
30367         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30368                 error "Failed to create directory"
30369         # open intent should update default EA size
30370         # see mdc_update_max_ea_from_body()
30371         # notice this is the very first RPC to MDS2
30372         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30373         ret=$?
30374         echo $out
30375         # With SSK, this situation can lead to -EPERM being returned.
30376         # In that case, simply retry.
30377         if [ $ret -ne 0 ] && $SHARED_KEY; then
30378                 if echo "$out" | grep -q "not permitted"; then
30379                         cp /etc/services $DIR/$tdir/mds2
30380                         ret=$?
30381                 fi
30382         fi
30383         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30384 }
30385 run_test 820 "update max EA from open intent"
30386
30387 test_823() {
30388         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30389         local OST_MAX_PRECREATE=20000
30390
30391         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30392                 skip "Need MDS version at least 2.14.56"
30393
30394         save_lustre_params mds1 \
30395                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30396         do_facet $SINGLEMDS "$LCTL set_param -n \
30397                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30398         do_facet $SINGLEMDS "$LCTL set_param -n \
30399                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30400
30401         stack_trap "restore_lustre_params < $p; rm $p"
30402
30403         do_facet $SINGLEMDS "$LCTL set_param -n \
30404                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30405
30406         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30407                       osp.$FSNAME-OST0000*MDT0000.create_count")
30408         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30409                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30410         local expect_count=$(((($max/2)/256) * 256))
30411
30412         log "setting create_count to 100200:"
30413         log " -result- count: $count with max: $max, expecting: $expect_count"
30414
30415         [[ $count -eq expect_count ]] ||
30416                 error "Create count not set to max precreate."
30417 }
30418 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30419
30420 test_831() {
30421         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30422                 skip "Need MDS version 2.14.56"
30423
30424         local sync_changes=$(do_facet $SINGLEMDS \
30425                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30426
30427         [ "$sync_changes" -gt 100 ] &&
30428                 skip "Sync changes $sync_changes > 100 already"
30429
30430         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30431
30432         $LFS mkdir -i 0 $DIR/$tdir
30433         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30434
30435         save_lustre_params mds1 \
30436                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30437         save_lustre_params mds1 \
30438                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30439
30440         do_facet mds1 "$LCTL set_param -n \
30441                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30442                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30443         stack_trap "restore_lustre_params < $p" EXIT
30444
30445         createmany -o $DIR/$tdir/f- 1000
30446         unlinkmany $DIR/$tdir/f- 1000 &
30447         local UNLINK_PID=$!
30448
30449         while sleep 1; do
30450                 sync_changes=$(do_facet mds1 \
30451                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30452                 # the check in the code is racy, fail the test
30453                 # if the value above the limit by 10.
30454                 [ $sync_changes -gt 110 ] && {
30455                         kill -2 $UNLINK_PID
30456                         wait
30457                         error "osp changes throttling failed, $sync_changes>110"
30458                 }
30459                 kill -0 $UNLINK_PID 2> /dev/null || break
30460         done
30461         wait
30462 }
30463 run_test 831 "throttling unlink/setattr queuing on OSP"
30464
30465 test_832() {
30466         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30467         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30468                 skip "Need MDS version 2.15.52+"
30469         is_rmentry_supported || skip "rm_entry not supported"
30470
30471         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30472         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30473         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30474                 error "mkdir remote_dir failed"
30475         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30476                 error "mkdir striped_dir failed"
30477         touch $DIR/$tdir/file || error "touch file failed"
30478         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30479         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30480 }
30481 run_test 832 "lfs rm_entry"
30482
30483 test_833() {
30484         local file=$DIR/$tfile
30485
30486         stack_trap "rm -f $file" EXIT
30487         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30488
30489         local wpid
30490         local rpid
30491         local rpid2
30492
30493         # Buffered I/O write
30494         (
30495                 while [ ! -e $DIR/sanity.833.lck ]; do
30496                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30497                                 error "failed to write $file"
30498                         sleep 0.$((RANDOM % 4 + 1))
30499                 done
30500         )&
30501         wpid=$!
30502
30503         # Buffered I/O read
30504         (
30505                 while [ ! -e $DIR/sanity.833.lck ]; do
30506                         dd if=$file of=/dev/null bs=1M count=50 ||
30507                                 error "failed to read $file"
30508                         sleep 0.$((RANDOM % 4 + 1))
30509                 done
30510         )&
30511         rpid=$!
30512
30513         # Direct I/O read
30514         (
30515                 while [ ! -e $DIR/sanity.833.lck ]; do
30516                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30517                                 error "failed to read $file in direct I/O mode"
30518                         sleep 0.$((RANDOM % 4 + 1))
30519                 done
30520         )&
30521         rpid2=$!
30522
30523         sleep 30
30524         touch $DIR/sanity.833.lck
30525         wait $wpid || error "$?: buffered write failed"
30526         wait $rpid || error "$?: buffered read failed"
30527         wait $rpid2 || error "$?: direct read failed"
30528 }
30529 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
30530
30531 #
30532 # tests that do cleanup/setup should be run at the end
30533 #
30534
30535 test_900() {
30536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30537         local ls
30538
30539         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
30540         $LCTL set_param fail_loc=0x903
30541
30542         cancel_lru_locks MGC
30543
30544         FAIL_ON_ERROR=true cleanup
30545         FAIL_ON_ERROR=true setup
30546 }
30547 run_test 900 "umount should not race with any mgc requeue thread"
30548
30549 # LUS-6253/LU-11185
30550 test_901() {
30551         local old
30552         local count
30553         local oldc
30554         local newc
30555         local olds
30556         local news
30557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30558
30559         # some get_param have a bug to handle dot in param name
30560         cancel_lru_locks MGC
30561         old=$(mount -t lustre | wc -l)
30562         # 1 config+sptlrpc
30563         # 2 params
30564         # 3 nodemap
30565         # 4 IR
30566         old=$((old * 4))
30567         oldc=0
30568         count=0
30569         while [ $old -ne $oldc ]; do
30570                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30571                 sleep 1
30572                 ((count++))
30573                 if [ $count -ge $TIMEOUT ]; then
30574                         error "too large timeout"
30575                 fi
30576         done
30577         umount_client $MOUNT || error "umount failed"
30578         mount_client $MOUNT || error "mount failed"
30579         cancel_lru_locks MGC
30580         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
30581
30582         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
30583
30584         return 0
30585 }
30586 run_test 901 "don't leak a mgc lock on client umount"
30587
30588 # LU-13377
30589 test_902() {
30590         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
30591                 skip "client does not have LU-13377 fix"
30592         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
30593         $LCTL set_param fail_loc=0x1415
30594         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30595         cancel_lru_locks osc
30596         rm -f $DIR/$tfile
30597 }
30598 run_test 902 "test short write doesn't hang lustre"
30599
30600 # LU-14711
30601 test_903() {
30602         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
30603         echo "blah" > $DIR/${tfile}-2
30604         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
30605         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
30606         $LCTL set_param fail_loc=0x417 fail_val=20
30607
30608         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
30609         sleep 1 # To start the destroy
30610         wait_destroy_complete 150 || error "Destroy taking too long"
30611         cat $DIR/$tfile > /dev/null || error "Evicted"
30612 }
30613 run_test 903 "Test long page discard does not cause evictions"
30614
30615 test_904() {
30616         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
30617         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
30618                 grep -q project || skip "skip project quota not supported"
30619
30620         local testfile="$DIR/$tdir/$tfile"
30621         local xattr="trusted.projid"
30622         local projid
30623         local mdts=$(comma_list $(mdts_nodes))
30624         local saved=$(do_facet mds1 $LCTL get_param -n \
30625                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
30626
30627         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
30628         stack_trap "do_nodes $mdts $LCTL set_param \
30629                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
30630
30631         mkdir -p $DIR/$tdir
30632         touch $testfile
30633         #hide projid xattr on server
30634         $LFS project -p 1 $testfile ||
30635                 error "set $testfile project id failed"
30636         getfattr -m - $testfile | grep $xattr &&
30637                 error "do not show trusted.projid when disabled on server"
30638         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
30639         #should be hidden when projid is 0
30640         $LFS project -p 0 $testfile ||
30641                 error "set $testfile project id failed"
30642         getfattr -m - $testfile | grep $xattr &&
30643                 error "do not show trusted.projid with project ID 0"
30644
30645         #still can getxattr explicitly
30646         projid=$(getfattr -n $xattr $testfile |
30647                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30648         [ $projid == "0" ] ||
30649                 error "projid expected 0 not $projid"
30650
30651         #set the projid via setxattr
30652         setfattr -n $xattr -v "1000" $testfile ||
30653                 error "setattr failed with $?"
30654         projid=($($LFS project $testfile))
30655         [ ${projid[0]} == "1000" ] ||
30656                 error "projid expected 1000 not $projid"
30657
30658         #check the new projid via getxattr
30659         $LFS project -p 1001 $testfile ||
30660                 error "set $testfile project id failed"
30661         getfattr -m - $testfile | grep $xattr ||
30662                 error "should show trusted.projid when project ID != 0"
30663         projid=$(getfattr -n $xattr $testfile |
30664                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30665         [ $projid == "1001" ] ||
30666                 error "projid expected 1001 not $projid"
30667
30668         #try to set invalid projid
30669         setfattr -n $xattr -v "4294967295" $testfile &&
30670                 error "set invalid projid should fail"
30671
30672         #remove the xattr means setting projid to 0
30673         setfattr -x $xattr $testfile ||
30674                 error "setfattr failed with $?"
30675         projid=($($LFS project $testfile))
30676         [ ${projid[0]} == "0" ] ||
30677                 error "projid expected 0 not $projid"
30678
30679         #should be hidden when parent has inherit flag and same projid
30680         $LFS project -srp 1002 $DIR/$tdir ||
30681                 error "set $tdir project id failed"
30682         getfattr -m - $testfile | grep $xattr &&
30683                 error "do not show trusted.projid with inherit flag"
30684
30685         #still can getxattr explicitly
30686         projid=$(getfattr -n $xattr $testfile |
30687                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
30688         [ $projid == "1002" ] ||
30689                 error "projid expected 1002 not $projid"
30690 }
30691 run_test 904 "virtual project ID xattr"
30692
30693 # LU-8582
30694 test_905() {
30695         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
30696                 skip "need OST version >= 2.15.50.220 for fail_loc"
30697
30698         remote_ost_nodsh && skip "remote OST with nodsh"
30699         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
30700
30701         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
30702
30703         #define OBD_FAIL_OST_OPCODE 0x253
30704         # OST_LADVISE = 21
30705         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
30706         $LFS ladvise -a willread $DIR/$tfile &&
30707                 error "unexpected success of ladvise with fault injection"
30708         $LFS ladvise -a willread $DIR/$tfile |&
30709                 grep -q "Operation not supported"
30710         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
30711 }
30712 run_test 905 "bad or new opcode should not stuck client"
30713
30714 test_906() {
30715         grep -q io_uring_setup /proc/kallsyms ||
30716                 skip "Client OS does not support io_uring I/O engine"
30717         io_uring_probe || skip "kernel does not support io_uring fully"
30718         which fio || skip_env "no fio installed"
30719         fio --enghelp | grep -q io_uring ||
30720                 skip_env "fio does not support io_uring I/O engine"
30721
30722         local file=$DIR/$tfile
30723         local ioengine="io_uring"
30724         local numjobs=2
30725         local size=50M
30726
30727         fio --name=seqwrite --ioengine=$ioengine        \
30728                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30729                 --iodepth=64 --size=$size --filename=$file --rw=write ||
30730                 error "fio seqwrite $file failed"
30731
30732         fio --name=seqread --ioengine=$ioengine \
30733                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
30734                 --iodepth=64 --size=$size --filename=$file --rw=read ||
30735                 error "fio seqread $file failed"
30736
30737         rm -f $file || error "rm -f $file failed"
30738 }
30739 run_test 906 "Simple test for io_uring I/O engine via fio"
30740
30741 complete_test $SECONDS
30742 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
30743 check_and_cleanup_lustre
30744 if [ "$I_MOUNTED" != "yes" ]; then
30745         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
30746 fi
30747 exit_status